From 2a101f15767326eceb4cf588e873d3f2dc779d33 Mon Sep 17 00:00:00 2001 From: blackilykat Date: Sat, 15 Jul 2023 12:10:05 +0200 Subject: [PATCH] made anti chat spam run in a different thread + made anti text obfuscation lag + i forgor --- .../chipmunk/chipmunkmod/ChipmunkMod.java | 7 +- .../chipmunkmod/command/CommandManager.java | 1 + .../ClearAntiChatSpamQueueCommand.java | 36 ++ .../chipmunkmod/memory/ModuleMemory.java | 315 ++++++++++++++++++ .../memory/UnknownOptionTypeException.java | 7 + .../chipmunkmod/mixin/ChatHudMixin.java | 47 ++- .../chipmunkmod/mixin/FontStorageMixin.java | 30 ++ .../chipmunkmod/mixin/TitleScreenMixin.java | 14 +- .../chipmunkmod/mixin/WorldRendererMixin.java | 19 ++ .../chipmunkmod/testclient/gui/Gui.java | 6 +- .../testclient/gui/components/Category.java | 2 +- .../testclient/gui/components/Module.java | 4 +- .../testclient/gui/components/Option.java | 4 + .../modules/utility/AntiChatSpamModule.java | 5 + .../utility/AntiTextObfuscationLagModule.java | 15 + .../chipmunk/chipmunkmod/util/Executor.java | 3 +- .../chipmunk/chipmunkmod/util/Webhook.java | 2 +- src/main/resources/chipmunkmod.mixins.json | 14 +- 18 files changed, 508 insertions(+), 23 deletions(-) create mode 100644 src/main/java/land/chipmunk/chipmunkmod/commands/ClearAntiChatSpamQueueCommand.java create mode 100644 src/main/java/land/chipmunk/chipmunkmod/memory/ModuleMemory.java create mode 100644 src/main/java/land/chipmunk/chipmunkmod/memory/UnknownOptionTypeException.java create mode 100644 src/main/java/land/chipmunk/chipmunkmod/mixin/FontStorageMixin.java create mode 100644 src/main/java/land/chipmunk/chipmunkmod/mixin/WorldRendererMixin.java create mode 100644 src/main/java/land/chipmunk/chipmunkmod/testclient/modules/utility/AntiTextObfuscationLagModule.java diff --git a/src/main/java/land/chipmunk/chipmunkmod/ChipmunkMod.java b/src/main/java/land/chipmunk/chipmunkmod/ChipmunkMod.java index ffc8b05..70285df 100644 --- a/src/main/java/land/chipmunk/chipmunkmod/ChipmunkMod.java +++ b/src/main/java/land/chipmunk/chipmunkmod/ChipmunkMod.java @@ -1,6 +1,7 @@ package land.chipmunk.chipmunkmod; import com.google.gson.GsonBuilder; +import land.chipmunk.chipmunkmod.memory.ModuleMemory; import land.chipmunk.chipmunkmod.util.Keybinds; import land.chipmunk.chipmunkmod.util.SharedVariables; import land.chipmunk.chipmunkmod.util.TickRunnableHandler; @@ -32,11 +33,13 @@ public class ChipmunkMod implements ModInitializer { // That way, it's clear which mod wrote info, warnings, and errors. public static final Logger LOGGER = LoggerFactory.getLogger("chipmunkmod"); public static Configuration CONFIG = new Configuration(); - private static File CONFIG_DIR = new File("config"); - private static File CONFIG_FILE = new File(CONFIG_DIR, "chipmunkmod.json"); + public static final File CONFIG_DIR = new File("config"); + private static final File CONFIG_FILE = new File(CONFIG_DIR, "chipmunkmod.json"); public static ExecutorService executorService = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors()); + public static final ModuleMemory MEMORY = new ModuleMemory(); + @Override public void onInitialize () { // This code runs as soon as Minecraft is in a mod-load-ready state. diff --git a/src/main/java/land/chipmunk/chipmunkmod/command/CommandManager.java b/src/main/java/land/chipmunk/chipmunkmod/command/CommandManager.java index e3854fc..150f41c 100644 --- a/src/main/java/land/chipmunk/chipmunkmod/command/CommandManager.java +++ b/src/main/java/land/chipmunk/chipmunkmod/command/CommandManager.java @@ -43,6 +43,7 @@ public class CommandManager { LoopCrouchCommand.register(this.dispatcher); AutoDeopCommand.register(this.dispatcher); DebugCommand.register(this.dispatcher); + ClearAntiChatSpamQueueCommand.register(this.dispatcher); } public void executeCommand (String command) { diff --git a/src/main/java/land/chipmunk/chipmunkmod/commands/ClearAntiChatSpamQueueCommand.java b/src/main/java/land/chipmunk/chipmunkmod/commands/ClearAntiChatSpamQueueCommand.java new file mode 100644 index 0000000..7e920f3 --- /dev/null +++ b/src/main/java/land/chipmunk/chipmunkmod/commands/ClearAntiChatSpamQueueCommand.java @@ -0,0 +1,36 @@ +package land.chipmunk.chipmunkmod.commands; + +import com.mojang.brigadier.CommandDispatcher; +import com.mojang.brigadier.context.CommandContext; +import com.mojang.brigadier.exceptions.CommandSyntaxException; +import com.mojang.brigadier.exceptions.SimpleCommandExceptionType; +import land.chipmunk.chipmunkmod.testclient.modules.op.AutoDeopModule; +import land.chipmunk.chipmunkmod.util.Chat; +import land.chipmunk.chipmunkmod.util.Executor; +import net.fabricmc.fabric.api.client.command.v2.FabricClientCommandSource; +import net.minecraft.text.Text; + +import java.util.List; +import java.util.concurrent.Executors; + +import static com.mojang.brigadier.arguments.StringArgumentType.getString; +import static com.mojang.brigadier.arguments.StringArgumentType.string; +import static land.chipmunk.chipmunkmod.command.CommandManager.argument; +import static land.chipmunk.chipmunkmod.command.CommandManager.literal; + +public class ClearAntiChatSpamQueueCommand { + public static void register (CommandDispatcher dispatcher) { + final ClearAntiChatSpamQueueCommand instance = new ClearAntiChatSpamQueueCommand(); + dispatcher.register( + literal("clearantichatspamqueue") + .executes(instance::run) + ); + } + + public int run(CommandContext context) throws CommandSyntaxException { + List runnables = Executor.antiChatSpamService.shutdownNow(); + Executor.antiChatSpamService = Executors.newFixedThreadPool(1); + Chat.sendGreen("Stopped " + runnables.size() + " chat messages from getting recieved!"); + return 1; + } +} diff --git a/src/main/java/land/chipmunk/chipmunkmod/memory/ModuleMemory.java b/src/main/java/land/chipmunk/chipmunkmod/memory/ModuleMemory.java new file mode 100644 index 0000000..06c530f --- /dev/null +++ b/src/main/java/land/chipmunk/chipmunkmod/memory/ModuleMemory.java @@ -0,0 +1,315 @@ +package land.chipmunk.chipmunkmod.memory; + +import land.chipmunk.chipmunkmod.ChipmunkMod; +import land.chipmunk.chipmunkmod.testclient.gui.Gui; +import land.chipmunk.chipmunkmod.testclient.gui.components.Category; +import land.chipmunk.chipmunkmod.testclient.gui.components.Module; +import land.chipmunk.chipmunkmod.testclient.gui.components.Option; + +import java.io.File; +import java.io.FileNotFoundException; +import java.io.FileReader; +import java.io.IOException; +import java.util.ArrayList; +import static land.chipmunk.chipmunkmod.ChipmunkMod.LOGGER; + +// i have realised this can also be used to save profiles +// like it would be so simple to implement that feature +// not 1.1.0 tho it's taking too long +public class ModuleMemory { + + private static final File MEMORY_FILE = new File(ChipmunkMod.CONFIG_DIR, "chipmunkmodmemory.data"); + public ArrayList categories = new ArrayList<>(); + + public void load() throws IOException { + if(!MEMORY_FILE.exists()) { + saveDefaults(); + return; + } + + // get the default values for everything and port it all to the local variables + for (land.chipmunk.chipmunkmod.testclient.gui.components.Category category : Gui.categoryList) { + Category localCategory = new Category(category.getMessage().getString(), false); + for (land.chipmunk.chipmunkmod.testclient.gui.components.Module module : category.moduleList) { + Module localModule = new Module(module.getMessage().getString(), module.isEnabled); + for (land.chipmunk.chipmunkmod.testclient.gui.components.Option option : module.optionList) { + localModule.options.add(option.toMemoryOption()); + } + localCategory.modules.add(localModule); + } + categories.add(localCategory); + } + + FileReader reader = null; + try{ + reader = new FileReader(MEMORY_FILE); + } catch(FileNotFoundException ignored) {} // this should never happen + + // all the constant keywords for easy switchery + final String startKeyword = "start"; + final String endKeyword = "end"; + final String categoryKeyword = "category"; + final String moduleKeyword = "module"; + final String optionKeyword = "option"; + final String commentKeyword = "comment"; + + // declare all variables needed + boolean hasStarted = false; + boolean hasEnded = false; + int charCode; + char character; + boolean isReading = false; + StringBuilder buffer = new StringBuilder(); + int reading = 0; // 0=keyword, 1=category, 2=module, 3=option, 4=comment + int argument = 0; + String firstArgument = null; + String secondArgument = null; + String currentCategory = null; + String currentModule = null; + + // do the magic reading + assert reader != null; + while(reader.ready() && !hasEnded) { + charCode = reader.read(); character = (char) charCode; + LOGGER.info("i read ac haracter woo "+character); + LOGGER.info("buffer is "+buffer.toString()); + switch(character) { + case '\n' -> {} // nothing else will get executed (i think) + case ';' -> { + if(argument==2) { + LOGGER.info("arg is 2"); + secondArgument = buffer.toString(); + switch (reading) { + case 1 -> { // category + LOGGER.info("doing magic category thing owo AAAAAAAAAAAAAAAAAAAAAAAAAAAA"); + // first argument is the name + boolean extended = Boolean.parseBoolean(secondArgument);// second argument is if it's extended + for (Category category : categories) { + LOGGER.info("comparing category "+category.name+" with argument "+firstArgument); + if(!category.name.equals(firstArgument)) continue; + LOGGER.info("found category "+category.name); + category.extended = extended; + break; + } + currentCategory = firstArgument; + } + case 2 -> { // module + // first argument is the name + if(currentCategory == null) { + LOGGER.warn(String.format("Found module %s before a category was declared! ignoring", firstArgument)); + continue; + } + boolean enabled = Boolean.parseBoolean(secondArgument); // second argument is if it's enabled + for(Category category : categories) { + if(!category.name.equals(currentCategory)) continue; + for (Module module : category.modules) { + if(!module.name.equals(firstArgument)) continue; + module.enabled = enabled; + break; + } + break; + } + currentModule = firstArgument; + } + case 3 -> { // option + if(currentModule == null) { + LOGGER.warn(String.format("Found option %s before a module was declared! ignoring", firstArgument)); + continue; + } + if(currentCategory == null) { + LOGGER.warn(String.format("Found option %s before a category was declared! ignoring", firstArgument)); + continue; + } + + for(Category category : categories) { + if(!category.name.equals(currentCategory)) continue; + for (Module module : category.modules) { + if(!module.name.equals(firstArgument)) continue; + for(Option option : module.options) { + if(!option.name.equals(firstArgument)) continue; + setOptionValue(option, secondArgument); + break; + } + break; + } + break; + } + + } + } + } + if(reading==0) switch (buffer.toString()) { + case startKeyword -> { + if(hasStarted) LOGGER.warn("Found multiple ;start statements, only accepting the first one."); + hasStarted = true; + LOGGER.info("found start astyemtnttnnnt owo"); + } + case endKeyword -> hasEnded = true; + } + buffer = new StringBuilder(); + isReading = true; + reading = 0; + argument = 0; + } + case ':' -> { + argument++; + switch (reading) { + case 0 -> { + switch (buffer.toString()) { + case categoryKeyword -> reading = 1; + case moduleKeyword -> reading = 2; + case optionKeyword -> reading = 3; + case commentKeyword -> reading = 4; + default -> LOGGER.warn("Unknown argumentful keyword '" + buffer + "', ignoring"); + } + } + case 4 -> {} // comment + default -> { // category, module and option all have 2 args so I can treat them equally + if(argument==2) firstArgument = buffer.toString(); + argument++; + } + } + buffer = new StringBuilder(); + } + default -> { + if(!isReading) continue; + buffer.append(character); + } + } + } + + if(!hasStarted) { + LOGGER.warn("Memory file exists but has no ;start statement! Overriding file..."); + saveDefaults(); + } + if(!hasEnded) { + LOGGER.warn("Memory file exists but has no ;end statement! Overriding file..."); + saveDefaults(); + } + + } + + public void apply() { + for (Category category : categories) { + // find matching category and set extended + // then loop through every module and do the same thing + // then loop through every option and do the same thing + + // get the matching category + land.chipmunk.chipmunkmod.testclient.gui.components.Category realCategory = null; + for (land.chipmunk.chipmunkmod.testclient.gui.components.Category categoryInGui : Gui.categoryList) { + if(category.name.equals(categoryInGui.getMessage().getString())) { + // it's the right category + realCategory = categoryInGui; + break; + } + } + if(realCategory == null) { + LOGGER.warn(String.format("Category '%s' somehow not found in categoryInGui?? report to dev on discord @blackilykat because this is not supposed to be possible :DD", category.name)); + continue; + } + LOGGER.info(String.format("Restoring category '%s' extended: %s", category.name, category.extended)); + realCategory.isExtended = category.extended; + for(Module module : category.modules) { + land.chipmunk.chipmunkmod.testclient.gui.components.Module realModule = null; + for(land.chipmunk.chipmunkmod.testclient.gui.components.Module moduleInRealCategory : realCategory.moduleList) { + if(module.name.equals(moduleInRealCategory.getMessage().getString())) { + realModule = moduleInRealCategory; + break; + } + } + if(realModule == null) { + LOGGER.warn(String.format("Module '%s' somehow not found in category '%s'?? report to dev on discord @blackilykat because this is not supposed to be possible :DD", module.name, category.name)); + continue; + } + LOGGER.info(String.format("Restoring module '%s' enabled: %s", module.name, module.enabled)); + realModule.isEnabled = module.enabled; + for(Option option : module.options) { + land.chipmunk.chipmunkmod.testclient.gui.components.Option realOption = null; + for(land.chipmunk.chipmunkmod.testclient.gui.components.Option optionInRealModule : realModule.optionList) { + if(option.name.equals(optionInRealModule.name)) { + realOption = optionInRealModule; + break; + } + } + if(realOption == null) { + LOGGER.warn(String.format("Option '%s' somehow not found in module '%s' in category '%s'?? report to dev on discord @blackilykat because this is not supposed to be possible :DD", option.name, module.name, category.name)); + continue; + } + LOGGER.info(String.format("Restoring option '%s' value: %s", option.name, option.value)); + setRealOptionValue(realOption, option); + } + } + + } + } + + public void saveDefaults() { + + } + public void save() { + + } + + public void setRealOptionValue(land.chipmunk.chipmunkmod.testclient.gui.components.Option real, Option fake) { + real.optionValue = (T) fake.value; // shut the fuck up intellij this cast is fine + } + + public void setOptionValue(Option option, String value) { + if(option.getType() == String.class) { + option.value = (T) value; // ignore warning it's (String) string + } else if (option.getType() == Integer.class) { + Integer newValue = null; + try { + newValue = Integer.valueOf(value); + } catch (NumberFormatException e) { + LOGGER.warn(String.format("Option %s expects an integer, however the value '%s' cannot be parsed as one.", option.name, value)); + return; + } + option.value = (T) newValue; + } else if (option.getType() == Double.class) { + Double newValue = null; + try { + newValue = Double.valueOf(value); + } catch (NumberFormatException e) { + LOGGER.warn(String.format("Option %s expects a double, however the value '%s' cannot be parsed as one.", option.name, value)); + return; + } + option.value = (T) newValue; + } else { + throw new UnknownOptionTypeException(option.getType()); + // no need to catch + // because pro runtime exception + } + } + + public static class Category { + public final String name; + public boolean extended; + public ArrayList modules = new ArrayList<>(); + public Category(String name, boolean extended) { + this.name = name; + this.extended = extended; + } + } + + public static class Module { + public final String name; + public boolean enabled; + public ArrayList> options = new ArrayList<>(); + public Module(String name, boolean enabled) { + this.name = name; + this.enabled = enabled; + } + } + + public static class Option { + public final String name; + public T value; + public Option(String name, T value) { + this.name = name; + this.value = value; + } + public Class getType() {return (Class) value.getClass();} // ignore warning cause intellij has the stupid + } +} diff --git a/src/main/java/land/chipmunk/chipmunkmod/memory/UnknownOptionTypeException.java b/src/main/java/land/chipmunk/chipmunkmod/memory/UnknownOptionTypeException.java new file mode 100644 index 0000000..0acce09 --- /dev/null +++ b/src/main/java/land/chipmunk/chipmunkmod/memory/UnknownOptionTypeException.java @@ -0,0 +1,7 @@ +package land.chipmunk.chipmunkmod.memory; + +public class UnknownOptionTypeException extends RuntimeException { //runtime exception because i dont wanna catch this i just want it to crash me when something goes wrong + public UnknownOptionTypeException(Class type) { + super(String.format("An option with type %s is not handled by ModuleMemory.", type.getTypeName())); + } +} diff --git a/src/main/java/land/chipmunk/chipmunkmod/mixin/ChatHudMixin.java b/src/main/java/land/chipmunk/chipmunkmod/mixin/ChatHudMixin.java index 24b2877..94c0b00 100644 --- a/src/main/java/land/chipmunk/chipmunkmod/mixin/ChatHudMixin.java +++ b/src/main/java/land/chipmunk/chipmunkmod/mixin/ChatHudMixin.java @@ -5,11 +5,17 @@ import land.chipmunk.chipmunkmod.listeners.ListenerManager; import land.chipmunk.chipmunkmod.modules.RainbowName; import land.chipmunk.chipmunkmod.testclient.modules.op.AutoDeopModule; import land.chipmunk.chipmunkmod.testclient.modules.utility.AntiChatSpamModule; +import land.chipmunk.chipmunkmod.util.Debug; +import land.chipmunk.chipmunkmod.util.Executor; +import net.minecraft.client.MinecraftClient; import net.minecraft.client.gui.hud.MessageIndicator; import net.minecraft.network.message.MessageSignatureData; import net.minecraft.text.Text; import net.minecraft.text.TranslatableTextContent; +import org.jetbrains.annotations.Nullable; +import org.spongepowered.asm.mixin.Final; import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; @@ -18,7 +24,13 @@ import java.util.regex.Matcher; import java.util.regex.Pattern; @Mixin(net.minecraft.client.gui.hud.ChatHud.class) -public class ChatHudMixin { +public abstract class ChatHudMixin { + + @Shadow protected abstract void addMessage(Text message, @Nullable MessageSignatureData signature, int ticks, @Nullable MessageIndicator indicator, boolean refresh); + + @Shadow @Final private MinecraftClient client; + + @Shadow protected abstract void logChatMessage(Text message, @Nullable MessageIndicator indicator); @Inject(method = "addMessage(Lnet/minecraft/text/Text;Lnet/minecraft/network/message/MessageSignatureData;Lnet/minecraft/client/gui/hud/MessageIndicator;)V", at = @At("TAIL")) private void testclient$autoDeopListener(Text message, MessageSignatureData signature, MessageIndicator indicator, CallbackInfo ci) { @@ -31,8 +43,20 @@ public class ChatHudMixin { AutoDeopModule.execute(matcher.group(1), matcher.group(2)); } } + + @Inject(method = "addMessage(Lnet/minecraft/text/Text;Lnet/minecraft/network/message/MessageSignatureData;Lnet/minecraft/client/gui/hud/MessageIndicator;)V", at = @At("HEAD"), cancellable = true) + public void chipmunkmod$preventDoubleMessageLogging(Text message, MessageSignatureData signature, MessageIndicator indicator, CallbackInfo ci) { + addMessage(message, signature, client.inGameHud.getTicks(), indicator, false); + ci.cancel(); + } + @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) - public void addMessage(Text message, MessageSignatureData signature, int ticks, MessageIndicator indicator, boolean refresh, CallbackInfo ci) { + public void chipmunkmod$generalAddMessageMixin(Text message, MessageSignatureData signature, int ticks, MessageIndicator indicator, boolean refresh, CallbackInfo ci) { + if(AntiChatSpamModule.instance.isEnabled && message.equals(AntiChatSpamModule.latestPassedThroughMessage)) { + AntiChatSpamModule.latestPassedThroughMessage = Text.empty(); + logChatMessage(message, indicator); + return; + } try { if (RainbowName.INSTANCE.enabled()) { if (message.getString().contains("Your nickname is now ") || message.getString().contains("Nickname changed.")) { @@ -54,8 +78,23 @@ public class ChatHudMixin { // for (AntiChatSpamModule.BlockedPattern pattern : AntiChatSpamModule.instance.patterns) { // if(pattern.pattern().matcher(message.getString()).matches()) ci.cancel(); // } - AntiChatSpamModule.ChatMessage cmessage = new AntiChatSpamModule.ChatMessage(message.getString()); - if(cmessage.hidden) ci.cancel(); + if(AntiChatSpamModule.instance.isEnabled) { + Executor.antiChatSpamService.submit(() -> { + try { + Debug.debug("started a run or wahever", "AntiChatSpam.addMessage.future"); + AntiChatSpamModule.ChatMessage cmessage = new AntiChatSpamModule.ChatMessage(message.getString()); + Debug.debug("hidden: " + cmessage.hidden, "AntiChatSpam.addMessage.future"); + if (cmessage.hidden) return; + AntiChatSpamModule.latestPassedThroughMessage = message; + Debug.debug("changed variable in module class", "AntiChatSpam.addMessage.future"); + MinecraftClient.getInstance().inGameHud.getChatHud().addMessage(message, signature, indicator); + Debug.debug("ended a run or wahever", "AntiChatSpam.addMessage.future"); + } catch (Exception e) { + e.printStackTrace(); + } + }); + ci.cancel(); + } } } diff --git a/src/main/java/land/chipmunk/chipmunkmod/mixin/FontStorageMixin.java b/src/main/java/land/chipmunk/chipmunkmod/mixin/FontStorageMixin.java new file mode 100644 index 0000000..368aed6 --- /dev/null +++ b/src/main/java/land/chipmunk/chipmunkmod/mixin/FontStorageMixin.java @@ -0,0 +1,30 @@ +package land.chipmunk.chipmunkmod.mixin; + +import land.chipmunk.chipmunkmod.testclient.modules.utility.AntiTextObfuscationLagModule; +import land.chipmunk.chipmunkmod.util.Debug; +import net.minecraft.client.MinecraftClient; +import net.minecraft.client.font.FontStorage; +import net.minecraft.client.font.Glyph; +import net.minecraft.client.font.GlyphRenderer; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; + +import java.time.Instant; + +@Mixin(FontStorage.class) +public class FontStorageMixin { + @Shadow private GlyphRenderer blankGlyphRenderer; + + @Inject(method = "getObfuscatedGlyphRenderer", at = @At("HEAD"), cancellable = true) + private void chipmunkmod$preventObfuscatedGlyphLag(Glyph glyph, CallbackInfoReturnable cir) { + if(!AntiTextObfuscationLagModule.instance.isEnabled) return; + if(AntiTextObfuscationLagModule.instance.exceededLimitThisTick || Instant.now().toEpochMilli() - AntiTextObfuscationLagModule.instance.renderTimeStart.toEpochMilli() > 18) { + AntiTextObfuscationLagModule.instance.exceededLimitThisTick = true; + cir.setReturnValue(blankGlyphRenderer); + } +// Debug.debug("Render time: "+(Instant.now().toEpochMilli() - AntiTextObfuscationLagModule.instance.renderTimeStart.toEpochMilli()), "AntiTextObfuscationLag.mixin"); + } +} diff --git a/src/main/java/land/chipmunk/chipmunkmod/mixin/TitleScreenMixin.java b/src/main/java/land/chipmunk/chipmunkmod/mixin/TitleScreenMixin.java index 122e9d6..a88d9be 100644 --- a/src/main/java/land/chipmunk/chipmunkmod/mixin/TitleScreenMixin.java +++ b/src/main/java/land/chipmunk/chipmunkmod/mixin/TitleScreenMixin.java @@ -1,18 +1,23 @@ package land.chipmunk.chipmunkmod.mixin; +import land.chipmunk.chipmunkmod.ChipmunkMod; import land.chipmunk.chipmunkmod.testclient.gui.Gui; import net.minecraft.client.gui.screen.SplashTextRenderer; import net.minecraft.client.gui.screen.TitleScreen; import org.jetbrains.annotations.Nullable; +import org.slf4j.Logger; +import org.spongepowered.asm.mixin.Final; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; +import java.io.IOException; + @Mixin(TitleScreen.class) public class TitleScreenMixin { - private SplashTextRenderer splashText; + private SplashTextRenderer splashText; @Inject(method = "init", at = @At("HEAD")) void testclient$initializeGui(CallbackInfo ci) { @@ -21,6 +26,13 @@ public class TitleScreenMixin { Gui.initAutoRefresher(); Gui.addComponents(); Gui.gui = new Gui(); + try { + ChipmunkMod.MEMORY.load(); + ChipmunkMod.MEMORY.apply(); + } catch (IOException e) { + ChipmunkMod.LOGGER.error("Could not load memory due to an IOException."); + e.printStackTrace(); + } } } } diff --git a/src/main/java/land/chipmunk/chipmunkmod/mixin/WorldRendererMixin.java b/src/main/java/land/chipmunk/chipmunkmod/mixin/WorldRendererMixin.java new file mode 100644 index 0000000..05e46b3 --- /dev/null +++ b/src/main/java/land/chipmunk/chipmunkmod/mixin/WorldRendererMixin.java @@ -0,0 +1,19 @@ +package land.chipmunk.chipmunkmod.mixin; + +import land.chipmunk.chipmunkmod.testclient.modules.utility.AntiTextObfuscationLagModule; +import net.minecraft.client.render.WorldRenderer; +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.callback.CallbackInfo; + +import java.time.Instant; + +@Mixin(WorldRenderer.class) +public class WorldRendererMixin { + @Inject(method = "render", at = @At("HEAD")) + private void chipmunkmod$saveRenderStartTime(CallbackInfo ci) { + AntiTextObfuscationLagModule.instance.renderTimeStart = Instant.now(); + AntiTextObfuscationLagModule.instance.exceededLimitThisTick = false; + } +} diff --git a/src/main/java/land/chipmunk/chipmunkmod/testclient/gui/Gui.java b/src/main/java/land/chipmunk/chipmunkmod/testclient/gui/Gui.java index 8f4c576..8f832aa 100644 --- a/src/main/java/land/chipmunk/chipmunkmod/testclient/gui/Gui.java +++ b/src/main/java/land/chipmunk/chipmunkmod/testclient/gui/Gui.java @@ -10,10 +10,7 @@ import land.chipmunk.chipmunkmod.testclient.modules.op.AntiTeleportModule; import land.chipmunk.chipmunkmod.testclient.modules.op.AutoDeopModule; import land.chipmunk.chipmunkmod.testclient.modules.op.AutoOpModule; import land.chipmunk.chipmunkmod.testclient.modules.op.AutoSudoKickModule; -import land.chipmunk.chipmunkmod.testclient.modules.utility.AntiChatSpamModule; -import land.chipmunk.chipmunkmod.testclient.modules.utility.AutoToolsModule; -import land.chipmunk.chipmunkmod.testclient.modules.utility.BlockGuardianParticlesModule; -import land.chipmunk.chipmunkmod.testclient.modules.utility.GuiMoveModule; +import land.chipmunk.chipmunkmod.testclient.modules.utility.*; import net.minecraft.client.MinecraftClient; import net.minecraft.client.gui.DrawContext; import net.minecraft.client.gui.Drawable; @@ -184,6 +181,7 @@ public class Gui extends Screen{ .withModule(BlockGuardianParticlesModule.instance) .withModule(GuiMoveModule.instance) .withModule(AntiChatSpamModule.instance) + .withModule(AntiTextObfuscationLagModule.instance) .register(); new Category("OP") .withModule(new AntiTeleportModule()) diff --git a/src/main/java/land/chipmunk/chipmunkmod/testclient/gui/components/Category.java b/src/main/java/land/chipmunk/chipmunkmod/testclient/gui/components/Category.java index 540271c..dd40df4 100644 --- a/src/main/java/land/chipmunk/chipmunkmod/testclient/gui/components/Category.java +++ b/src/main/java/land/chipmunk/chipmunkmod/testclient/gui/components/Category.java @@ -1,5 +1,6 @@ package land.chipmunk.chipmunkmod.testclient.gui.components; +import com.google.gson.annotations.Expose; import land.chipmunk.chipmunkmod.ChipmunkMod; import land.chipmunk.chipmunkmod.testclient.gui.Gui; import land.chipmunk.chipmunkmod.util.Chat; @@ -14,7 +15,6 @@ import java.util.ArrayList; import java.util.concurrent.atomic.AtomicInteger; public class Category extends ButtonWidget { - public ArrayList moduleList = new ArrayList<>(); public boolean isExtended; private int fullHeight; diff --git a/src/main/java/land/chipmunk/chipmunkmod/testclient/gui/components/Module.java b/src/main/java/land/chipmunk/chipmunkmod/testclient/gui/components/Module.java index 9f5a9a0..a7d7e63 100644 --- a/src/main/java/land/chipmunk/chipmunkmod/testclient/gui/components/Module.java +++ b/src/main/java/land/chipmunk/chipmunkmod/testclient/gui/components/Module.java @@ -1,5 +1,6 @@ package land.chipmunk.chipmunkmod.testclient.gui.components; +import com.google.gson.annotations.Expose; import land.chipmunk.chipmunkmod.testclient.gui.OptionsScreen; import land.chipmunk.chipmunkmod.util.TickRunnableHandler; import net.minecraft.client.MinecraftClient; @@ -12,7 +13,6 @@ import net.minecraft.util.math.MathHelper; import java.util.ArrayList; public class Module extends ButtonWidget { - public Runnable activateRunnable; public Runnable deactivateRunnable; public Runnable endTickRunnable; @@ -125,8 +125,6 @@ public class Module extends ButtonWidget { return this; } - private Module getThis() {return this;} - @Override public void renderButton(DrawContext context, int mouseX, int mouseY, float delta) { boolean hovered = (mouseX>=getX() && mouseY>=getY() && mouseX { @@ -11,5 +12,8 @@ public abstract class Option { this.name = name; optionValue = defaultValue; } + + public ModuleMemory.Option toMemoryOption() {return new ModuleMemory.Option<>(name, optionValue);} + public Class getType() {return (Class) optionValue.getClass();} // ignore this error intellij has the stupid } diff --git a/src/main/java/land/chipmunk/chipmunkmod/testclient/modules/utility/AntiChatSpamModule.java b/src/main/java/land/chipmunk/chipmunkmod/testclient/modules/utility/AntiChatSpamModule.java index 8028c87..9b2c564 100644 --- a/src/main/java/land/chipmunk/chipmunkmod/testclient/modules/utility/AntiChatSpamModule.java +++ b/src/main/java/land/chipmunk/chipmunkmod/testclient/modules/utility/AntiChatSpamModule.java @@ -5,11 +5,13 @@ import land.chipmunk.chipmunkmod.testclient.gui.components.Module; import land.chipmunk.chipmunkmod.util.Debug; import lombok.Getter; import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientTickEvents; +import net.minecraft.text.Text; import org.apache.commons.text.similarity.LevenshteinDistance; import java.util.ArrayList; public class AntiChatSpamModule extends Module { + public static Text latestPassedThroughMessage = Text.empty(); public static AntiChatSpamModule instance = new AntiChatSpamModule(); public ArrayList messages = new ArrayList<>(); private static final String debugCallerPrefix = "AntiChatSpam."; @@ -19,8 +21,10 @@ public class AntiChatSpamModule extends Module { public AntiChatSpamModule() { super("Anti chat spam"); + isEnabled = true; ClientTickEvents.END_CLIENT_TICK.register(client -> { for (int i = 0; i < messages.size(); i++) { + if(messages.get(i) == null) continue; Debug.debug("Ticked message: " + messages.get(i).content, debugTickedCaller); messages.get(i).tick(); } @@ -42,6 +46,7 @@ public class AntiChatSpamModule extends Module { LevenshteinDistance ld = new LevenshteinDistance(); // thanks maniaplay fo r teaching me about levenshtein distance for (int i = 0; i < chatMessages.size(); i++) { ChatMessage message = chatMessages.get(i); + if(message == null) continue; int distance = ld.apply(this.content(), message.content()); Debug.debug("Distance: " + distance, debugLevenshteinDistanceCaller); if (distance <= ChipmunkMod.CONFIG.antiSpam.minimumLevenshteinDistanceToBeSpam) similarMessages++; diff --git a/src/main/java/land/chipmunk/chipmunkmod/testclient/modules/utility/AntiTextObfuscationLagModule.java b/src/main/java/land/chipmunk/chipmunkmod/testclient/modules/utility/AntiTextObfuscationLagModule.java new file mode 100644 index 0000000..adfe20d --- /dev/null +++ b/src/main/java/land/chipmunk/chipmunkmod/testclient/modules/utility/AntiTextObfuscationLagModule.java @@ -0,0 +1,15 @@ +package land.chipmunk.chipmunkmod.testclient.modules.utility; + +import land.chipmunk.chipmunkmod.testclient.gui.components.Module; + +import java.time.Instant; + +public class AntiTextObfuscationLagModule extends Module { + public static AntiTextObfuscationLagModule instance = new AntiTextObfuscationLagModule(); + public Instant renderTimeStart = Instant.now(); + public boolean exceededLimitThisTick = false; + public AntiTextObfuscationLagModule() { + super("Anti Text Obfuscation"); + isEnabled = true; + } +} diff --git a/src/main/java/land/chipmunk/chipmunkmod/util/Executor.java b/src/main/java/land/chipmunk/chipmunkmod/util/Executor.java index b485d17..f77d743 100644 --- a/src/main/java/land/chipmunk/chipmunkmod/util/Executor.java +++ b/src/main/java/land/chipmunk/chipmunkmod/util/Executor.java @@ -5,7 +5,8 @@ import java.util.concurrent.Executors; import java.util.concurrent.Future; public class Executor { - public static ExecutorService service = Executors.newFixedThreadPool(10); + public static ExecutorService service = Executors.newFixedThreadPool(20); + public static ExecutorService antiChatSpamService = Executors.newFixedThreadPool(1); public static Future submit(Runnable runnable) { return service.submit(runnable); } diff --git a/src/main/java/land/chipmunk/chipmunkmod/util/Webhook.java b/src/main/java/land/chipmunk/chipmunkmod/util/Webhook.java index def1efa..51fea83 100644 --- a/src/main/java/land/chipmunk/chipmunkmod/util/Webhook.java +++ b/src/main/java/land/chipmunk/chipmunkmod/util/Webhook.java @@ -10,7 +10,7 @@ import java.util.List; import java.util.*; // i am sure blackilykat did not write this - chayapak -// you are correct - blackilykat +// i am sure you did not write this either - blackilykat /** * Class used to execute Discord Webhooks with low effort diff --git a/src/main/resources/chipmunkmod.mixins.json b/src/main/resources/chipmunkmod.mixins.json index e0e07e2..3b9db46 100644 --- a/src/main/resources/chipmunkmod.mixins.json +++ b/src/main/resources/chipmunkmod.mixins.json @@ -7,13 +7,19 @@ "ChatHudMixin", "ChatInputSuggestorMixin", "ChatScreenMixin", + "ClientConnectionAccessor", + "ClientConnectionInvoker", "ClientConnectionMixin", "ClientPlayerEntityMixin", "ClientPlayNetworkHandlerAccessor", - "ClientPlayNetworkHandlerMixin", "ClientPlayNetworkHandlerInvoker", + "ClientPlayNetworkHandlerMixin", "DecoderHandlerMixin", + "DecoratedPotBlockEntitySherdsMixin", "ElderGuardianAppearanceParticleMixin", + "FontStorageMixin", + "WorldRendererMixin", + "IdentifierMixin", "KeyboardInputMixin", "KeyboardMixin", "LightmapTextureManagerMixin", @@ -22,12 +28,8 @@ "NbtIoMixin", "SessionMixin", "StringHelperMixin", - "TitleScreenMixin", - "IdentifierMixin", - "DecoratedPotBlockEntitySherdsMixin", "TextMixin", - "ClientConnectionInvoker", - "ClientConnectionAccessor" + "TitleScreenMixin" ], "injectors": { "defaultRequire": 1