From e1c9b900a98ae30b6f0c5dcf6d259f7a617bba18 Mon Sep 17 00:00:00 2001
From: Ic3Tank <61137113+IceTank@users.noreply.github.com>
Date: Wed, 21 May 2025 22:39:56 +0200
Subject: [PATCH 1/7] feat(PacketLimiter): Add click packet limit to
PacketLimiter
---
.../render/GenericContainerScreenMixin.java | 40 +++++++++++++
.../mixin/render/HandledScreenMixin.java | 31 ++++++++++
.../com/lambda/event/events/RenderEvent.kt | 5 ++
.../module/modules/network/PacketLimiter.kt | 60 ++++++++++++++++++-
.../src/main/resources/lambda.accesswidener | 4 ++
.../main/resources/lambda.mixins.common.json | 8 ++-
6 files changed, 142 insertions(+), 6 deletions(-)
create mode 100644 common/src/main/java/com/lambda/mixin/render/GenericContainerScreenMixin.java
create mode 100644 common/src/main/java/com/lambda/mixin/render/HandledScreenMixin.java
diff --git a/common/src/main/java/com/lambda/mixin/render/GenericContainerScreenMixin.java b/common/src/main/java/com/lambda/mixin/render/GenericContainerScreenMixin.java
new file mode 100644
index 000000000..74b0a2977
--- /dev/null
+++ b/common/src/main/java/com/lambda/mixin/render/GenericContainerScreenMixin.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright 2025 Lambda
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+package com.lambda.mixin.render;
+
+import com.lambda.event.EventFlow;
+import com.lambda.event.events.RenderEvent;
+import net.minecraft.client.gui.DrawContext;
+import net.minecraft.client.gui.screen.ingame.GenericContainerScreen;
+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;
+
+/*
+ * @author IceTank
+ * @since 21.05.2025
+ */
+@Mixin(GenericContainerScreen.class)
+public class GenericContainerScreenMixin extends HandledScreenMixin {
+ @Inject(method = "render", at = @At("TAIL"))
+ public void onRender(DrawContext context, int mouseX, int mouseY, float delta, CallbackInfo ci) {
+ RenderEvent.GUI.Container event = new RenderEvent.GUI.Container(((GenericContainerScreen) (Object) this), context, mouseX, mouseY, delta);
+ EventFlow.post(event);
+ }
+}
diff --git a/common/src/main/java/com/lambda/mixin/render/HandledScreenMixin.java b/common/src/main/java/com/lambda/mixin/render/HandledScreenMixin.java
new file mode 100644
index 000000000..8e2fa37ac
--- /dev/null
+++ b/common/src/main/java/com/lambda/mixin/render/HandledScreenMixin.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright 2025 Lambda
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+package com.lambda.mixin.render;
+
+import net.minecraft.client.gui.screen.ingame.HandledScreen;
+import org.spongepowered.asm.mixin.Mixin;
+import org.spongepowered.asm.mixin.Shadow;
+import org.spongepowered.asm.mixin.Unique;
+
+/*
+ * @author IceTank
+ * @since 21.05.2025
+ */
+@Mixin(HandledScreen.class)
+public class HandledScreenMixin {
+}
diff --git a/common/src/main/kotlin/com/lambda/event/events/RenderEvent.kt b/common/src/main/kotlin/com/lambda/event/events/RenderEvent.kt
index 6c895d02d..7f348cb0f 100644
--- a/common/src/main/kotlin/com/lambda/event/events/RenderEvent.kt
+++ b/common/src/main/kotlin/com/lambda/event/events/RenderEvent.kt
@@ -24,6 +24,8 @@ import com.lambda.event.callback.ICancellable
import com.lambda.graphics.renderer.esp.global.DynamicESP
import com.lambda.graphics.renderer.esp.global.StaticESP
import com.lambda.util.math.Vec2d
+import net.minecraft.client.gui.DrawContext
+import net.minecraft.client.gui.screen.ingame.GenericContainerScreen
sealed class RenderEvent {
class World : Event
@@ -40,6 +42,9 @@ sealed class RenderEvent {
class Scaled(scaleFactor: Double) : GUI(scaleFactor)
class HUD(scaleFactor: Double) : GUI(scaleFactor)
class Fixed : GUI(1.0)
+ class Container(val genericContainerScreen: GenericContainerScreen, val drawContext: DrawContext, val mouseX: Int, val mouseY: Int, val delta: Float) : GUI(1.0) {
+ val mouse = Vec2d(mouseX, mouseY)
+ }
val screenSize = Vec2d(mc.window.framebufferWidth, mc.window.framebufferHeight) / scale
}
diff --git a/common/src/main/kotlin/com/lambda/module/modules/network/PacketLimiter.kt b/common/src/main/kotlin/com/lambda/module/modules/network/PacketLimiter.kt
index 729e8a718..891eb7305 100644
--- a/common/src/main/kotlin/com/lambda/module/modules/network/PacketLimiter.kt
+++ b/common/src/main/kotlin/com/lambda/module/modules/network/PacketLimiter.kt
@@ -18,14 +18,21 @@
package com.lambda.module.modules.network
import com.lambda.event.events.PacketEvent
+import com.lambda.event.events.PlayerEvent
+import com.lambda.event.events.RenderEvent
import com.lambda.event.listener.SafeListener.Companion.listen
import com.lambda.module.Module
import com.lambda.module.tag.ModuleTag
import com.lambda.util.Communication.info
import com.lambda.util.collections.LimitedDecayQueue
+import com.mojang.blaze3d.systems.RenderSystem
+import net.minecraft.client.gui.DrawContext
+import net.minecraft.client.gui.screen.ingame.HandledScreen
import net.minecraft.network.packet.c2s.common.CommonPongC2SPacket
+import net.minecraft.network.packet.c2s.play.ClickSlotC2SPacket
import net.minecraft.network.packet.c2s.play.PlayerMoveC2SPacket.*
import net.minecraft.network.packet.c2s.play.TeleportConfirmC2SPacket
+import net.minecraft.text.Text
// ToDo: HUD info
object PacketLimiter : Module(
@@ -33,8 +40,9 @@ object PacketLimiter : Module(
description = "Limits the amount of packets sent to the server",
defaultTags = setOf(ModuleTag.NETWORK)
) {
- private var packetQueue = LimitedDecayQueue(99, 1000)
- private val limit by setting("Limit", 99, 1..100, 1, "The maximum amount of packets to send per given time interval", unit = " packets")
+ private var packetQueue = LimitedDecayQueue(999, 1000)
+ private var clickPacketQueue = LimitedDecayQueue(500, 30000)
+ private val limit by setting("Limit", 99, 1..1000, 1, "The maximum amount of packets to send per given time interval", unit = " packets")
.onValueChange { _, to -> packetQueue.setSizeLimit(to) }
private val interval by setting("Duration", 4000L, 1L..10000L, 50L, "The interval / duration in milliseconds to limit packets for", unit = " ms")
@@ -48,7 +56,18 @@ object PacketLimiter : Module(
OnGroundOnly::class,
TeleportConfirmC2SPacket::class
)
- private val ignorePackets by setting("Ignore Packets", defaultIgnorePackets.mapNotNull { it.simpleName }, "Packets to ignore when limiting")
+ private val limitAllPackets by setting("Limit All", false, "Limit all send packets")
+ private val ignorePackets by setting("Ignore Packets", defaultIgnorePackets.mapNotNull { it.simpleName }, "Packets to ignore when limiting") { limitAllPackets }
+ private val limitClickPackets by setting("Clicks limit", true, "Limits the amount of click packets you can send to prevent kicks.")
+ private val limitClickWindowSize by setting("Click limit window size", 4f, 0.1f..10.0f, 0.1f, "Click limit window size", unit = " s") {
+ limitClickPackets
+ }.onValueChange { _, to -> clickPacketQueue.setDecayTime((to * 1000).toLong()) }
+ private val limitClickRate by setting("Click limit rate", 19.3f, 0.1f..40f, 0.1f, "Click limit rate", unit = " packets/sec") {
+ limitClickPackets
+ }.onValueChange { _, to -> clickPacketQueue.setSizeLimit((limitClickWindowSize * to).toInt()) }
+ private val limitClickRender by setting("Render Limit in Container", true, "Render the amount of clicks remaining in the container screen") {
+ limitClickPackets
+ }
init {
onEnable {
@@ -58,11 +77,46 @@ object PacketLimiter : Module(
listen(Int.MAX_VALUE) {
if (it.packet::class.simpleName in ignorePackets) return@listen
+ if (limitClickPackets && it.packet is ClickSlotC2SPacket) {
+ if (!canSendClickPackets(1)) {
+ it.cancel()
+ return@listen
+ } else {
+ clickPacketQueue.add(System.currentTimeMillis())
+ }
+ }
+
// this@PacketLimiter.info("Packet sent: ${it.packet::class.simpleName} (${packetQueue.size} / $limit) ${Instant.now()}")
if (packetQueue.add(it)) return@listen
it.cancel()
this@PacketLimiter.info("Packet limit reached, dropping packet: ${it.packet::class.simpleName} (${packetQueue.size} / $limit)")
}
+
+ listen{
+ if (!limitClickPackets) return@listen
+ if (!canSendClickPackets(1)) {
+ it.cancel()
+ return@listen
+ }
+ }
+
+ listen {
+ if (!limitClickRender) return@listen
+ val renderScreen: HandledScreen<*> = it.genericContainerScreen
+ val context: DrawContext = it.drawContext
+ val x = renderScreen.x
+ val y = renderScreen.y
+
+ RenderSystem.disableDepthTest()
+ val remainingText = "Clicks Remaining: " + clickPacketsRemaining().toInt().toString()
+ context.drawText(renderScreen.textRenderer, Text.literal(remainingText), x + renderScreen.backgroundWidth, y, 4210752, false)
+ RenderSystem.enableDepthTest()
+ }
}
+
+ fun canSendClickPackets(packets: Int) = clickPacketQueue.size + packets < clickPacketsWindowAmount()
+ fun clickPacketsRemaining() = clickPacketsWindowAmount() - clickPacketQueue.size
+
+ private fun clickPacketsWindowAmount() = limitClickWindowSize * limitClickRate
}
diff --git a/common/src/main/resources/lambda.accesswidener b/common/src/main/resources/lambda.accesswidener
index 9e33b952c..5dbe47b66 100644
--- a/common/src/main/resources/lambda.accesswidener
+++ b/common/src/main/resources/lambda.accesswidener
@@ -40,6 +40,10 @@ accessible field com/mojang/blaze3d/systems/RenderSystem$ShapeIndexBuffer id I
accessible field net/minecraft/client/render/BufferRenderer currentVertexBuffer Lnet/minecraft/client/gl/VertexBuffer;
accessible field net/minecraft/client/texture/NativeImage pointer J
accessible class net/minecraft/client/gui/screen/SplashOverlay$LogoTexture
+accessible field net/minecraft/client/gui/screen/ingame/HandledScreen x I
+accessible field net/minecraft/client/gui/screen/ingame/HandledScreen y I
+accessible field net/minecraft/client/gui/screen/ingame/HandledScreen backgroundWidth I
+accessible field net/minecraft/client/gui/screen/Screen textRenderer Lnet/minecraft/client/font/TextRenderer;
# Text
accessible field net/minecraft/text/Style color Lnet/minecraft/text/TextColor;
diff --git a/common/src/main/resources/lambda.mixins.common.json b/common/src/main/resources/lambda.mixins.common.json
index 133a8b1a4..8e40c712b 100644
--- a/common/src/main/resources/lambda.mixins.common.json
+++ b/common/src/main/resources/lambda.mixins.common.json
@@ -4,6 +4,7 @@
"package": "com.lambda.mixin",
"compatibilityLevel": "JAVA_17",
"client": [
+ "CrashReportMixin",
"MinecraftClientMixin",
"baritone.MixinBaritonePlayerContext",
"baritone.MixinLookBehavior",
@@ -36,7 +37,9 @@
"render.DebugHudMixin",
"render.ElytraFeatureRendererMixin",
"render.GameRendererMixin",
+ "render.GenericContainerScreenMixin",
"render.GlStateManagerMixin",
+ "render.HandledScreenMixin",
"render.InGameHudMixin",
"render.InGameOverlayRendererMixin",
"render.LightmapTextureManagerMixin",
@@ -54,10 +57,9 @@
"world.BlockCollisionSpliteratorMixin",
"world.ClientChunkManagerMixin",
"world.ClientWorldMixin",
- "world.StructureTemplateMixin",
"world.ExplosionMixin",
- "world.WorldMixin",
- "CrashReportMixin"
+ "world.StructureTemplateMixin",
+ "world.WorldMixin"
],
"injectors": {
"defaultRequire": 1
From 20d17c78036c31a93170a67fc5c25f86c3a62238 Mon Sep 17 00:00:00 2001
From: Ic3Tank <61137113+IceTank@users.noreply.github.com>
Date: Sat, 24 May 2025 14:29:10 +0200
Subject: [PATCH 2/7] Use properties with getters instead of methods for simple
values
---
.../lambda/module/modules/network/PacketLimiter.kt | 13 ++++++++-----
1 file changed, 8 insertions(+), 5 deletions(-)
diff --git a/common/src/main/kotlin/com/lambda/module/modules/network/PacketLimiter.kt b/common/src/main/kotlin/com/lambda/module/modules/network/PacketLimiter.kt
index 891eb7305..eb7d10de5 100644
--- a/common/src/main/kotlin/com/lambda/module/modules/network/PacketLimiter.kt
+++ b/common/src/main/kotlin/com/lambda/module/modules/network/PacketLimiter.kt
@@ -33,6 +33,7 @@ import net.minecraft.network.packet.c2s.play.ClickSlotC2SPacket
import net.minecraft.network.packet.c2s.play.PlayerMoveC2SPacket.*
import net.minecraft.network.packet.c2s.play.TeleportConfirmC2SPacket
import net.minecraft.text.Text
+import kotlin.math.floor
// ToDo: HUD info
object PacketLimiter : Module(
@@ -69,6 +70,11 @@ object PacketLimiter : Module(
limitClickPackets
}
+ private val clickPacketsWindowAmount: Int
+ get() = floor(limitClickWindowSize * limitClickRate).toInt()
+ private val clickPacketsRemaining: Int
+ get() = clickPacketsWindowAmount - clickPacketQueue.size
+
init {
onEnable {
packetQueue = LimitedDecayQueue(limit, interval)
@@ -109,14 +115,11 @@ object PacketLimiter : Module(
val y = renderScreen.y
RenderSystem.disableDepthTest()
- val remainingText = "Clicks Remaining: " + clickPacketsRemaining().toInt().toString()
+ val remainingText = "Clicks Remaining: $clickPacketsRemaining"
context.drawText(renderScreen.textRenderer, Text.literal(remainingText), x + renderScreen.backgroundWidth, y, 4210752, false)
RenderSystem.enableDepthTest()
}
}
- fun canSendClickPackets(packets: Int) = clickPacketQueue.size + packets < clickPacketsWindowAmount()
- fun clickPacketsRemaining() = clickPacketsWindowAmount() - clickPacketQueue.size
-
- private fun clickPacketsWindowAmount() = limitClickWindowSize * limitClickRate
+ fun canSendClickPackets(packets: Int) = clickPacketQueue.size + packets < clickPacketsWindowAmount
}
From 953e58b0c1f5b3b247dd03c1ae2a057926548727 Mon Sep 17 00:00:00 2001
From: Ic3Tank <61137113+IceTank@users.noreply.github.com>
Date: Sat, 24 May 2025 15:52:45 +0200
Subject: [PATCH 3/7] Use RenderEvent.GUI.Fixed event to render text
---
.../render/GenericContainerScreenMixin.java | 40 -------------------
.../com/lambda/event/events/RenderEvent.kt | 3 --
.../module/modules/network/PacketLimiter.kt | 38 +++++++++---------
.../main/resources/lambda.mixins.common.json | 1 -
4 files changed, 20 insertions(+), 62 deletions(-)
delete mode 100644 common/src/main/java/com/lambda/mixin/render/GenericContainerScreenMixin.java
diff --git a/common/src/main/java/com/lambda/mixin/render/GenericContainerScreenMixin.java b/common/src/main/java/com/lambda/mixin/render/GenericContainerScreenMixin.java
deleted file mode 100644
index 74b0a2977..000000000
--- a/common/src/main/java/com/lambda/mixin/render/GenericContainerScreenMixin.java
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Copyright 2025 Lambda
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see .
- */
-
-package com.lambda.mixin.render;
-
-import com.lambda.event.EventFlow;
-import com.lambda.event.events.RenderEvent;
-import net.minecraft.client.gui.DrawContext;
-import net.minecraft.client.gui.screen.ingame.GenericContainerScreen;
-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;
-
-/*
- * @author IceTank
- * @since 21.05.2025
- */
-@Mixin(GenericContainerScreen.class)
-public class GenericContainerScreenMixin extends HandledScreenMixin {
- @Inject(method = "render", at = @At("TAIL"))
- public void onRender(DrawContext context, int mouseX, int mouseY, float delta, CallbackInfo ci) {
- RenderEvent.GUI.Container event = new RenderEvent.GUI.Container(((GenericContainerScreen) (Object) this), context, mouseX, mouseY, delta);
- EventFlow.post(event);
- }
-}
diff --git a/common/src/main/kotlin/com/lambda/event/events/RenderEvent.kt b/common/src/main/kotlin/com/lambda/event/events/RenderEvent.kt
index 7f348cb0f..7d4f99399 100644
--- a/common/src/main/kotlin/com/lambda/event/events/RenderEvent.kt
+++ b/common/src/main/kotlin/com/lambda/event/events/RenderEvent.kt
@@ -42,9 +42,6 @@ sealed class RenderEvent {
class Scaled(scaleFactor: Double) : GUI(scaleFactor)
class HUD(scaleFactor: Double) : GUI(scaleFactor)
class Fixed : GUI(1.0)
- class Container(val genericContainerScreen: GenericContainerScreen, val drawContext: DrawContext, val mouseX: Int, val mouseY: Int, val delta: Float) : GUI(1.0) {
- val mouse = Vec2d(mouseX, mouseY)
- }
val screenSize = Vec2d(mc.window.framebufferWidth, mc.window.framebufferHeight) / scale
}
diff --git a/common/src/main/kotlin/com/lambda/module/modules/network/PacketLimiter.kt b/common/src/main/kotlin/com/lambda/module/modules/network/PacketLimiter.kt
index eb7d10de5..1a5b21116 100644
--- a/common/src/main/kotlin/com/lambda/module/modules/network/PacketLimiter.kt
+++ b/common/src/main/kotlin/com/lambda/module/modules/network/PacketLimiter.kt
@@ -21,18 +21,21 @@ import com.lambda.event.events.PacketEvent
import com.lambda.event.events.PlayerEvent
import com.lambda.event.events.RenderEvent
import com.lambda.event.listener.SafeListener.Companion.listen
+import com.lambda.graphics.renderer.gui.FontRenderer
import com.lambda.module.Module
import com.lambda.module.tag.ModuleTag
import com.lambda.util.Communication.info
import com.lambda.util.collections.LimitedDecayQueue
-import com.mojang.blaze3d.systems.RenderSystem
-import net.minecraft.client.gui.DrawContext
-import net.minecraft.client.gui.screen.ingame.HandledScreen
+import com.lambda.util.math.Vec2d
+import net.minecraft.client.gui.screen.ingame.GenericContainerScreen
import net.minecraft.network.packet.c2s.common.CommonPongC2SPacket
import net.minecraft.network.packet.c2s.play.ClickSlotC2SPacket
-import net.minecraft.network.packet.c2s.play.PlayerMoveC2SPacket.*
+import net.minecraft.network.packet.c2s.play.PlayerMoveC2SPacket.Full
+import net.minecraft.network.packet.c2s.play.PlayerMoveC2SPacket.LookAndOnGround
+import net.minecraft.network.packet.c2s.play.PlayerMoveC2SPacket.OnGroundOnly
+import net.minecraft.network.packet.c2s.play.PlayerMoveC2SPacket.PositionAndOnGround
import net.minecraft.network.packet.c2s.play.TeleportConfirmC2SPacket
-import net.minecraft.text.Text
+import java.awt.Color
import kotlin.math.floor
// ToDo: HUD info
@@ -92,14 +95,14 @@ object PacketLimiter : Module(
}
}
-// this@PacketLimiter.info("Packet sent: ${it.packet::class.simpleName} (${packetQueue.size} / $limit) ${Instant.now()}")
+ // this@PacketLimiter.info("Packet sent: ${it.packet::class.simpleName} (${packetQueue.size} / $limit) ${Instant.now()}")
if (packetQueue.add(it)) return@listen
it.cancel()
this@PacketLimiter.info("Packet limit reached, dropping packet: ${it.packet::class.simpleName} (${packetQueue.size} / $limit)")
}
- listen{
+ listen {
if (!limitClickPackets) return@listen
if (!canSendClickPackets(1)) {
it.cancel()
@@ -107,19 +110,18 @@ object PacketLimiter : Module(
}
}
- listen {
- if (!limitClickRender) return@listen
- val renderScreen: HandledScreen<*> = it.genericContainerScreen
- val context: DrawContext = it.drawContext
- val x = renderScreen.x
- val y = renderScreen.y
-
- RenderSystem.disableDepthTest()
+ listen {
+ if (!limitClickRender) {
+ return@listen
+ }
+ val sh = mc.currentScreen as? GenericContainerScreen ?: return@listen
val remainingText = "Clicks Remaining: $clickPacketsRemaining"
- context.drawText(renderScreen.textRenderer, Text.literal(remainingText), x + renderScreen.backgroundWidth, y, 4210752, false)
- RenderSystem.enableDepthTest()
+ val mcScale = mc.window.scaleFactor
+ val fontScale = mcScale * 1.5
+ val fontHeight = FontRenderer.getHeight(fontScale)
+ FontRenderer.drawString(remainingText, Vec2d(sh.x * mcScale, sh.y * mcScale - fontHeight), Color(0x9DFFFF), fontScale, false)
}
}
- fun canSendClickPackets(packets: Int) = clickPacketQueue.size + packets < clickPacketsWindowAmount
+ fun canSendClickPackets(packets: Int) = clickPacketQueue.size + packets <= clickPacketsWindowAmount
}
diff --git a/common/src/main/resources/lambda.mixins.common.json b/common/src/main/resources/lambda.mixins.common.json
index 8e40c712b..bf473d545 100644
--- a/common/src/main/resources/lambda.mixins.common.json
+++ b/common/src/main/resources/lambda.mixins.common.json
@@ -37,7 +37,6 @@
"render.DebugHudMixin",
"render.ElytraFeatureRendererMixin",
"render.GameRendererMixin",
- "render.GenericContainerScreenMixin",
"render.GlStateManagerMixin",
"render.HandledScreenMixin",
"render.InGameHudMixin",
From ff69d57ebb9872769e5f1e21c0af46ff58f4ccaf Mon Sep 17 00:00:00 2001
From: Ic3Tank <61137113+IceTank@users.noreply.github.com>
Date: Sat, 24 May 2025 17:14:57 +0200
Subject: [PATCH 4/7] Removed unused HandledScreenMixin
---
.../mixin/render/HandledScreenMixin.java | 31 -------------------
.../main/resources/lambda.mixins.common.json | 1 -
2 files changed, 32 deletions(-)
delete mode 100644 common/src/main/java/com/lambda/mixin/render/HandledScreenMixin.java
diff --git a/common/src/main/java/com/lambda/mixin/render/HandledScreenMixin.java b/common/src/main/java/com/lambda/mixin/render/HandledScreenMixin.java
deleted file mode 100644
index 8e2fa37ac..000000000
--- a/common/src/main/java/com/lambda/mixin/render/HandledScreenMixin.java
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * Copyright 2025 Lambda
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see .
- */
-
-package com.lambda.mixin.render;
-
-import net.minecraft.client.gui.screen.ingame.HandledScreen;
-import org.spongepowered.asm.mixin.Mixin;
-import org.spongepowered.asm.mixin.Shadow;
-import org.spongepowered.asm.mixin.Unique;
-
-/*
- * @author IceTank
- * @since 21.05.2025
- */
-@Mixin(HandledScreen.class)
-public class HandledScreenMixin {
-}
diff --git a/common/src/main/resources/lambda.mixins.common.json b/common/src/main/resources/lambda.mixins.common.json
index bf473d545..4a32df76c 100644
--- a/common/src/main/resources/lambda.mixins.common.json
+++ b/common/src/main/resources/lambda.mixins.common.json
@@ -38,7 +38,6 @@
"render.ElytraFeatureRendererMixin",
"render.GameRendererMixin",
"render.GlStateManagerMixin",
- "render.HandledScreenMixin",
"render.InGameHudMixin",
"render.InGameOverlayRendererMixin",
"render.LightmapTextureManagerMixin",
From f339962555e4eba781389266fe1202aa4d2590b1 Mon Sep 17 00:00:00 2001
From: Ic3Tank <61137113+IceTank@users.noreply.github.com>
Date: Sat, 24 May 2025 17:16:07 +0200
Subject: [PATCH 5/7] Cleanup RenderEvent.kt imports
---
common/src/main/kotlin/com/lambda/event/events/RenderEvent.kt | 2 --
1 file changed, 2 deletions(-)
diff --git a/common/src/main/kotlin/com/lambda/event/events/RenderEvent.kt b/common/src/main/kotlin/com/lambda/event/events/RenderEvent.kt
index 7d4f99399..6c895d02d 100644
--- a/common/src/main/kotlin/com/lambda/event/events/RenderEvent.kt
+++ b/common/src/main/kotlin/com/lambda/event/events/RenderEvent.kt
@@ -24,8 +24,6 @@ import com.lambda.event.callback.ICancellable
import com.lambda.graphics.renderer.esp.global.DynamicESP
import com.lambda.graphics.renderer.esp.global.StaticESP
import com.lambda.util.math.Vec2d
-import net.minecraft.client.gui.DrawContext
-import net.minecraft.client.gui.screen.ingame.GenericContainerScreen
sealed class RenderEvent {
class World : Event
From cde1417ea744aab6b17dca49897b5ddaab28a097 Mon Sep 17 00:00:00 2001
From: Ic3Tank <61137113+IceTank@users.noreply.github.com>
Date: Sat, 24 May 2025 17:17:49 +0200
Subject: [PATCH 6/7] Cleanup lambda.mixin.common.json
---
common/src/main/resources/lambda.mixins.common.json | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/common/src/main/resources/lambda.mixins.common.json b/common/src/main/resources/lambda.mixins.common.json
index 4a32df76c..133a8b1a4 100644
--- a/common/src/main/resources/lambda.mixins.common.json
+++ b/common/src/main/resources/lambda.mixins.common.json
@@ -4,7 +4,6 @@
"package": "com.lambda.mixin",
"compatibilityLevel": "JAVA_17",
"client": [
- "CrashReportMixin",
"MinecraftClientMixin",
"baritone.MixinBaritonePlayerContext",
"baritone.MixinLookBehavior",
@@ -55,9 +54,10 @@
"world.BlockCollisionSpliteratorMixin",
"world.ClientChunkManagerMixin",
"world.ClientWorldMixin",
- "world.ExplosionMixin",
"world.StructureTemplateMixin",
- "world.WorldMixin"
+ "world.ExplosionMixin",
+ "world.WorldMixin",
+ "CrashReportMixin"
],
"injectors": {
"defaultRequire": 1
From d5e8180761db18ac23c2c1a04d8e4782b1fdee6d Mon Sep 17 00:00:00 2001
From: Edouard127 <46357922+Edouard127@users.noreply.github.com>
Date: Thu, 29 May 2025 18:23:47 -0400
Subject: [PATCH 7/7] Update PacketLimiter.kt
---
.../module/modules/network/PacketLimiter.kt | 93 +++++++++----------
1 file changed, 43 insertions(+), 50 deletions(-)
diff --git a/common/src/main/kotlin/com/lambda/module/modules/network/PacketLimiter.kt b/common/src/main/kotlin/com/lambda/module/modules/network/PacketLimiter.kt
index 1a5b21116..c11a3769b 100644
--- a/common/src/main/kotlin/com/lambda/module/modules/network/PacketLimiter.kt
+++ b/common/src/main/kotlin/com/lambda/module/modules/network/PacketLimiter.kt
@@ -29,14 +29,12 @@ import com.lambda.util.collections.LimitedDecayQueue
import com.lambda.util.math.Vec2d
import net.minecraft.client.gui.screen.ingame.GenericContainerScreen
import net.minecraft.network.packet.c2s.common.CommonPongC2SPacket
-import net.minecraft.network.packet.c2s.play.ClickSlotC2SPacket
import net.minecraft.network.packet.c2s.play.PlayerMoveC2SPacket.Full
import net.minecraft.network.packet.c2s.play.PlayerMoveC2SPacket.LookAndOnGround
import net.minecraft.network.packet.c2s.play.PlayerMoveC2SPacket.OnGroundOnly
import net.minecraft.network.packet.c2s.play.PlayerMoveC2SPacket.PositionAndOnGround
import net.minecraft.network.packet.c2s.play.TeleportConfirmC2SPacket
import java.awt.Color
-import kotlin.math.floor
// ToDo: HUD info
object PacketLimiter : Module(
@@ -44,12 +42,12 @@ object PacketLimiter : Module(
description = "Limits the amount of packets sent to the server",
defaultTags = setOf(ModuleTag.NETWORK)
) {
- private var packetQueue = LimitedDecayQueue(999, 1000)
- private var clickPacketQueue = LimitedDecayQueue(500, 30000)
- private val limit by setting("Limit", 99, 1..1000, 1, "The maximum amount of packets to send per given time interval", unit = " packets")
+ private val page by setting("Page", Page.General)
+
+ private val limit by setting("Limit", 99, 1..1000, 1, "The maximum amount of packets to send per given time interval", unit = " packets") { page == Page.General }
.onValueChange { _, to -> packetQueue.setSizeLimit(to) }
- private val interval by setting("Duration", 4000L, 1L..10000L, 50L, "The interval / duration in milliseconds to limit packets for", unit = " ms")
+ private val interval by setting("Duration", 4000L, 1L..10000L, 50L, "The interval / duration in milliseconds to limit packets for", unit = " ms") { page == Page.General }
.onValueChange { _, to -> packetQueue.setDecayTime(to) }
private val defaultIgnorePackets = setOf(
@@ -60,42 +58,32 @@ object PacketLimiter : Module(
OnGroundOnly::class,
TeleportConfirmC2SPacket::class
)
- private val limitAllPackets by setting("Limit All", false, "Limit all send packets")
- private val ignorePackets by setting("Ignore Packets", defaultIgnorePackets.mapNotNull { it.simpleName }, "Packets to ignore when limiting") { limitAllPackets }
- private val limitClickPackets by setting("Clicks limit", true, "Limits the amount of click packets you can send to prevent kicks.")
- private val limitClickWindowSize by setting("Click limit window size", 4f, 0.1f..10.0f, 0.1f, "Click limit window size", unit = " s") {
- limitClickPackets
- }.onValueChange { _, to -> clickPacketQueue.setDecayTime((to * 1000).toLong()) }
- private val limitClickRate by setting("Click limit rate", 19.3f, 0.1f..40f, 0.1f, "Click limit rate", unit = " packets/sec") {
- limitClickPackets
- }.onValueChange { _, to -> clickPacketQueue.setSizeLimit((limitClickWindowSize * to).toInt()) }
- private val limitClickRender by setting("Render Limit in Container", true, "Render the amount of clicks remaining in the container screen") {
- limitClickPackets
- }
- private val clickPacketsWindowAmount: Int
- get() = floor(limitClickWindowSize * limitClickRate).toInt()
+ private val limitAllPackets by setting("Limit All", false, "Limit all send packets") { page == Page.General }
+ private val ignorePackets by setting("Ignore Packets", defaultIgnorePackets.mapNotNull { it.simpleName }, "Packets to ignore when limiting") { page == Page.General && limitAllPackets }
+
+ private val limitClicks by setting("Clicks Limit", true, "Limits the amount of click packets you can send to prevent kicks on certain servers.") { page == Page.Clicks }
+ private val limitClickWindowSize by setting("Click Limit Window Size", 4.0, 0.1..10.0, 0.1, "Click limit window size", unit = " s") { page == Page.Clicks && limitClicks }
+ .onValueChange { _, to -> clickPacketQueue.setDecayTime((to * 1000).toLong()) }
+ private val limitClickRate by setting("Click Limit Rate", 19, 1..40, 1, "Click limit rate", unit = " packets/sec") { page == Page.Clicks && limitClicks }
+ .onValueChange { _, to -> clickPacketQueue.setSizeLimit((limitClickWindowSize * to).toInt()) }
+ private val limitClickRender by setting("Render Limit in Container", true, "Render the amount of clicks remaining in the container screen") { page == Page.Clicks && limitClicks }
+
+ private var packetQueue = LimitedDecayQueue(999, 1000)
+ private var clickPacketQueue = LimitedDecayQueue(500, 30000)
+
+ private val clickPacketsWindowAmount: Double
+ get() = limitClickWindowSize * limitClickRate
+
private val clickPacketsRemaining: Int
- get() = clickPacketsWindowAmount - clickPacketQueue.size
+ get() = clickPacketsWindowAmount.toInt() - clickPacketQueue.size
- init {
- onEnable {
- packetQueue = LimitedDecayQueue(limit, interval)
- }
+ private val canSendClickPackets: Boolean
+ get() = clickPacketQueue.size + 1 <= clickPacketsWindowAmount
+ init {
listen(Int.MAX_VALUE) {
if (it.packet::class.simpleName in ignorePackets) return@listen
-
- if (limitClickPackets && it.packet is ClickSlotC2SPacket) {
- if (!canSendClickPackets(1)) {
- it.cancel()
- return@listen
- } else {
- clickPacketQueue.add(System.currentTimeMillis())
- }
- }
-
- // this@PacketLimiter.info("Packet sent: ${it.packet::class.simpleName} (${packetQueue.size} / $limit) ${Instant.now()}")
if (packetQueue.add(it)) return@listen
it.cancel()
@@ -103,25 +91,30 @@ object PacketLimiter : Module(
}
listen {
- if (!limitClickPackets) return@listen
- if (!canSendClickPackets(1)) {
- it.cancel()
- return@listen
- }
+ if (limitClicks && !canSendClickPackets) it.cancel()
+ else if (clickPacketQueue.add(Unit)) return@listen
+
+ this@PacketLimiter.info("Slot click limit reached, dropping ${it.action} at ${it.slot} in ${it.screenHandler::class.simpleName} (${clickPacketQueue.size} / $limitClickRate)")
}
listen {
- if (!limitClickRender) {
- return@listen
- }
- val sh = mc.currentScreen as? GenericContainerScreen ?: return@listen
- val remainingText = "Clicks Remaining: $clickPacketsRemaining"
+ if (!limitClickRender) return@listen
+
+ val screen = mc.currentScreen as? GenericContainerScreen ?: return@listen
val mcScale = mc.window.scaleFactor
- val fontScale = mcScale * 1.5
- val fontHeight = FontRenderer.getHeight(fontScale)
- FontRenderer.drawString(remainingText, Vec2d(sh.x * mcScale, sh.y * mcScale - fontHeight), Color(0x9DFFFF), fontScale, false)
+ val fontHeight = FontRenderer.getHeight(mcScale * 1.5)
+ val position = Vec2d(screen.x * mcScale, screen.y * mcScale - fontHeight)
+
+ FontRenderer.drawString("Clicks Remaining: $clickPacketsRemaining", position, Color(0x9DFFFF))
+ }
+
+ onEnable {
+ packetQueue = LimitedDecayQueue(limit, interval)
}
}
- fun canSendClickPackets(packets: Int) = clickPacketQueue.size + packets <= clickPacketsWindowAmount
+ enum class Page {
+ General,
+ Clicks
+ }
}