Skip to content

Commit 818e81a

Browse files
committed
feat: added per-player toggle to redirect chat into ftb teams chat
* `/ftbteams redirect_chat` command * toggle button on the teams GUI FTBTeam/FTB-Mods-Issues#1768
1 parent f978100 commit 818e81a

File tree

13 files changed

+199
-4
lines changed

13 files changed

+199
-4
lines changed

common/src/main/java/dev/ftb/mods/ftbteams/FTBTeams.java

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
package dev.ftb.mods.ftbteams;
22

33
import com.mojang.brigadier.CommandDispatcher;
4+
import dev.architectury.event.EventResult;
5+
import dev.architectury.event.events.common.ChatEvent;
46
import dev.architectury.event.events.common.CommandRegistrationEvent;
57
import dev.architectury.event.events.common.LifecycleEvent;
68
import dev.architectury.event.events.common.PlayerEvent;
@@ -18,11 +20,13 @@
1820
import net.minecraft.commands.CommandBuildContext;
1921
import net.minecraft.commands.CommandSourceStack;
2022
import net.minecraft.commands.Commands;
23+
import net.minecraft.network.chat.Component;
2124
import net.minecraft.server.MinecraftServer;
2225
import net.minecraft.server.level.ServerLevel;
2326
import net.minecraft.server.level.ServerPlayer;
2427
import org.apache.logging.log4j.LogManager;
2528
import org.apache.logging.log4j.Logger;
29+
import org.jetbrains.annotations.Nullable;
2630

2731
public class FTBTeams {
2832
public static final Logger LOGGER = LogManager.getLogger(FTBTeamsAPI.MOD_NAME);
@@ -37,6 +41,7 @@ public FTBTeams() {
3741
TeamEvent.COLLECT_PROPERTIES.register(this::teamConfig);
3842
PlayerEvent.PLAYER_JOIN.register(this::playerLoggedIn);
3943
PlayerEvent.PLAYER_QUIT.register(this::playerLoggedOut);
44+
ChatEvent.RECEIVED.register(this::chatReceived);
4045

4146
EnvExecutor.runInEnv(Env.CLIENT, () -> FTBTeamsClient::init);
4247

@@ -83,4 +88,14 @@ private void playerLoggedOut(ServerPlayer player) {
8388
TeamManagerImpl.INSTANCE.playerLoggedOut(player);
8489
}
8590
}
91+
92+
private EventResult chatReceived(@Nullable ServerPlayer player, Component component) {
93+
if (TeamManagerImpl.INSTANCE != null && player != null && TeamManagerImpl.INSTANCE.isChatRedirected(player)) {
94+
return FTBTeamsAPI.api().getManager().getTeamForPlayer(player).map(team -> {
95+
team.sendMessage(player.getUUID(), component);
96+
return EventResult.interruptFalse();
97+
}).orElse(EventResult.pass());
98+
}
99+
return EventResult.pass();
100+
}
86101
}

common/src/main/java/dev/ftb/mods/ftbteams/api/Team.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,14 @@ default boolean isServerTeam() {
137137
*/
138138
void sendMessage(UUID senderId, String message);
139139

140+
/**
141+
* Send a team message to this team. This is a no-op if called on a client-side team.
142+
*
143+
* @param senderId UUID of the player sending the message
144+
* @param message the message text
145+
*/
146+
void sendMessage(UUID senderId, Component message);
147+
140148
/**
141149
* Return a nicely marked-up block of text info for this team, for display purposes.
142150
*

common/src/main/java/dev/ftb/mods/ftbteams/api/TeamManager.java

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,4 +125,22 @@ public interface TeamManager {
125125
* most commonly that the player is already in a party
126126
*/
127127
Team createPartyTeam(ServerPlayer player, String name, @Nullable String description, @Nullable Color4I color) throws CommandSyntaxException;
128+
129+
/**
130+
* Set chat redirection for the given player. When chat redirection is enabled, all chat messages from the player
131+
* are instead sent to FTB Teams team chat, to be seen by the player's team only.
132+
*
133+
* @param player the player
134+
* @param redirected true if messages should go to team chat, false if they should be broadcast as normal
135+
*/
136+
void setChatRedirected(ServerPlayer player, boolean redirected);
137+
138+
/**
139+
* {@return true if messages should go to team chat, false if they should be broadcast as normal}
140+
* See {@link #setChatRedirected(ServerPlayer, boolean)} for more information.
141+
*
142+
* @param player the player
143+
*/
144+
boolean isChatRedirected(ServerPlayer player);
145+
128146
}

common/src/main/java/dev/ftb/mods/ftbteams/client/FTBTeamsClient.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ public class FTBTeamsClient {
2525
public static final ResourceLocation OPEN_GUI_ID = FTBTeamsAPI.rl("open_gui");
2626

2727
public static KeyMapping openTeamsKey;
28+
private static boolean chatRedirected = false;
2829

2930
public static void init() {
3031
registerKeys();
@@ -85,4 +86,12 @@ public static void updatePresence(KnownClientPlayer update) {
8586
ClientTeamManagerImpl.getInstance().updatePresence(update);
8687
}
8788
}
89+
90+
public static void setChatRedirected(boolean chatRedirected) {
91+
FTBTeamsClient.chatRedirected = chatRedirected;
92+
}
93+
94+
public static boolean isChatRedirected() {
95+
return chatRedirected;
96+
}
8897
}

common/src/main/java/dev/ftb/mods/ftbteams/client/gui/MyTeamScreen.java

Lines changed: 35 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
import dev.ftb.mods.ftblibrary.ui.*;
1010
import dev.ftb.mods.ftblibrary.ui.input.Key;
1111
import dev.ftb.mods.ftblibrary.ui.misc.NordColors;
12+
import dev.ftb.mods.ftblibrary.util.NetworkHelper;
1213
import dev.ftb.mods.ftblibrary.util.TooltipList;
1314
import dev.ftb.mods.ftbteams.api.FTBTeamsAPI;
1415
import dev.ftb.mods.ftbteams.api.Team;
@@ -18,8 +19,10 @@
1819
import dev.ftb.mods.ftbteams.api.client.KnownClientPlayer;
1920
import dev.ftb.mods.ftbteams.api.property.TeamProperties;
2021
import dev.ftb.mods.ftbteams.api.property.TeamPropertyCollection;
22+
import dev.ftb.mods.ftbteams.client.FTBTeamsClient;
2123
import dev.ftb.mods.ftbteams.data.*;
2224
import dev.ftb.mods.ftbteams.net.SendMessageMessage;
25+
import dev.ftb.mods.ftbteams.net.ToggleChatRedirectionMessage;
2326
import dev.ftb.mods.ftbteams.net.UpdatePropertiesRequestMessage;
2427
import net.minecraft.ChatFormatting;
2528
import net.minecraft.Util;
@@ -39,6 +42,7 @@ public class MyTeamScreen extends BaseScreen implements NordColors {
3942
private Button infoButton;
4043
private Button missingDataButton;
4144
private Button colorButton;
45+
private Button toggleChatButton;
4246
private Button inviteButton;
4347
private Button allyButton;
4448
private Panel memberPanel;
@@ -80,7 +84,6 @@ public boolean onInit() {
8084

8185
@Override
8286
public void addWidgets() {
83-
8487
add(settingsButton = new SettingsButton());
8588

8689
add(infoButton = new SimpleButton(this, Component.empty(), Icons.INFO, (w,mb) -> {}) {
@@ -127,6 +130,7 @@ public void draw(GuiGraphics graphics, Theme theme, int x, int y, int w, int h)
127130
}
128131
});
129132

133+
add(toggleChatButton = new ToggleChatButton(this));
130134
add(inviteButton = new InviteButton(this));
131135
add(allyButton = new AllyButton(this));
132136

@@ -146,6 +150,7 @@ public void alignWidgets() {
146150
settingsButton.setPosAndSize(width - 19, 3, 16, 16);
147151
inviteButton.setPosAndSize(width - 37, 3, 16, 16);
148152
allyButton.setPosAndSize(width - 55, 3, 16, 16);
153+
toggleChatButton.setPosAndSize(width - 73, 3, 16, 16);
149154

150155
memberPanel.setPosAndSize(1, 22, Math.max(memberPanel.width, MIN_MEMBER_PANEL_WIDTH), height - 23);
151156
}
@@ -229,6 +234,35 @@ public boolean shouldDraw() {
229234
}
230235
}
231236

237+
private static class ToggleChatButton extends SimpleButton {
238+
public ToggleChatButton(Panel panel) {
239+
super(panel, Component.translatable("ftbteams.gui.toggle_chat"), Icons.CHAT,
240+
(b, mb) -> NetworkManager.sendToServer(ToggleChatRedirectionMessage.INSTANCE)
241+
);
242+
}
243+
244+
@Override
245+
public void addMouseOverText(TooltipList list) {
246+
list.add(Component.translatable("ftbteams.message.chat_redirected." + (FTBTeamsClient.isChatRedirected() ? "on" : "off")));
247+
list.add(Component.translatable("ftbteams.gui.toggle_chat").withStyle(ChatFormatting.GRAY));
248+
}
249+
250+
@Override
251+
public void tick() {
252+
setIcon(FTBTeamsClient.isChatRedirected() ? Icons.CHAT.withTint(Color4I.rgb(0xFFA060)) : Icons.CHAT);
253+
}
254+
255+
@Override
256+
public boolean isEnabled() {
257+
return ClientTeamManagerImpl.getInstance().selfTeam().getType() == TeamType.PARTY;
258+
}
259+
260+
@Override
261+
public boolean shouldDraw() {
262+
return isEnabled();
263+
}
264+
}
265+
232266
private class ChatPanel extends Panel {
233267
public ChatPanel() {
234268
super(MyTeamScreen.this);

common/src/main/java/dev/ftb/mods/ftbteams/data/AbstractTeam.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -237,7 +237,8 @@ public void sendMessage(UUID senderId, String message) {
237237
sendMessage(senderId, TextComponentUtils.withLinks(message));
238238
}
239239

240-
void sendMessage(UUID from, Component text) {
240+
@Override
241+
public void sendMessage(UUID from, Component text) {
241242
addMessage(FTBTeamsAPI.api().createMessage(from, text));
242243

243244
MutableComponent component = Component.literal("<");

common/src/main/java/dev/ftb/mods/ftbteams/data/ClientTeam.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,11 @@ public void sendMessage(UUID senderId, String message) {
7171
// no-op
7272
}
7373

74+
@Override
75+
public void sendMessage(UUID senderId, Component message) {
76+
// no-op
77+
}
78+
7479
@Override
7580
public List<Component> getTeamInfo() {
7681
return List.of();

common/src/main/java/dev/ftb/mods/ftbteams/data/FTBTeamsCommands.java

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
import dev.ftb.mods.ftbteams.FTBTeamsAPIImpl;
1212
import dev.ftb.mods.ftbteams.api.FTBTeamsAPI;
1313
import dev.ftb.mods.ftbteams.api.Team;
14+
import dev.ftb.mods.ftbteams.api.TeamManager;
1415
import dev.ftb.mods.ftbteams.api.TeamRank;
1516
import dev.ftb.mods.ftbteams.api.event.TeamEvent;
1617
import dev.ftb.mods.ftbteams.api.event.TeamInfoEvent;
@@ -178,6 +179,9 @@ public void register(CommandDispatcher<CommandSourceStack> dispatcher) {
178179
.executes(ctx -> partyTeamArg(ctx, TeamRank.NONE).forceDisband(ctx.getSource()))
179180
)
180181
)
182+
.then(Commands.literal("redirect_chat")
183+
.executes(FTBTeamsCommands::redirectChatToggle)
184+
)
181185
);
182186

183187
if (Platform.isDevelopmentEnvironment()) {
@@ -312,6 +316,15 @@ private int list(CommandSourceStack source, Predicate<Team> predicate) {
312316
return Command.SINGLE_SUCCESS;
313317
}
314318

319+
private static int redirectChatToggle(CommandContext<CommandSourceStack> ctx) throws CommandSyntaxException {
320+
ServerPlayer player = ctx.getSource().getPlayerOrException();
321+
TeamManager mgr = FTBTeamsAPI.api().getManager();
322+
mgr.setChatRedirected(player, !mgr.isChatRedirected(player));
323+
String key = "ftbteams.message.chat_redirected." + (mgr.isChatRedirected(player) ? "on" : "off");
324+
ctx.getSource().sendSuccess(() -> Component.translatable(key).withStyle(ChatFormatting.ITALIC, ChatFormatting.GOLD), false);
325+
return Command.SINGLE_SUCCESS;
326+
}
327+
315328
private int addFakePlayer(Collection<GameProfile> profiles) {
316329
for (GameProfile profile : profiles) {
317330
TeamManagerImpl.INSTANCE.playerLoggedIn(null, profile.getId(), profile.getName());

common/src/main/java/dev/ftb/mods/ftbteams/data/TeamManagerImpl.java

Lines changed: 32 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
package dev.ftb.mods.ftbteams.data;
22

3-
import com.google.common.collect.ImmutableList;
43
import com.mojang.brigadier.Command;
54
import com.mojang.brigadier.exceptions.CommandSyntaxException;
65
import dev.architectury.networking.NetworkManager;
76
import dev.ftb.mods.ftblibrary.icon.Color4I;
87
import dev.ftb.mods.ftblibrary.snbt.SNBT;
98
import dev.ftb.mods.ftblibrary.snbt.SNBTCompoundTag;
9+
import dev.ftb.mods.ftblibrary.util.NetworkHelper;
1010
import dev.ftb.mods.ftbteams.FTBTeams;
1111
import dev.ftb.mods.ftbteams.api.Team;
1212
import dev.ftb.mods.ftbteams.api.TeamManager;
@@ -17,11 +17,15 @@
1717
import dev.ftb.mods.ftbteams.api.property.TeamProperties;
1818
import dev.ftb.mods.ftbteams.net.SyncMessageHistoryMessage;
1919
import dev.ftb.mods.ftbteams.net.SyncTeamsMessage;
20+
import dev.ftb.mods.ftbteams.net.ToggleChatResponseMessage;
2021
import net.minecraft.ChatFormatting;
2122
import net.minecraft.Util;
2223
import net.minecraft.commands.CommandSourceStack;
2324
import net.minecraft.core.UUIDUtil;
2425
import net.minecraft.nbt.CompoundTag;
26+
import net.minecraft.nbt.ListTag;
27+
import net.minecraft.nbt.StringTag;
28+
import net.minecraft.nbt.Tag;
2529
import net.minecraft.network.chat.Component;
2630
import net.minecraft.server.MinecraftServer;
2731
import net.minecraft.server.level.ServerPlayer;
@@ -48,6 +52,7 @@ public class TeamManagerImpl implements TeamManager {
4852
private boolean shouldSave;
4953
private final Map<UUID, PlayerTeam> knownPlayers;
5054
private final Map<UUID, AbstractTeam> teamMap;
55+
private final Set<UUID> chatRedirected;
5156
Map<String, Team> nameMap;
5257
private CompoundTag extraData;
5358

@@ -56,6 +61,7 @@ public TeamManagerImpl(MinecraftServer s) {
5661
knownPlayers = new LinkedHashMap<>();
5762
teamMap = new LinkedHashMap<>();
5863
extraData = new CompoundTag();
64+
chatRedirected = new HashSet<>();
5965
}
6066

6167
@Override
@@ -130,7 +136,7 @@ public Optional<Team> getTeamForPlayer(ServerPlayer player) {
130136
@Override
131137
public boolean arePlayersInSameTeam(UUID id1, UUID id2) {
132138
return getTeamForPlayerID(id1).map(team1 -> getTeamForPlayerID(id2)
133-
.map(team2 -> team1.getId().equals(team2.getId())).orElse(false))
139+
.map(team2 -> team1.getId().equals(team2.getId())).orElse(false))
134140
.orElse(false);
135141
}
136142

@@ -151,6 +157,15 @@ public void load() {
151157

152158
extraData = dataFileTag.getCompoundOrEmpty("extra");
153159
TeamManagerEvent.LOADED.invoker().accept(new TeamManagerEvent(this));
160+
161+
chatRedirected.clear();
162+
dataFileTag.getList("chat_redirected", Tag.TAG_STRING).forEach(tag -> {
163+
try {
164+
chatRedirected.add(UUID.fromString(tag.getAsString()));
165+
} catch (IllegalArgumentException e) {
166+
FTBTeams.LOGGER.error("invalid uuid {} in 'chat_redirection', ignoring", tag.getAsString());
167+
}
168+
});
154169
}
155170

156171
for (TeamType type : TeamType.values()) {
@@ -230,6 +245,7 @@ public SNBTCompoundTag serializeNBT() {
230245
SNBTCompoundTag nbt = new SNBTCompoundTag();
231246
nbt.store("id", UUIDUtil.CODEC, getId());
232247
nbt.put("extra", extraData);
248+
nbt.put("chat_redirected", Util.make(new ListTag(), l -> chatRedirected.forEach(id -> l.add(StringTag.valueOf(id.toString())))));
233249
return nbt;
234250
}
235251

@@ -336,6 +352,7 @@ public void syncAllToPlayer(ServerPlayer player, AbstractTeam selfTeam) {
336352

337353
NetworkManager.sendToPlayer(player, new SyncTeamsMessage(manager.setSelfTeamId(selfTeam.id), selfTeam.getTeamId(), true));
338354
NetworkManager.sendToPlayer(player, SyncMessageHistoryMessage.forTeam(selfTeam));
355+
NetworkManager.sendToPlayer(player, new ToggleChatResponseMessage(isChatRedirected(player)));
339356
server.getPlayerList().sendPlayerPermissionLevel(player);
340357
}
341358

@@ -366,6 +383,19 @@ public Team createPartyTeam(ServerPlayer player, String name, @Nullable String d
366383
return res.getRight();
367384
}
368385

386+
@Override
387+
public void setChatRedirected(ServerPlayer player, boolean redirect) {
388+
if (redirect && chatRedirected.add(player.getUUID()) || !redirect && chatRedirected.remove(player.getUUID())) {
389+
NetworkHelper.sendTo(player, new ToggleChatResponseMessage(redirect));
390+
shouldSave = true;
391+
}
392+
}
393+
394+
@Override
395+
public boolean isChatRedirected(ServerPlayer player) {
396+
return chatRedirected.contains(player.getUUID());
397+
}
398+
369399
// Command Handlers //
370400

371401
public Pair<Integer, PartyTeam> createParty(ServerPlayer player, String name) throws CommandSyntaxException {

common/src/main/java/dev/ftb/mods/ftbteams/net/FTBTeamsNet.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,13 @@ public static void register() {
1010
NetworkHelper.registerS2C(UpdatePropertiesResponseMessage.TYPE, UpdatePropertiesResponseMessage.STREAM_CODEC, UpdatePropertiesResponseMessage::handle);
1111
NetworkHelper.registerS2C(SendMessageResponseMessage.TYPE, SendMessageResponseMessage.STREAM_CODEC, SendMessageResponseMessage::handle);
1212
NetworkHelper.registerS2C(UpdatePresenceMessage.TYPE, UpdatePresenceMessage.STREAM_CODEC, UpdatePresenceMessage::handle);
13+
NetworkHelper.registerS2C(ToggleChatResponseMessage.TYPE, ToggleChatResponseMessage.STREAM_CODEC, ToggleChatResponseMessage::handle);
1314

1415
NetworkHelper.registerC2S(OpenGUIMessage.TYPE, OpenGUIMessage.STREAM_CODEC, OpenGUIMessage::handle);
1516
NetworkHelper.registerC2S(UpdatePropertiesRequestMessage.TYPE, UpdatePropertiesRequestMessage.STREAM_CODEC, UpdatePropertiesRequestMessage::handle);
1617
NetworkHelper.registerC2S(SendMessageMessage.TYPE, SendMessageMessage.STREAM_CODEC, SendMessageMessage::handle);
1718
NetworkHelper.registerC2S(CreatePartyMessage.TYPE, CreatePartyMessage.STREAM_CODEC, CreatePartyMessage::handle);
1819
NetworkHelper.registerC2S(PlayerGUIOperationMessage.TYPE, PlayerGUIOperationMessage.STREAM_CODEC, PlayerGUIOperationMessage::handle);
20+
NetworkHelper.registerC2S(ToggleChatRedirectionMessage.TYPE, ToggleChatRedirectionMessage.STREAM_CODEC, ToggleChatRedirectionMessage::handle);
1921
}
2022
}

0 commit comments

Comments
 (0)