Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
69 changes: 33 additions & 36 deletions src/main/java/io/github/meatwo310/tsukichat/event/ServerChat.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,26 +6,35 @@
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;
import net.minecraftforge.eventbus.api.EventPriority;
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();
Expand Down Expand Up @@ -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<ServerPlayer> recipients, String message) {
int forwardLevel = CommonConfigs.forwardTeamMsgLevel.get();
ArrayList<ServerPlayer> 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<ServerPlayer> 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.");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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<ServerPlayer> 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<ServerPlayer> recipients;
// PlayerChatMessage chatMessage = args.get(4);
//
// if (!CommonConfigs.formatTeamMsg.get()) return;
//
// ServerPlayer sender = (ServerPlayer) senderEntity;
// Set<String> playerTags = sender.getTags();
//
// CompoundTag dict = PlayerNbtUtil.loadCompoundTag(sender, UserDictionaryCommand.KEY_NAME);
// LinkedHashMap<String, String> 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(" +
Expand All @@ -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<CommandSourceStack> ctx,
Expand All @@ -127,34 +48,26 @@ private static void resolveChatMessage(
PlayerTeam playerteam,
List<ServerPlayer> list
) throws CommandSyntaxException {
int forwardLevel = CommonConfigs.forwardTeamMsgLevel.get();
ArrayList<ServerPlayer> 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<String> playerTags = player.getTags();

CompoundTag dict = PlayerNbtUtil.loadCompoundTag(player, UserDictionaryCommand.KEY_NAME);
Component message = MessageArgument.getMessage(ctx, "message");
String original = message.getString();
Set<String> playerTags = entity.getTags();
CompoundTag dict = PlayerNbtUtil.loadCompoundTag((ServerPlayer) entity, UserDictionaryCommand.KEY_NAME);
LinkedHashMap<String, String> 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());
}
}
Loading