From 661f5d7627bfb2463f4ae2dc396f254d5d642098 Mon Sep 17 00:00:00 2001 From: Patbox <39821509+Patbox@users.noreply.github.com> Date: Sun, 10 Sep 2023 09:01:37 +0200 Subject: [PATCH] Respect client's "Colors" setting, update placeholders, fix crash with forge/connector --- build.gradle | 9 ++--- gradle.properties | 2 +- .../eu/pb4/styledchat/StyledChatUtils.java | 16 +++++++- .../styledchat/config/data/ConfigData.java | 6 ++- .../config/data/old/ConfigDataV2.java | 2 +- .../ducks/ExtPlayNetworkHandler.java | 4 +- .../styledchat/mixin/SentMessageMixin.java | 5 ++- .../mixin/ServerPlayNetworkManagerMixin.java | 30 +++++++++++--- .../pb4/styledchat/other/GenericModInfo.java | 2 +- .../other/StyledChatSentMessage.java | 39 +++++++++++++++---- src/main/resources/fabric.mod.json | 2 +- 11 files changed, 88 insertions(+), 29 deletions(-) diff --git a/build.gradle b/build.gradle index f9ec476..c48eaea 100644 --- a/build.gradle +++ b/build.gradle @@ -1,5 +1,5 @@ plugins { - id 'fabric-loom' version '1.0.+' + id 'fabric-loom' version '1.1.+' id 'maven-publish' id "com.modrinth.minotaur" version "2.+" id 'com.matthewprenger.cursegradle' version '1.4.0' @@ -35,18 +35,17 @@ dependencies { mappings "net.fabricmc:yarn:${project.yarn_mappings}:v2" modImplementation "net.fabricmc:fabric-loader:${project.loader_version}" - //modCompileOnly "net.fabricmc.fabric-api:fabric-api:${project.fabric_version}" + modCompileOnly "net.fabricmc.fabric-api:fabric-api:${project.fabric_version}" modLocalRuntime("net.fabricmc.fabric-api:fabric-api:${project.fabric_version}") - modCompileOnly fabricApi.module("fabric-api-base", project.fabric_version) + //modCompileOnly fabricApi.module("fabric-api-base", project.fabric_version) //modLocalRuntime fabricApi.module("fabric-api-base", project.fabric_version) modImplementation include("eu.pb4:predicate-api:0.1.2+1.20") - modImplementation include("eu.pb4:placeholder-api:2.1.2+1.20.1") + modImplementation include("eu.pb4:placeholder-api:2.1.3+1.20.1") 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.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 5a48493..870d082 100644 --- a/gradle.properties +++ b/gradle.properties @@ -12,7 +12,7 @@ fabric_version=0.83.0+1.20.1 # Mod Properties - mod_version = 2.2.2+1.20.1 + mod_version = 2.2.3+1.20.1 maven_group = eu.pb4 archives_base_name = styled-chat diff --git a/src/main/java/eu/pb4/styledchat/StyledChatUtils.java b/src/main/java/eu/pb4/styledchat/StyledChatUtils.java index 6acfe22..4cd7540 100644 --- a/src/main/java/eu/pb4/styledchat/StyledChatUtils.java +++ b/src/main/java/eu/pb4/styledchat/StyledChatUtils.java @@ -7,6 +7,7 @@ import eu.pb4.placeholders.api.node.LiteralNode; import eu.pb4.placeholders.api.node.TextNode; import eu.pb4.placeholders.api.parsers.*; +import eu.pb4.placeholders.impl.GeneralUtils; import eu.pb4.playerdata.api.PlayerDataApi; import eu.pb4.playerdata.api.storage.JsonDataStorage; import eu.pb4.styledchat.config.ChatStyle; @@ -27,7 +28,9 @@ import net.minecraft.scoreboard.Team; import net.minecraft.server.command.ServerCommandSource; import net.minecraft.server.network.ServerPlayerEntity; +import net.minecraft.text.MutableText; import net.minecraft.text.Text; +import net.minecraft.text.TextColor; import net.minecraft.text.TextContent; import net.minecraft.util.Formatting; import org.jetbrains.annotations.Nullable; @@ -35,6 +38,7 @@ import java.util.*; import java.util.concurrent.CompletableFuture; import java.util.function.BiFunction; +import java.util.function.Function; import java.util.regex.Pattern; public final class StyledChatUtils { @@ -45,6 +49,7 @@ public final class StyledChatUtils { public static final String ITEM_KEY = "item"; public static final String POS_KEY = "pos"; public static final String SPOILER_TAG = "spoiler"; + private static final Function COLOR_CLEARING = (t) -> t.setStyle(t.getStyle().withColor((TextColor) null)); public static JsonDataStorage PLAYER_DATA = new JsonDataStorage<>("styled_chat_style", VersionedChatStyleData.class, ConfigManager.GSON); @@ -187,7 +192,7 @@ public static Text formatFor(PlaceholderContext context, String input) { var text = value.toText(context); - if (config.configData.formatting.allowModdedDecorators) { + if (config.configData.formatting.respectColors) { try { text = context.server().getMessageDecorator().decorate(context.player(), text).get(); } catch (Exception e) { @@ -310,6 +315,15 @@ public static TextNode parseLinks(TextNode node, PlaceholderContext context) { return TextNode.asSingle(LinkParser.parse(node, context)); } + public static MessageType.Parameters removeColor(MessageType.Parameters parameters) { + return new MessageType.Parameters(parameters.type(), removeColor(parameters.name()), parameters.targetName()); + } + + public static Text removeColor(Text text) { + // Should expose this as a function is tpapi, but too lazt for now + return GeneralUtils.cloneTransformText(text, COLOR_CLEARING); + } + public static boolean isHandledByMod(RegistryKey typeKey) { return DECORABLE.contains(typeKey); } diff --git a/src/main/java/eu/pb4/styledchat/config/data/ConfigData.java b/src/main/java/eu/pb4/styledchat/config/data/ConfigData.java index 3ce07e9..41c6aff 100644 --- a/src/main/java/eu/pb4/styledchat/config/data/ConfigData.java +++ b/src/main/java/eu/pb4/styledchat/config/data/ConfigData.java @@ -24,8 +24,10 @@ public static class Formatting { public boolean parseMentionsInChat = false; @SerializedName("markdown") public boolean markdown = true; - @SerializedName("formatting_from_other_mods") - public boolean allowModdedDecorators = false; + //@SerializedName("formatting_from_other_mods") + //public boolean allowModdedDecorators = false; + @SerializedName("respect_colors_client_setting") + public boolean respectColors = true; } @SerializedName("auto_completion") diff --git a/src/main/java/eu/pb4/styledchat/config/data/old/ConfigDataV2.java b/src/main/java/eu/pb4/styledchat/config/data/old/ConfigDataV2.java index bf33302..6f9bdc2 100644 --- a/src/main/java/eu/pb4/styledchat/config/data/old/ConfigDataV2.java +++ b/src/main/java/eu/pb4/styledchat/config/data/old/ConfigDataV2.java @@ -53,7 +53,7 @@ public ConfigData update() { data.formatting.markdown = this.enableMarkdown; data.formatting.legacyChatFormatting = this.legacyChatFormatting; - data.formatting.allowModdedDecorators = this.allowModdedDecorators; + data.formatting.respectColors = this.allowModdedDecorators; data.formatting.parseLinksInChat = this.parseLinksInChat; var pairs = new ArrayList>(); diff --git a/src/main/java/eu/pb4/styledchat/ducks/ExtPlayNetworkHandler.java b/src/main/java/eu/pb4/styledchat/ducks/ExtPlayNetworkHandler.java index 522bc4a..bbeeb18 100644 --- a/src/main/java/eu/pb4/styledchat/ducks/ExtPlayNetworkHandler.java +++ b/src/main/java/eu/pb4/styledchat/ducks/ExtPlayNetworkHandler.java @@ -1,8 +1,6 @@ package eu.pb4.styledchat.ducks; import eu.pb4.styledchat.config.ChatStyle; -import net.minecraft.text.Text; -import org.jetbrains.annotations.Nullable; public interface ExtPlayNetworkHandler { /*@Nullable @@ -10,4 +8,6 @@ public interface ExtPlayNetworkHandler { void styledChat$setStyle(ChatStyle style); ChatStyle styledChat$getStyle(); + + boolean styledChat$chatColors(); } diff --git a/src/main/java/eu/pb4/styledchat/mixin/SentMessageMixin.java b/src/main/java/eu/pb4/styledchat/mixin/SentMessageMixin.java index f116bd8..c2ad2e6 100644 --- a/src/main/java/eu/pb4/styledchat/mixin/SentMessageMixin.java +++ b/src/main/java/eu/pb4/styledchat/mixin/SentMessageMixin.java @@ -8,6 +8,7 @@ import net.minecraft.network.message.MessageType; import net.minecraft.network.message.SentMessage; import net.minecraft.network.message.SignedMessage; +import org.apache.commons.lang3.mutable.MutableObject; import org.spongepowered.asm.mixin.Final; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Shadow; @@ -25,9 +26,9 @@ public interface SentMessageMixin { var type = ((ExtSignedMessage) (Object) message).styledChat_getType(); if (message.isSenderMissing()) { - cir.setReturnValue(new StyledChatSentMessage.System(message, override, StyledChatUtils.createParameters(override), type)); + cir.setReturnValue(new StyledChatSentMessage.System(message, override, StyledChatUtils.createParameters(override), type, new MutableObject<>())); } else { - cir.setReturnValue(new StyledChatSentMessage.Chat(message, override, StyledChatUtils.createParameters(override), type)); + cir.setReturnValue(new StyledChatSentMessage.Chat(message, override, StyledChatUtils.createParameters(override), type, new MutableObject<>())); } } } diff --git a/src/main/java/eu/pb4/styledchat/mixin/ServerPlayNetworkManagerMixin.java b/src/main/java/eu/pb4/styledchat/mixin/ServerPlayNetworkManagerMixin.java index beba055..06f6f3b 100644 --- a/src/main/java/eu/pb4/styledchat/mixin/ServerPlayNetworkManagerMixin.java +++ b/src/main/java/eu/pb4/styledchat/mixin/ServerPlayNetworkManagerMixin.java @@ -1,14 +1,16 @@ package eu.pb4.styledchat.mixin; +import eu.pb4.placeholders.api.PlaceholderContext; +import eu.pb4.styledchat.StyledChatMod; import eu.pb4.styledchat.StyledChatStyles; import eu.pb4.styledchat.config.ChatStyle; +import eu.pb4.styledchat.config.ConfigManager; import eu.pb4.styledchat.ducks.ExtPlayNetworkHandler; import eu.pb4.styledchat.StyledChatUtils; -import eu.pb4.styledchat.config.ConfigManager; import net.minecraft.network.message.MessageDecorator; import net.minecraft.network.message.MessageType; import net.minecraft.network.message.SignedMessage; -import net.minecraft.server.MinecraftServer; +import net.minecraft.network.packet.c2s.play.ClientSettingsC2SPacket; import net.minecraft.server.network.ServerPlayNetworkHandler; import net.minecraft.server.network.ServerPlayerEntity; import net.minecraft.text.*; @@ -19,6 +21,8 @@ import org.spongepowered.asm.mixin.injection.Redirect; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; +import java.util.concurrent.CompletableFuture; + @Mixin(ServerPlayNetworkHandler.class) public abstract class ServerPlayNetworkManagerMixin implements ExtPlayNetworkHandler { @@ -27,15 +31,21 @@ public abstract class ServerPlayNetworkManagerMixin implements ExtPlayNetworkHan @Unique private ChatStyle styledChat$style; + @Unique + private boolean styledChat$chatColors = true; @ModifyArg(method = "onDisconnected", at = @At(value = "INVOKE", target = "Lnet/minecraft/server/PlayerManager;broadcast(Lnet/minecraft/text/Text;Z)V")) private Text styledChat_replaceDisconnectMessage(Text text) { return StyledChatStyles.getLeft(this.player); } - @Redirect(method = "method_44900", at = @At(value = "INVOKE", target = "Lnet/minecraft/server/MinecraftServer;getMessageDecorator()Lnet/minecraft/network/message/MessageDecorator;")) - private MessageDecorator styledChat_replaceDecorator2(MinecraftServer instance) { - return StyledChatUtils.getRawDecorator(); + @Redirect(method = "method_44900", at = @At(value = "INVOKE", target = "Lnet/minecraft/network/message/MessageDecorator;decorate(Lnet/minecraft/server/network/ServerPlayerEntity;Lnet/minecraft/text/Text;)Ljava/util/concurrent/CompletableFuture;")) + private CompletableFuture styledChat_replaceDecorator2(MessageDecorator instance, ServerPlayerEntity player, Text text) { + if (player != null) { + return CompletableFuture.completedFuture(StyledChatUtils.formatFor(PlaceholderContext.of(player), text.getString())); + } else { + return CompletableFuture.completedFuture(StyledChatUtils.formatFor(PlaceholderContext.of(StyledChatMod.server), text.getString())); + } } @Inject(method = "handleDecoratedMessage", at = @At("HEAD")) @@ -43,6 +53,11 @@ private void styledChat_setFormattedMessage(SignedMessage signedMessage, Callbac StyledChatUtils.modifyForSending(signedMessage, this.player.getCommandSource(), MessageType.CHAT); } + @Inject(method = "onClientSettings", at = @At("TAIL")) + private void styledChat_setFormattedMessage(ClientSettingsC2SPacket packet, CallbackInfo ci) { + this.styledChat$chatColors = packet.chatColors(); + } + @Override public ChatStyle styledChat$getStyle() { if (this.styledChat$style == null) { @@ -55,4 +70,9 @@ private void styledChat_setFormattedMessage(SignedMessage signedMessage, Callbac public void styledChat$setStyle(ChatStyle style) { this.styledChat$style = style; } + + @Override + public boolean styledChat$chatColors() { + return this.styledChat$chatColors || !ConfigManager.getConfig().configData.formatting.respectColors; + } } diff --git a/src/main/java/eu/pb4/styledchat/other/GenericModInfo.java b/src/main/java/eu/pb4/styledchat/other/GenericModInfo.java index d8794b4..50dd2e3 100644 --- a/src/main/java/eu/pb4/styledchat/other/GenericModInfo.java +++ b/src/main/java/eu/pb4/styledchat/other/GenericModInfo.java @@ -62,7 +62,7 @@ public static void build(ModContainer container) { try { about.add(Text.literal(container.getMetadata().getName()).setStyle(Style.EMPTY.withColor(Formatting.YELLOW).withBold(true).withClickEvent(new ClickEvent(ClickEvent.Action.OPEN_URL,container.getMetadata().getContact().get("github").orElse(""))))); - about.add(Text.translatable("Version: %s").setStyle(Style.EMPTY.withColor(0xf7e1a7)) + about.add(Text.translatable("Version: ").setStyle(Style.EMPTY.withColor(0xf7e1a7)) .append(Text.literal(container.getMetadata().getVersion().getFriendlyString()).setStyle(Style.EMPTY.withColor(Formatting.WHITE)))); aboutBasic.addAll(about); diff --git a/src/main/java/eu/pb4/styledchat/other/StyledChatSentMessage.java b/src/main/java/eu/pb4/styledchat/other/StyledChatSentMessage.java index 2b67d26..5eb4976 100644 --- a/src/main/java/eu/pb4/styledchat/other/StyledChatSentMessage.java +++ b/src/main/java/eu/pb4/styledchat/other/StyledChatSentMessage.java @@ -3,6 +3,7 @@ import eu.pb4.styledchat.StyledChatMod; import eu.pb4.styledchat.StyledChatStyles; import eu.pb4.styledchat.StyledChatUtils; +import eu.pb4.styledchat.ducks.ExtPlayNetworkHandler; import eu.pb4.styledchat.ducks.ExtSignedMessage; import net.minecraft.network.message.MessageType; import net.minecraft.network.message.SentMessage; @@ -12,6 +13,7 @@ import net.minecraft.server.network.ServerPlayerEntity; import net.minecraft.text.Text; import net.minecraft.text.TextContent; +import org.apache.commons.lang3.mutable.MutableObject; import java.util.Objects; @@ -29,7 +31,7 @@ public interface StyledChatSentMessage extends SentMessage, ExtendedSentMessage return this.message(); } - record Chat(SignedMessage message, Text override, MessageType.Parameters parameters, RegistryKey sourceType) implements StyledChatSentMessage { + record Chat(SignedMessage message, Text override, MessageType.Parameters parameters, RegistryKey sourceType, MutableObject colorless) implements StyledChatSentMessage { public Text getContent() { return message.unsignedContent(); } @@ -37,11 +39,15 @@ public Text getContent() { @Override public void send(ServerPlayerEntity receiver, boolean filterMaskEnabled, MessageType.Parameters params) { SignedMessage signedMessage = this.message.withFilterMaskEnabled(filterMaskEnabled); + var color = ((ExtPlayNetworkHandler) receiver.networkHandler).styledChat$chatColors(); + if (!color && colorless.getValue() == null) { + colorless.setValue(StyledChatUtils.removeColor(parameters)); + } if (!signedMessage.isFullyFiltered()) { 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); + receiver.networkHandler.sendChatMessage(signedMessage, color ? this.parameters : colorless.getValue()); } else { var baseInput = ExtSignedMessage.getArg(signedMessage, "base_input"); var source = ExtSignedMessage.of(signedMessage).styledChat_getSource(); @@ -50,19 +56,24 @@ public void send(ServerPlayerEntity receiver, boolean filterMaskEnabled, Message ? baseInput : signedMessage.getContent(); + var text = StyledChatStyles.getCustom(id, params.name(), input, params.targetName(), source != null ? source : StyledChatMod.server.getCommandSource()); + + if (!color) { + text = StyledChatUtils.removeColor(text); + } - receiver.networkHandler.sendChatMessage(signedMessage, StyledChatUtils.createParameters(StyledChatStyles.getCustom(id, params.name(), input, params.targetName(), source != null ? source : StyledChatMod.server.getCommandSource()))); + receiver.networkHandler.sendChatMessage(signedMessage, StyledChatUtils.createParameters(text)); } } } @Override public StyledChatSentMessage reformat(MessageType.Parameters pars, RegistryKey sourceType) { - return new StyledChatSentMessage.Chat(message, override, pars, sourceType); + return new StyledChatSentMessage.Chat(message, override, pars, sourceType, new MutableObject<>()); } } - record System(SignedMessage message, Text override, MessageType.Parameters parameters, RegistryKey sourceType) implements StyledChatSentMessage { + record System(SignedMessage message, Text override, MessageType.Parameters parameters, RegistryKey sourceType, MutableObject colorless) implements StyledChatSentMessage { public Text getContent() { return this.message.unsignedContent(); } @@ -70,9 +81,13 @@ public Text getContent() { @Override public void send(ServerPlayerEntity receiver, boolean filterMaskEnabled, MessageType.Parameters params) { var id = receiver.server.getRegistryManager().get(RegistryKeys.MESSAGE_TYPE).getId(params.type()); + var color = ((ExtPlayNetworkHandler) receiver.networkHandler).styledChat$chatColors(); + if (!color && colorless.getValue() == null) { + colorless.setValue(StyledChatUtils.removeColor(parameters)); + } if (sourceType == null || Objects.equals(id, this.sourceType.getValue())) { - receiver.networkHandler.sendProfilelessChatMessage(message.getContent(), this.parameters); + receiver.networkHandler.sendProfilelessChatMessage(message.getContent(), color ? this.parameters : colorless.getValue()); } else { var baseInput = ExtSignedMessage.getArg(message, "base_input"); var source = ExtSignedMessage.of(message).styledChat_getSource(); @@ -81,13 +96,21 @@ public void send(ServerPlayerEntity receiver, boolean filterMaskEnabled, Message ? baseInput : message.getContent(); - receiver.networkHandler.sendProfilelessChatMessage(message.getContent(), StyledChatUtils.createParameters(StyledChatStyles.getCustom(id, params.name(), input, params.targetName(), source != null ? source : StyledChatMod.server.getCommandSource()))); + var text = StyledChatStyles.getCustom(id, params.name(), input, params.targetName(), source != null ? source : StyledChatMod.server.getCommandSource()); + + if (!color) { + text = StyledChatUtils.removeColor(text); + } + + receiver.networkHandler.sendProfilelessChatMessage(message.getContent(), StyledChatUtils.createParameters(text)); } } @Override public StyledChatSentMessage reformat(MessageType.Parameters pars, RegistryKey sourceType) { - return new StyledChatSentMessage.Chat(message, override, pars, sourceType); + return new StyledChatSentMessage.Chat(message, override, pars, sourceType, new MutableObject<>()); } } + + } diff --git a/src/main/resources/fabric.mod.json b/src/main/resources/fabric.mod.json index 9728159..255af97 100644 --- a/src/main/resources/fabric.mod.json +++ b/src/main/resources/fabric.mod.json @@ -14,7 +14,7 @@ }, "license": "LGPLv3", - "icon": "./assets/icon.png", + "icon": "assets/icon.png", "environment": "*", "entrypoints": { "main": [