diff --git a/src/main/java/land/chipmunk/chipmunkmod/commands/CustomChatCommand.java b/src/main/java/land/chipmunk/chipmunkmod/commands/CustomChatCommand.java index 02b0014..a808026 100644 --- a/src/main/java/land/chipmunk/chipmunkmod/commands/CustomChatCommand.java +++ b/src/main/java/land/chipmunk/chipmunkmod/commands/CustomChatCommand.java @@ -29,6 +29,13 @@ public class CustomChatCommand { .executes(CustomChatCommand::enabled) ) ) + .then( + literal("onlyUseWhenNecessary") + .then( + argument("boolean", bool()) + .executes(CustomChatCommand::onlyUseWhenNecessary) + ) + ) .then( literal("format") .then( @@ -48,6 +55,17 @@ public class CustomChatCommand { return Command.SINGLE_SUCCESS; } + public static int onlyUseWhenNecessary (final CommandContext context) { + final FabricClientCommandSource source = context.getSource(); + final boolean bool = getBool(context, "boolean"); + CustomChat.INSTANCE.onlyUseWhenNecessary = bool; + + if (bool) source.sendFeedback(Text.literal("Custom chat now only gets used when necessary")); + else source.sendFeedback(Text.literal("Custom chat now always get used")); + + return Command.SINGLE_SUCCESS; + } + public static int setFormat (final CommandContext context) { final FabricClientCommandSource source = context.getSource(); final String format = getString(context, "format"); diff --git a/src/main/java/land/chipmunk/chipmunkmod/commands/ReloadConfigCommand.java b/src/main/java/land/chipmunk/chipmunkmod/commands/ReloadConfigCommand.java index cbc0d46..2be414e 100644 --- a/src/main/java/land/chipmunk/chipmunkmod/commands/ReloadConfigCommand.java +++ b/src/main/java/land/chipmunk/chipmunkmod/commands/ReloadConfigCommand.java @@ -5,6 +5,7 @@ import com.mojang.brigadier.CommandDispatcher; import com.mojang.brigadier.context.CommandContext; import land.chipmunk.chipmunkmod.ChipmunkMod; import land.chipmunk.chipmunkmod.modules.CommandCore; +import land.chipmunk.chipmunkmod.modules.custom_chat.CustomChat; import net.fabricmc.fabric.api.client.command.v2.FabricClientCommandSource; import net.minecraft.text.Text; @@ -25,12 +26,14 @@ public class ReloadConfigCommand { try { ChipmunkMod.CONFIG = ChipmunkMod.loadConfig(); + CommandCore.INSTANCE.reloadRelativeArea(); + CustomChat.INSTANCE.reloadFromConfig(); source.sendFeedback(Text.literal("Successfully reloaded the config")); } catch (final IOException e) { source.sendError(Text.literal("Could not load config, check the logs for stacktrace")); - e.printStackTrace(); + ChipmunkMod.LOGGER.error("Could not load the config!", e); } return Command.SINGLE_SUCCESS; diff --git a/src/main/java/land/chipmunk/chipmunkmod/config/Configuration.java b/src/main/java/land/chipmunk/chipmunkmod/config/Configuration.java index 6123ec0..7d16a8b 100644 --- a/src/main/java/land/chipmunk/chipmunkmod/config/Configuration.java +++ b/src/main/java/land/chipmunk/chipmunkmod/config/Configuration.java @@ -79,6 +79,9 @@ public class Configuration { @ConfigSerializable public static class CustomChat { + public boolean enabled = true; + public boolean onlyUseWhenNecessary = false; + public @NotNull Component format = // chipmunk's custom chat format // §8[§7Chat§8] §aUSERNAME§8 › §7MESSAGE diff --git a/src/main/java/land/chipmunk/chipmunkmod/config/migrations/MigrationV2.java b/src/main/java/land/chipmunk/chipmunkmod/config/migrations/MigrationV2.java index 258b9d5..d27e865 100644 --- a/src/main/java/land/chipmunk/chipmunkmod/config/migrations/MigrationV2.java +++ b/src/main/java/land/chipmunk/chipmunkmod/config/migrations/MigrationV2.java @@ -6,7 +6,7 @@ import org.spongepowered.configurate.transformation.TransformAction; import static org.spongepowered.configurate.NodePath.path; -public class MigrationV2 implements ConfigMigration { +public final class MigrationV2 implements ConfigMigration { @Override public int version () { return 2; diff --git a/src/main/java/land/chipmunk/chipmunkmod/config/migrations/MigrationV3.java b/src/main/java/land/chipmunk/chipmunkmod/config/migrations/MigrationV3.java index c78ac58..17e7610 100644 --- a/src/main/java/land/chipmunk/chipmunkmod/config/migrations/MigrationV3.java +++ b/src/main/java/land/chipmunk/chipmunkmod/config/migrations/MigrationV3.java @@ -6,7 +6,7 @@ import org.spongepowered.configurate.transformation.TransformAction; import static org.spongepowered.configurate.NodePath.path; -public class MigrationV3 implements ConfigMigration { +public final class MigrationV3 implements ConfigMigration { @Override public int version () { return 3; diff --git a/src/main/java/land/chipmunk/chipmunkmod/mixin/StringHelperMixin.java b/src/main/java/land/chipmunk/chipmunkmod/mixin/StringHelperMixin.java index adb85aa..0c6fe53 100644 --- a/src/main/java/land/chipmunk/chipmunkmod/mixin/StringHelperMixin.java +++ b/src/main/java/land/chipmunk/chipmunkmod/mixin/StringHelperMixin.java @@ -1,5 +1,6 @@ package land.chipmunk.chipmunkmod.mixin; +import land.chipmunk.chipmunkmod.modules.custom_chat.CustomChat; import net.minecraft.util.StringHelper; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; @@ -10,6 +11,11 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; public class StringHelperMixin { @Inject(method = "isValidChar", at = @At("RETURN"), cancellable = true) private static void isValidChar (final char c, final CallbackInfoReturnable cir) { + if (!CustomChat.SHOULD_IGNORE_INVALID_CHAR.get()) { + CustomChat.SHOULD_IGNORE_INVALID_CHAR.set(true); + return; + } + // very legal [NUL] [LF] § Allowance. cir.setReturnValue(true); } diff --git a/src/main/java/land/chipmunk/chipmunkmod/modules/custom_chat/CustomChat.java b/src/main/java/land/chipmunk/chipmunkmod/modules/custom_chat/CustomChat.java index be5f99f..bd39f3f 100644 --- a/src/main/java/land/chipmunk/chipmunkmod/modules/custom_chat/CustomChat.java +++ b/src/main/java/land/chipmunk/chipmunkmod/modules/custom_chat/CustomChat.java @@ -13,6 +13,7 @@ import net.kyori.adventure.text.serializer.gson.GsonComponentSerializer; import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer; import net.minecraft.client.MinecraftClient; import net.minecraft.client.network.ClientPlayerEntity; +import net.minecraft.util.StringHelper; import java.util.Map; import java.util.regex.Pattern; @@ -51,19 +52,30 @@ public class CustomChat { .build(); - private final MinecraftClient client; - public boolean enabled = true; + public static final ThreadLocal SHOULD_IGNORE_INVALID_CHAR = ThreadLocal.withInitial(() -> true); - public Component format = ChipmunkMod.CONFIG.customChat.format; + private final MinecraftClient client; + + public boolean enabled; + public boolean onlyUseWhenNecessary; + + public Component format; public CustomChat (final MinecraftClient client) { this.client = client; + reloadFromConfig(); + } + + public void reloadFromConfig () { + this.format = ChipmunkMod.CONFIG.customChat.format; + this.enabled = ChipmunkMod.CONFIG.customChat.enabled; + this.onlyUseWhenNecessary = ChipmunkMod.CONFIG.customChat.onlyUseWhenNecessary; } public void chat (final String message) { final ClientPlayerEntity player = client.player; if (player == null) return; - if (!enabled || !player.hasPermissionLevel(2) || !player.isCreative()) { + if (shouldUsePlayerChat(player, message)) { Chat.sendChatMessage(message, true); return; } @@ -80,4 +92,19 @@ public class CustomChat { CommandCore.INSTANCE.run((KaboomCheck.INSTANCE.isKaboom ? "minecraft:tellraw @a " : "tellraw @a ") + json); } + + private boolean shouldUsePlayerChat (final ClientPlayerEntity player, final String message) { + return !enabled || isUnnecessary(message) || !player.hasPermissionLevel(2) || !player.isCreative(); + } + + private boolean isUnnecessary (final String message) { + if (!onlyUseWhenNecessary || message.isEmpty() || message.length() > 256) return false; + + for (final char character : message.toCharArray()) { + SHOULD_IGNORE_INVALID_CHAR.set(false); + if (!StringHelper.isValidChar(character)) return false; + } + + return true; + } }