diff --git a/build.gradle b/build.gradle index 8c025ef..88fc3a4 100644 --- a/build.gradle +++ b/build.gradle @@ -1,5 +1,5 @@ plugins { - id 'fabric-loom' version '0.12-SNAPSHOT' + id 'fabric-loom' version '1.+' id 'maven-publish' id "com.modrinth.minotaur" version "2.+" id 'com.matthewprenger.cursegradle' version '1.4.0' @@ -48,8 +48,7 @@ dependencies { modImplementation include("me.lucko:fabric-permissions-api:0.2-SNAPSHOT") modImplementation include("eu.pb4:player-data-api:0.2.2+1.19.3") - - modCompileOnly("fr.catcore:server-translations-api:1.4.18+1.19.2") + modCompileOnly("fr.catcore:server-translations-api:1.4.19+1.19.3") modCompileOnly("maven.modrinth:vanish:1.1.0") //modLocalRuntime("fr.catcore:server-translations-api:1.4.17+1.19.2") diff --git a/gradle.properties b/gradle.properties index 76bd172..9cfe407 100644 --- a/gradle.properties +++ b/gradle.properties @@ -3,8 +3,8 @@ org.gradle.jvmargs=-Xmx1G # Fabric Properties # check these on https://fabricmc.net/use -minecraft_version=1.19.3-rc1 -yarn_mappings=1.19.3-rc1+build.1 +minecraft_version=1.19.3 +yarn_mappings=1.19.3+build.1 loader_version=0.14.11 #Fabric api @@ -12,7 +12,7 @@ fabric_version=0.68.1+1.19.3 # Mod Properties - mod_version = 2.1.0+1.19.3 + mod_version = 2.1.1+1.19.3 maven_group = eu.pb4 archives_base_name = styled-chat diff --git a/src/main/java/eu/pb4/styledchat/StyledChatStyles.java b/src/main/java/eu/pb4/styledchat/StyledChatStyles.java index 1416326..26febd2 100644 --- a/src/main/java/eu/pb4/styledchat/StyledChatStyles.java +++ b/src/main/java/eu/pb4/styledchat/StyledChatStyles.java @@ -4,9 +4,12 @@ import eu.pb4.placeholders.api.node.TextNode; import eu.pb4.styledchat.config.ConfigManager; import net.minecraft.entity.passive.TameableEntity; +import net.minecraft.registry.RegistryKeys; import net.minecraft.server.command.ServerCommandSource; import net.minecraft.server.network.ServerPlayerEntity; import net.minecraft.text.Text; +import net.minecraft.util.Identifier; +import org.jetbrains.annotations.Nullable; import java.util.Map; @@ -174,4 +177,33 @@ public static Map getEmotes(ServerCommandSource source) { return ConfigManager.getConfig().getEmotes(source); } + + public static Text getCustom(Identifier identifier, Text displayName, Text message, @Nullable Text receiver, ServerCommandSource source) { + if (source.isExecutedByPlayer()) { + var style = StyledChatUtils.getPersonalStyle(source.getPlayer()).getCustom(identifier, displayName, message, receiver, source); + if (style != null) { + return style; + } + } + + var out = ConfigManager.getConfig().getCustom(identifier, displayName, message, receiver, source); + + if (out != null) { + return out; + } + + var type = StyledChatMod.server.getRegistryManager().get(RegistryKeys.MESSAGE_TYPE).get(identifier); + + if (type == null) { + return Text.empty(); + } + + var params = type.params(displayName); + + if (receiver != null) { + params = params.withTargetName(receiver); + } + + return type.chat().apply(message, params); + } } diff --git a/src/main/java/eu/pb4/styledchat/StyledChatUtils.java b/src/main/java/eu/pb4/styledchat/StyledChatUtils.java index 0cb561f..838db48 100644 --- a/src/main/java/eu/pb4/styledchat/StyledChatUtils.java +++ b/src/main/java/eu/pb4/styledchat/StyledChatUtils.java @@ -326,7 +326,9 @@ public static boolean isHandledByMod(RegistryKey typeKey) { public static void modifyForSending(SignedMessage message, ServerCommandSource source, RegistryKey type) { try { - ((ExtSignedMessage) (Object) message).styledChat_setArg("override", StyledChatUtils.formatMessage(message, source, type)); + ExtSignedMessage.setArg(message, "override", StyledChatUtils.formatMessage(message, source, type)); + ((ExtSignedMessage) (Object) message).styledChat_setType(type); + ((ExtSignedMessage) (Object) message).styledChat_setSource(source); } catch (Exception e) { e.printStackTrace(); } @@ -341,6 +343,9 @@ public static Text formatMessage(SignedMessage message, ServerCommandSource sour ? baseInput : maybeFormatFor(source, ext.styledChat_getOriginal(), message.getContent()); + if (baseInput == null) { + ext.styledChat_setArg("base_input", input); + } return switch (type.getValue().getPath()) { case "msg_command_incoming" -> { @@ -394,7 +399,7 @@ public static Text formatMessage(SignedMessage message, ServerCommandSource sour case "chat" -> StyledChatStyles.getChat(source.getPlayer(), input); - default -> input; + default -> StyledChatStyles.getCustom(type.getValue(), source.getDisplayName(), input, null, source); }; } @@ -415,6 +420,9 @@ public static SignedMessage toEventMessage(SignedMessage message, PlaceholderCon var baseInput = ext.styledChat_getArg("base_input"); var input = baseInput != null && baseInput.getContent() != TextContent.EMPTY ? baseInput : formatFor(context, ext.styledChat_getOriginal()); + if (baseInput == null) { + ext.styledChat_setArg("base_input", input); + } return new SignedMessage(message.link(), null, MessageBody.ofUnsigned(message.getSignedContent()), input, null); } @@ -497,4 +505,8 @@ public static ChatStyle createStyleOf(ServerPlayerEntity player) { return new ChatStyle(style); } + + public static MessageType.Parameters createParameters(Text override) { + return new MessageType.Parameters(StyledChatMod.getMessageType(), override, null); + } } diff --git a/src/main/java/eu/pb4/styledchat/command/Commands.java b/src/main/java/eu/pb4/styledchat/command/Commands.java index 4edb5c2..d0a694c 100644 --- a/src/main/java/eu/pb4/styledchat/command/Commands.java +++ b/src/main/java/eu/pb4/styledchat/command/Commands.java @@ -9,6 +9,7 @@ import eu.pb4.placeholders.api.PlaceholderContext; import eu.pb4.placeholders.api.Placeholders; import eu.pb4.placeholders.api.node.TextNode; +import eu.pb4.styledchat.StyledChatMod; import eu.pb4.styledchat.StyledChatUtils; import eu.pb4.styledchat.config.ConfigManager; import eu.pb4.styledchat.config.data.ChatStyleData; @@ -16,6 +17,8 @@ import me.lucko.fabric.api.permissions.v0.Permissions; import net.minecraft.command.CommandRegistryAccess; import net.minecraft.command.argument.EntityArgumentType; +import net.minecraft.command.argument.IdentifierArgumentType; +import net.minecraft.registry.RegistryKeys; import net.minecraft.server.command.CommandManager; import net.minecraft.server.command.ServerCommandSource; import net.minecraft.server.network.ServerPlayerEntity; @@ -23,6 +26,7 @@ import net.minecraft.util.Formatting; import java.util.function.BiConsumer; +import java.util.function.Function; import static net.minecraft.server.command.CommandManager.argument; import static net.minecraft.server.command.CommandManager.literal; @@ -43,7 +47,7 @@ public static void register(CommandDispatcher dispatcher, C .requires(Permissions.require("styledchat.set", 3)) .then(fillWithProperties(argument("players", EntityArgumentType.players()), (x, p) -> x.then(argument("value", StringArgumentType.greedyString()) - .executes((ctx) -> Commands.setProperty(ctx, p)) + .executes((ctx) -> Commands.setProperty(ctx, p.apply(ctx))) )) ) ) @@ -51,14 +55,14 @@ public static void register(CommandDispatcher dispatcher, C .then(literal("get") .requires(Permissions.require("styledchat.get", 3)) .then(fillWithProperties(argument("player", EntityArgumentType.player()), - (x, p) -> x.executes((ctx) -> Commands.getProperty(ctx, p)) + (x, p) -> x.executes((ctx) -> Commands.getProperty(ctx, p.apply(ctx))) )) ) .then(literal("clear") .requires(Permissions.require("styledchat.clear", 3)) .then(fillWithProperties(argument("players", EntityArgumentType.players()), - (x, p) -> x.executes((ctx) -> Commands.clearProperty(ctx, p)) + (x, p) -> x.executes((ctx) -> Commands.clearProperty(ctx, p.apply(ctx))) ).then(literal("*").executes((ctx) -> Commands.clearProperty(ctx, null)))) ) ); @@ -140,12 +144,29 @@ private static int clearProperty(CommandContext context, Ch return players.size(); } - private static ArgumentBuilder fillWithProperties(ArgumentBuilder base, BiConsumer, ChatStyleData.PropertyGetSet> command) { + private static ArgumentBuilder fillWithProperties(ArgumentBuilder base, BiConsumer, Function, ChatStyleData.PropertyGetSet>> command) { for (var prop : ChatStyleData.PROPERTIES.entrySet()) { var x = literal(prop.getKey()); - command.accept(x, prop.getValue()); + command.accept(x, (ctx) -> prop.getValue()); base = base.then(x); } + + { + var x = argument("id", IdentifierArgumentType.identifier()) + .suggests((context, builder) -> { + for (var id : context.getSource().getServer().getRegistryManager().get(RegistryKeys.MESSAGE_TYPE).getIds()) { + if (!id.getNamespace().equals("minecraft") && !id.equals(StyledChatMod.MESSAGE_TYPE_ID.getValue())) { + builder.suggest(id.toString()); + } + } + + return builder.buildFuture(); + }); + + command.accept(x, (ctx) -> ChatStyleData.PropertyGetSet.ofCustom(IdentifierArgumentType.getIdentifier(ctx, "id").toString())); + base = base.then(literal("custom").then(x)); + } + return base; } diff --git a/src/main/java/eu/pb4/styledchat/config/ChatStyle.java b/src/main/java/eu/pb4/styledchat/config/ChatStyle.java index 7956e74..3ca9ccc 100644 --- a/src/main/java/eu/pb4/styledchat/config/ChatStyle.java +++ b/src/main/java/eu/pb4/styledchat/config/ChatStyle.java @@ -6,18 +6,16 @@ import eu.pb4.placeholders.api.node.TextNode; import eu.pb4.predicate.api.BuiltinPredicates; import eu.pb4.predicate.api.MinecraftPredicate; -import eu.pb4.predicate.api.PredicateContext; -import eu.pb4.predicate.api.PredicateRegistry; import eu.pb4.styledchat.StyledChatUtils; import eu.pb4.styledchat.config.data.ChatStyleData; import eu.pb4.styledchat.config.data.ConfigData; import it.unimi.dsi.fastutil.objects.Object2BooleanMap; import it.unimi.dsi.fastutil.objects.Object2BooleanOpenHashMap; import net.minecraft.entity.passive.TameableEntity; -import net.minecraft.server.MinecraftServer; import net.minecraft.server.command.ServerCommandSource; import net.minecraft.server.network.ServerPlayerEntity; import net.minecraft.text.Text; +import net.minecraft.util.Identifier; import org.jetbrains.annotations.Nullable; import java.util.HashMap; @@ -52,6 +50,7 @@ public class ChatStyle { public final TextNode mentionStyle; public final Map emoticons = new HashMap<>(); public final Object2BooleanMap formatting = new Object2BooleanOpenHashMap<>(); + public final Map custom = new HashMap<>(); public ChatStyle(ChatStyleData data, ChatStyle defaultStyle) { @@ -88,6 +87,16 @@ public ChatStyle(ChatStyleData data, ChatStyle defaultStyle) { for (var formatting : data.formatting.entrySet()) { this.formatting.put(formatting.getKey(), formatting.getValue().booleanValue()); } + + if (data.custom != null) { + for (var entry : data.custom.entrySet()) { + var id = Identifier.tryParse(entry.getKey()); + + if (id != null) { + this.custom.put(id, StyledChatUtils.parseText(entry.getValue())); + } + } + } } public ChatStyle(ChatStyleData data) { @@ -123,6 +132,16 @@ public ChatStyle(ChatStyleData data) { for (var formatting : data.formatting.entrySet()) { this.formatting.put(formatting.getKey(), formatting.getValue().booleanValue()); } + + if (data.custom != null) { + for (var entry : data.custom.entrySet()) { + var id = Identifier.tryParse(entry.getKey()); + + if (id != null) { + this.custom.put(id, StyledChatUtils.parseText(entry.getValue())); + } + } + } } @@ -419,6 +438,26 @@ public Text getTeamChatReceived(Text team, Text displayName, Text message, Serve ); } + @Nullable + public Text getCustom(Identifier identifier, Text displayName, Text message, @Nullable Text receiver, ServerCommandSource source) { + var node = this.custom.get(identifier); + + if (node == null) { + return null; + } else if (node == EmptyNode.INSTANCE) { + return StyledChatUtils.IGNORED_TEXT; + } + + return Placeholders.parseText( + node, + PlaceholderContext.of(source), + Placeholders.PREDEFINED_PLACEHOLDER_PATTERN, + Map.of("receiver", receiver == null ? Text.empty() : receiver, + "displayName", displayName, + "message", message) + ); + } + @Nullable public TextNode getLink() { return this.linkStyle; @@ -444,12 +483,12 @@ public Text getPetDeath(TameableEntity entity, Text vanillaMessage) { return null; } - return Placeholders.parseText( - this.petDeath, - PlaceholderContext.of(entity), - Placeholders.PREDEFINED_PLACEHOLDER_PATTERN, - Map.of("pet", entity.getDisplayName(), - "default_message", vanillaMessage) - ); + return Placeholders.parseText( + this.petDeath, + PlaceholderContext.of(entity), + Placeholders.PREDEFINED_PLACEHOLDER_PATTERN, + Map.of("pet", entity.getDisplayName(), + "default_message", vanillaMessage) + ); } } diff --git a/src/main/java/eu/pb4/styledchat/config/Config.java b/src/main/java/eu/pb4/styledchat/config/Config.java index 4674688..4ff678b 100644 --- a/src/main/java/eu/pb4/styledchat/config/Config.java +++ b/src/main/java/eu/pb4/styledchat/config/Config.java @@ -13,6 +13,8 @@ import net.minecraft.server.command.ServerCommandSource; import net.minecraft.server.network.ServerPlayerEntity; import net.minecraft.text.Text; +import net.minecraft.util.Identifier; +import org.jetbrains.annotations.Nullable; import java.util.*; @@ -42,8 +44,8 @@ public Config(ConfigData data) { } } - - + + for (var tag : TextParserV1.DEFAULT.getTags()) { this.allPossibleAutoCompletionKeys.add("<" + tag.name() + ">"); if (tag.aliases() != null) { @@ -368,4 +370,19 @@ public Object2BooleanOpenHashMap getAllowedFormatting(ServerCommandSourc return base; } + + @Nullable + public Text getCustom(Identifier identifier, Text displayName, Text message, @Nullable Text receiver, ServerCommandSource source) { + var context2 = PredicateContext.of(source); + for (var entry : this.permissionStyle) { + if (entry.require.test(context2).success()) { + var text = entry.getCustom(identifier, displayName, message, receiver, source); + if (text != null) { + return text; + } + } + } + + return this.defaultStyle.getCustom(identifier, displayName, message, receiver, source); + } } diff --git a/src/main/java/eu/pb4/styledchat/config/ConfigManager.java b/src/main/java/eu/pb4/styledchat/config/ConfigManager.java index 7003bbd..8160f72 100644 --- a/src/main/java/eu/pb4/styledchat/config/ConfigManager.java +++ b/src/main/java/eu/pb4/styledchat/config/ConfigManager.java @@ -42,7 +42,6 @@ public static boolean loadConfig() { ConfigData config; var configFile = FabricLoader.getInstance().getConfigDir().resolve("styled-chat.json"); - if (Files.exists(configFile)) { String json = Files.readString(configFile, StandardCharsets.UTF_8); VersionConfigData versionConfigData = GSON.fromJson(json, VersionConfigData.class); diff --git a/src/main/java/eu/pb4/styledchat/config/data/ChatStyleData.java b/src/main/java/eu/pb4/styledchat/config/data/ChatStyleData.java index 07a4aa6..106a2c1 100644 --- a/src/main/java/eu/pb4/styledchat/config/data/ChatStyleData.java +++ b/src/main/java/eu/pb4/styledchat/config/data/ChatStyleData.java @@ -39,6 +39,9 @@ public class ChatStyleData implements Cloneable { @SerializedName("emoticons") public Map emoticons = new HashMap<>(); + @SerializedName("custom_message_types") + public Map custom = new HashMap<>(); + public static class Messages implements Cloneable { @SerializedName("chat") public String chat; @@ -88,6 +91,7 @@ public ChatStyleData clone() { base.messages = this.messages.clone(); base.formatting = new HashMap<>(this.formatting); base.emoticons = new HashMap<>(this.emoticons); + base.custom = new HashMap<>(this.custom); return base; } catch (CloneNotSupportedException e) { @@ -136,7 +140,6 @@ public static ChatStyleData createDefault() { data.spoilerStyle = "${spoiler}"; data.spoilerSymbol = "▌"; - { data.formatting.put(StyledChatUtils.SPOILER_TAG, true); data.formatting.put("bold", true); @@ -194,6 +197,8 @@ public void fillMissing() { this.spoilerStyle = Objects.requireNonNullElse(this.spoilerStyle, DEFAULT.spoilerStyle); this.spoilerSymbol = Objects.requireNonNullElse(this.spoilerSymbol, DEFAULT.spoilerSymbol); + this.custom = Objects.requireNonNullElse(this.custom, new HashMap<>()); + for (var key : DEFAULT.formatting.keySet()) { if (!this.formatting.containsKey(key)) { this.formatting.put(key, DEFAULT.formatting.get(key)); @@ -225,6 +230,24 @@ public String get(ChatStyleData data) { }; } + static PropertyGetSet ofCustom(String key) { + return new PropertyGetSet() { + @Override + public void set(ChatStyleData data, String value) { + if (value == null) { + data.custom.remove(key); + } else { + data.custom.put(key, value); + } + } + + @Override + public String get(ChatStyleData data) { + return data.custom.get(key); + } + }; + } + static PropertyGetSet ofMessage(Field field) { return new PropertyGetSet() { @Override diff --git a/src/main/java/eu/pb4/styledchat/ducks/ExtSignedMessage.java b/src/main/java/eu/pb4/styledchat/ducks/ExtSignedMessage.java index 7ca9341..8f3ea70 100644 --- a/src/main/java/eu/pb4/styledchat/ducks/ExtSignedMessage.java +++ b/src/main/java/eu/pb4/styledchat/ducks/ExtSignedMessage.java @@ -1,7 +1,11 @@ package eu.pb4.styledchat.ducks; +import net.minecraft.network.message.MessageType; import net.minecraft.network.message.SignedMessage; +import net.minecraft.registry.RegistryKey; +import net.minecraft.server.command.ServerCommandSource; import net.minecraft.text.Text; +import org.jetbrains.annotations.Nullable; public interface ExtSignedMessage { static Text getArg(SignedMessage message, String name) { @@ -12,8 +16,19 @@ static void setArg(SignedMessage message, String name, Text value) { ((ExtSignedMessage) (Object) message).styledChat_setArg(name, value); } - //void styledChat_setOriginal(String message); + static ExtSignedMessage of(SignedMessage message) { + return (ExtSignedMessage) (Object) message; + } + void styledChat_setArg(String name, Text arg); String styledChat_getOriginal(); Text styledChat_getArg(String name); + + void styledChat_setType(RegistryKey type1); + @Nullable + RegistryKey styledChat_getType(); + + void styledChat_setSource(ServerCommandSource source); + @Nullable + ServerCommandSource styledChat_getSource(); } diff --git a/src/main/java/eu/pb4/styledchat/mixin/MessageArgumentTypeMixin.java b/src/main/java/eu/pb4/styledchat/mixin/MessageArgumentTypeMixin.java index be8e862..35899e9 100644 --- a/src/main/java/eu/pb4/styledchat/mixin/MessageArgumentTypeMixin.java +++ b/src/main/java/eu/pb4/styledchat/mixin/MessageArgumentTypeMixin.java @@ -2,20 +2,30 @@ import com.mojang.brigadier.context.CommandContext; import eu.pb4.styledchat.ducks.ExtMessageFormat; +import eu.pb4.styledchat.ducks.ExtSignedMessage; import net.minecraft.command.argument.MessageArgumentType; +import net.minecraft.network.message.SignedMessage; import net.minecraft.server.command.ServerCommandSource; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.ModifyArg; import org.spongepowered.asm.mixin.injection.Redirect; +import java.util.function.Consumer; + @Mixin(MessageArgumentType.class) public class MessageArgumentTypeMixin { - /*@Redirect(method = { "getMessage", "getSignedMessage" }, at = @At(value = "INVOKE", target = "Lcom/mojang/brigadier/context/CommandContext;getArgument(Ljava/lang/String;Ljava/lang/Class;)Ljava/lang/Object;")) - private static Object styledChat_setContext(CommandContext instance, String name, Class clazz) { - var obj = (MessageArgumentType.MessageFormat) instance.getArgument(name, MessageArgumentType.MessageFormat.class); - ((ExtMessageFormat) obj).styledChat_setSource(instance.getInput(), (ServerCommandSource) instance.getSource(), instance::getArgument); - return obj; - }*/ + @ModifyArg(method = "getSignedMessage", at = @At(value = "INVOKE", target = "Lnet/minecraft/command/argument/MessageArgumentType;chain(Ljava/util/function/Consumer;Lnet/minecraft/server/command/ServerCommandSource;Lnet/minecraft/network/message/SignedMessage;)V"), index = 2) + private static SignedMessage styledChat_attachSource(Consumer callback, ServerCommandSource source, SignedMessage message) { + ExtSignedMessage.of(message).styledChat_setSource(source); + return message; + } + + @ModifyArg(method = "getSignedMessage", at = @At(value = "INVOKE", target = "Lnet/minecraft/command/argument/MessageArgumentType;chainUnsigned(Ljava/util/function/Consumer;Lnet/minecraft/server/command/ServerCommandSource;Lnet/minecraft/network/message/SignedMessage;)V"), index = 2) + private static SignedMessage styledChat_attachSource2(Consumer callback, ServerCommandSource source, SignedMessage message) { + ExtSignedMessage.of(message).styledChat_setSource(source); + return message; + } } diff --git a/src/main/java/eu/pb4/styledchat/mixin/MessageArgumentTypeSignedMessageMixin.java b/src/main/java/eu/pb4/styledchat/mixin/MessageArgumentTypeSignedMessageMixin.java deleted file mode 100644 index ba63499..0000000 --- a/src/main/java/eu/pb4/styledchat/mixin/MessageArgumentTypeSignedMessageMixin.java +++ /dev/null @@ -1,26 +0,0 @@ -package eu.pb4.styledchat.mixin; - - -import eu.pb4.styledchat.ducks.ExtPlayNetworkHandler; -import net.minecraft.command.argument.MessageArgumentType; -import net.minecraft.network.message.MessageDecorator; -import net.minecraft.server.MinecraftServer; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Redirect; - -import java.util.concurrent.CompletableFuture; - -@Mixin(MessageArgumentType.class) -public class MessageArgumentTypeSignedMessageMixin { - /*@Redirect(method = "method_45566", at = @At(value = "INVOKE", target = "Lnet/minecraft/server/MinecraftServer;getMessageDecorator()Lnet/minecraft/network/message/MessageDecorator;")) - private MessageDecorator styledChat_returnCached(MinecraftServer instance) { - return (player, message) -> { - if (player != null) { - var cached = ((ExtPlayNetworkHandler) player.networkHandler).styledChat_getLastCached(); - return CompletableFuture.completedFuture(cached != null ? cached : message); - } - return CompletableFuture.completedFuture(message); - }; - }*/ -} diff --git a/src/main/java/eu/pb4/styledchat/mixin/SentMessageMixin.java b/src/main/java/eu/pb4/styledchat/mixin/SentMessageMixin.java index 864962f..5e41a53 100644 --- a/src/main/java/eu/pb4/styledchat/mixin/SentMessageMixin.java +++ b/src/main/java/eu/pb4/styledchat/mixin/SentMessageMixin.java @@ -1,6 +1,7 @@ package eu.pb4.styledchat.mixin; import eu.pb4.styledchat.StyledChatMod; +import eu.pb4.styledchat.StyledChatUtils; import eu.pb4.styledchat.ducks.ExtSignedMessage; import eu.pb4.styledchat.other.StyledChatSentMessage; import net.minecraft.network.message.MessageType; @@ -17,10 +18,12 @@ public interface SentMessageMixin { private static void styledChat$patchStyle(SignedMessage message, CallbackInfoReturnable cir) { var override = ((ExtSignedMessage) (Object) message).styledChat_getArg("override"); if (override != null && StyledChatMod.server != null) { + var type = ((ExtSignedMessage) (Object) message).styledChat_getType(); + if (message.isSenderMissing()) { - cir.setReturnValue(new StyledChatSentMessage.System(message, override, new MessageType.Parameters(StyledChatMod.getMessageType(), override, null))); + cir.setReturnValue(new StyledChatSentMessage.System(message, override, StyledChatUtils.createParameters(override), type)); } else { - cir.setReturnValue(new StyledChatSentMessage.Chat(message, override, new MessageType.Parameters(StyledChatMod.getMessageType(), override, null))); + cir.setReturnValue(new StyledChatSentMessage.Chat(message, override, StyledChatUtils.createParameters(override), type)); } } } diff --git a/src/main/java/eu/pb4/styledchat/mixin/SignedMessageMixin.java b/src/main/java/eu/pb4/styledchat/mixin/SignedMessageMixin.java index 0d4adb3..5b6ea07 100644 --- a/src/main/java/eu/pb4/styledchat/mixin/SignedMessageMixin.java +++ b/src/main/java/eu/pb4/styledchat/mixin/SignedMessageMixin.java @@ -2,32 +2,35 @@ import eu.pb4.styledchat.StyledChatUtils; import eu.pb4.styledchat.ducks.ExtSignedMessage; -import net.minecraft.network.message.MessageBody; -import net.minecraft.network.message.SignedMessage; +import net.minecraft.network.message.*; +import net.minecraft.registry.RegistryKey; +import net.minecraft.server.command.ServerCommandSource; import net.minecraft.text.Text; +import org.jetbrains.annotations.Nullable; import org.spongepowered.asm.mixin.Final; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.Unique; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.Redirect; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; import java.util.HashMap; import java.util.Map; @Mixin(SignedMessage.class) public class SignedMessageMixin implements ExtSignedMessage { - /*@Unique - private String styledChat_original;*/ - @Shadow @Final private MessageBody signedBody; @Unique private final Map styledChat_args = new HashMap<>(); + @Unique + private RegistryKey styledChat_type = null; - /*@Override - public void styledChat_setOriginal(String message) { - this.styledChat_original = message; - }*/ + @Unique + private ServerCommandSource styledChat_source = null; @Override public void styledChat_setArg(String name, Text arg) { @@ -44,8 +47,56 @@ public Text styledChat_getArg(String name) { return this.styledChat_args.getOrDefault(name, StyledChatUtils.EMPTY_TEXT); } - /*@Inject(method = "(Lnet/minecraft/network/message/MessageHeader;Lnet/minecraft/network/message/MessageSignatureData;Lnet/minecraft/network/message/MessageBody;Ljava/util/Optional;)V", at = @At("RETURN")) - private static void styledChat_setOriginal(MessageHeader messageHeader, MessageSignatureData messageSignatureData, MessageBody messageBody, Optional optional, CallbackInfo ci) { - ((ExtSignedMessage) this).styledChat_setOriginal(text.getString()); - }*/ + @Override + public void styledChat_setType(RegistryKey type) { + this.styledChat_type = type; + } + + @Override + public RegistryKey styledChat_getType() { + return this.styledChat_type; + } + + @Override + public void styledChat_setSource(ServerCommandSource source) { + this.styledChat_source = source; + } + + @Override + public @Nullable ServerCommandSource styledChat_getSource() { + return this.styledChat_source; + } + + @Inject(method = "withUnsignedContent", at = @At("RETURN")) + private void styledChat$copyData1(Text unsignedContent, CallbackInfoReturnable cir) { + this.styledChat$copyData(cir.getReturnValue()); + } + + @Inject(method = "withFilterMask", at = @At("RETURN")) + private void styledChat$copyData2(FilterMask filterMask, CallbackInfoReturnable cir) { + this.styledChat$copyData(cir.getReturnValue()); + } + + @Inject(method = "withoutUnsigned", at = @At("RETURN")) + private void styledChat$copyData3(CallbackInfoReturnable cir) { + this.styledChat$copyData(cir.getReturnValue()); + } + + @Inject(method = "withFilterMaskEnabled", at = @At("RETURN")) + private void styledChat$copyData4(boolean enabled, CallbackInfoReturnable cir) { + this.styledChat$copyData(cir.getReturnValue()); + } + + @Unique + private void styledChat$copyData(SignedMessage returnValue) { + var mixin = (SignedMessageMixin) (Object) returnValue; + + if ((Object) returnValue == this) { + return; + } + + mixin.styledChat_type = this.styledChat_type; + mixin.styledChat_args.putAll(this.styledChat_args); + mixin.styledChat_source = this.styledChat_source; + } } diff --git a/src/main/java/eu/pb4/styledchat/mixin/commands/MessageCommandMixin.java b/src/main/java/eu/pb4/styledchat/mixin/commands/MessageCommandMixin.java index 281e902..3d0bdf1 100644 --- a/src/main/java/eu/pb4/styledchat/mixin/commands/MessageCommandMixin.java +++ b/src/main/java/eu/pb4/styledchat/mixin/commands/MessageCommandMixin.java @@ -44,7 +44,7 @@ private static void styledChat_formatText(ServerPlayerEntity instance, SentMessa )); - source.sendChatMessage(styledChatSentMessage.reformat(sent), bl, sent); + source.sendChatMessage(styledChatSentMessage.reformat(sent, MessageType.MSG_COMMAND_OUTGOING), bl, sent); var rex = StyledChatMod.getMessageType().params(StyledChatStyles.getPrivateMessageReceived( source.getDisplayName(), @@ -52,7 +52,7 @@ private static void styledChat_formatText(ServerPlayerEntity instance, SentMessa ExtSignedMessage.getArg(styledChatSentMessage.message(), "base_input"), source )); - instance.sendChatMessage(styledChatSentMessage.reformat(rex), bl, rex); + instance.sendChatMessage(styledChatSentMessage.reformat(rex, MessageType.TEAM_MSG_COMMAND_INCOMING), bl, rex); return; } catch (Exception e) { e.printStackTrace(); diff --git a/src/main/java/eu/pb4/styledchat/mixin/commands/TeamMsgCommandMixin.java b/src/main/java/eu/pb4/styledchat/mixin/commands/TeamMsgCommandMixin.java index 8cc4dbb..84d11e8 100644 --- a/src/main/java/eu/pb4/styledchat/mixin/commands/TeamMsgCommandMixin.java +++ b/src/main/java/eu/pb4/styledchat/mixin/commands/TeamMsgCommandMixin.java @@ -26,11 +26,11 @@ public class TeamMsgCommandMixin { @Inject(method = "execute", at = @At(value = "HEAD")) private static void styledChat_formatOgText(ServerCommandSource serverCommandSource, Entity entity, Team team, List list, SignedMessage signedMessage, CallbackInfo ci) { - var input = ((ExtSignedMessage) (Object) signedMessage).styledChat_getArg("base_input"); + var input = ExtSignedMessage.getArg(signedMessage, "base_input"); if (input == null) { input = StyledChatUtils.formatFor(serverCommandSource, ((ExtSignedMessage) (Object) signedMessage).styledChat_getOriginal()); - ((ExtSignedMessage) (Object) signedMessage).styledChat_setArg("base_input", input); + ExtSignedMessage.setArg(signedMessage,"base_input", input); } } @@ -45,7 +45,7 @@ private static void styledChat_replaceForSelf(ServerPlayerEntity instance, SentM ExtSignedMessage.getArg(styledChatSentMessage.message(), "base_input"), instance.getCommandSource() )); - source.sendChatMessage(styledChatSentMessage.reformat(sent), bl, sent); + source.sendChatMessage(styledChatSentMessage.reformat(sent, MessageType.TEAM_MSG_COMMAND_OUTGOING), bl, sent); } else { var rex = StyledChatMod.getMessageType().params(StyledChatStyles.getTeamChatReceived( ((Team) source.getEntity().getScoreboardTeam()).getFormattedName(), @@ -53,7 +53,7 @@ private static void styledChat_replaceForSelf(ServerPlayerEntity instance, SentM ExtSignedMessage.getArg(styledChatSentMessage.message(), "base_input"), source )); - instance.sendChatMessage(styledChatSentMessage.reformat(rex), bl, rex); + instance.sendChatMessage(styledChatSentMessage.reformat(rex, MessageType.TEAM_MSG_COMMAND_INCOMING), bl, rex); } return; } catch (Exception e) { diff --git a/src/main/java/eu/pb4/styledchat/other/StyledChatSentMessage.java b/src/main/java/eu/pb4/styledchat/other/StyledChatSentMessage.java index 76c2312..2e865ab 100644 --- a/src/main/java/eu/pb4/styledchat/other/StyledChatSentMessage.java +++ b/src/main/java/eu/pb4/styledchat/other/StyledChatSentMessage.java @@ -1,52 +1,89 @@ package eu.pb4.styledchat.other; +import eu.pb4.styledchat.StyledChatMod; +import eu.pb4.styledchat.StyledChatStyles; +import eu.pb4.styledchat.StyledChatUtils; +import eu.pb4.styledchat.ducks.ExtSignedMessage; import net.minecraft.network.message.MessageType; import net.minecraft.network.message.SentMessage; import net.minecraft.network.message.SignedMessage; +import net.minecraft.registry.RegistryKey; +import net.minecraft.registry.RegistryKeys; import net.minecraft.server.network.ServerPlayerEntity; import net.minecraft.text.Text; +import net.minecraft.text.TextContent; + +import java.util.Objects; public interface StyledChatSentMessage extends SentMessage { Text override(); SignedMessage message(); - StyledChatSentMessage reformat(MessageType.Parameters sent); + StyledChatSentMessage reformat(MessageType.Parameters sent, RegistryKey sourceType); + + RegistryKey sourceType(); - record Chat(SignedMessage message, Text override, MessageType.Parameters parameters) implements StyledChatSentMessage { + record Chat(SignedMessage message, Text override, MessageType.Parameters parameters, RegistryKey sourceType) implements StyledChatSentMessage { public Text getContent() { return message.unsignedContent(); } @Override - public void send(ServerPlayerEntity sender, boolean filterMaskEnabled, MessageType.Parameters params) { + public void send(ServerPlayerEntity receiver, boolean filterMaskEnabled, MessageType.Parameters params) { SignedMessage signedMessage = this.message.withFilterMaskEnabled(filterMaskEnabled); if (!signedMessage.isFullyFiltered()) { - sender.networkHandler.sendChatMessage(signedMessage, this.parameters); + var id = receiver.server.getRegistryManager().get(RegistryKeys.MESSAGE_TYPE).getId(params.type()); + + if (sourceType == null || Objects.equals(id, this.sourceType.getValue())) { + receiver.networkHandler.sendChatMessage(signedMessage, this.parameters); + } else { + var baseInput = ExtSignedMessage.getArg(signedMessage, "base_input"); + var source = ExtSignedMessage.of(signedMessage).styledChat_getSource(); + + var input = baseInput != null && baseInput.getContent() != TextContent.EMPTY + ? baseInput + : signedMessage.getContent(); + + + receiver.networkHandler.sendChatMessage(signedMessage, StyledChatUtils.createParameters(StyledChatStyles.getCustom(id, params.name(), input, params.targetName(), source != null ? source : StyledChatMod.server.getCommandSource()))); + } } } @Override - public StyledChatSentMessage reformat(MessageType.Parameters pars) { - return new StyledChatSentMessage.Chat(message, override, pars); + public StyledChatSentMessage reformat(MessageType.Parameters pars, RegistryKey sourceType) { + return new StyledChatSentMessage.Chat(message, override, pars, sourceType); } } - record System(SignedMessage message, Text override, MessageType.Parameters parameters) implements StyledChatSentMessage { - + record System(SignedMessage message, Text override, MessageType.Parameters parameters, RegistryKey sourceType) implements StyledChatSentMessage { public Text getContent() { return this.message.unsignedContent(); } @Override - public void send(ServerPlayerEntity sender, boolean filterMaskEnabled, MessageType.Parameters params) { - sender.networkHandler.sendProfilelessChatMessage(message.getContent(), this.parameters); + public void send(ServerPlayerEntity receiver, boolean filterMaskEnabled, MessageType.Parameters params) { + var id = receiver.server.getRegistryManager().get(RegistryKeys.MESSAGE_TYPE).getId(params.type()); + + if (sourceType == null || Objects.equals(id, this.sourceType.getValue())) { + receiver.networkHandler.sendProfilelessChatMessage(message.getContent(), this.parameters); + } else { + var baseInput = ExtSignedMessage.getArg(message, "base_input"); + var source = ExtSignedMessage.of(message).styledChat_getSource(); + + var input = baseInput != null && baseInput.getContent() != TextContent.EMPTY + ? baseInput + : message.getContent(); + + receiver.networkHandler.sendChatMessage(message, StyledChatUtils.createParameters(StyledChatStyles.getCustom(id, params.name(), input, params.targetName(), source != null ? source : StyledChatMod.server.getCommandSource()))); + } } @Override - public StyledChatSentMessage reformat(MessageType.Parameters pars) { - return new StyledChatSentMessage.Chat(message, override, pars); + public StyledChatSentMessage reformat(MessageType.Parameters pars, RegistryKey sourceType) { + return new StyledChatSentMessage.Chat(message, override, pars, sourceType); } } } diff --git a/src/main/resources/styledchat.mixins.json b/src/main/resources/styledchat.mixins.json index dcb4a1d..0c72d79 100644 --- a/src/main/resources/styledchat.mixins.json +++ b/src/main/resources/styledchat.mixins.json @@ -7,7 +7,6 @@ "RegistryLoaderMixin", "CommandManagerMixin", "MessageArgumentTypeMixin", - "MessageArgumentTypeSignedMessageMixin", "MessageFormatMixin", "MinecraftServerMixin", "PlayerAdvancementTrackerMixin",