diff --git a/src/main/java/io/github/meatwo310/tsukichat/event/ServerChat.java b/src/main/java/io/github/meatwo310/tsukichat/event/ServerChat.java index c1b2e6f..3966e55 100644 --- a/src/main/java/io/github/meatwo310/tsukichat/event/ServerChat.java +++ b/src/main/java/io/github/meatwo310/tsukichat/event/ServerChat.java @@ -6,13 +6,14 @@ import io.github.meatwo310.tsukichat.config.CommonConfigs; import io.github.meatwo310.tsukichat.util.ChatCustomizer; import io.github.meatwo310.tsukichat.util.PlayerNbtUtil; -import net.minecraft.core.RegistryAccess; +import net.minecraft.FieldsAreNonnullByDefault; import net.minecraft.nbt.CompoundTag; -import net.minecraft.network.chat.*; +import net.minecraft.network.chat.ClickEvent; +import net.minecraft.network.chat.Component; +import net.minecraft.network.chat.HoverEvent; +import net.minecraft.network.chat.Style; import net.minecraft.server.MinecraftServer; -import net.minecraft.server.commands.TeamMsgCommand; import net.minecraft.server.level.ServerPlayer; -import net.minecraft.server.players.PlayerList; import net.minecraft.world.entity.Entity; import net.minecraft.world.scores.PlayerTeam; import net.minecraftforge.event.ServerChatEvent; @@ -20,12 +21,20 @@ import net.minecraftforge.eventbus.api.SubscribeEvent; import net.minecraftforge.fml.common.Mod; +import javax.annotation.ParametersAreNonnullByDefault; +import java.util.ArrayList; import java.util.LinkedHashMap; import java.util.List; import java.util.Set; +@ParametersAreNonnullByDefault +@FieldsAreNonnullByDefault @Mod.EventBusSubscriber(modid = TsukiChat.MODID, bus = Mod.EventBusSubscriber.Bus.FORGE) public class ServerChat { + private static final Style TEAMMSG_SUGGEST_STYLE = Style.EMPTY + .withHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, Component.translatable("chat.type.team.hover"))) + .withClickEvent(new ClickEvent(ClickEvent.Action.SUGGEST_COMMAND, "/teammsg ")); + @SubscribeEvent(priority = EventPriority.HIGHEST) public static void onChat(ServerChatEvent event) { ServerPlayer player = event.getPlayer(); @@ -85,45 +94,33 @@ private static void sendTeamMessage(ServerPlayer sender, String message) throws var serverDictionary = ServerDictionaryCommand.getServerDictionary(); var result = ChatCustomizer.recognizeChat(message, playerTags, userDictionary, serverDictionary); - -// result.ifMessagePresent(s -> event.setMessage(Component.literal(s))); -// result.ifDeferredMessagePresent(s -> -// player.server.getPlayerList().broadcastSystemMessage(Component.literal(s), false) -// ); -// -// var chatMessage = PlayerChatMessage.unsigned(sender.getUUID(), message); var converted = result.getMessageSynced(); - var chatMessage = PlayerChatMessage.unsigned(sender.getUUID(), converted == null ? message : converted); - sendTeamMessage(sender, team, recipients, chatMessage); + sendTeamMessage(server, sender, team, recipients, converted == null ? message : converted); } + public static void sendTeamMessage(MinecraftServer server, ServerPlayer sender, PlayerTeam team, List recipients, String message) { + int forwardLevel = CommonConfigs.forwardTeamMsgLevel.get(); + ArrayList listModified = new ArrayList<>(recipients); + if (forwardLevel >= 0) listModified.addAll(server.getPlayerList().getPlayers().stream() + .filter(player -> player.hasPermissions(forwardLevel) && !listModified.contains(player)) + .toList() + ); - private static void sendTeamMessage(ServerPlayer sender, PlayerTeam team, List recipients, PlayerChatMessage chatMessage) { - Component teamDisplayName = team.getFormattedDisplayName(); - Component senderName = sender.getDisplayName(); - RegistryAccess.Frozen registryAccess = sender.server.registryAccess(); - ChatType.Bound incomingChatType = ChatType.bind(ChatType.TEAM_MSG_COMMAND_INCOMING, registryAccess, senderName).withTargetName(teamDisplayName); - ChatType.Bound outgoingChatType = ChatType.bind(ChatType.TEAM_MSG_COMMAND_OUTGOING, registryAccess, senderName).withTargetName(teamDisplayName); - OutgoingChatMessage outgoingMessage = OutgoingChatMessage.create(chatMessage); - boolean anyMessageFullyFiltered = false; - - for (ServerPlayer recipient : recipients) { - var chatType = recipient == sender ? outgoingChatType : incomingChatType; - boolean shouldFilter = shouldFilterMessage(sender, recipient); - recipient.sendChatMessage(outgoingMessage, shouldFilter, chatType); - anyMessageFullyFiltered |= shouldFilter && chatMessage.isFullyFiltered(); - } - - if (anyMessageFullyFiltered) { - sender.sendSystemMessage(PlayerList.CHAT_FILTERED_FULL); + var teamComponent = team.getFormattedDisplayName().withStyle(TEAMMSG_SUGGEST_STYLE); + var senderComponent = sender.getDisplayName(); + var component = Component + .literal("-> ") + .append(teamComponent) + .append(" <") + .append(senderComponent) + .append("> ") + .append(message); + + for (ServerPlayer serverPlayer : listModified) { + serverPlayer.sendSystemMessage(component); } } - private static boolean shouldFilterMessage(ServerPlayer sender, ServerPlayer recipient) { - if (sender == recipient) return false; - return sender != null && sender.isTextFilteringEnabled() || recipient.isTextFilteringEnabled(); - } - private static class NotOnTeamException extends RuntimeException { public NotOnTeamException(Entity entity) { super("Entity " + entity.getName().getString() + " is not on a team."); diff --git a/src/main/java/io/github/meatwo310/tsukichat/mixin/TeamMsgCommandMixin.java b/src/main/java/io/github/meatwo310/tsukichat/mixin/TeamMsgCommandMixin.java index 702a4ca..ecaf1e7 100644 --- a/src/main/java/io/github/meatwo310/tsukichat/mixin/TeamMsgCommandMixin.java +++ b/src/main/java/io/github/meatwo310/tsukichat/mixin/TeamMsgCommandMixin.java @@ -4,109 +4,29 @@ import com.mojang.brigadier.exceptions.CommandSyntaxException; import io.github.meatwo310.tsukichat.commands.ServerDictionaryCommand; import io.github.meatwo310.tsukichat.commands.UserDictionaryCommand; -import io.github.meatwo310.tsukichat.config.CommonConfigs; +import io.github.meatwo310.tsukichat.event.ServerChat; import io.github.meatwo310.tsukichat.util.ChatCustomizer; import io.github.meatwo310.tsukichat.util.PlayerNbtUtil; import net.minecraft.commands.CommandSourceStack; import net.minecraft.commands.arguments.MessageArgument; import net.minecraft.nbt.CompoundTag; -import net.minecraft.network.chat.ChatType; import net.minecraft.network.chat.Component; -import net.minecraft.network.chat.OutgoingChatMessage; -import net.minecraft.network.chat.PlayerChatMessage; import net.minecraft.server.commands.TeamMsgCommand; import net.minecraft.server.level.ServerPlayer; import net.minecraft.world.entity.Entity; import net.minecraft.world.scores.PlayerTeam; import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Unique; -import org.spongepowered.asm.mixin.injection.*; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; import org.spongepowered.asm.mixin.injection.callback.LocalCapture; -import java.util.ArrayList; import java.util.LinkedHashMap; import java.util.List; import java.util.Set; -import java.util.concurrent.atomic.AtomicReference; @Mixin(TeamMsgCommand.class) public class TeamMsgCommandMixin { -// @Inject(at = @At("TAIL"), method = "sendMessage(" + -// "Lnet/minecraft/commands/CommandSourceStack;" + -// "Lnet/minecraft/world/entity/Entity;" + -// "Lnet/minecraft/world/scores/PlayerTeam;" + -// "Ljava/util/List;" + -// "Lnet/minecraft/network/chat/PlayerChatMessage;" + -// ")V", -// locals = LocalCapture.CAPTURE_FAILHARD -// ) -// private static void sendMessage( -// CommandSourceStack source, -// Entity senderEntity, -// PlayerTeam team, -// List recipients, -// PlayerChatMessage chatMessage, -// CallbackInfo ci, -// Component teamDisplayName, -// ChatType.Bound incomingChatType, -// ChatType.Bound outgoingChatType, -// OutgoingChatMessage outgoingchatmessage -// ) { -// int forwardLevel = CommonConfigs.forwardTeamMsgLevel.get(); -// if (forwardLevel < 0) return; -// -// source.getServer().getPlayerList().getPlayers().stream() -// .filter(player -> player.hasPermissions(forwardLevel) && !recipients.contains(player)) -// .forEach(player -> player.sendChatMessage(outgoingchatmessage, false, outgoingChatType)); -// } - - // @ModifyArgs(at = @At( - // value = "INVOKE", - // target = "Lnet/minecraft/server/commands/TeamMsgCommand;sendMessage(" + - // "Lnet/minecraft/commands/CommandSourceStack;" + - // "Lnet/minecraft/world/entity/Entity;" + - // "Lnet/minecraft/world/scores/PlayerTeam;" + - // "Ljava/util/List;" + - // "Lnet/minecraft/network/chat/PlayerChatMessage;" + - // ")V"), - // method = "lambda$register$1(" + - // "Lnet/minecraft/commands/CommandSourceStack;" + - // "Lnet/minecraft/world/entity/Entity;" + - // "Lnet/minecraft/world/scores/PlayerTeam;" + - // "Ljava/util/List;" + - // "Lnet/minecraft/network/chat/PlayerChatMessage;" + - // ")V" - // ) - // private static void processTsukiChat(Args args) { - //// CommandSourceStack source; - // Entity senderEntity = args.get(1); - //// PlayerTeam team; - //// List recipients; - // PlayerChatMessage chatMessage = args.get(4); - // - // if (!CommonConfigs.formatTeamMsg.get()) return; - // - // ServerPlayer sender = (ServerPlayer) senderEntity; - // Set playerTags = sender.getTags(); - // - // CompoundTag dict = PlayerNbtUtil.loadCompoundTag(sender, UserDictionaryCommand.KEY_NAME); - // LinkedHashMap userDictionary = new LinkedHashMap<>(); - // dict.getAllKeys().forEach(k -> userDictionary.put(k, dict.getString(k))); - // var serverDictionary = ServerDictionaryCommand.getServerDictionary(); - // - // var result = ChatCustomizer.recognizeChat(chatMessage.signedContent(), playerTags, userDictionary, serverDictionary); - // - // result.ifMessagePresent(converted -> tsukichat$setArg(args, chatMessage, converted)); - // result.ifDefferedMessagePresentSync(converted -> tsukichat$setArg(args, chatMessage, converted)); - // } - // - // @Unique - // private static void tsukichat$setArg(Args args, PlayerChatMessage chatMessage, String converted) { - // args.set(4, PlayerChatMessage.unsigned(chatMessage.sender(), converted)); - // } - @Inject(at = @At( value = "INVOKE", target = "net/minecraft/commands/arguments/MessageArgument.resolveChatMessage(" + @@ -117,7 +37,8 @@ public class TeamMsgCommandMixin { method = "lambda$register$2(" + "Lcom/mojang/brigadier/context/CommandContext;" + ")I", - locals = LocalCapture.CAPTURE_FAILHARD + locals = LocalCapture.CAPTURE_FAILHARD, + cancellable = true ) private static void resolveChatMessage( CommandContext ctx, @@ -127,34 +48,26 @@ private static void resolveChatMessage( PlayerTeam playerteam, List list ) throws CommandSyntaxException { - int forwardLevel = CommonConfigs.forwardTeamMsgLevel.get(); - ArrayList listModified = new ArrayList<>(list); - if (forwardLevel >= 0) listModified.addAll(commandsourcestack.getServer().getPlayerList().getPlayers().stream() - .filter(player -> player.hasPermissions(forwardLevel) && !listModified.contains(player)) - .toList() - ); - - MessageArgument.resolveChatMessage(ctx, "message", (playerChatMessage -> { - PlayerChatMessage processed = tsukichat$processTsukiChat(playerChatMessage, (ServerPlayer) entity); - TeamMsgCommand.sendMessage(commandsourcestack, entity, playerteam, list, processed); - })); - } - - @Unique - private static PlayerChatMessage tsukichat$processTsukiChat(PlayerChatMessage playerChatMessage, ServerPlayer player) { - var original = playerChatMessage.signedContent(); - Set playerTags = player.getTags(); - - CompoundTag dict = PlayerNbtUtil.loadCompoundTag(player, UserDictionaryCommand.KEY_NAME); + Component message = MessageArgument.getMessage(ctx, "message"); + String original = message.getString(); + Set playerTags = entity.getTags(); + CompoundTag dict = PlayerNbtUtil.loadCompoundTag((ServerPlayer) entity, UserDictionaryCommand.KEY_NAME); LinkedHashMap userDictionary = new LinkedHashMap<>(); dict.getAllKeys().forEach(k -> userDictionary.put(k, dict.getString(k))); var serverDictionary = ServerDictionaryCommand.getServerDictionary(); var result = ChatCustomizer.recognizeChat(original, playerTags, userDictionary, serverDictionary); + var converted = result.getMessageSynced(); + if (converted == null) return; - String converted = result.getMessageSynced(); - if (converted == null) return playerChatMessage; + ServerChat.sendTeamMessage( + commandsourcestack.getServer(), + (ServerPlayer) entity, + playerteam, + list, + converted + ); - return PlayerChatMessage.unsigned(playerChatMessage.sender(), converted); + cir.setReturnValue(list.size()); } }