made anti chat spam run in a different thread + made anti text obfuscation lag + i forgor

This commit is contained in:
blackilykat 2023-07-15 12:10:05 +02:00
parent 03478b3133
commit 2a101f1576
18 changed files with 508 additions and 23 deletions

View file

@ -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.

View file

@ -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) {

View file

@ -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<FabricClientCommandSource> dispatcher) {
final ClearAntiChatSpamQueueCommand instance = new ClearAntiChatSpamQueueCommand();
dispatcher.register(
literal("clearantichatspamqueue")
.executes(instance::run)
);
}
public int run(CommandContext<FabricClientCommandSource> context) throws CommandSyntaxException {
List<Runnable> runnables = Executor.antiChatSpamService.shutdownNow();
Executor.antiChatSpamService = Executors.newFixedThreadPool(1);
Chat.sendGreen("Stopped " + runnables.size() + " chat messages from getting recieved!");
return 1;
}
}

View file

@ -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<Category> 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 <T> void setRealOptionValue(land.chipmunk.chipmunkmod.testclient.gui.components.Option<T> real, Option<?> fake) {
real.optionValue = (T) fake.value; // shut the fuck up intellij this cast is fine
}
public <T> void setOptionValue(Option<T> 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<Module> 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<Option<?>> options = new ArrayList<>();
public Module(String name, boolean enabled) {
this.name = name;
this.enabled = enabled;
}
}
public static class Option<T extends Object> {
public final String name;
public T value;
public Option(String name, T value) {
this.name = name;
this.value = value;
}
public Class<T> getType() {return (Class<T>) value.getClass();} // ignore warning cause intellij has the stupid
}
}

View file

@ -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()));
}
}

View file

@ -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();
}
}
}

View file

@ -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<GlyphRenderer> 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");
}
}

View file

@ -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();
}
}
}
}

View file

@ -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;
}
}

View file

@ -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())

View file

@ -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<Module> moduleList = new ArrayList<>();
public boolean isExtended;
private int fullHeight;

View file

@ -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<getWidth()+getX() && mouseY<getHeight()+getY());

View file

@ -1,6 +1,7 @@
package land.chipmunk.chipmunkmod.testclient.gui.components;
import land.chipmunk.chipmunkmod.memory.ModuleMemory;
import net.minecraft.client.gui.widget.ClickableWidget;
public abstract class Option<ValueType> {
@ -11,5 +12,8 @@ public abstract class Option<ValueType> {
this.name = name;
optionValue = defaultValue;
}
public ModuleMemory.Option<ValueType> toMemoryOption() {return new ModuleMemory.Option<>(name, optionValue);}
public Class<ValueType> getType() {return (Class<ValueType>) optionValue.getClass();} // ignore this error intellij has the stupid
}

View file

@ -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<ChatMessage> 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++;

View file

@ -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;
}
}

View file

@ -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);
}

View file

@ -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

View file

@ -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