From 2723483b7bc620b6c99bf78a5dfb68331ccea079 Mon Sep 17 00:00:00 2001 From: ChomeNS <95471003+chomens@users.noreply.github.com> Date: Sun, 23 Mar 2025 08:40:55 +0700 Subject: [PATCH] feat: re-add ChomeNSAuth refactor: improve the chat stuff in ClientPlayNetworkHandlerMixin a bit --- .../mixin/ClientPlayNetworkHandlerMixin.java | 36 ++++-- .../chipmunkmod/modules/ChomeNSAuth.java | 108 ++++++++++++++++++ 2 files changed, 132 insertions(+), 12 deletions(-) create mode 100644 src/main/java/land/chipmunk/chipmunkmod/modules/ChomeNSAuth.java diff --git a/src/main/java/land/chipmunk/chipmunkmod/mixin/ClientPlayNetworkHandlerMixin.java b/src/main/java/land/chipmunk/chipmunkmod/mixin/ClientPlayNetworkHandlerMixin.java index 80fc7f0..2b8ed28 100644 --- a/src/main/java/land/chipmunk/chipmunkmod/mixin/ClientPlayNetworkHandlerMixin.java +++ b/src/main/java/land/chipmunk/chipmunkmod/mixin/ClientPlayNetworkHandlerMixin.java @@ -21,6 +21,7 @@ import net.minecraft.network.packet.s2c.play.GameJoinS2CPacket; import net.minecraft.network.packet.s2c.play.GameMessageS2CPacket; import net.minecraft.registry.DynamicRegistryManager; import net.minecraft.resource.featuretoggle.FeatureSet; +import net.minecraft.text.PlainTextContent; import net.minecraft.text.Text; import net.minecraft.text.TranslatableTextContent; import org.spongepowered.asm.mixin.Final; @@ -57,6 +58,7 @@ public class ClientPlayNetworkHandlerMixin { CommandCore.INSTANCE.init(); SongPlayer.INSTANCE.coreReady(); RainbowName.INSTANCE.init(); + ChomeNSAuth.INSTANCE.init(); ChomeNSBotCommandSuggestions.INSTANCE.init(); CustomChat.INSTANCE.init(); } @@ -71,36 +73,46 @@ public class ClientPlayNetworkHandlerMixin { final Text message = packet.content(); try { - if (RainbowName.INSTANCE.enabled) { - if (message.getString().contains("Your nickname is now ") || message.getString().contains("Nickname changed.")) { - ci.cancel(); - return; - } + if ( + RainbowName.INSTANCE.enabled && + ( + message.getString().contains("Your nickname is now ") || + message.getString().contains("Nickname changed.") + ) + ) { + ci.cancel(); + return; } - try { - final String key = ((TranslatableTextContent) message.getContent()).getKey(); + if (message.getContent() instanceof TranslatableTextContent translatableTextContent) { + final String key = translatableTextContent.getKey(); + if (key.equals("advMode.setCommand.success") || key.equals("قيادة المجموعة: %s")) { ci.cancel(); return; } - } catch (ClassCastException ignored) { } for (Listener listener : ListenerManager.listeners) { listener.chatMessageReceived(message); } - try { + if (message.getSiblings().size() > 1) { final String suggestionId = message.getSiblings().getFirst().getString(); if (suggestionId.equals(ChomeNSBotCommandSuggestions.ID)) { ci.cancel(); + return; } - } catch (Exception ignored) { } - } catch (Exception ignored) { - } + + if ( + message.getContent() instanceof PlainTextContent plainTextContent && + plainTextContent.string().equals(ChomeNSAuth.ID) + ) { + ci.cancel(); + } + } catch (Exception ignored) {} } @Inject(method = "sendChatMessage", at = @At("HEAD"), cancellable = true) diff --git a/src/main/java/land/chipmunk/chipmunkmod/modules/ChomeNSAuth.java b/src/main/java/land/chipmunk/chipmunkmod/modules/ChomeNSAuth.java new file mode 100644 index 0000000..1847349 --- /dev/null +++ b/src/main/java/land/chipmunk/chipmunkmod/modules/ChomeNSAuth.java @@ -0,0 +1,108 @@ +package land.chipmunk.chipmunkmod.modules; + +import land.chipmunk.chipmunkmod.listeners.Listener; +import land.chipmunk.chipmunkmod.listeners.ListenerManager; +import net.fabricmc.loader.api.FabricLoader; +import net.kyori.adventure.text.Component; +import net.kyori.adventure.text.serializer.gson.GsonComponentSerializer; +import net.minecraft.text.PlainTextContent; +import net.minecraft.text.Text; +import net.minecraft.text.TextContent; + +import javax.crypto.Cipher; +import java.io.IOException; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.nio.file.Path; +import java.security.KeyFactory; +import java.security.NoSuchAlgorithmException; +import java.security.PublicKey; +import java.security.spec.InvalidKeySpecException; +import java.security.spec.X509EncodedKeySpec; +import java.util.Base64; +import java.util.List; + +public class ChomeNSAuth implements Listener { + public static ChomeNSAuth INSTANCE = new ChomeNSAuth(); + + private static PublicKey PUBLIC_KEY; + private static final Path PUBLIC_KEY_PATH = FabricLoader.getInstance() + .getGameDir() + .resolve("data") + .resolve("chipmunkmod") + .resolve("chomens_auth") + .resolve("public.key"); + + private static final String BEGIN_PUBLIC_KEY = "-----BEGIN CHOMENS BOT PUBLIC KEY-----"; + private static final String END_PUBLIC_KEY = "-----END CHOMENS BOT PUBLIC KEY-----"; + + public static final String ID = "chomens_bot_verify"; + + static { + try { + if (Files.exists(PUBLIC_KEY_PATH)) { + final String publicKeyString = new String(Files.readAllBytes(PUBLIC_KEY_PATH)) + .replace(BEGIN_PUBLIC_KEY + "\n", "") + .replace("\n" + END_PUBLIC_KEY, "") + .replace("\n", "") + .trim(); + + final byte[] publicKeyBytes = Base64.getDecoder().decode(publicKeyString); + final KeyFactory keyFactory = KeyFactory.getInstance("RSA"); + + PUBLIC_KEY = keyFactory.generatePublic(new X509EncodedKeySpec(publicKeyBytes)); + } + } catch (IOException | InvalidKeySpecException | NoSuchAlgorithmException | IllegalArgumentException ignored) {} + } + + public ChomeNSAuth () { + ListenerManager.addListener(this); + } + + public void init () {} + + @Override + public void chatMessageReceived (Text message) { + if (PUBLIC_KEY == null) return; + + if (message.getContent() == null || !(message.getContent() instanceof PlainTextContent idTextContent)) return; + + final String id = idTextContent.string(); + + if (!id.equals(ID)) return; + + final List children = message.getSiblings(); + + if (children.size() != 1) return; + + if (!(children.getFirst().getContent() instanceof PlainTextContent selectorTextContent)) return; + + final String selector = selectorTextContent.string(); + + try { + final String encrypted = encrypt(ID.getBytes(StandardCharsets.UTF_8)); + + final Component component = Component + .text(ID) + .append(Component.text(encrypted)); + + CommandCore.INSTANCE.run( + String.format( + "tellraw %s %s", + selector, + GsonComponentSerializer.gson() + .serialize(component) + ) + ); + } catch (Exception ignored) {} + } + + public String encrypt (byte[] data) throws Exception { + final Cipher cipher = Cipher.getInstance("RSA"); + cipher.init(Cipher.ENCRYPT_MODE, PUBLIC_KEY); + + final byte[] encryptedBytes = cipher.doFinal(data); + + return Base64.getEncoder().encodeToString(encryptedBytes); + } +}