diff --git a/src/main/java/meteordevelopment/meteorclient/systems/modules/misc/BetterChat.java b/src/main/java/meteordevelopment/meteorclient/systems/modules/misc/BetterChat.java index 1c77e88557..d4d519f995 100644 --- a/src/main/java/meteordevelopment/meteorclient/systems/modules/misc/BetterChat.java +++ b/src/main/java/meteordevelopment/meteorclient/systems/modules/misc/BetterChat.java @@ -47,6 +47,10 @@ import java.util.regex.PatternSyntaxException; public class BetterChat extends Module { + private final int FIRST_USABLE_ASCII = (int) ' '; // 32 + private final int LAST_USABLE_ASCII = (int) '~'; // 126 + private final int NUM_USABLE_ASCII = LAST_USABLE_ASCII - FIRST_USABLE_ASCII + 1; + private final SettingGroup sgGeneral = settings.getDefaultGroup(); private final SettingGroup sgFilter = settings.createGroup("Filter"); private final SettingGroup sgLongerChat = settings.createGroup("Longer Chat"); @@ -104,6 +108,30 @@ public class BetterChat extends Module { .build() ); + private final Setting encrypt = sgGeneral.add(new BoolSetting.Builder() + .name("encrypt") + .description("Applies an encryption routine to chat messages") + .defaultValue(false) + .build() + ); + + private final Setting decrypt = sgGeneral.add(new BoolSetting.Builder() + .name("decrypt") + .description("Applies a decryption routine to encrypted chat messages") + .defaultValue(true) + .build() + ); + + private final Setting cypherOffset = sgGeneral.add(new IntSetting.Builder() + .name("cypher-offset") + .description("Ceasar cypher offset used for encrypting messages") + .defaultValue(20) + .range(0, NUM_USABLE_ASCII - 1) + .sliderRange(0, NUM_USABLE_ASCII - 1) + .visible(encrypt::get) + .build() + ); + // Filter private final Setting antiSpam = sgFilter.add(new BoolSetting.Builder() @@ -257,6 +285,13 @@ public BetterChat() { private void onMessageReceive(ReceiveMessageEvent event) { Component message = event.getMessage(); + if (decrypt.get()) { + Optional decryptedMessage = applyDecryption(message.getString()); + if (decryptedMessage.isPresent()) { + message = Component.empty().append(decryptedMessage.get()); + } + } + if (filterRegex.get()) { String messageString = message.getString(); for (Pattern pattern : filterRegexList) { @@ -322,6 +357,8 @@ private void onMessageSend(SendMessageEvent event) { return; } + if (encrypt.get()) message = applyEncryption(message); + event.message = message; } @@ -511,6 +548,82 @@ private String applyAnnoy(String message) { return message; } + // Encrypt + + private String applyEncryption(String message) { + int msgLen = message.length(); + int offset = cypherOffset.get(); + StringBuilder modString = new StringBuilder(msgLen + 2); + + // Encode offset into message with char for validation + modString.append((char) (FIRST_USABLE_ASCII + offset)); + modString.append(encryptChar('%', offset)); + + for (int i = 0; i < msgLen; ++i) { + char chr = message.charAt(i); + chr = encryptChar(chr, offset); + modString.append(chr); + } + return modString.toString(); + } + + private char encryptChar(char chr, int offset) { + int ascii = (int) chr; + if (ascii > FIRST_USABLE_ASCII && ascii <= LAST_USABLE_ASCII) { + ascii -= FIRST_USABLE_ASCII; + ascii += offset; + ascii %= NUM_USABLE_ASCII; + ascii += FIRST_USABLE_ASCII; + chr = (char) ascii; + } + return chr; + } + + // Decrypt + + private Optional applyDecryption(String message) { + int rawMsgLen = message.length(); + int nameTagEnd = message.indexOf("> "); + int msgStart = nameTagEnd + 2; + int msgLen = rawMsgLen - msgStart; + StringBuilder modString = new StringBuilder(); + + if (msgLen <= 2) { + return Optional.empty(); + } + + int offset = (int)(message.charAt(msgStart)) - FIRST_USABLE_ASCII; + boolean isEncrypted = decryptChar(message.charAt(msgStart+1), offset) == '%'; + + if (isEncrypted) { + for (int i = 0; i < rawMsgLen; ++i) { + char chr = message.charAt(i); + if (i >= msgStart + 2) { + chr = decryptChar(chr, offset); + } + else if (i >= msgStart) { + continue; + } + modString.append(chr); + } + return Optional.of(modString.toString()); + } + return Optional.empty(); + } + + private char decryptChar(char chr, int offset) { + int ascii = (int) chr; + if (ascii > FIRST_USABLE_ASCII && ascii <= LAST_USABLE_ASCII) { + ascii -= FIRST_USABLE_ASCII; + ascii -= offset; + ascii += NUM_USABLE_ASCII; + ascii %= NUM_USABLE_ASCII; + ascii += FIRST_USABLE_ASCII; + chr = (char) ascii; + } + return chr; + } + // Fancy private String applyFancy(String message) {