From 1b7ace7aa8f32adc1ea302797fa0f589b8aedbdf Mon Sep 17 00:00:00 2001 From: ChomeNS <95471003+ChomeNS@users.noreply.github.com> Date: Thu, 13 Jul 2023 20:22:19 +0700 Subject: [PATCH] add and fix stuff about chomens bot 15 files modified basically this fixes and improves the command suggestion and make the validation automatic --- .../chipmunkmod/command/CommandManager.java | 2 +- .../chipmunkmod/commands/ValidateCommand.java | 143 ++---------------- .../chipmunkmod/data/ChomeNSBotCommand.java | 20 +++ .../chipmunkmod/listeners/Listener.java | 4 + .../chipmunkmod/mixin/ChatHudMixin.java | 49 +----- .../mixin/ChatInputSuggestorAccessor.java | 17 --- .../mixin/ChatInputSuggestorMixin.java | 52 +++---- .../chipmunkmod/mixin/ChatScreenAccessor.java | 12 -- .../chipmunkmod/mixin/ChatScreenMixin.java | 29 +++- .../mixin/ClientPlayNetworkHandlerMixin.java | 2 + .../chipmunkmod/modules/ChatInputGlobals.java | 8 - .../modules/ChomeNSBotCommandSuggestions.java | 79 ++++++++++ .../chipmunkmod/modules/CommandCore.java | 49 +++++- .../util/BotValidationUtilities.java | 116 ++++++++++++++ src/main/resources/chipmunkmod.mixins.json | 2 - 15 files changed, 336 insertions(+), 248 deletions(-) create mode 100644 src/main/java/land/chipmunk/chipmunkmod/data/ChomeNSBotCommand.java delete mode 100644 src/main/java/land/chipmunk/chipmunkmod/mixin/ChatInputSuggestorAccessor.java delete mode 100644 src/main/java/land/chipmunk/chipmunkmod/mixin/ChatScreenAccessor.java delete mode 100644 src/main/java/land/chipmunk/chipmunkmod/modules/ChatInputGlobals.java create mode 100644 src/main/java/land/chipmunk/chipmunkmod/modules/ChomeNSBotCommandSuggestions.java create mode 100644 src/main/java/land/chipmunk/chipmunkmod/util/BotValidationUtilities.java diff --git a/src/main/java/land/chipmunk/chipmunkmod/command/CommandManager.java b/src/main/java/land/chipmunk/chipmunkmod/command/CommandManager.java index c8cfbb0..6e438f8 100644 --- a/src/main/java/land/chipmunk/chipmunkmod/command/CommandManager.java +++ b/src/main/java/land/chipmunk/chipmunkmod/command/CommandManager.java @@ -53,7 +53,7 @@ public class CommandManager { if (context != null) commandSource.sendError(context); } catch (CommandException e) { commandSource.sendError(e.getTextMessage()); - } catch (RuntimeException e) { + } catch (Exception e) { commandSource.sendError(Text.of(e.getMessage())); } } diff --git a/src/main/java/land/chipmunk/chipmunkmod/commands/ValidateCommand.java b/src/main/java/land/chipmunk/chipmunkmod/commands/ValidateCommand.java index fa4734d..806f4cf 100644 --- a/src/main/java/land/chipmunk/chipmunkmod/commands/ValidateCommand.java +++ b/src/main/java/land/chipmunk/chipmunkmod/commands/ValidateCommand.java @@ -1,141 +1,28 @@ package land.chipmunk.chipmunkmod.commands; -import com.mojang.brigadier.Command; import com.mojang.brigadier.CommandDispatcher; -import com.mojang.brigadier.context.CommandContext; -import static land.chipmunk.chipmunkmod.command.CommandManager.literal; -import static land.chipmunk.chipmunkmod.command.CommandManager.argument; -import static com.mojang.brigadier.arguments.StringArgumentType.greedyString; -import static com.mojang.brigadier.arguments.StringArgumentType.getString; import net.fabricmc.fabric.api.client.command.v2.FabricClientCommandSource; -import com.mojang.brigadier.exceptions.CommandSyntaxException; -import com.mojang.brigadier.exceptions.SimpleCommandExceptionType; import net.minecraft.text.Text; -import net.minecraft.client.MinecraftClient; -import net.minecraft.client.network.ClientPlayNetworkHandler; -import java.util.Arrays; -import java.math.BigInteger; -import java.nio.charset.StandardCharsets; -import java.security.MessageDigest; -import java.security.NoSuchAlgorithmException; -import land.chipmunk.chipmunkmod.ChipmunkMod; -import land.chipmunk.chipmunkmod.Configuration; -import land.chipmunk.chipmunkmod.util.Hexadecimal; + +import static com.mojang.brigadier.arguments.StringArgumentType.getString; +import static com.mojang.brigadier.arguments.StringArgumentType.greedyString; +import static land.chipmunk.chipmunkmod.command.CommandManager.argument; +import static land.chipmunk.chipmunkmod.command.CommandManager.literal; +import static land.chipmunk.chipmunkmod.util.BotValidationUtilities.*; public class ValidateCommand { - private static final SimpleCommandExceptionType UNSPECIFIED_KEY = new SimpleCommandExceptionType(Text.literal("The key of the bot is unspecified (null), did you incorrectly add it to your config?")); - public static void register (CommandDispatcher dispatcher) { dispatcher.register( literal("validate") - .then(literal("hbot").then(argument("command", greedyString()).executes(c -> hbot(c)))) - .then(literal("sbot").then(argument("command", greedyString()).executes(c -> sbot(c)))) - // .then(literal("chipmunk").then(argument("command", greedyString()).executes(c -> chipmunk(c)))) - .then(literal("chomens").then(argument("command", greedyString()).executes(c -> chomens(c)))) - .then(literal("kittycorp").then(argument("command", greedyString()).executes(c -> kittycorp(c)))) + .then(literal("hbot").then(argument("command", greedyString()).executes(c -> hbot(getString(c, "command"))))) + .then(literal("sbot").then(argument("command", greedyString()).executes(c -> sbot(getString(c, "command"))))) + // .then(literal("chipmunk").then(argument("command", greedyString()).executes(c -> chipmunk(getString(c, "command"))))) + .then(literal("chomens").then(argument("command", greedyString()).executes(c -> { + c.getSource().sendFeedback(Text.literal("Warning: Manual ChomeNS Bot validation is deprecated")); + + return chomens(getString(c, "command")); + }))) + .then(literal("kittycorp").then(argument("command", greedyString()).executes(c -> kittycorp(getString(c, "command"))))) ); } - - - public static int hbot (CommandContext context) throws CommandSyntaxException { - final Configuration.BotInfo info = ChipmunkMod.CONFIG.bots.hbot; - final String command = getString(context, "command"); - final MinecraftClient client = context.getSource().getClient(); - final ClientPlayNetworkHandler networkHandler = client.getNetworkHandler(); - - final String prefix = info.prefix; - final String key = info.key; - if (key == null) throw UNSPECIFIED_KEY.create(); - - try { - MessageDigest md = MessageDigest.getInstance("SHA-256"); - String time = String.valueOf(System.currentTimeMillis() / 10000); - String input = command.replaceAll("&[0-9a-fklmnor]", "") + ";" + client.player.getUuidAsString() + ";" + time + ";" + key; - byte[] hash = md.digest(input.getBytes(StandardCharsets.UTF_8)); - BigInteger bigInt = new BigInteger(1, Arrays.copyOfRange(hash, 0, 4)); - String stringHash = bigInt.toString(Character.MAX_RADIX); - - networkHandler.sendChatMessage(prefix + command + " " + stringHash); - } catch (NoSuchAlgorithmException e) { - throw new SimpleCommandExceptionType(Text.literal(e.getMessage())).create(); - } - - return Command.SINGLE_SUCCESS; - } - - public static int sbot (CommandContext context) throws CommandSyntaxException { - final Configuration.BotInfo info = ChipmunkMod.CONFIG.bots.sbot; - final String command = getString(context, "command"); - final MinecraftClient client = context.getSource().getClient(); - final ClientPlayNetworkHandler networkHandler = client.getNetworkHandler(); - - final String prefix = info.prefix; - final String key = info.key; - if (key == null) throw UNSPECIFIED_KEY.create(); - - try { - MessageDigest md = MessageDigest.getInstance("SHA-256"); - String time = String.valueOf(System.currentTimeMillis() / 20000); - String input = prefix + command.replaceAll("&[0-9a-fklmnorx]", "") + ";" + client.player.getName() + ";" + time + ";" + key; - byte[] hash = md.digest(input.getBytes(StandardCharsets.UTF_8)); - BigInteger bigInt = new BigInteger(1, Arrays.copyOfRange(hash, 0, 4)); - String stringHash = bigInt.toString(Character.MAX_RADIX); - - networkHandler.sendChatMessage(prefix + command + " " + stringHash); - } catch (NoSuchAlgorithmException e) { - throw new SimpleCommandExceptionType(Text.literal(e.getMessage())).create(); - } - - return Command.SINGLE_SUCCESS; - } - - public static int chomens (CommandContext context) throws CommandSyntaxException { - final Configuration.BotInfo info = ChipmunkMod.CONFIG.bots.chomens; - final String command = getString(context, "command"); - final ClientPlayNetworkHandler networkHandler = context.getSource().getClient().getNetworkHandler(); - - final String prefix = info.prefix; - final String key = info.key; - if (key == null) throw UNSPECIFIED_KEY.create(); - - try { - MessageDigest md = MessageDigest.getInstance("SHA-256"); - String time = String.valueOf(System.currentTimeMillis() / 5_000); - String input = time + key; - byte[] hash = md.digest(input.getBytes(StandardCharsets.UTF_8)); - String stringHash = Hexadecimal.encode(hash).substring(0, 16); - - String[] arguments = command.split(" "); - networkHandler.sendChatMessage(prefix + arguments[0] + " " + stringHash + " " + String.join(" ", Arrays.copyOfRange(arguments, 1, arguments.length))); - } catch (NoSuchAlgorithmException e) { - throw new SimpleCommandExceptionType(Text.literal(e.getMessage())).create(); - } - - return Command.SINGLE_SUCCESS; - } - - public static int kittycorp (CommandContext context) throws CommandSyntaxException { - final Configuration.BotInfo info = ChipmunkMod.CONFIG.bots.kittycorp; - final String command = getString(context, "command"); - final ClientPlayNetworkHandler networkHandler = context.getSource().getClient().getNetworkHandler(); - - final String prefix = info.prefix; - final String key = info.key; - if (key == null) throw UNSPECIFIED_KEY.create(); - - try { - MessageDigest md = MessageDigest.getInstance("SHA-256"); - String time = String.valueOf(System.currentTimeMillis() / 10000); - String input = prefix + command.replaceAll("&[0-9a-fklmnorx]", "") + ";" + time + ";" + key; - byte[] hash = md.digest(input.getBytes(StandardCharsets.UTF_8)); - BigInteger bigInt = new BigInteger(1, Arrays.copyOfRange(hash, 0, 4)); - String stringHash = bigInt.toString(Character.MAX_RADIX); - - networkHandler.sendChatMessage(prefix + command + " " + stringHash); - } catch (NoSuchAlgorithmException e) { - throw new SimpleCommandExceptionType(Text.literal(e.getMessage())).create(); - } - - return Command.SINGLE_SUCCESS; - } } diff --git a/src/main/java/land/chipmunk/chipmunkmod/data/ChomeNSBotCommand.java b/src/main/java/land/chipmunk/chipmunkmod/data/ChomeNSBotCommand.java new file mode 100644 index 0000000..978e705 --- /dev/null +++ b/src/main/java/land/chipmunk/chipmunkmod/data/ChomeNSBotCommand.java @@ -0,0 +1,20 @@ +package land.chipmunk.chipmunkmod.data; + +public class ChomeNSBotCommand { + public final String name; + public final TrustLevel trustLevel; + + public ChomeNSBotCommand ( + String name, + TrustLevel trustLevel + ) { + this.name = name; + this.trustLevel = trustLevel; + } + + public enum TrustLevel { + PUBLIC, + TRUSTED, + OWNER + } +} diff --git a/src/main/java/land/chipmunk/chipmunkmod/listeners/Listener.java b/src/main/java/land/chipmunk/chipmunkmod/listeners/Listener.java index 5542c0e..26864e8 100644 --- a/src/main/java/land/chipmunk/chipmunkmod/listeners/Listener.java +++ b/src/main/java/land/chipmunk/chipmunkmod/listeners/Listener.java @@ -9,4 +9,8 @@ public class Listener { public void packetReceived (Packet packet) {} public void packetSent (Packet packet) {} + + public void coreReady () {} + + public void coreMoved () {} } diff --git a/src/main/java/land/chipmunk/chipmunkmod/mixin/ChatHudMixin.java b/src/main/java/land/chipmunk/chipmunkmod/mixin/ChatHudMixin.java index 5d0075c..1d83869 100644 --- a/src/main/java/land/chipmunk/chipmunkmod/mixin/ChatHudMixin.java +++ b/src/main/java/land/chipmunk/chipmunkmod/mixin/ChatHudMixin.java @@ -1,15 +1,11 @@ package land.chipmunk.chipmunkmod.mixin; -import com.mojang.brigadier.suggestion.SuggestionsBuilder; -import land.chipmunk.chipmunkmod.ChipmunkMod; import land.chipmunk.chipmunkmod.listeners.Listener; import land.chipmunk.chipmunkmod.listeners.ListenerManager; -import land.chipmunk.chipmunkmod.modules.ChatInputGlobals; +import land.chipmunk.chipmunkmod.modules.ChomeNSBotCommandSuggestions; import land.chipmunk.chipmunkmod.modules.RainbowName; -import net.minecraft.client.MinecraftClient; +import net.kyori.adventure.text.TextComponent; import net.minecraft.client.gui.hud.MessageIndicator; -import net.minecraft.client.gui.screen.ChatScreen; -import net.minecraft.command.CommandSource; import net.minecraft.network.message.MessageSignatureData; import net.minecraft.text.Text; import net.minecraft.text.TranslatableTextContent; @@ -18,8 +14,6 @@ import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; -import java.util.List; - @Mixin(net.minecraft.client.gui.hud.ChatHud.class) public class ChatHudMixin { @Inject(at = @At("HEAD"), method = "addMessage(Lnet/minecraft/text/Text;Lnet/minecraft/network/message/MessageSignatureData;ILnet/minecraft/client/gui/hud/MessageIndicator;Z)V", cancellable = true) @@ -43,40 +37,9 @@ public class ChatHudMixin { } try { - final List children = message.getSiblings(); - - if (children.size() == 0) return; - - if (!children.get(0).getString().equals("chomens_bot_command_suggestion")) return; - - ci.cancel(); - - final String[] matches = children.subList(2, children.size()) - .stream() - .map(Text::getString) - .toArray(String[]::new); - - if (!(MinecraftClient.getInstance().currentScreen instanceof ChatScreen chatScreen)) return; - - final ChatScreenAccessor chatScreenAccessor = (ChatScreenAccessor) chatScreen; - - final ChatInputSuggestorAccessor chatInputSuggestorAccessor = (ChatInputSuggestorAccessor) chatScreenAccessor.chatInputSuggestor(); - - chatInputSuggestorAccessor.setPendingSuggestions( - CommandSource.suggestMatching( - matches, - new SuggestionsBuilder( - ChatInputGlobals.textUpToCursor, - ChipmunkMod.CONFIG.bots.chomens.prefix.length() - ) - ) - ); - - chatInputSuggestorAccessor.pendingSuggestions().thenRun(() -> { - if (!chatInputSuggestorAccessor.pendingSuggestions().isDone()) return; - - ((ChatScreenAccessor) chatScreen).chatInputSuggestor().show(true); - }); - } catch (ClassCastException | NumberFormatException ignored) {} + if (((TextComponent) message.asComponent().children().get(0)).content().equals(ChomeNSBotCommandSuggestions.ID)) { + ci.cancel(); + } + } catch (Exception ignored) {} } } diff --git a/src/main/java/land/chipmunk/chipmunkmod/mixin/ChatInputSuggestorAccessor.java b/src/main/java/land/chipmunk/chipmunkmod/mixin/ChatInputSuggestorAccessor.java deleted file mode 100644 index dd9e9c5..0000000 --- a/src/main/java/land/chipmunk/chipmunkmod/mixin/ChatInputSuggestorAccessor.java +++ /dev/null @@ -1,17 +0,0 @@ -package land.chipmunk.chipmunkmod.mixin; - -import com.mojang.brigadier.suggestion.Suggestions; -import net.minecraft.client.gui.screen.ChatInputSuggestor; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.gen.Accessor; - -import java.util.concurrent.CompletableFuture; - -@Mixin(ChatInputSuggestor.class) -public interface ChatInputSuggestorAccessor { - @Accessor("pendingSuggestions") - CompletableFuture pendingSuggestions (); - - @Accessor("pendingSuggestions") - void setPendingSuggestions (CompletableFuture pendingSuggestions); -} diff --git a/src/main/java/land/chipmunk/chipmunkmod/mixin/ChatInputSuggestorMixin.java b/src/main/java/land/chipmunk/chipmunkmod/mixin/ChatInputSuggestorMixin.java index 49ce058..eef285a 100644 --- a/src/main/java/land/chipmunk/chipmunkmod/mixin/ChatInputSuggestorMixin.java +++ b/src/main/java/land/chipmunk/chipmunkmod/mixin/ChatInputSuggestorMixin.java @@ -3,18 +3,16 @@ package land.chipmunk.chipmunkmod.mixin; import com.mojang.brigadier.CommandDispatcher; import com.mojang.brigadier.StringReader; import com.mojang.brigadier.suggestion.Suggestions; +import com.mojang.brigadier.suggestion.SuggestionsBuilder; import land.chipmunk.chipmunkmod.ChipmunkMod; import land.chipmunk.chipmunkmod.command.CommandManager; -import land.chipmunk.chipmunkmod.modules.ChatInputGlobals; -import land.chipmunk.chipmunkmod.modules.CommandCore; -import land.chipmunk.chipmunkmod.modules.TransactionManager; -import land.chipmunk.chipmunkmod.util.UUIDUtilities; +import land.chipmunk.chipmunkmod.data.ChomeNSBotCommand; +import land.chipmunk.chipmunkmod.modules.ChomeNSBotCommandSuggestions; import net.fabricmc.fabric.api.client.command.v2.FabricClientCommandSource; -import net.kyori.adventure.text.Component; -import net.kyori.adventure.text.serializer.gson.GsonComponentSerializer; import net.minecraft.client.MinecraftClient; import net.minecraft.client.gui.widget.TextFieldWidget; import net.minecraft.client.network.ClientPlayerEntity; +import net.minecraft.command.CommandSource; import org.spongepowered.asm.mixin.Final; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Mutable; @@ -38,6 +36,11 @@ public class ChatInputSuggestorMixin { @Shadow public void show (boolean narrateFirstSuggestion) {} + @Shadow + private static int getStartOfCurrentWord (String input) { + return 0; + } + @Mutable @Final @Shadow @@ -47,8 +50,6 @@ public class ChatInputSuggestorMixin { textField = null; } - public int transactionId = 0; - @Inject(at = @At("TAIL"), method = "refresh()V") public void refresh (CallbackInfo ci) { if (slashOptional) return; @@ -62,28 +63,27 @@ public class ChatInputSuggestorMixin { final String chomeNSPrefix = ChipmunkMod.CONFIG.bots.chomens.prefix; - if (text.startsWith(chomeNSPrefix) && player != null) { - final String textUpToCursor = text.substring(chomeNSPrefix.length(), Math.max(chomeNSPrefix.length(), cursor)); + if (!text.contains(" ") && text.startsWith(chomeNSPrefix) && player != null) { + final String textUpToCursor = text.substring(0, cursor); - ChatInputGlobals.text = text; - ChatInputGlobals.cursor = cursor; - ChatInputGlobals.textUpToCursor = textUpToCursor; + final List commands = ChomeNSBotCommandSuggestions.INSTANCE.commands + .stream() + .map((command) -> command.name) + .toList(); - final String selfSelector = UUIDUtilities.selector(player.getUuid()); - - TransactionManager.INSTANCE.nextTransactionId(); - - final Component component = Component - .text("chomens_bot_command_suggestion") - .append(Component.text(transactionId)) - .append(Component.text(selfSelector)) - .append(Component.text(textUpToCursor)); - - CommandCore.INSTANCE.run( - "minecraft:tellraw @a[tag=chomens_bot] " + GsonComponentSerializer.gson().serialize(component) + pendingSuggestions = CommandSource.suggestMatching( + commands, + new SuggestionsBuilder( + textUpToCursor, + getStartOfCurrentWord(textUpToCursor) + ) ); - transactionId++; + pendingSuggestions.thenRun(() -> { + if (!pendingSuggestions.isDone()) return; + + show(true); + }); return; } diff --git a/src/main/java/land/chipmunk/chipmunkmod/mixin/ChatScreenAccessor.java b/src/main/java/land/chipmunk/chipmunkmod/mixin/ChatScreenAccessor.java deleted file mode 100644 index e2e9ae2..0000000 --- a/src/main/java/land/chipmunk/chipmunkmod/mixin/ChatScreenAccessor.java +++ /dev/null @@ -1,12 +0,0 @@ -package land.chipmunk.chipmunkmod.mixin; - -import net.minecraft.client.gui.screen.ChatInputSuggestor; -import net.minecraft.client.gui.screen.ChatScreen; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.gen.Accessor; - -@Mixin(ChatScreen.class) -public interface ChatScreenAccessor { - @Accessor("chatInputSuggestor") - ChatInputSuggestor chatInputSuggestor (); -} diff --git a/src/main/java/land/chipmunk/chipmunkmod/mixin/ChatScreenMixin.java b/src/main/java/land/chipmunk/chipmunkmod/mixin/ChatScreenMixin.java index 99829f9..07b30b6 100644 --- a/src/main/java/land/chipmunk/chipmunkmod/mixin/ChatScreenMixin.java +++ b/src/main/java/land/chipmunk/chipmunkmod/mixin/ChatScreenMixin.java @@ -2,7 +2,10 @@ package land.chipmunk.chipmunkmod.mixin; import land.chipmunk.chipmunkmod.ChipmunkMod; import land.chipmunk.chipmunkmod.command.CommandManager; +import land.chipmunk.chipmunkmod.data.ChomeNSBotCommand; +import land.chipmunk.chipmunkmod.modules.ChomeNSBotCommandSuggestions; import land.chipmunk.chipmunkmod.modules.CustomChat; +import land.chipmunk.chipmunkmod.util.BotValidationUtilities; import land.chipmunk.chipmunkmod.util.Webhook; import net.minecraft.client.MinecraftClient; import net.minecraft.client.gui.screen.ChatInputSuggestor; @@ -12,12 +15,14 @@ import net.minecraft.text.MutableText; import net.minecraft.text.Text; 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.callback.CallbackInfo; import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; import java.io.IOException; +import java.util.List; @Mixin(net.minecraft.client.gui.screen.ChatScreen.class) public class ChatScreenMixin extends Screen { @@ -28,6 +33,8 @@ public class ChatScreenMixin extends Screen { @Inject(at = @At("HEAD"), method = "sendMessage", cancellable = true) public void sendMessage(String chatText, boolean addToHistory, CallbackInfoReturnable cir) { + if (addToHistory) MinecraftClient.getInstance().inGameHud.getChatHud().addToMessageHistory(chatText); + final CommandManager commandManager = CommandManager.INSTANCE; if (ChipmunkMod.CONFIG.bots.testbot.webhookUrl != null && chatText.startsWith(ChipmunkMod.CONFIG.bots.testbot.prefix)) { @@ -41,19 +48,32 @@ public class ChatScreenMixin extends Screen { e.printStackTrace(); } }); + } else if (chatText.startsWith(ChipmunkMod.CONFIG.bots.chomens.prefix)) { + final List commands = ChomeNSBotCommandSuggestions.INSTANCE.commands; + + final List moreOrTrustedCommands = commands.stream() + .filter((command) -> command.trustLevel != ChomeNSBotCommand.TrustLevel.PUBLIC) + .map((command) -> command.name.toLowerCase()) + .toList(); + + if (moreOrTrustedCommands.contains(chatText.toLowerCase().split("\\s")[0])) { + try { + BotValidationUtilities.chomens(chatText.substring(ChipmunkMod.CONFIG.bots.chomens.prefix.length())); + + cir.setReturnValue(true); + + return; + } catch (Exception ignored) {} + } } if (chatText.startsWith(commandManager.prefix)) { commandManager.executeCommand(chatText.substring(commandManager.prefix.length())); - if (addToHistory) MinecraftClient.getInstance().inGameHud.getChatHud().addToMessageHistory(chatText); - cir.setReturnValue(true); } else if (!chatText.startsWith("/")) { CustomChat.INSTANCE.chat(chatText); - if (addToHistory) MinecraftClient.getInstance().inGameHud.getChatHud().addToMessageHistory(chatText); - cir.setReturnValue(true); } } @@ -86,6 +106,7 @@ public class ChatScreenMixin extends Screen { ci.cancel(); } + @Unique private void onChatFieldUpdate(String chatText) { String string = this.chatField.getText(); this.chatInputSuggestor.setWindowActive(!string.equals(this.originalChatText)); diff --git a/src/main/java/land/chipmunk/chipmunkmod/mixin/ClientPlayNetworkHandlerMixin.java b/src/main/java/land/chipmunk/chipmunkmod/mixin/ClientPlayNetworkHandlerMixin.java index 27c8c53..d36ec6c 100644 --- a/src/main/java/land/chipmunk/chipmunkmod/mixin/ClientPlayNetworkHandlerMixin.java +++ b/src/main/java/land/chipmunk/chipmunkmod/mixin/ClientPlayNetworkHandlerMixin.java @@ -38,8 +38,10 @@ public class ClientPlayNetworkHandlerMixin { KaboomCheck.INSTANCE.onJoin(); CommandManager.INSTANCE = new CommandManager(ChipmunkMod.CONFIG.commands.prefix, commandRegistryAccess); SelfCare.INSTANCE.onJoin(); + CommandCore.INSTANCE.init(); SongPlayer.INSTANCE.coreReady(); RainbowName.INSTANCE.init(); + ChomeNSBotCommandSuggestions.INSTANCE.init(); } @Inject(method = "onPlayerRemove", at = @At("HEAD"), cancellable = true) diff --git a/src/main/java/land/chipmunk/chipmunkmod/modules/ChatInputGlobals.java b/src/main/java/land/chipmunk/chipmunkmod/modules/ChatInputGlobals.java deleted file mode 100644 index e30d5dc..0000000 --- a/src/main/java/land/chipmunk/chipmunkmod/modules/ChatInputGlobals.java +++ /dev/null @@ -1,8 +0,0 @@ -package land.chipmunk.chipmunkmod.modules; - -// bad -public class ChatInputGlobals { - public static String text = ""; - public static int cursor; - public static String textUpToCursor = ""; -} diff --git a/src/main/java/land/chipmunk/chipmunkmod/modules/ChomeNSBotCommandSuggestions.java b/src/main/java/land/chipmunk/chipmunkmod/modules/ChomeNSBotCommandSuggestions.java new file mode 100644 index 0000000..7f86071 --- /dev/null +++ b/src/main/java/land/chipmunk/chipmunkmod/modules/ChomeNSBotCommandSuggestions.java @@ -0,0 +1,79 @@ +package land.chipmunk.chipmunkmod.modules; + +import land.chipmunk.chipmunkmod.ChipmunkMod; +import land.chipmunk.chipmunkmod.data.ChomeNSBotCommand; +import land.chipmunk.chipmunkmod.listeners.Listener; +import land.chipmunk.chipmunkmod.listeners.ListenerManager; +import land.chipmunk.chipmunkmod.util.UUIDUtilities; +import net.kyori.adventure.text.Component; +import net.kyori.adventure.text.TextComponent; +import net.kyori.adventure.text.serializer.gson.GsonComponentSerializer; +import net.minecraft.client.MinecraftClient; +import net.minecraft.client.network.ClientPlayerEntity; +import net.minecraft.text.Text; + +import java.util.ArrayList; +import java.util.List; + +public class ChomeNSBotCommandSuggestions extends Listener { + public static final String ID = "chomens_bot_request_command_suggestion"; + + public static ChomeNSBotCommandSuggestions INSTANCE = new ChomeNSBotCommandSuggestions(MinecraftClient.getInstance()); + + private final MinecraftClient client; + + public List commands = new ArrayList<>(); + + public ChomeNSBotCommandSuggestions (MinecraftClient client) { + this.client = client; + + ListenerManager.addListener(this); + } + + public void init () {} + + @Override + public void coreMoved () { forceRequest(); } + + public void forceRequest () { + final ClientPlayerEntity player = client.player; + + if (player == null) return; + + final String selector = UUIDUtilities.selector(player.getUuid()); + + final Component component = Component + .text(ID) + .append(Component.text(selector)); + + final String serialized = GsonComponentSerializer.gson().serialize(component); + + CommandCore.INSTANCE.run("tellraw @a[tag=chomens_bot] " + serialized); + } + + @Override + public void chatMessageReceived(Text message) { + try { + final Component component = message.asComponent(); + + final List children = component.children(); + + if (children.size() == 0) return; + + final TextComponent textComponent = (TextComponent) children.get(0); + + if (!textComponent.content().equals(ID)) return; + + commands = children.subList(1, children.size()) + .stream() + .map( + (eachCum) -> + new ChomeNSBotCommand( + ChipmunkMod.CONFIG.bots.chomens.prefix + ((TextComponent) eachCum).content(), + ChomeNSBotCommand.TrustLevel.valueOf(((TextComponent) eachCum.children().get(0)).content()) + ) + ) + .toList(); + } catch (Exception ignored) {} + } +} diff --git a/src/main/java/land/chipmunk/chipmunkmod/modules/CommandCore.java b/src/main/java/land/chipmunk/chipmunkmod/modules/CommandCore.java index 0b77372..8e00299 100644 --- a/src/main/java/land/chipmunk/chipmunkmod/modules/CommandCore.java +++ b/src/main/java/land/chipmunk/chipmunkmod/modules/CommandCore.java @@ -4,14 +4,18 @@ import land.chipmunk.chipmunkmod.ChipmunkMod; import land.chipmunk.chipmunkmod.data.BlockArea; +import land.chipmunk.chipmunkmod.listeners.Listener; +import land.chipmunk.chipmunkmod.listeners.ListenerManager; import net.minecraft.block.entity.CommandBlockBlockEntity; import net.minecraft.client.MinecraftClient; +import net.minecraft.client.network.ClientPlayNetworkHandler; import net.minecraft.nbt.NbtCompound; import net.minecraft.network.ClientConnection; import net.minecraft.network.packet.c2s.play.UpdateCommandBlockC2SPacket; import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.Vec3d; +import java.util.List; import java.util.Timer; import java.util.TimerTask; import java.util.concurrent.CompletableFuture; @@ -23,6 +27,8 @@ public class CommandCore { public BlockArea relativeArea; public BlockPos currentBlockRelative; + private Timer timer; + public static CommandCore INSTANCE = new CommandCore(MinecraftClient.getInstance(), ChipmunkMod.CONFIG.core.relativeArea); public CommandCore (MinecraftClient client, BlockArea relativeArea) { @@ -30,16 +36,34 @@ public class CommandCore { this.relativeArea = relativeArea; } + public void init () { + if (timer != null) { + cleanup(); + return; + } + + final TimerTask task = new TimerTask() { + public void run () { + tick(); + } + }; + + timer = new Timer(); + + timer.schedule(task, 50, 50); + } + + private void tick () { + final ClientPlayNetworkHandler networkHandler = client.getNetworkHandler(); + + if (networkHandler == null) cleanup(); + } + public void reloadRelativeArea () { relativeArea = ChipmunkMod.CONFIG.core.relativeArea; } public void move (Vec3d position) { - if (!ready) { - ready = true; - // for (Listener listener : listeners) listener.ready(); - } - origin = new BlockPos( ((int) position.getX() / 16) * 16, 0, // TODO: Use the actual bottom of the world instead of hardcoding to 0 @@ -48,6 +72,13 @@ public class CommandCore { if (currentBlockRelative == null) currentBlockRelative = new BlockPos(relativeArea.start); refill(); + + for (Listener listener : ListenerManager.listeners) listener.coreMoved(); + if (!ready) { + ready = true; + + for (Listener listener : ListenerManager.listeners) listener.coreReady(); + } } public void refill () { @@ -131,8 +162,7 @@ public class CommandCore { final TimerTask queryTask = new TimerTask() { public void run () { - client.getNetworkHandler().getDataQueryHandler().queryBlockNbt(currentBlock, - future::complete); + client.getNetworkHandler().getDataQueryHandler().queryBlockNbt(currentBlock, future::complete); timer.cancel(); // ? Is this necesary? timer.purge(); @@ -145,6 +175,11 @@ public class CommandCore { } public void cleanup () { + if (timer == null) return; + + timer.cancel(); + timer.purge(); + origin = null; currentBlockRelative = null; ready = false; diff --git a/src/main/java/land/chipmunk/chipmunkmod/util/BotValidationUtilities.java b/src/main/java/land/chipmunk/chipmunkmod/util/BotValidationUtilities.java new file mode 100644 index 0000000..d300d1b --- /dev/null +++ b/src/main/java/land/chipmunk/chipmunkmod/util/BotValidationUtilities.java @@ -0,0 +1,116 @@ +package land.chipmunk.chipmunkmod.util; + +import com.mojang.brigadier.Command; +import land.chipmunk.chipmunkmod.ChipmunkMod; +import land.chipmunk.chipmunkmod.Configuration; +import land.chipmunk.chipmunkmod.modules.CustomChat; +import net.minecraft.client.MinecraftClient; +import net.minecraft.client.network.ClientPlayNetworkHandler; + +import java.math.BigInteger; +import java.nio.charset.StandardCharsets; +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; +import java.util.Arrays; + +public class BotValidationUtilities { + public static int hbot (String command) throws RuntimeException { + final Configuration.BotInfo info = ChipmunkMod.CONFIG.bots.hbot; + final MinecraftClient client = MinecraftClient.getInstance(); + final ClientPlayNetworkHandler networkHandler = client.getNetworkHandler(); + + final String prefix = info.prefix; + final String key = info.key; + if (key == null) throw new RuntimeException("The key of the bot is unspecified (null), did you incorrectly add it to your config?"); + + try { + MessageDigest md = MessageDigest.getInstance("SHA-256"); + String time = String.valueOf(System.currentTimeMillis() / 10000); + String input = command.replaceAll("&[0-9a-fklmnor]", "") + ";" + client.player.getUuidAsString() + ";" + time + ";" + key; + byte[] hash = md.digest(input.getBytes(StandardCharsets.UTF_8)); + BigInteger bigInt = new BigInteger(1, Arrays.copyOfRange(hash, 0, 4)); + String stringHash = bigInt.toString(Character.MAX_RADIX); + + networkHandler.sendChatMessage(prefix + command + " " + stringHash); + } catch (NoSuchAlgorithmException e) { + e.printStackTrace(); + } + + return Command.SINGLE_SUCCESS; + } + + public static int sbot (String command) throws RuntimeException { + final Configuration.BotInfo info = ChipmunkMod.CONFIG.bots.sbot; + final MinecraftClient client = MinecraftClient.getInstance(); + final ClientPlayNetworkHandler networkHandler = client.getNetworkHandler(); + + final String prefix = info.prefix; + final String key = info.key; + if (key == null) throw new RuntimeException("The key of the bot is unspecified (null), did you incorrectly add it to your config?"); + + try { + MessageDigest md = MessageDigest.getInstance("SHA-256"); + String time = String.valueOf(System.currentTimeMillis() / 20000); + String input = prefix + command.replaceAll("&[0-9a-fklmnorx]", "") + ";" + client.player.getName() + ";" + time + ";" + key; + byte[] hash = md.digest(input.getBytes(StandardCharsets.UTF_8)); + BigInteger bigInt = new BigInteger(1, Arrays.copyOfRange(hash, 0, 4)); + String stringHash = bigInt.toString(Character.MAX_RADIX); + + networkHandler.sendChatMessage(prefix + command + " " + stringHash); + } catch (NoSuchAlgorithmException e) { + e.printStackTrace(); + } + + return Command.SINGLE_SUCCESS; + } + + public static int chomens (String command) throws RuntimeException { + final Configuration.BotInfo info = ChipmunkMod.CONFIG.bots.chomens; + + final String prefix = info.prefix; + final String key = info.key; + if (key == null) throw new RuntimeException("The key of the bot is unspecified (null), did you incorrectly add it to your config?"); + + try { + MessageDigest md = MessageDigest.getInstance("SHA-256"); + String time = String.valueOf(System.currentTimeMillis() / 5_000); + String input = time + key; + byte[] hash = md.digest(input.getBytes(StandardCharsets.UTF_8)); + String stringHash = Hexadecimal.encode(hash).substring(0, 16); + + String[] arguments = command.split(" "); + + final String toSend = prefix + arguments[0] + " " + stringHash + " " + String.join(" ", Arrays.copyOfRange(arguments, 1, arguments.length)); + + CustomChat.INSTANCE.chat(toSend); + } catch (NoSuchAlgorithmException e) { + e.printStackTrace(); + } + + return Command.SINGLE_SUCCESS; + } + + public static int kittycorp (String command) throws RuntimeException { + final Configuration.BotInfo info = ChipmunkMod.CONFIG.bots.kittycorp; + final ClientPlayNetworkHandler networkHandler = MinecraftClient.getInstance().getNetworkHandler(); + + final String prefix = info.prefix; + final String key = info.key; + if (key == null) throw new RuntimeException("The key of the bot is unspecified (null), did you incorrectly add it to your config?"); + + try { + MessageDigest md = MessageDigest.getInstance("SHA-256"); + String time = String.valueOf(System.currentTimeMillis() / 10000); + String input = prefix + command.replaceAll("&[0-9a-fklmnorx]", "") + ";" + time + ";" + key; + byte[] hash = md.digest(input.getBytes(StandardCharsets.UTF_8)); + BigInteger bigInt = new BigInteger(1, Arrays.copyOfRange(hash, 0, 4)); + String stringHash = bigInt.toString(Character.MAX_RADIX); + + networkHandler.sendChatMessage(prefix + command + " " + stringHash); + } catch (NoSuchAlgorithmException e) { + e.printStackTrace(); + } + + return Command.SINGLE_SUCCESS; + } +} diff --git a/src/main/resources/chipmunkmod.mixins.json b/src/main/resources/chipmunkmod.mixins.json index bad472d..920438c 100644 --- a/src/main/resources/chipmunkmod.mixins.json +++ b/src/main/resources/chipmunkmod.mixins.json @@ -6,9 +6,7 @@ "client": [ "ChatHudMixin", "ChatInputSuggestorMixin", - "ChatInputSuggestorAccessor", "ChatScreenMixin", - "ChatScreenAccessor", "ClientConnectionMixin", "ClientPlayerEntityMixin", "ClientPlayNetworkHandlerAccessor",