diff --git a/build.gradle b/build.gradle index 17fde4a..89f25cb 100644 --- a/build.gradle +++ b/build.gradle @@ -37,7 +37,7 @@ dependencies { modCompileOnly("net.fabricmc.fabric-api:fabric-api:${project.fabric_version}") modLocalRuntime("net.fabricmc.fabric-api:fabric-api:${project.fabric_version}") - modImplementation include("eu.pb4:placeholder-api:2.0.0-beta.5+1.19") + modImplementation include("eu.pb4:placeholder-api:2.0.0-beta.7+1.19") modImplementation include("me.lucko:fabric-permissions-api:0.1-SNAPSHOT") //modRuntime "supercoder79:databreaker:0.2.7" diff --git a/gradle.properties b/gradle.properties index 1e91817..c0cf67c 100644 --- a/gradle.properties +++ b/gradle.properties @@ -8,10 +8,10 @@ yarn_mappings=1.19+build.1 loader_version=0.14.6 #Fabric api -fabric_version=0.55.1+1.19 +fabric_version=0.57.0+1.19 # Mod Properties - mod_version = 1.3.2+1.19 + mod_version = 1.3.3+1.19 maven_group = eu.pb4 archives_base_name = styled-chat diff --git a/src/main/java/eu/pb4/styledchat/StyledChatMod.java b/src/main/java/eu/pb4/styledchat/StyledChatMod.java index e7a4d18..90e3946 100644 --- a/src/main/java/eu/pb4/styledchat/StyledChatMod.java +++ b/src/main/java/eu/pb4/styledchat/StyledChatMod.java @@ -1,6 +1,7 @@ package eu.pb4.styledchat; import com.mojang.serialization.Lifecycle; +import eu.pb4.placeholders.api.Placeholders; import eu.pb4.styledchat.command.Commands; import eu.pb4.styledchat.config.ConfigManager; import net.fabricmc.api.ModInitializer; @@ -32,24 +33,17 @@ public void onInitialize() { this.crabboardDetection(); Commands.register(); - BuiltinRegistries.add(BuiltinRegistries.MESSAGE_TYPE, MESSAGE_TYPE, - new MessageType(Optional.of(new MessageType.DisplayRule(Optional.of(Decoration.ofChat("%s")))), - Optional.empty(), - Optional.of(MessageType.NarrationRule.of(Decoration.ofChat("%s"), MessageType.NarrationRule.Kind.CHAT))) - ); - ServerLifecycleEvents.SERVER_STARTING.register((s) -> { this.crabboardDetection(); - server = s; - }); - - ServerLifecycleEvents.SERVER_STARTED.register((s) -> { ConfigManager.loadConfig(); + server = s; }); ServerLifecycleEvents.SERVER_STOPPED.register((s) -> { server = null; }); + + Placeholders.registerChangeEvent((id, removed) -> ConfigManager.clearCached()); } private void crabboardDetection() { diff --git a/src/main/java/eu/pb4/styledchat/StyledChatUtils.java b/src/main/java/eu/pb4/styledchat/StyledChatUtils.java index 7b32cd3..41a6f9f 100644 --- a/src/main/java/eu/pb4/styledchat/StyledChatUtils.java +++ b/src/main/java/eu/pb4/styledchat/StyledChatUtils.java @@ -48,12 +48,16 @@ public final class StyledChatUtils { public static final String POS_TAG = "pos"; public static final String SPOILER_TAG = "spoiler"; + public static final TextParserV1.TagNodeBuilder SPOILER_TAG_HANDLER = (tag, data, input, handlers, endAt) -> { var out = TextParserV1.parseNodesWith(input, handlers, endAt); return new TextParserV1.TagNodeValue(new SpoilerNode(out.nodes()), out.length()); }; + public static final TextParserV1.TextTag SPOILER_TEXT_TAG = TextParserV1.TextTag.of(SPOILER_TAG, List.of("hide"), "styledchat", true, SPOILER_TAG_HANDLER); + + public static final String FORMAT_PERMISSION_BASE = "styledchat.format."; public static final String FORMAT_PERMISSION_UNSAFE = "styledchat.unsafe_format."; public static final Pattern EMOTE_PATTERN = Pattern.compile("[:](?[^:]+)[:]"); @@ -69,7 +73,7 @@ public static TextParserV1 createParser(ServerCommandSource source) { Config config = ConfigManager.getConfig(); for (var entry : TextParserV1.DEFAULT.getTags()) { - if (config.defaultFormattingCodes.getBoolean(entry) + if (config.defaultFormattingCodes.getBoolean(entry.name()) || Permissions.check(source, (entry.userSafe() ? FORMAT_PERMISSION_BASE : FORMAT_PERMISSION_UNSAFE) + entry.name(), entry.userSafe() ? 2 : 4) || Permissions.check(source, (entry.userSafe() ? FORMAT_PERMISSION_BASE : FORMAT_PERMISSION_UNSAFE) + ".type." + entry.type(), entry.userSafe() ? 2 : 4) ) { @@ -79,8 +83,7 @@ public static TextParserV1 createParser(ServerCommandSource source) { if (config.defaultFormattingCodes.getBoolean(SPOILER_TAG) || Permissions.check(source, FORMAT_PERMISSION_BASE + SPOILER_TAG, 2)) { - - parser.register(TextParserV1.TextTag.of(SPOILER_TAG, List.of("hide"), "styledchat", true, SPOILER_TAG_HANDLER)); + parser.register(SPOILER_TEXT_TAG); } StyledChatEvents.FORMATTING_CREATION_EVENT.invoker().onFormattingBuild(source, parser); @@ -346,4 +349,13 @@ public static Text formatFor(ServerCommandSource source, String original) { return formatFor(PlaceholderContext.of(source.getServer()), original); } } + + public static FilteredMessage toEventMessage(FilteredMessage message, PlaceholderContext context) { + var ext = (ExtSignedMessage) (Object) message.raw(); + + var baseInput = ext.styledChat_getArg("base_input"); + var input = baseInput != null && baseInput.getContent() != TextContent.EMPTY ? baseInput : formatFor(context, ext.styledChat_getOriginal()); + + return FilteredMessage.permitted(SignedMessage.of(input)); + } } diff --git a/src/main/java/eu/pb4/styledchat/config/ConfigManager.java b/src/main/java/eu/pb4/styledchat/config/ConfigManager.java index 4ac004c..102d0b7 100644 --- a/src/main/java/eu/pb4/styledchat/config/ConfigManager.java +++ b/src/main/java/eu/pb4/styledchat/config/ConfigManager.java @@ -15,13 +15,27 @@ public class ConfigManager { public static final int VERSION = 2; private static final Gson GSON = new GsonBuilder().setPrettyPrinting().disableHtmlEscaping().setLenient().create(); - private static Config CONFIG = null; + private static Config config = null; + private static ConfigData configData = null; public static Config getConfig() { - return CONFIG; + if (config == null) { + if (configData == null) { + loadConfig(); + } + + config = new Config(configData); + } + + return config; + } + + public static void clearCached() { + config = null; } public static boolean loadConfig() { + config = null; try { ConfigData config; File configFile = new File(FabricLoader.getInstance().getConfigDir().toFile(), "styled-chat.json"); @@ -44,14 +58,13 @@ public static boolean loadConfig() { writer.write(GSON.toJson(config)); writer.close(); - - CONFIG = new Config(config); + configData = config; return true; } catch(Exception exception) { StyledChatMod.LOGGER.error("Something went wrong while reading config! Make sure format is correct!"); exception.printStackTrace(); - if (CONFIG == null) { - CONFIG = new Config(new ConfigData()); + if (configData == null) { + configData = new ConfigData(); } return false; } diff --git a/src/main/java/eu/pb4/styledchat/mixin/MessageTypeMixin.java b/src/main/java/eu/pb4/styledchat/mixin/MessageTypeMixin.java index 20cdeee..bd4e9c1 100644 --- a/src/main/java/eu/pb4/styledchat/mixin/MessageTypeMixin.java +++ b/src/main/java/eu/pb4/styledchat/mixin/MessageTypeMixin.java @@ -1,16 +1,28 @@ package eu.pb4.styledchat.mixin; +import eu.pb4.styledchat.StyledChatMod; import net.minecraft.network.message.MessageType; +import net.minecraft.text.Decoration; +import net.minecraft.util.registry.BuiltinRegistries; +import net.minecraft.util.registry.Registry; +import net.minecraft.util.registry.RegistryEntry; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.ModifyArg; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; import java.util.Optional; @Mixin(MessageType.class) public class MessageTypeMixin { - @ModifyArg(method = "initialize", at = @At(value = "INVOKE", target = "Lnet/minecraft/network/message/MessageType;(Ljava/util/Optional;Ljava/util/Optional;Ljava/util/Optional;)V"), index = 0) - private static Optional styledChat_replace(Optional optional) { - return optional.isPresent() && optional.get().decoration().isPresent() ? Optional.of(MessageType.DisplayRule.of()) : optional; + @Inject(method = "initialize", at = @At("TAIL")) + private static void styledChat_replace(Registry registry, CallbackInfoReturnable> cir) { + + BuiltinRegistries.add(registry, StyledChatMod.MESSAGE_TYPE, + new MessageType(Optional.of(new MessageType.DisplayRule(Optional.of(Decoration.ofChat("%s")))), + Optional.empty(), + Optional.of(MessageType.NarrationRule.of(Decoration.ofChat("%s"), MessageType.NarrationRule.Kind.CHAT))) + ); } } diff --git a/src/main/java/eu/pb4/styledchat/mixin/PlayerManagerMixin.java b/src/main/java/eu/pb4/styledchat/mixin/PlayerManagerMixin.java index 08ecf9e..326d93c 100644 --- a/src/main/java/eu/pb4/styledchat/mixin/PlayerManagerMixin.java +++ b/src/main/java/eu/pb4/styledchat/mixin/PlayerManagerMixin.java @@ -72,7 +72,7 @@ private void styledChat_excludeSendingOfHiddenMessages2(Text message, Function ALLOW_CHAT_MESSAGE; + + @Mutable + @Shadow @Final public static Event ALLOW_COMMAND_MESSAGE; + + @Mutable + @Shadow @Final public static Event CHAT_MESSAGE; + + @Mutable + @Shadow @Final public static Event COMMAND_MESSAGE; + + @Inject(method = "", at = @At("TAIL")) + private static void styledChat_replaceEvents(CallbackInfo ci) { + ALLOW_CHAT_MESSAGE = new WrappedEvent<>(ALLOW_CHAT_MESSAGE, + e -> (message, sender, typeKey) -> e.invoker().allowChatMessage(StyledChatUtils.toEventMessage(message, PlaceholderContext.of(sender)), sender, typeKey)); + + ALLOW_COMMAND_MESSAGE = new WrappedEvent<>(ALLOW_COMMAND_MESSAGE, + e -> (message, sender, typeKey) -> e.invoker().allowCommandMessage(StyledChatUtils.toEventMessage(message, PlaceholderContext.of(sender)), sender, typeKey)); + + CHAT_MESSAGE = new WrappedEvent<>(CHAT_MESSAGE, + e -> (message, sender, typeKey) -> e.invoker().onChatMessage(StyledChatUtils.toEventMessage(message, PlaceholderContext.of(sender)), sender, typeKey)); + + COMMAND_MESSAGE = new WrappedEvent<>(COMMAND_MESSAGE, + e -> (message, sender, typeKey) -> e.invoker().onCommandMessage(StyledChatUtils.toEventMessage(message, PlaceholderContext.of(sender)), sender, typeKey)); + + } +} diff --git a/src/main/java/eu/pb4/styledchat/other/WrappedEvent.java b/src/main/java/eu/pb4/styledchat/other/WrappedEvent.java new file mode 100644 index 0000000..4b6111d --- /dev/null +++ b/src/main/java/eu/pb4/styledchat/other/WrappedEvent.java @@ -0,0 +1,19 @@ +package eu.pb4.styledchat.other; + +import net.fabricmc.fabric.api.event.Event; + +import java.util.function.Function; + +public final class WrappedEvent extends Event { + public final Event event; + + public WrappedEvent(Event event, Function, T> argModifier) { + this.event = event; + this.invoker = argModifier.apply(event); + } + + @Override + public void register(T listener) { + this.event.register(listener); + } +} diff --git a/src/main/resources/fabric.mod.json b/src/main/resources/fabric.mod.json index 98a59ab..58bb17e 100644 --- a/src/main/resources/fabric.mod.json +++ b/src/main/resources/fabric.mod.json @@ -26,7 +26,7 @@ ], "depends": { - "minecraft": ">=1.18-rc.1" + "minecraft": "1.19" }, "custom": { "modmenu": { diff --git a/src/main/resources/styledchat.mixins.json b/src/main/resources/styledchat.mixins.json index 2a7d016..8d042e5 100644 --- a/src/main/resources/styledchat.mixins.json +++ b/src/main/resources/styledchat.mixins.json @@ -16,6 +16,7 @@ "PlayerEntityMixin", "PlayerManagerMixin", "SayCommandMixin", + "ServerMessageEventsMixin", "ServerPlayerEntityMixin", "ServerPlayNetworkManagerMixin", "SignedMessageMixin",