Skip to content
Closed
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -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 <http://www.gnu.org/licenses/>.
*/

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
*/
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We have git blame in intellij 😄

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can remove the author templates. I took this idea from the baritone project.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

File was removed

@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);
}
}
Original file line number Diff line number Diff line change
@@ -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 <http://www.gnu.org/licenses/>.
*/

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 {
}
5 changes: 5 additions & 0 deletions common/src/main/kotlin/com/lambda/event/events/RenderEvent.kt
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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)
}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We already have container events and mouse events, this is not needed

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I need access to HandledScreen render methods which I did not find any existing mixins for. x y and background width don't exist on Screen.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This comment goes alongside the module's event review


val screenSize = Vec2d(mc.window.framebufferWidth, mc.window.framebufferHeight) / scale
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,23 +18,31 @@
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(
name = "PacketLimiter",
description = "Limits the amount of packets sent to the server",
defaultTags = setOf(ModuleTag.NETWORK)
) {
private var packetQueue = LimitedDecayQueue<PacketEvent.Send.Pre>(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<PacketEvent.Send.Pre>(999, 1000)
private var clickPacketQueue = LimitedDecayQueue<Long>(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")
Expand All @@ -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 {
Expand All @@ -58,11 +77,46 @@ object PacketLimiter : Module(
listen<PacketEvent.Send.Pre>(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())
}
}

// [email protected]("Packet sent: ${it.packet::class.simpleName} (${packetQueue.size} / $limit) ${Instant.now()}")
if (packetQueue.add(it)) return@listen

it.cancel()
[email protected]("Packet limit reached, dropping packet: ${it.packet::class.simpleName} (${packetQueue.size} / $limit)")
}

listen<PlayerEvent.SlotClick>{
if (!limitClickPackets) return@listen
if (!canSendClickPackets(1)) {
it.cancel()
return@listen
}
}

listen<RenderEvent.GUI.Container> {
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()
}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should be replaced by RenderEvent.GUI.Scaled and then use FontRenderer to build the string information that will then be dispatched to opengl

You should also get the current screen with the global context mc property of the SafeContext class, every extensions of that class has access to its properties and other extensions
This allows for a safe access of the game's content with the expectation of these properties to not be null

You can read more about that at https://kotlinlang.org/docs/extensions.html#

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can look into that

}

fun canSendClickPackets(packets: Int) = clickPacketQueue.size + packets < clickPacketsWindowAmount()
fun clickPacketsRemaining() = clickPacketsWindowAmount() - clickPacketQueue.size

private fun clickPacketsWindowAmount() = limitClickWindowSize * limitClickRate
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Simple methods returning values should be replaced by properties with getters

https://kotlinlang.org/docs/coding-conventions.html#properties

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok

}
4 changes: 4 additions & 0 deletions common/src/main/resources/lambda.accesswidener
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
8 changes: 5 additions & 3 deletions common/src/main/resources/lambda.mixins.common.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
"package": "com.lambda.mixin",
"compatibilityLevel": "JAVA_17",
"client": [
"CrashReportMixin",
"MinecraftClientMixin",
"baritone.MixinBaritonePlayerContext",
"baritone.MixinLookBehavior",
Expand Down Expand Up @@ -36,7 +37,9 @@
"render.DebugHudMixin",
"render.ElytraFeatureRendererMixin",
"render.GameRendererMixin",
"render.GenericContainerScreenMixin",
"render.GlStateManagerMixin",
"render.HandledScreenMixin",
"render.InGameHudMixin",
"render.InGameOverlayRendererMixin",
"render.LightmapTextureManagerMixin",
Expand All @@ -54,10 +57,9 @@
"world.BlockCollisionSpliteratorMixin",
"world.ClientChunkManagerMixin",
"world.ClientWorldMixin",
"world.StructureTemplateMixin",
"world.ExplosionMixin",
"world.WorldMixin",
"CrashReportMixin"
"world.StructureTemplateMixin",
"world.WorldMixin"
],
"injectors": {
"defaultRequire": 1
Expand Down