From e0bbfcdf8149cbdb1cae7e9fa16e6b6ddbb4e8c0 Mon Sep 17 00:00:00 2001 From: Edouard127 <46357922+Edouard127@users.noreply.github.com> Date: Thu, 21 Aug 2025 20:31:40 -0400 Subject: [PATCH 1/9] shapedsl https://youtu.be/efc7njKAfgo --- .../com/lambda/event/events/RenderEvent.kt | 20 +- .../kotlin/com/lambda/graphics/RenderMain.kt | 16 +- .../lambda/graphics/pipeline/VertexBuilder.kt | 3 - .../graphics/renderer/esp/ChunkedESP.kt | 48 +-- .../graphics/renderer/esp/DynamicAABB.kt | 12 +- .../graphics/renderer/esp/ESPRenderer.kt | 81 ----- .../lambda/graphics/renderer/esp/ShapeDsl.kt | 339 ++++++++++++++++++ .../com/lambda/graphics/renderer/esp/Treed.kt | 79 ++++ .../esp/builders/DynamicESPBuilders.kt | 110 ------ .../esp/builders/StaticESPBuilders.kt | 224 ------------ .../renderer/esp/global/DynamicESP.kt | 22 -- .../graphics/renderer/esp/global/StaticESP.kt | 22 -- .../renderer/esp/impl/DynamicESPRenderer.kt | 22 -- .../renderer/esp/impl/StaticESPRenderer.kt | 22 -- .../construction/result/Drawable.kt | 4 +- .../request/breaking/BreakManager.kt | 14 +- .../module/modules/client/TaskFlowModule.kt | 7 +- .../lambda/module/modules/debug/BlockTest.kt | 8 +- .../lambda/module/modules/debug/RenderTest.kt | 14 +- .../module/modules/movement/BackTrack.kt | 9 +- .../lambda/module/modules/movement/Blink.kt | 6 +- .../module/modules/player/PacketMine.kt | 12 +- .../lambda/module/modules/player/Scaffold.kt | 18 +- .../module/modules/player/WorldEater.kt | 8 +- .../lambda/module/modules/render/BlockESP.kt | 15 +- .../module/modules/render/StorageESP.kt | 57 ++- 26 files changed, 519 insertions(+), 673 deletions(-) delete mode 100644 src/main/kotlin/com/lambda/graphics/renderer/esp/ESPRenderer.kt create mode 100644 src/main/kotlin/com/lambda/graphics/renderer/esp/ShapeDsl.kt create mode 100644 src/main/kotlin/com/lambda/graphics/renderer/esp/Treed.kt delete mode 100644 src/main/kotlin/com/lambda/graphics/renderer/esp/builders/DynamicESPBuilders.kt delete mode 100644 src/main/kotlin/com/lambda/graphics/renderer/esp/builders/StaticESPBuilders.kt delete mode 100644 src/main/kotlin/com/lambda/graphics/renderer/esp/global/DynamicESP.kt delete mode 100644 src/main/kotlin/com/lambda/graphics/renderer/esp/global/StaticESP.kt delete mode 100644 src/main/kotlin/com/lambda/graphics/renderer/esp/impl/DynamicESPRenderer.kt delete mode 100644 src/main/kotlin/com/lambda/graphics/renderer/esp/impl/StaticESPRenderer.kt diff --git a/src/main/kotlin/com/lambda/event/events/RenderEvent.kt b/src/main/kotlin/com/lambda/event/events/RenderEvent.kt index de8dbc6e8..f1c790242 100644 --- a/src/main/kotlin/com/lambda/event/events/RenderEvent.kt +++ b/src/main/kotlin/com/lambda/event/events/RenderEvent.kt @@ -17,22 +17,22 @@ package com.lambda.event.events +import com.lambda.context.SafeContext import com.lambda.event.Event import com.lambda.event.callback.Cancellable 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.event.listener.SafeListener.Companion.listen +import com.lambda.graphics.renderer.esp.ShapeBuilder +import com.lambda.graphics.renderer.esp.Treed -sealed class RenderEvent { - class World : Event +fun Any.onStaticRender(block: SafeContext.(ShapeBuilder) -> Unit) = + listen { block(ShapeBuilder(Treed.staticFaceBuilder, Treed.staticEdgeBuilder)) } - class StaticESP : Event { - val renderer = StaticESP - } +fun Any.onDynamicRender(block: SafeContext.(ShapeBuilder) -> Unit) = + listen { block(ShapeBuilder(Treed.dynamicFaceBuilder, Treed.dynamicEdgeBuilder)) } - class DynamicESP : Event { - val renderer = DynamicESP - } +sealed class RenderEvent { + class World : Event class UpdateTarget : ICancellable by Cancellable() } diff --git a/src/main/kotlin/com/lambda/graphics/RenderMain.kt b/src/main/kotlin/com/lambda/graphics/RenderMain.kt index 1d3b5b20b..43c3cffb5 100644 --- a/src/main/kotlin/com/lambda/graphics/RenderMain.kt +++ b/src/main/kotlin/com/lambda/graphics/RenderMain.kt @@ -25,8 +25,7 @@ import com.lambda.event.listener.SafeListener.Companion.listen import com.lambda.graphics.gl.GlStateUtils.setupGL import com.lambda.graphics.gl.Matrices import com.lambda.graphics.gl.Matrices.resetMatrices -import com.lambda.graphics.renderer.esp.global.DynamicESP -import com.lambda.graphics.renderer.esp.global.StaticESP +import com.lambda.graphics.renderer.esp.Treed import com.lambda.util.math.Vec2d import com.mojang.blaze3d.opengl.GlStateManager import com.mojang.blaze3d.systems.RenderSystem @@ -56,21 +55,16 @@ object RenderMain { GlStateManager._glBindFramebuffer(GL_FRAMEBUFFER, prevFramebuffer) + Treed.clear() RenderEvent.World().post() - StaticESP.render() - DynamicESP.render() + Treed.upload() + Treed.render() } } init { listen { - StaticESP.clear() - RenderEvent.StaticESP().post() - StaticESP.upload() - - DynamicESP.clear() - RenderEvent.DynamicESP().post() - DynamicESP.upload() + //Treed.clear() } } } diff --git a/src/main/kotlin/com/lambda/graphics/pipeline/VertexBuilder.kt b/src/main/kotlin/com/lambda/graphics/pipeline/VertexBuilder.kt index 676e27fff..aa4716035 100644 --- a/src/main/kotlin/com/lambda/graphics/pipeline/VertexBuilder.kt +++ b/src/main/kotlin/com/lambda/graphics/pipeline/VertexBuilder.kt @@ -115,9 +115,6 @@ class VertexBuilder( fun collect(vararg indices: Int) = indices - fun use(block: VertexBuilder.() -> Unit) = - apply(block) - /** * Creates a new vertex with specified attributes * @param block Configuration lambda for defining vertex attributes diff --git a/src/main/kotlin/com/lambda/graphics/renderer/esp/ChunkedESP.kt b/src/main/kotlin/com/lambda/graphics/renderer/esp/ChunkedESP.kt index 7caa5f688..18f2df868 100644 --- a/src/main/kotlin/com/lambda/graphics/renderer/esp/ChunkedESP.kt +++ b/src/main/kotlin/com/lambda/graphics/renderer/esp/ChunkedESP.kt @@ -17,14 +17,14 @@ package com.lambda.graphics.renderer.esp -import com.lambda.event.events.RenderEvent import com.lambda.event.events.TickEvent import com.lambda.event.events.WorldEvent +import com.lambda.event.events.onStaticRender import com.lambda.event.listener.SafeListener.Companion.listen import com.lambda.event.listener.SafeListener.Companion.listenConcurrently -import com.lambda.graphics.renderer.esp.impl.StaticESPRenderer import com.lambda.module.modules.client.StyleEditor -import com.lambda.threading.awaitMainThread +import com.lambda.util.world.FastVector +import com.lambda.util.world.fastVectorOf import net.minecraft.util.math.ChunkPos import net.minecraft.world.World import net.minecraft.world.chunk.WorldChunk @@ -33,7 +33,7 @@ import java.util.concurrent.ConcurrentLinkedDeque class ChunkedESP private constructor( owner: Any, - private val update: StaticESPRenderer.(World, Int, Int, Int) -> Unit + private val update: ShapeBuilder.(World, FastVector) -> Unit ) { private val rendererMap = ConcurrentHashMap() private val WorldChunk.renderer @@ -64,12 +64,12 @@ class ChunkedESP private constructor( rendererMap.remove(event.chunk.pos.toLong())?.notifyChunks() } - owner.listenConcurrently { + owner.onStaticRender { builder -> if (++ticks % StyleEditor.updateFrequency == 0) { val polls = minOf(StyleEditor.rebuildsPerTick, rebuildQueue.size) repeat(polls) { - rebuildQueue.poll()?.rebuild() + rebuildQueue.poll()?.rebuild(builder) } ticks = 0 } @@ -84,28 +84,16 @@ class ChunkedESP private constructor( uploadQueue.poll()?.invoke() } } - - owner.listen { - rendererMap.values.forEach { - it.renderer?.render() - } - } } companion object { fun Any.newChunkedESP( - update: StaticESPRenderer.(World, Int, Int, Int) -> Unit - ) = ChunkedESP(this, update) + update: ShapeBuilder.(World, FastVector) -> Unit + ) = ChunkedESP(this@newChunkedESP, update) } private class EspChunk(val chunk: WorldChunk, val owner: ChunkedESP) { - var renderer: StaticESPRenderer? = null - - private val chunkOffsets = listOf(1 to 0, 0 to 1, -1 to 0, 0 to -1) - - val neighbors = chunkOffsets.map { - ChunkPos(chunk.pos.x + it.first, chunk.pos.z + it.second) - }.toTypedArray() + val neighbors = listOf(1 to 0, 0 to 1, -1 to 0, 0 to -1).map { ChunkPos(chunk.pos.x + it.first, chunk.pos.z + it.second) } fun notifyChunks() { neighbors.forEach { @@ -117,24 +105,14 @@ class ChunkedESP private constructor( } } - suspend fun rebuild() { - val newRenderer = awaitMainThread { StaticESPRenderer() } - - iterateChunk { x, y, z -> - owner.update(newRenderer, chunk.world, x, y, z) - } - - owner.uploadQueue.add { - newRenderer.upload() - renderer = newRenderer - } - } + fun rebuild(builder: ShapeBuilder) = + iterateChunk { owner.update(builder, chunk.world, it) } - private fun iterateChunk(block: (Int, Int, Int) -> Unit) = chunk.apply { + inline fun iterateChunk(crossinline block: (FastVector) -> Unit) = chunk.apply { for (x in pos.startX..pos.endX) { for (z in pos.startZ..pos.endZ) { for (y in bottomY..height) { - block(x, y, z) + block(fastVectorOf(x, y, z)) } } } diff --git a/src/main/kotlin/com/lambda/graphics/renderer/esp/DynamicAABB.kt b/src/main/kotlin/com/lambda/graphics/renderer/esp/DynamicAABB.kt index 1b58e7cbf..159b32268 100644 --- a/src/main/kotlin/com/lambda/graphics/renderer/esp/DynamicAABB.kt +++ b/src/main/kotlin/com/lambda/graphics/renderer/esp/DynamicAABB.kt @@ -26,6 +26,8 @@ class DynamicAABB { private var prev: Box? = null private var curr: Box? = null + val pair get() = prev?.let { prev -> curr?.let { curr -> prev to curr } } + fun update(box: Box): DynamicAABB { prev = curr ?: box curr = box @@ -38,16 +40,6 @@ class DynamicAABB { curr = null } - fun getBoxPair(): Pair? { - prev?.let { previous -> - curr?.let { current -> - return previous to current - } - } - - return null - } - companion object { val Entity.dynamicBox get() = DynamicAABB().apply { diff --git a/src/main/kotlin/com/lambda/graphics/renderer/esp/ESPRenderer.kt b/src/main/kotlin/com/lambda/graphics/renderer/esp/ESPRenderer.kt deleted file mode 100644 index bf6676636..000000000 --- a/src/main/kotlin/com/lambda/graphics/renderer/esp/ESPRenderer.kt +++ /dev/null @@ -1,81 +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.graphics.renderer.esp - -import com.lambda.Lambda -import com.lambda.graphics.buffer.vertex.attributes.VertexAttrib -import com.lambda.graphics.buffer.vertex.attributes.VertexMode -import com.lambda.graphics.gl.GlStateUtils -import com.lambda.graphics.pipeline.VertexBuilder -import com.lambda.graphics.pipeline.VertexPipeline -import com.lambda.graphics.shader.Shader -import com.lambda.graphics.shader.Shader.Companion.shader -import com.lambda.module.modules.client.StyleEditor -import com.lambda.util.extension.partialTicks - -open class ESPRenderer(tickedMode: Boolean) { - val shader: Shader - - val faces: VertexPipeline - var faceBuilder: VertexBuilder - - val outlines: VertexPipeline - var outlineBuilder: VertexBuilder - - init { - val mode = if (tickedMode) dynamicMode else staticMode - shader = mode.first - - faces = VertexPipeline(VertexMode.TRIANGLES, mode.second) - faceBuilder = faces.build() - - outlines = VertexPipeline(VertexMode.LINES, mode.second) - outlineBuilder = outlines.build() - } - - fun upload() { - faces.upload(faceBuilder) - outlines.upload(outlineBuilder) - } - - fun render() { - shader.use() - shader["u_TickDelta"] = Lambda.mc.partialTicks - shader["u_CameraPosition"] = Lambda.mc.gameRenderer.camera.pos - - GlStateUtils.withFaceCulling(faces::render) - GlStateUtils.withLineWidth(StyleEditor.outlineWidth, outlines::render) - } - - fun clear() { - faces.clear() - outlines.clear() - faceBuilder = faces.build() - outlineBuilder = outlines.build() - } - - companion object { - private val staticMode = shader( - "renderer/box_static" - ) to VertexAttrib.Group.STATIC_RENDERER - - private val dynamicMode = shader( - "renderer/box_dynamic" - ) to VertexAttrib.Group.DYNAMIC_RENDERER - } -} diff --git a/src/main/kotlin/com/lambda/graphics/renderer/esp/ShapeDsl.kt b/src/main/kotlin/com/lambda/graphics/renderer/esp/ShapeDsl.kt new file mode 100644 index 000000000..35ba1dd02 --- /dev/null +++ b/src/main/kotlin/com/lambda/graphics/renderer/esp/ShapeDsl.kt @@ -0,0 +1,339 @@ +/* + * 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.graphics.renderer.esp + +import com.lambda.context.SafeContext +import com.lambda.graphics.pipeline.VertexBuilder +import com.lambda.graphics.renderer.esp.DirectionMask.hasDirection +import com.lambda.util.BlockUtils.blockState +import com.lambda.util.extension.max +import com.lambda.util.extension.min +import com.lambda.util.extension.outlineShape +import net.minecraft.block.BlockState +import net.minecraft.block.entity.BlockEntity +import net.minecraft.entity.Entity +import net.minecraft.util.math.BlockPos +import net.minecraft.util.math.Box +import net.minecraft.util.shape.VoxelShape +import java.awt.Color + +@DslMarker +annotation class ShapeDsl + +class ShapeBuilder( + val faces: VertexBuilder, + val edges: VertexBuilder, +) { + @ShapeDsl + fun filled( + box : DynamicAABB, + color : Color, + sides : Int = DirectionMask.ALL, + ) = faces.apply { + val boxes = box.pair ?: return@apply + + val pos11 = boxes.first.min + val pos12 = boxes.first.max + val pos21 = boxes.second.min + val pos22 = boxes.second.max + + val blb by lazy { vertex { vec3(pos11.x, pos11.y, pos11.z).vec3(pos21.x, pos21.y, pos21.z).color(color) } } + val blf by lazy { vertex { vec3(pos11.x, pos11.y, pos12.z).vec3(pos21.x, pos21.y, pos22.z).color(color) } } + val brb by lazy { vertex { vec3(pos12.x, pos11.y, pos11.z).vec3(pos22.x, pos21.y, pos21.z).color(color) } } + val brf by lazy { vertex { vec3(pos12.x, pos11.y, pos12.z).vec3(pos22.x, pos21.y, pos22.z).color(color) } } + val tlb by lazy { vertex { vec3(pos11.x, pos12.y, pos11.z).vec3(pos21.x, pos22.y, pos21.z).color(color) } } + val tlf by lazy { vertex { vec3(pos11.x, pos12.y, pos12.z).vec3(pos21.x, pos22.y, pos22.z).color(color) } } + val trb by lazy { vertex { vec3(pos12.x, pos12.y, pos11.z).vec3(pos22.x, pos22.y, pos21.z).color(color) } } + val trf by lazy { vertex { vec3(pos12.x, pos12.y, pos12.z).vec3(pos22.x, pos22.y, pos22.z).color(color) } } + + if (sides.hasDirection(DirectionMask.EAST)) buildQuad(brb, trb, trf, brf) + if (sides.hasDirection(DirectionMask.WEST)) buildQuad(blb, blf, tlf, tlb) + if (sides.hasDirection(DirectionMask.UP)) buildQuad(tlb, tlf, trf, trb) + if (sides.hasDirection(DirectionMask.DOWN)) buildQuad(blb, brb, brf, blf) + if (sides.hasDirection(DirectionMask.SOUTH)) buildQuad(blf, brf, trf, tlf) + if (sides.hasDirection(DirectionMask.NORTH)) buildQuad(blb, tlb, trb, brb) + } + + @ShapeDsl + fun filled( + box : Box, + bottomColor : Color, + topColor : Color = bottomColor, + sides : Int = DirectionMask.ALL + ) = faces.apply { + val pos1 = box.min + val pos2 = box.max + + val blb by lazy { vertex { vec3(pos1.x, pos1.y, pos1.z).color(bottomColor) } } + val blf by lazy { vertex { vec3(pos1.x, pos1.y, pos2.z).color(bottomColor) } } + val brb by lazy { vertex { vec3(pos2.x, pos1.y, pos1.z).color(bottomColor) } } + val brf by lazy { vertex { vec3(pos2.x, pos1.y, pos2.z).color(bottomColor) } } + + val tlb by lazy { vertex { vec3(pos1.x, pos2.y, pos1.z).color(topColor) } } + val tlf by lazy { vertex { vec3(pos1.x, pos2.y, pos2.z).color(topColor) } } + val trb by lazy { vertex { vec3(pos2.x, pos2.y, pos1.z).color(topColor) } } + val trf by lazy { vertex { vec3(pos2.x, pos2.y, pos2.z).color(topColor) } } + + if (sides.hasDirection(DirectionMask.EAST)) buildQuad(brb, trb, trf, brf) + if (sides.hasDirection(DirectionMask.WEST)) buildQuad(blb, blf, tlf, tlb) + if (sides.hasDirection(DirectionMask.UP)) buildQuad(tlb, tlf, trf, trb) + if (sides.hasDirection(DirectionMask.DOWN)) buildQuad(blb, brb, brf, blf) + if (sides.hasDirection(DirectionMask.SOUTH)) buildQuad(blf, brf, trf, tlf) + if (sides.hasDirection(DirectionMask.NORTH)) buildQuad(blb, tlb, trb, brb) + } + + @ShapeDsl + fun SafeContext.filled( + pos : BlockPos, + state : BlockState, + color : Color, + sides : Int = DirectionMask.ALL, + ) = faces.apply { + val shape = state.getOutlineShape(world, pos) + filled(shape, color, sides) + } + + @ShapeDsl + fun SafeContext.filled( + pos : BlockPos, + color : Color, + sides : Int = DirectionMask.ALL, + ) = faces.apply { + val shape = blockState(pos).getOutlineShape(world, pos) + filled(shape, color, sides) + } + + @ShapeDsl + fun SafeContext.filled( + pos : BlockPos, + entity : BlockEntity, + color : Color, + sides : Int = DirectionMask.ALL, + ) { + val shape = outlineShape(entity.cachedState, pos) + filled(shape, color, sides) + } + + @ShapeDsl + fun filled( + shape: VoxelShape, + color: Color, + sides: Int = DirectionMask.ALL, + ) { + shape.boundingBoxes + .forEach { filled(it, color, color, sides) } + } + + @ShapeDsl + fun filled( + box : Box, + color : Color, + sides : Int = DirectionMask.ALL, + ) = filled(box, color, color, sides) + + @ShapeDsl + fun outline( + box : DynamicAABB, + color : Color, + sides : Int = DirectionMask.ALL, + mode : DirectionMask.OutlineMode = DirectionMask.OutlineMode.OR, + ) = edges.apply { + val boxes = box.pair ?: return@apply + + val pos11 = boxes.first.min + val pos12 = boxes.first.max + val pos21 = boxes.second.min + val pos22 = boxes.second.max + + val blb by lazy { vertex { vec3(pos11.x, pos11.y, pos11.z).vec3(pos21.x, pos21.y, pos21.z).color(color) } } + val blf by lazy { vertex { vec3(pos11.x, pos11.y, pos12.z).vec3(pos21.x, pos21.y, pos22.z).color(color) } } + val brb by lazy { vertex { vec3(pos12.x, pos11.y, pos11.z).vec3(pos22.x, pos21.y, pos21.z).color(color) } } + val brf by lazy { vertex { vec3(pos12.x, pos11.y, pos12.z).vec3(pos22.x, pos21.y, pos22.z).color(color) } } + val tlb by lazy { vertex { vec3(pos11.x, pos12.y, pos11.z).vec3(pos21.x, pos22.y, pos21.z).color(color) } } + val tlf by lazy { vertex { vec3(pos11.x, pos12.y, pos12.z).vec3(pos21.x, pos22.y, pos22.z).color(color) } } + val trb by lazy { vertex { vec3(pos12.x, pos12.y, pos11.z).vec3(pos22.x, pos22.y, pos21.z).color(color) } } + val trf by lazy { vertex { vec3(pos12.x, pos12.y, pos12.z).vec3(pos22.x, pos22.y, pos22.z).color(color) } } + + val hasEast = sides.hasDirection(DirectionMask.EAST) + val hasWest = sides.hasDirection(DirectionMask.WEST) + val hasUp = sides.hasDirection(DirectionMask.UP) + val hasDown = sides.hasDirection(DirectionMask.DOWN) + val hasSouth = sides.hasDirection(DirectionMask.SOUTH) + val hasNorth = sides.hasDirection(DirectionMask.NORTH) + + if (mode.check(hasUp, hasNorth)) buildLine(tlb, trb) + if (mode.check(hasUp, hasSouth)) buildLine(tlf, trf) + if (mode.check(hasUp, hasWest)) buildLine(tlb, tlf) + if (mode.check(hasUp, hasEast)) buildLine(trf, trb) + + if (mode.check(hasDown, hasNorth)) buildLine(blb, brb) + if (mode.check(hasDown, hasSouth)) buildLine(blf, brf) + if (mode.check(hasDown, hasWest)) buildLine(blb, blf) + if (mode.check(hasDown, hasEast)) buildLine(brb, brf) + + if (mode.check(hasWest, hasNorth)) buildLine(tlb, blb) + if (mode.check(hasNorth, hasEast)) buildLine(trb, brb) + if (mode.check(hasEast, hasSouth)) buildLine(trf, brf) + if (mode.check(hasSouth, hasWest)) buildLine(tlf, blf) + } + + @ShapeDsl + fun outline( + box : Box, + bottomColor : Color, + topColor : Color = bottomColor, + sides : Int = DirectionMask.ALL, + mode : DirectionMask.OutlineMode = DirectionMask.OutlineMode.OR, + ) = edges.apply { + val pos1 = box.min + val pos2 = box.max + + val blb by lazy { vertex { vec3(pos1.x, pos1.y, pos1.z).color(bottomColor) } } + val blf by lazy { vertex { vec3(pos1.x, pos1.y, pos2.z).color(bottomColor) } } + val brb by lazy { vertex { vec3(pos2.x, pos1.y, pos1.z).color(bottomColor) } } + val brf by lazy { vertex { vec3(pos2.x, pos1.y, pos2.z).color(bottomColor) } } + val tlb by lazy { vertex { vec3(pos1.x, pos2.y, pos1.z).color(topColor) } } + val tlf by lazy { vertex { vec3(pos1.x, pos2.y, pos2.z).color(topColor) } } + val trb by lazy { vertex { vec3(pos2.x, pos2.y, pos1.z).color(topColor) } } + val trf by lazy { vertex { vec3(pos2.x, pos2.y, pos2.z).color(topColor) } } + + val hasEast = sides.hasDirection(DirectionMask.EAST) + val hasWest = sides.hasDirection(DirectionMask.WEST) + val hasUp = sides.hasDirection(DirectionMask.UP) + val hasDown = sides.hasDirection(DirectionMask.DOWN) + val hasSouth = sides.hasDirection(DirectionMask.SOUTH) + val hasNorth = sides.hasDirection(DirectionMask.NORTH) + + if (mode.check(hasUp, hasNorth)) buildLine(tlb, trb) + if (mode.check(hasUp, hasSouth)) buildLine(tlf, trf) + if (mode.check(hasUp, hasWest)) buildLine(tlb, tlf) + if (mode.check(hasUp, hasEast)) buildLine(trf, trb) + + if (mode.check(hasDown, hasNorth)) buildLine(blb, brb) + if (mode.check(hasDown, hasSouth)) buildLine(blf, brf) + if (mode.check(hasDown, hasWest)) buildLine(blb, blf) + if (mode.check(hasDown, hasEast)) buildLine(brb, brf) + + if (mode.check(hasWest, hasNorth)) buildLine(tlb, blb) + if (mode.check(hasNorth, hasEast)) buildLine(trb, brb) + if (mode.check(hasEast, hasSouth)) buildLine(trf, brf) + if (mode.check(hasSouth, hasWest)) buildLine(tlf, blf) + } + + @ShapeDsl + fun SafeContext.outline( + pos : BlockPos, + state : BlockState, + color : Color, + sides : Int = DirectionMask.ALL, + mode : DirectionMask.OutlineMode = DirectionMask.OutlineMode.OR, + ) { + val shape = state.getOutlineShape(world, pos) + outline(shape, color, sides, mode) + } + + @ShapeDsl + fun SafeContext.outline( + pos : BlockPos, + color : Color, + sides : Int = DirectionMask.ALL, + mode : DirectionMask.OutlineMode = DirectionMask.OutlineMode.OR, + ) { + val shape = blockState(pos).getOutlineShape(world, pos) + outline(shape, color, sides, mode) + } + + @ShapeDsl + fun SafeContext.outline( + pos : BlockPos, + entity : BlockEntity, + color : Color, + sides : Int = DirectionMask.ALL, + mode : DirectionMask.OutlineMode = DirectionMask.OutlineMode.OR, + ) { + val shape = outlineShape(entity.cachedState, pos) + outline(shape, color, sides, mode) + } + + @ShapeDsl + fun outline( + shape : VoxelShape, + color : Color, + sides : Int = DirectionMask.ALL, + mode : DirectionMask.OutlineMode = DirectionMask.OutlineMode.OR, + ) { + shape.boundingBoxes + .forEach { outline(it, color, sides, mode) } + } + + @ShapeDsl + fun outline( + box : Box, + color : Color, + sides : Int = DirectionMask.ALL, + mode : DirectionMask.OutlineMode = DirectionMask.OutlineMode.OR, + ) { + outline(box, color, color, sides, mode) + } + + @ShapeDsl + fun box( + box : DynamicAABB, + filled : Color, + outline : Color, + sides : Int = DirectionMask.ALL, + mode : DirectionMask.OutlineMode = DirectionMask.OutlineMode.OR, + ) { + filled(box, filled, sides) + outline(box, outline, sides, mode) + } + + @ShapeDsl + fun box( + box : Box, + filled : Color, + outline : Color, + sides : Int = DirectionMask.ALL, + mode : DirectionMask.OutlineMode = DirectionMask.OutlineMode.OR, + ) { + filled(box, filled, sides) + outline(box, outline, sides, mode) + } + + @ShapeDsl + fun SafeContext.box( + entity : BlockEntity, + color : Color, + sides : Int = DirectionMask.ALL, + mode : DirectionMask.OutlineMode = DirectionMask.OutlineMode.OR, + ) { + filled(entity.pos, entity, color, sides) + outline(entity.pos, entity, color, sides, mode) + } + + @ShapeDsl + fun SafeContext.box( + entity : Entity, + color : Color, + sides : Int = DirectionMask.ALL, + mode : DirectionMask.OutlineMode = DirectionMask.OutlineMode.OR, + ) { + filled(entity.boundingBox, color, sides) + outline(entity.boundingBox, color, sides, mode) + } +} diff --git a/src/main/kotlin/com/lambda/graphics/renderer/esp/Treed.kt b/src/main/kotlin/com/lambda/graphics/renderer/esp/Treed.kt new file mode 100644 index 000000000..a560c9e96 --- /dev/null +++ b/src/main/kotlin/com/lambda/graphics/renderer/esp/Treed.kt @@ -0,0 +1,79 @@ +/* + * 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.graphics.renderer.esp + +import com.lambda.Lambda +import com.lambda.graphics.buffer.vertex.attributes.VertexAttrib +import com.lambda.graphics.buffer.vertex.attributes.VertexMode +import com.lambda.graphics.gl.GlStateUtils +import com.lambda.graphics.pipeline.VertexBuilder +import com.lambda.graphics.pipeline.VertexPipeline +import com.lambda.graphics.shader.Shader.Companion.shader +import com.lambda.module.modules.client.StyleEditor +import com.lambda.util.extension.partialTicks + +object Treed { + val staticShader = shader("renderer/box_static") + val dynamicShader = shader("renderer/box_dynamic") + + val staticFaces = VertexPipeline(VertexMode.TRIANGLES, VertexAttrib.Group.STATIC_RENDERER) + val staticEdges = VertexPipeline(VertexMode.LINES, VertexAttrib.Group.STATIC_RENDERER) + val dynamicFaces = VertexPipeline(VertexMode.TRIANGLES, VertexAttrib.Group.DYNAMIC_RENDERER) + val dynamicEdges = VertexPipeline(VertexMode.LINES, VertexAttrib.Group.DYNAMIC_RENDERER) + + // Vertex builders for shape building + var staticFaceBuilder = VertexBuilder(); private set + var dynamicFaceBuilder = VertexBuilder(); private set + var staticEdgeBuilder = VertexBuilder(); private set + var dynamicEdgeBuilder = VertexBuilder(); private set + + fun upload() { + staticFaces.upload(staticFaceBuilder) + staticEdges.upload(staticEdgeBuilder) + dynamicFaces.upload(dynamicFaceBuilder) + dynamicEdges.upload(dynamicEdgeBuilder) + } + + fun render() { + staticShader.use() + staticShader["u_TickDelta"] = Lambda.mc.partialTicks + staticShader["u_CameraPosition"] = Lambda.mc.gameRenderer.camera.pos + + GlStateUtils.withFaceCulling(staticFaces::render) + GlStateUtils.withLineWidth(StyleEditor.outlineWidth, staticEdges::render) + + dynamicShader.use() + dynamicShader["u_TickDelta"] = Lambda.mc.partialTicks + dynamicShader["u_CameraPosition"] = Lambda.mc.gameRenderer.camera.pos + + GlStateUtils.withFaceCulling(dynamicFaces::render) + GlStateUtils.withLineWidth(StyleEditor.outlineWidth, dynamicEdges::render) + } + + fun clear() { + staticFaces.clear() + staticEdges.clear() + dynamicFaces.clear() + dynamicEdges.clear() + + staticFaceBuilder = VertexBuilder() + staticEdgeBuilder = VertexBuilder() + dynamicFaceBuilder = VertexBuilder() + dynamicEdgeBuilder = VertexBuilder() + } +} diff --git a/src/main/kotlin/com/lambda/graphics/renderer/esp/builders/DynamicESPBuilders.kt b/src/main/kotlin/com/lambda/graphics/renderer/esp/builders/DynamicESPBuilders.kt deleted file mode 100644 index cb0653245..000000000 --- a/src/main/kotlin/com/lambda/graphics/renderer/esp/builders/DynamicESPBuilders.kt +++ /dev/null @@ -1,110 +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.graphics.renderer.esp.builders - -import com.lambda.graphics.renderer.esp.DirectionMask -import com.lambda.graphics.renderer.esp.DirectionMask.hasDirection -import com.lambda.graphics.renderer.esp.DynamicAABB -import com.lambda.graphics.renderer.esp.impl.DynamicESPRenderer -import com.lambda.util.extension.max -import com.lambda.util.extension.min -import java.awt.Color - -fun DynamicESPRenderer.ofBox( - box: DynamicAABB, - filledColor: Color, - outlineColor: Color, - sides: Int = DirectionMask.ALL, - outlineMode: DirectionMask.OutlineMode = DirectionMask.OutlineMode.OR -) { - buildFilled(box, filledColor, sides) - buildOutline(box, outlineColor, sides, outlineMode) -} - -fun DynamicESPRenderer.buildFilled( - box: DynamicAABB, - color: Color, - sides: Int = DirectionMask.ALL -) = faceBuilder.use { - val boxes = box.getBoxPair() ?: return@use - val pos11 = boxes.first.min - val pos12 = boxes.first.max - val pos21 = boxes.second.min - val pos22 = boxes.second.max - - val blb by lazy { vertex { vec3(pos11.x, pos11.y, pos11.z).vec3(pos21.x, pos21.y, pos21.z).color(color) } } - val blf by lazy { vertex { vec3(pos11.x, pos11.y, pos12.z).vec3(pos21.x, pos21.y, pos22.z).color(color) } } - val brb by lazy { vertex { vec3(pos12.x, pos11.y, pos11.z).vec3(pos22.x, pos21.y, pos21.z).color(color) } } - val brf by lazy { vertex { vec3(pos12.x, pos11.y, pos12.z).vec3(pos22.x, pos21.y, pos22.z).color(color) } } - val tlb by lazy { vertex { vec3(pos11.x, pos12.y, pos11.z).vec3(pos21.x, pos22.y, pos21.z).color(color) } } - val tlf by lazy { vertex { vec3(pos11.x, pos12.y, pos12.z).vec3(pos21.x, pos22.y, pos22.z).color(color) } } - val trb by lazy { vertex { vec3(pos12.x, pos12.y, pos11.z).vec3(pos22.x, pos22.y, pos21.z).color(color) } } - val trf by lazy { vertex { vec3(pos12.x, pos12.y, pos12.z).vec3(pos22.x, pos22.y, pos22.z).color(color) } } - - if (sides.hasDirection(DirectionMask.EAST)) buildQuad(brb, trb, trf, brf) - if (sides.hasDirection(DirectionMask.WEST)) buildQuad(blb, blf, tlf, tlb) - if (sides.hasDirection(DirectionMask.UP)) buildQuad(tlb, tlf, trf, trb) - if (sides.hasDirection(DirectionMask.DOWN)) buildQuad(blb, brb, brf, blf) - if (sides.hasDirection(DirectionMask.SOUTH)) buildQuad(blf, brf, trf, tlf) - if (sides.hasDirection(DirectionMask.NORTH)) buildQuad(blb, tlb, trb, brb) -} - -fun DynamicESPRenderer.buildOutline( - box: DynamicAABB, - color: Color, - sides: Int = DirectionMask.ALL, - outlineMode: DirectionMask.OutlineMode = DirectionMask.OutlineMode.OR -) = outlineBuilder.use { - val boxes = box.getBoxPair() ?: return@use - - val pos11 = boxes.first.min - val pos12 = boxes.first.max - val pos21 = boxes.second.min - val pos22 = boxes.second.max - - val blb by lazy { vertex { vec3(pos11.x, pos11.y, pos11.z).vec3(pos21.x, pos21.y, pos21.z).color(color) } } - val blf by lazy { vertex { vec3(pos11.x, pos11.y, pos12.z).vec3(pos21.x, pos21.y, pos22.z).color(color) } } - val brb by lazy { vertex { vec3(pos12.x, pos11.y, pos11.z).vec3(pos22.x, pos21.y, pos21.z).color(color) } } - val brf by lazy { vertex { vec3(pos12.x, pos11.y, pos12.z).vec3(pos22.x, pos21.y, pos22.z).color(color) } } - val tlb by lazy { vertex { vec3(pos11.x, pos12.y, pos11.z).vec3(pos21.x, pos22.y, pos21.z).color(color) } } - val tlf by lazy { vertex { vec3(pos11.x, pos12.y, pos12.z).vec3(pos21.x, pos22.y, pos22.z).color(color) } } - val trb by lazy { vertex { vec3(pos12.x, pos12.y, pos11.z).vec3(pos22.x, pos22.y, pos21.z).color(color) } } - val trf by lazy { vertex { vec3(pos12.x, pos12.y, pos12.z).vec3(pos22.x, pos22.y, pos22.z).color(color) } } - - val hasEast = sides.hasDirection(DirectionMask.EAST) - val hasWest = sides.hasDirection(DirectionMask.WEST) - val hasUp = sides.hasDirection(DirectionMask.UP) - val hasDown = sides.hasDirection(DirectionMask.DOWN) - val hasSouth = sides.hasDirection(DirectionMask.SOUTH) - val hasNorth = sides.hasDirection(DirectionMask.NORTH) - - if (outlineMode.check(hasUp, hasNorth)) buildLine(tlb, trb) - if (outlineMode.check(hasUp, hasSouth)) buildLine(tlf, trf) - if (outlineMode.check(hasUp, hasWest)) buildLine(tlb, tlf) - if (outlineMode.check(hasUp, hasEast)) buildLine(trf, trb) - - if (outlineMode.check(hasDown, hasNorth)) buildLine(blb, brb) - if (outlineMode.check(hasDown, hasSouth)) buildLine(blf, brf) - if (outlineMode.check(hasDown, hasWest)) buildLine(blb, blf) - if (outlineMode.check(hasDown, hasEast)) buildLine(brb, brf) - - if (outlineMode.check(hasWest, hasNorth)) buildLine(tlb, blb) - if (outlineMode.check(hasNorth, hasEast)) buildLine(trb, brb) - if (outlineMode.check(hasEast, hasSouth)) buildLine(trf, brf) - if (outlineMode.check(hasSouth, hasWest)) buildLine(tlf, blf) -} diff --git a/src/main/kotlin/com/lambda/graphics/renderer/esp/builders/StaticESPBuilders.kt b/src/main/kotlin/com/lambda/graphics/renderer/esp/builders/StaticESPBuilders.kt deleted file mode 100644 index d4a733726..000000000 --- a/src/main/kotlin/com/lambda/graphics/renderer/esp/builders/StaticESPBuilders.kt +++ /dev/null @@ -1,224 +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.graphics.renderer.esp.builders - -import com.lambda.graphics.renderer.esp.DirectionMask -import com.lambda.graphics.renderer.esp.DirectionMask.hasDirection -import com.lambda.graphics.renderer.esp.impl.StaticESPRenderer -import com.lambda.threading.runSafe -import com.lambda.util.BlockUtils.blockState -import com.lambda.util.extension.max -import com.lambda.util.extension.min -import net.minecraft.block.BlockState -import net.minecraft.util.math.BlockPos -import net.minecraft.util.math.Box -import net.minecraft.util.shape.VoxelShape -import java.awt.Color - -fun StaticESPRenderer.ofShape( - pos: BlockPos, - filledColor: Color, - outlineColor: Color, - sides: Int = DirectionMask.ALL, - outlineMode: DirectionMask.OutlineMode = DirectionMask.OutlineMode.OR -) = runSafe { - val shape = blockState(pos).getOutlineShape(world, pos) - ofShape(pos, shape, filledColor, outlineColor, sides, outlineMode) -} - -fun StaticESPRenderer.ofShape( - pos: BlockPos, - state: BlockState, - filledColor: Color, - outlineColor: Color, - sides: Int = DirectionMask.ALL, - outlineMode: DirectionMask.OutlineMode = DirectionMask.OutlineMode.OR -) = runSafe { - val shape = state.getOutlineShape(world, pos) - ofShape(pos, shape, filledColor, outlineColor, sides, outlineMode) -} - -fun StaticESPRenderer.ofShape( - pos: BlockPos, - shape: VoxelShape, - filledColor: Color, - outlineColor: Color, - sides: Int = DirectionMask.ALL, - outlineMode: DirectionMask.OutlineMode = DirectionMask.OutlineMode.OR -) { - shape.boundingBoxes.forEach { - ofBox(it.offset(pos), filledColor, outlineColor, sides, outlineMode) - } -} - -fun StaticESPRenderer.ofBox( - box: Box, - filledColor: Color, - outlineColor: Color, - sides: Int = DirectionMask.ALL, - outlineMode: DirectionMask.OutlineMode = DirectionMask.OutlineMode.OR -) { - buildFilled(box, filledColor, sides) - buildOutline(box, outlineColor, sides, outlineMode) -} - -fun StaticESPRenderer.buildFilledShape( - pos: BlockPos, - state: BlockState, - color: Color, - sides: Int = DirectionMask.ALL, -) = runSafe { - val shape = state.getOutlineShape(world, pos) - buildFilledShape(shape, color, sides) -} - -fun StaticESPRenderer.buildFilledShape( - pos: BlockPos, - color: Color, - sides: Int = DirectionMask.ALL, -) = runSafe { - val shape = blockState(pos).getOutlineShape(world, pos) - buildFilledShape(shape, color, sides) -} - -fun StaticESPRenderer.buildFilledShape( - shape: VoxelShape, - color: Color, - sides: Int = DirectionMask.ALL, -) { - shape.boundingBoxes - .forEach { buildFilled(it, color, sides) } -} - - -fun StaticESPRenderer.buildFilled( - box: Box, - color: Color, - sides: Int = DirectionMask.ALL -) { - buildFilled(box, color, color, sides) -} - -fun StaticESPRenderer.buildOutlineShape( - pos: BlockPos, - state: BlockState, - color: Color, - sides: Int = DirectionMask.ALL, - outlineMode: DirectionMask.OutlineMode = DirectionMask.OutlineMode.OR -) = runSafe { - val shape = state.getOutlineShape(world, pos) - buildOutlineShape(shape, color, sides, outlineMode) -} - -fun StaticESPRenderer.buildOutlineShape( - pos: BlockPos, - color: Color, - sides: Int = DirectionMask.ALL, - outlineMode: DirectionMask.OutlineMode = DirectionMask.OutlineMode.OR -) = runSafe { - val shape = blockState(pos).getOutlineShape(world, pos) - buildOutlineShape(shape, color, sides, outlineMode) -} - -fun StaticESPRenderer.buildOutlineShape( - shape: VoxelShape, - color: Color, - sides: Int = DirectionMask.ALL, - outlineMode: DirectionMask.OutlineMode = DirectionMask.OutlineMode.OR -) { - shape.boundingBoxes - .forEach { buildOutline(it, color, sides, outlineMode) } -} - -fun StaticESPRenderer.buildOutline( - box: Box, - color: Color, - sides: Int = DirectionMask.ALL, - outlineMode: DirectionMask.OutlineMode = DirectionMask.OutlineMode.OR -) { - buildOutline(box, color, color, sides, outlineMode) -} - -fun StaticESPRenderer.buildFilled( - box: Box, - colorBottom: Color, - colorTop: Color = colorBottom, - sides: Int = DirectionMask.ALL -) = faceBuilder.use { - val pos1 = box.min - val pos2 = box.max - - val blb by lazy { vertex { vec3(pos1.x, pos1.y, pos1.z).color(colorBottom) } } - val blf by lazy { vertex { vec3(pos1.x, pos1.y, pos2.z).color(colorBottom) } } - val brb by lazy { vertex { vec3(pos2.x, pos1.y, pos1.z).color(colorBottom) } } - val brf by lazy { vertex { vec3(pos2.x, pos1.y, pos2.z).color(colorBottom) } } - - val tlb by lazy { vertex { vec3(pos1.x, pos2.y, pos1.z).color(colorTop) } } - val tlf by lazy { vertex { vec3(pos1.x, pos2.y, pos2.z).color(colorTop) } } - val trb by lazy { vertex { vec3(pos2.x, pos2.y, pos1.z).color(colorTop) } } - val trf by lazy { vertex { vec3(pos2.x, pos2.y, pos2.z).color(colorTop) } } - - if (sides.hasDirection(DirectionMask.EAST)) buildQuad(brb, trb, trf, brf) - if (sides.hasDirection(DirectionMask.WEST)) buildQuad(blb, blf, tlf, tlb) - if (sides.hasDirection(DirectionMask.UP)) buildQuad(tlb, tlf, trf, trb) - if (sides.hasDirection(DirectionMask.DOWN)) buildQuad(blb, brb, brf, blf) - if (sides.hasDirection(DirectionMask.SOUTH)) buildQuad(blf, brf, trf, tlf) - if (sides.hasDirection(DirectionMask.NORTH)) buildQuad(blb, tlb, trb, brb) -} - -fun StaticESPRenderer.buildOutline( - box: Box, - colorBottom: Color, - colorTop: Color = colorBottom, - sides: Int = DirectionMask.ALL, - outlineMode: DirectionMask.OutlineMode = DirectionMask.OutlineMode.OR -) = outlineBuilder.use { - val pos1 = box.min - val pos2 = box.max - - val blb by lazy { vertex { vec3(pos1.x, pos1.y, pos1.z).color(colorBottom) } } - val blf by lazy { vertex { vec3(pos1.x, pos1.y, pos2.z).color(colorBottom) } } - val brb by lazy { vertex { vec3(pos2.x, pos1.y, pos1.z).color(colorBottom) } } - val brf by lazy { vertex { vec3(pos2.x, pos1.y, pos2.z).color(colorBottom) } } - val tlb by lazy { vertex { vec3(pos1.x, pos2.y, pos1.z).color(colorTop) } } - val tlf by lazy { vertex { vec3(pos1.x, pos2.y, pos2.z).color(colorTop) } } - val trb by lazy { vertex { vec3(pos2.x, pos2.y, pos1.z).color(colorTop) } } - val trf by lazy { vertex { vec3(pos2.x, pos2.y, pos2.z).color(colorTop) } } - - val hasEast = sides.hasDirection(DirectionMask.EAST) - val hasWest = sides.hasDirection(DirectionMask.WEST) - val hasUp = sides.hasDirection(DirectionMask.UP) - val hasDown = sides.hasDirection(DirectionMask.DOWN) - val hasSouth = sides.hasDirection(DirectionMask.SOUTH) - val hasNorth = sides.hasDirection(DirectionMask.NORTH) - - if (outlineMode.check(hasUp, hasNorth)) buildLine(tlb, trb) - if (outlineMode.check(hasUp, hasSouth)) buildLine(tlf, trf) - if (outlineMode.check(hasUp, hasWest)) buildLine(tlb, tlf) - if (outlineMode.check(hasUp, hasEast)) buildLine(trf, trb) - - if (outlineMode.check(hasDown, hasNorth)) buildLine(blb, brb) - if (outlineMode.check(hasDown, hasSouth)) buildLine(blf, brf) - if (outlineMode.check(hasDown, hasWest)) buildLine(blb, blf) - if (outlineMode.check(hasDown, hasEast)) buildLine(brb, brf) - - if (outlineMode.check(hasWest, hasNorth)) buildLine(tlb, blb) - if (outlineMode.check(hasNorth, hasEast)) buildLine(trb, brb) - if (outlineMode.check(hasEast, hasSouth)) buildLine(trf, brf) - if (outlineMode.check(hasSouth, hasWest)) buildLine(tlf, blf) -} diff --git a/src/main/kotlin/com/lambda/graphics/renderer/esp/global/DynamicESP.kt b/src/main/kotlin/com/lambda/graphics/renderer/esp/global/DynamicESP.kt deleted file mode 100644 index cc8758055..000000000 --- a/src/main/kotlin/com/lambda/graphics/renderer/esp/global/DynamicESP.kt +++ /dev/null @@ -1,22 +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.graphics.renderer.esp.global - -import com.lambda.graphics.renderer.esp.impl.DynamicESPRenderer - -object DynamicESP : DynamicESPRenderer() diff --git a/src/main/kotlin/com/lambda/graphics/renderer/esp/global/StaticESP.kt b/src/main/kotlin/com/lambda/graphics/renderer/esp/global/StaticESP.kt deleted file mode 100644 index 7e0c9b6ce..000000000 --- a/src/main/kotlin/com/lambda/graphics/renderer/esp/global/StaticESP.kt +++ /dev/null @@ -1,22 +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.graphics.renderer.esp.global - -import com.lambda.graphics.renderer.esp.impl.StaticESPRenderer - -object StaticESP : StaticESPRenderer() diff --git a/src/main/kotlin/com/lambda/graphics/renderer/esp/impl/DynamicESPRenderer.kt b/src/main/kotlin/com/lambda/graphics/renderer/esp/impl/DynamicESPRenderer.kt deleted file mode 100644 index 9ba314bdd..000000000 --- a/src/main/kotlin/com/lambda/graphics/renderer/esp/impl/DynamicESPRenderer.kt +++ /dev/null @@ -1,22 +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.graphics.renderer.esp.impl - -import com.lambda.graphics.renderer.esp.ESPRenderer - -open class DynamicESPRenderer : ESPRenderer(true) diff --git a/src/main/kotlin/com/lambda/graphics/renderer/esp/impl/StaticESPRenderer.kt b/src/main/kotlin/com/lambda/graphics/renderer/esp/impl/StaticESPRenderer.kt deleted file mode 100644 index d3d48deea..000000000 --- a/src/main/kotlin/com/lambda/graphics/renderer/esp/impl/StaticESPRenderer.kt +++ /dev/null @@ -1,22 +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.graphics.renderer.esp.impl - -import com.lambda.graphics.renderer.esp.ESPRenderer - -open class StaticESPRenderer : ESPRenderer(false) \ No newline at end of file diff --git a/src/main/kotlin/com/lambda/interaction/construction/result/Drawable.kt b/src/main/kotlin/com/lambda/interaction/construction/result/Drawable.kt index 04b6f84a1..108e56200 100644 --- a/src/main/kotlin/com/lambda/interaction/construction/result/Drawable.kt +++ b/src/main/kotlin/com/lambda/interaction/construction/result/Drawable.kt @@ -20,8 +20,6 @@ package com.lambda.interaction.construction.result import com.lambda.context.SafeContext import com.lambda.graphics.renderer.esp.DirectionMask import com.lambda.graphics.renderer.esp.DirectionMask.include -import com.lambda.graphics.renderer.esp.builders.buildFilled -import com.lambda.graphics.renderer.esp.global.StaticESP import com.lambda.util.BlockUtils.blockState import net.minecraft.block.BlockState import net.minecraft.util.math.BlockPos @@ -34,7 +32,7 @@ interface Drawable { fun SafeContext.buildRenderer() fun SafeContext.withBox(box: Box, color: Color, mask: Int = DirectionMask.ALL) { - StaticESP.buildFilled(box, color, mask) + //StaticESP.filled(box, color, mask) //StaticESP.buildOutline(box, color, mask) } diff --git a/src/main/kotlin/com/lambda/interaction/request/breaking/BreakManager.kt b/src/main/kotlin/com/lambda/interaction/request/breaking/BreakManager.kt index 8765cf276..a0dddecc0 100644 --- a/src/main/kotlin/com/lambda/interaction/request/breaking/BreakManager.kt +++ b/src/main/kotlin/com/lambda/interaction/request/breaking/BreakManager.kt @@ -22,14 +22,12 @@ import com.lambda.event.Event import com.lambda.event.EventFlow.post import com.lambda.event.events.ConnectionEvent import com.lambda.event.events.EntityEvent -import com.lambda.event.events.RenderEvent import com.lambda.event.events.TickEvent import com.lambda.event.events.UpdateManagerEvent import com.lambda.event.events.WorldEvent +import com.lambda.event.events.onStaticRender import com.lambda.event.listener.SafeListener.Companion.listen import com.lambda.event.listener.UnsafeListener.Companion.listenUnsafe -import com.lambda.graphics.renderer.esp.builders.buildFilled -import com.lambda.graphics.renderer.esp.builders.buildOutline import com.lambda.interaction.construction.blueprint.Blueprint.Companion.toStructure import com.lambda.interaction.construction.blueprint.StaticBlueprint.Companion.toBlueprint import com.lambda.interaction.construction.context.BreakContext @@ -226,16 +224,16 @@ object BreakManager : RequestHandler( ?.internalOnItemDrop(it.entity) } - listen { event -> + onStaticRender { val activeStack = breakInfos .filterNotNull() - .firstOrNull()?.swapStack ?: return@listen + .firstOrNull()?.swapStack ?: return@onStaticRender breakInfos .filterNotNull() .forEach { info -> val config = info.breakConfig - if (!config.renders) return@listen + if (!config.renders) return@onStaticRender val swapMode = info.breakConfig.swapMode val breakDelta = info.context.cachedState.calcBreakDelta( player, @@ -270,8 +268,8 @@ object BreakManager : RequestHandler( it.offset(info.context.blockPos) }.forEach boxes@ { box -> val interpolated = interpolateBox(box, interpolatedProgress, info.breakConfig) - if (config.fill) event.renderer.buildFilled(interpolated, fillColor) - if (config.outline) event.renderer.buildOutline(interpolated, outlineColor) + if (config.fill) it.filled(interpolated, fillColor) + if (config.outline) it.outline(interpolated, outlineColor) } } } diff --git a/src/main/kotlin/com/lambda/module/modules/client/TaskFlowModule.kt b/src/main/kotlin/com/lambda/module/modules/client/TaskFlowModule.kt index 314657674..ed7f9287f 100644 --- a/src/main/kotlin/com/lambda/module/modules/client/TaskFlowModule.kt +++ b/src/main/kotlin/com/lambda/module/modules/client/TaskFlowModule.kt @@ -23,6 +23,7 @@ import com.lambda.config.groups.InteractionSettings import com.lambda.config.groups.InventorySettings import com.lambda.config.groups.RotationSettings import com.lambda.event.events.RenderEvent +import com.lambda.event.events.onStaticRender import com.lambda.event.listener.SafeListener.Companion.listen import com.lambda.interaction.construction.result.Drawable import com.lambda.module.Module @@ -58,10 +59,8 @@ object TaskFlowModule : Module( var drawables = listOf() init { - listen { - drawables.toList().forEach { res -> - with(res) { buildRenderer() } - } + onStaticRender { + drawables.forEach { with(it) { buildRenderer() } } } } } diff --git a/src/main/kotlin/com/lambda/module/modules/debug/BlockTest.kt b/src/main/kotlin/com/lambda/module/modules/debug/BlockTest.kt index 223812b68..1a649301c 100644 --- a/src/main/kotlin/com/lambda/module/modules/debug/BlockTest.kt +++ b/src/main/kotlin/com/lambda/module/modules/debug/BlockTest.kt @@ -17,9 +17,7 @@ package com.lambda.module.modules.debug -import com.lambda.event.events.RenderEvent -import com.lambda.event.listener.SafeListener.Companion.listen -import com.lambda.graphics.renderer.esp.builders.ofBox +import com.lambda.event.events.onStaticRender import com.lambda.module.Module import com.lambda.module.tag.ModuleTag import com.lambda.util.world.blockSearch @@ -49,12 +47,12 @@ object BlockTest : Module( private val outlineColor = Color(100, 150, 255, 51) init { - listen { + onStaticRender { blockSearch(range, step = step) { _, state -> state.isOf(Blocks.DIAMOND_BLOCK) }.forEach { (pos, state) -> state.getOutlineShape(world, pos).boundingBoxes.forEach { box -> - it.renderer.ofBox(box.offset(pos), filledColor, outlineColor) + it.box(box.offset(pos), filledColor, outlineColor) } } } diff --git a/src/main/kotlin/com/lambda/module/modules/debug/RenderTest.kt b/src/main/kotlin/com/lambda/module/modules/debug/RenderTest.kt index 71248fedd..1618c3a6f 100644 --- a/src/main/kotlin/com/lambda/module/modules/debug/RenderTest.kt +++ b/src/main/kotlin/com/lambda/module/modules/debug/RenderTest.kt @@ -17,10 +17,10 @@ package com.lambda.module.modules.debug -import com.lambda.event.events.RenderEvent -import com.lambda.event.listener.SafeListener.Companion.listen +import com.lambda.event.events.onDynamicRender +import com.lambda.event.events.onStaticRender +import com.lambda.graphics.renderer.esp.DirectionMask import com.lambda.graphics.renderer.esp.DynamicAABB.Companion.dynamicBox -import com.lambda.graphics.renderer.esp.builders.ofBox import com.lambda.module.Module import com.lambda.module.tag.ModuleTag import com.lambda.util.math.setAlpha @@ -45,15 +45,15 @@ object RenderTest : Module( private val filledColor = outlineColor.setAlpha(0.2) init { - listen { + onDynamicRender { entitySearch(8.0) .forEach { entity -> - it.renderer.ofBox(entity.dynamicBox, filledColor, outlineColor) + it.box(entity.dynamicBox, filledColor, outlineColor, DirectionMask.ALL, DirectionMask.OutlineMode.AND) } } - listen { - it.renderer.ofBox(Box.of(player.pos, 0.3, 0.3, 0.3), filledColor, outlineColor) + onStaticRender { + it.box(Box.of(player.pos, 0.3, 0.3, 0.3), filledColor, outlineColor) } } } diff --git a/src/main/kotlin/com/lambda/module/modules/movement/BackTrack.kt b/src/main/kotlin/com/lambda/module/modules/movement/BackTrack.kt index a7fc452e3..98f8d6ab2 100644 --- a/src/main/kotlin/com/lambda/module/modules/movement/BackTrack.kt +++ b/src/main/kotlin/com/lambda/module/modules/movement/BackTrack.kt @@ -20,11 +20,10 @@ package com.lambda.module.modules.movement import com.lambda.context.SafeContext import com.lambda.event.events.ConnectionEvent import com.lambda.event.events.PacketEvent -import com.lambda.event.events.RenderEvent import com.lambda.event.events.TickEvent +import com.lambda.event.events.onDynamicRender import com.lambda.event.listener.SafeListener.Companion.listen import com.lambda.graphics.renderer.esp.DynamicAABB -import com.lambda.graphics.renderer.esp.builders.ofBox import com.lambda.module.Module import com.lambda.module.modules.client.GuiSettings import com.lambda.module.modules.combat.KillAura @@ -111,15 +110,15 @@ object BackTrack : Module( poolPackets() } - listen { - val target = target ?: return@listen + onDynamicRender { + val target = target ?: return@onDynamicRender val c1 = GuiSettings.primaryColor val c2 = Color.RED val p = target.hurtTime / 10.0 val c = lerp(p, c1, c2) - it.renderer.ofBox(box, c.multAlpha(0.3), c.multAlpha(0.8)) + it.box(box, c.multAlpha(0.3), c.multAlpha(0.8)) } listen { event -> diff --git a/src/main/kotlin/com/lambda/module/modules/movement/Blink.kt b/src/main/kotlin/com/lambda/module/modules/movement/Blink.kt index 6b54ed4f4..4b04a8576 100644 --- a/src/main/kotlin/com/lambda/module/modules/movement/Blink.kt +++ b/src/main/kotlin/com/lambda/module/modules/movement/Blink.kt @@ -20,9 +20,9 @@ package com.lambda.module.modules.movement import com.lambda.context.SafeContext import com.lambda.event.events.PacketEvent import com.lambda.event.events.RenderEvent +import com.lambda.event.events.onDynamicRender import com.lambda.event.listener.SafeListener.Companion.listen import com.lambda.graphics.renderer.esp.DynamicAABB -import com.lambda.graphics.renderer.esp.builders.ofBox import com.lambda.module.Module import com.lambda.module.modules.client.GuiSettings import com.lambda.module.modules.combat.KillAura @@ -67,9 +67,9 @@ object Blink : Module( poolPackets() } - listen { event -> + onDynamicRender { val color = GuiSettings.primaryColor - event.renderer.ofBox(box.update(lastBox), color.setAlpha(0.3), color) + it.box(box.update(lastBox), color.setAlpha(0.3), color) } listen { event -> diff --git a/src/main/kotlin/com/lambda/module/modules/player/PacketMine.kt b/src/main/kotlin/com/lambda/module/modules/player/PacketMine.kt index 387418393..c42d2ec79 100644 --- a/src/main/kotlin/com/lambda/module/modules/player/PacketMine.kt +++ b/src/main/kotlin/com/lambda/module/modules/player/PacketMine.kt @@ -24,11 +24,9 @@ import com.lambda.config.groups.InventorySettings import com.lambda.config.groups.RotationSettings import com.lambda.context.SafeContext import com.lambda.event.events.PlayerEvent -import com.lambda.event.events.RenderEvent import com.lambda.event.events.TickEvent +import com.lambda.event.events.onStaticRender import com.lambda.event.listener.SafeListener.Companion.listen -import com.lambda.graphics.renderer.esp.builders.buildFilled -import com.lambda.graphics.renderer.esp.builders.buildOutline import com.lambda.interaction.construction.blueprint.StaticBlueprint.Companion.toBlueprint import com.lambda.interaction.construction.context.BreakContext import com.lambda.interaction.construction.context.BuildContext @@ -161,8 +159,8 @@ object PacketMine : Module( } } - listen { event -> - if (!renderQueue) return@listen + onStaticRender { + if (!renderQueue) return@onStaticRender queueSorted.forEachIndexed { index, positions -> positions.forEach { pos -> val color = if (dynamicColor) lerp(index / queuePositions.size.toDouble(), startColor, endColor) @@ -173,8 +171,8 @@ object PacketMine : Module( }.map { lerp(renderSize.toDouble(), Box(it.center, it.center), it).offset(pos) } boxes.forEach { box -> - event.renderer.buildFilled(box, color) - event.renderer.buildOutline(box, color.setAlpha(1.0)) + it.filled(box, color) + it.outline(box, color.setAlpha(1.0)) } } } diff --git a/src/main/kotlin/com/lambda/module/modules/player/Scaffold.kt b/src/main/kotlin/com/lambda/module/modules/player/Scaffold.kt index 0541200b7..fe89631c2 100644 --- a/src/main/kotlin/com/lambda/module/modules/player/Scaffold.kt +++ b/src/main/kotlin/com/lambda/module/modules/player/Scaffold.kt @@ -22,12 +22,12 @@ import com.lambda.config.groups.InteractionSettings import com.lambda.config.groups.RotationSettings import com.lambda.context.SafeContext import com.lambda.event.events.MovementEvent -import com.lambda.event.events.RenderEvent import com.lambda.event.events.TickEvent +import com.lambda.event.events.onStaticRender import com.lambda.event.listener.SafeListener.Companion.listen import com.lambda.graphics.renderer.esp.DirectionMask import com.lambda.graphics.renderer.esp.DirectionMask.buildSideMesh -import com.lambda.graphics.renderer.esp.builders.ofBox +import com.lambda.graphics.renderer.esp.ShapeBuilder import com.lambda.interaction.blockplace.PlaceFinder.Companion.buildPlaceInfo import com.lambda.interaction.blockplace.PlaceInfo import com.lambda.interaction.blockplace.PlaceInteraction.placeBlock @@ -152,9 +152,7 @@ object Scaffold : Module( updateSneaking() } - listen { event -> - buildRenderer(event) - } + onStaticRender { with(it) { buildRenderer() } } onEnable { placeInfo = null @@ -324,7 +322,7 @@ object Scaffold : Module( if (sneak) sneakTicks = 3 } - private fun buildRenderer(event: RenderEvent.StaticESP) { + private fun ShapeBuilder.buildRenderer() { val c = GuiSettings.primaryColor renderInfo.removeIf { info -> @@ -340,13 +338,7 @@ object Scaffold : Module( val box = Box(info.placedPos) val alpha = transform(seconds, 0.0, 0.5, 1.0, 0.0).coerceIn(0.0, 1.0) - event.renderer.ofBox( - box, - c.multAlpha(0.3 * alpha), - c.multAlpha(alpha), - sides, - DirectionMask.OutlineMode.AND - ) + box(box, c.multAlpha(0.3 * alpha), c.multAlpha(alpha), sides, DirectionMask.OutlineMode.AND) seconds > 1 } diff --git a/src/main/kotlin/com/lambda/module/modules/player/WorldEater.kt b/src/main/kotlin/com/lambda/module/modules/player/WorldEater.kt index a8d6208d2..42a8807e2 100644 --- a/src/main/kotlin/com/lambda/module/modules/player/WorldEater.kt +++ b/src/main/kotlin/com/lambda/module/modules/player/WorldEater.kt @@ -17,9 +17,7 @@ package com.lambda.module.modules.player -import com.lambda.event.events.RenderEvent -import com.lambda.event.listener.SafeListener.Companion.listen -import com.lambda.graphics.renderer.esp.builders.buildOutline +import com.lambda.event.events.onStaticRender import com.lambda.interaction.construction.blueprint.Blueprint.Companion.toStructure import com.lambda.interaction.construction.blueprint.StaticBlueprint.Companion.toBlueprint import com.lambda.interaction.construction.verify.TargetState @@ -67,9 +65,7 @@ object WorldEater : Module( BaritoneUtils.cancel() } - listen { - it.renderer.buildOutline(Box.enclosing(pos1, pos2), Color.BLUE) - } + onStaticRender { it.outline(Box.enclosing(pos1, pos2), Color.BLUE) } } private fun buildLayer() { diff --git a/src/main/kotlin/com/lambda/module/modules/render/BlockESP.kt b/src/main/kotlin/com/lambda/module/modules/render/BlockESP.kt index fd68a2504..271363eaa 100644 --- a/src/main/kotlin/com/lambda/module/modules/render/BlockESP.kt +++ b/src/main/kotlin/com/lambda/module/modules/render/BlockESP.kt @@ -18,19 +18,17 @@ package com.lambda.module.modules.render import com.lambda.Lambda.mc +import com.lambda.graphics.pipeline.VertexBuilder import com.lambda.graphics.renderer.esp.ChunkedESP.Companion.newChunkedESP import com.lambda.graphics.renderer.esp.DirectionMask import com.lambda.graphics.renderer.esp.DirectionMask.buildSideMesh -import com.lambda.graphics.renderer.esp.builders.buildFilledShape -import com.lambda.graphics.renderer.esp.builders.buildOutlineShape -import com.lambda.graphics.renderer.esp.impl.StaticESPRenderer +import com.lambda.graphics.renderer.esp.ShapeBuilder import com.lambda.module.Module import com.lambda.module.tag.ModuleTag import com.lambda.threading.runSafe import com.lambda.util.extension.blockColor import com.lambda.util.extension.getBlockState import com.lambda.util.extension.outlineShape -import com.lambda.util.world.fastVectorOf import com.lambda.util.world.toBlockPos import net.minecraft.block.BlockState import net.minecraft.block.Blocks @@ -71,8 +69,7 @@ object BlockESP : Module( } } - private val esp = newChunkedESP { world, x, y, z -> - val position = fastVectorOf(x, y, z) + private val esp = newChunkedESP { world, position -> val state = world.getBlockState(position) if (state.block !in blocks) return@newChunkedESP @@ -85,7 +82,7 @@ object BlockESP : Module( build(state, position.toBlockPos(), sides) } - private fun StaticESPRenderer.build( + private fun ShapeBuilder.build( state: BlockState, pos: BlockPos, sides: Int, @@ -93,8 +90,8 @@ object BlockESP : Module( val shape = outlineShape(state, pos) val blockColor = blockColor(state, pos) - if (drawFaces) buildFilledShape(shape, if (useBlockColor) blockColor else faceColor, sides) - if (drawOutlines) buildOutlineShape(shape, if (useBlockColor) blockColor else outlineColor, sides, outlineMode) + if (drawFaces) filled(shape, if (useBlockColor) blockColor else faceColor, sides) + if (drawOutlines) outline(shape, if (useBlockColor) blockColor else outlineColor, sides, outlineMode) } private fun rebuildMesh(from: Any, to: Any): Unit = esp.rebuild() diff --git a/src/main/kotlin/com/lambda/module/modules/render/StorageESP.kt b/src/main/kotlin/com/lambda/module/modules/render/StorageESP.kt index 853d0d8b5..60e164121 100644 --- a/src/main/kotlin/com/lambda/module/modules/render/StorageESP.kt +++ b/src/main/kotlin/com/lambda/module/modules/render/StorageESP.kt @@ -18,15 +18,10 @@ package com.lambda.module.modules.render import com.lambda.context.SafeContext -import com.lambda.event.events.RenderEvent -import com.lambda.event.listener.SafeListener.Companion.listen +import com.lambda.event.events.onStaticRender import com.lambda.graphics.renderer.esp.DirectionMask import com.lambda.graphics.renderer.esp.DirectionMask.buildSideMesh -import com.lambda.graphics.renderer.esp.builders.buildFilled -import com.lambda.graphics.renderer.esp.builders.buildFilledShape -import com.lambda.graphics.renderer.esp.builders.buildOutline -import com.lambda.graphics.renderer.esp.builders.buildOutlineShape -import com.lambda.graphics.renderer.esp.impl.StaticESPRenderer +import com.lambda.graphics.renderer.esp.ShapeBuilder import com.lambda.module.Module import com.lambda.module.tag.ModuleTag import com.lambda.threading.runSafe @@ -52,7 +47,6 @@ import net.minecraft.entity.Entity import net.minecraft.entity.decoration.ItemFrameEntity import net.minecraft.entity.vehicle.AbstractMinecartEntity import net.minecraft.entity.vehicle.MinecartEntity -import net.minecraft.util.math.BlockPos import java.awt.Color object StorageESP : Module( @@ -64,14 +58,15 @@ object StorageESP : Module( private val distance by setting("Distance", 64.0, 10.0..256.0, 1.0, "Maximum distance for rendering").group(Group.General) /* Render settings */ - private var drawFaces: Boolean by setting("Draw Faces", true, "Draw faces of blocks").onValueSet { _, to -> if (!to) drawOutlines = true }.group(Group.Render) - private var drawOutlines: Boolean by setting("Draw Outlines", true, "Draw outlines of blocks").onValueSet { _, to -> if (!to) drawFaces = true }.group(Group.Render) - private val outlineMode by setting("Outline Mode", DirectionMask.OutlineMode.AND, "Outline mode").group(Group.Render) + private var drawFaces: Boolean by setting("Draw Faces", true, "Draw faces of blocks").onValueSet { _, to -> if (!to) drawEdges = true }.group(Group.Render) + private var drawEdges: Boolean by setting("Draw Edges", true, "Draw edges of blocks").onValueSet { _, to -> if (!to) drawFaces = true }.group(Group.Render) + private val mode by setting("Outline Mode", DirectionMask.OutlineMode.AND, "Outline mode").group(Group.Render) private val mesh by setting("Mesh", true, "Connect similar adjacent blocks").group(Group.Render) /* Color settings */ private val useBlockColor by setting("Use Block Color", true, "Use the color of the block instead").group(Group.Color) - private val alpha by setting("Alpha", 0.3, 0.1..1.0, 0.05).group(Group.Color) + private val facesAlpha by setting("Faces Alpha", 0.3, 0.1..1.0, 0.05).group(Group.Color) + private val edgesAlpha by setting("Edges Alpha", 0.3, 0.1..1.0, 0.05).group(Group.Color) // TODO: // val blockColors by setting("Block Colors", mapOf()) { page == Page.Color && !useBlockColor } @@ -118,15 +113,15 @@ object StorageESP : Module( ) init { - listen { event -> + onStaticRender { builder -> blockEntitySearch(distance) .filter { it::class in entities } - .forEach { event.renderer.build(it, it.pos, excludedSides(it)) } + .forEach { with(builder) { build(it, excludedSides(it)) } } val mineCarts = entitySearch(distance) val itemFrames = entitySearch(distance) (mineCarts + itemFrames) - .forEach { event.renderer.build(it, DirectionMask.ALL) } + .forEach { with(builder) { build(it, DirectionMask.ALL) } } // FixMe: Exclude entity shape sides } } @@ -144,32 +139,32 @@ object StorageESP : Module( } else DirectionMask.ALL } - private fun StaticESPRenderer.build( + private fun ShapeBuilder.build( block: BlockEntity, - pos: BlockPos, sides: Int, ) = runSafe { - val color = if (useBlockColor) { - blockColor(block.cachedState, pos) - } else getBlockEntityColor(block) ?: return@runSafe - val shape = outlineShape(block.cachedState, pos) + val color = + if (useBlockColor) blockColor(block.cachedState, block.pos) + else block.color ?: return@runSafe - if (drawFaces) buildFilledShape(shape, color.setAlpha(alpha), sides) - if (drawOutlines) buildOutlineShape(shape, color, sides, outlineMode) + val shape = outlineShape(block.cachedState, block.pos) + + if (drawFaces) filled(shape, color.setAlpha(facesAlpha), sides) + if (drawEdges) outline(shape, color.setAlpha(edgesAlpha), sides, mode) } - private fun StaticESPRenderer.build( + private fun ShapeBuilder.build( entity: Entity, sides: Int, ) = runSafe { - val color = getEntityColor(entity) ?: return@runSafe + val color = entity.color ?: return@runSafe - if (drawFaces) buildFilled(entity.boundingBox, color.setAlpha(alpha), sides) - if (drawOutlines) buildOutline(entity.boundingBox, color, sides, outlineMode) + if (drawFaces) filled(entity.boundingBox, color.setAlpha(facesAlpha), sides) + if (drawEdges) outline(entity.boundingBox, color.setAlpha(edgesAlpha), sides, mode) } - private fun getBlockEntityColor(block: BlockEntity?) = - when (block) { + private val BlockEntity?.color get() = + when (this) { is BarrelBlockEntity -> barrelColor is BlastFurnaceBlockEntity -> blastFurnaceColor is BrewingStandBlockEntity -> brewingStandColor @@ -184,8 +179,8 @@ object StorageESP : Module( else -> null } - private fun getEntityColor(entity: Entity?) = - when (entity) { + private val Entity?.color get() = + when (this) { is AbstractMinecartEntity -> cartColor is ItemFrameEntity -> itemFrameColor else -> null From 848f1076b01173df9d7fe54bd3c92254b43fec50 Mon Sep 17 00:00:00 2001 From: Edouard127 <46357922+Edouard127@users.noreply.github.com> Date: Sat, 23 Aug 2025 12:23:13 -0400 Subject: [PATCH 2/9] Fixed 3d, 3d classes --- .../com/lambda/event/events/RenderEvent.kt | 8 +-- .../kotlin/com/lambda/graphics/RenderMain.kt | 16 +++-- .../graphics/renderer/esp/ChunkedESP.kt | 67 +++++++++---------- .../lambda/graphics/renderer/esp/ShapeDsl.kt | 4 +- .../com/lambda/graphics/renderer/esp/Treed.kt | 59 +++++++--------- .../module/modules/combat/CrystalAura.kt | 2 +- .../lambda/module/modules/movement/Blink.kt | 2 +- .../module/modules/network/PacketDelay.kt | 2 +- 8 files changed, 75 insertions(+), 85 deletions(-) diff --git a/src/main/kotlin/com/lambda/event/events/RenderEvent.kt b/src/main/kotlin/com/lambda/event/events/RenderEvent.kt index f1c790242..812979bfa 100644 --- a/src/main/kotlin/com/lambda/event/events/RenderEvent.kt +++ b/src/main/kotlin/com/lambda/event/events/RenderEvent.kt @@ -26,13 +26,13 @@ import com.lambda.graphics.renderer.esp.ShapeBuilder import com.lambda.graphics.renderer.esp.Treed fun Any.onStaticRender(block: SafeContext.(ShapeBuilder) -> Unit) = - listen { block(ShapeBuilder(Treed.staticFaceBuilder, Treed.staticEdgeBuilder)) } - + listen { block(ShapeBuilder(Treed.Static.faceBuilder, Treed.Static.edgeBuilder)) } fun Any.onDynamicRender(block: SafeContext.(ShapeBuilder) -> Unit) = - listen { block(ShapeBuilder(Treed.dynamicFaceBuilder, Treed.dynamicEdgeBuilder)) } + listen { block(ShapeBuilder(Treed.Dynamic.faceBuilder, Treed.Dynamic.edgeBuilder)) } sealed class RenderEvent { - class World : Event + object Upload : Event + object Render : Event class UpdateTarget : ICancellable by Cancellable() } diff --git a/src/main/kotlin/com/lambda/graphics/RenderMain.kt b/src/main/kotlin/com/lambda/graphics/RenderMain.kt index 43c3cffb5..3668298f2 100644 --- a/src/main/kotlin/com/lambda/graphics/RenderMain.kt +++ b/src/main/kotlin/com/lambda/graphics/RenderMain.kt @@ -55,16 +55,22 @@ object RenderMain { GlStateManager._glBindFramebuffer(GL_FRAMEBUFFER, prevFramebuffer) - Treed.clear() - RenderEvent.World().post() - Treed.upload() - Treed.render() + Treed.Static.render() + Treed.Dynamic.render() + + RenderEvent.Render.post() } } init { listen { - //Treed.clear() + Treed.Static.clear() + Treed.Dynamic.clear() + + RenderEvent.Upload.post() + + Treed.Static.upload() + Treed.Dynamic.upload() } } } diff --git a/src/main/kotlin/com/lambda/graphics/renderer/esp/ChunkedESP.kt b/src/main/kotlin/com/lambda/graphics/renderer/esp/ChunkedESP.kt index 18f2df868..ca5c06dc8 100644 --- a/src/main/kotlin/com/lambda/graphics/renderer/esp/ChunkedESP.kt +++ b/src/main/kotlin/com/lambda/graphics/renderer/esp/ChunkedESP.kt @@ -17,11 +17,11 @@ package com.lambda.graphics.renderer.esp +import com.lambda.event.events.RenderEvent import com.lambda.event.events.TickEvent import com.lambda.event.events.WorldEvent import com.lambda.event.events.onStaticRender import com.lambda.event.listener.SafeListener.Companion.listen -import com.lambda.event.listener.SafeListener.Companion.listenConcurrently import com.lambda.module.modules.client.StyleEditor import com.lambda.util.world.FastVector import com.lambda.util.world.fastVectorOf @@ -37,9 +37,7 @@ class ChunkedESP private constructor( ) { private val rendererMap = ConcurrentHashMap() private val WorldChunk.renderer - get() = rendererMap.getOrPut(pos.toLong()) { - EspChunk(this, this@ChunkedESP) - } + get() = rendererMap.getOrPut(pos.toLong()) { EspChunk(this, this@ChunkedESP) } private val uploadQueue = ConcurrentLinkedDeque<() -> Unit>() private val rebuildQueue = ConcurrentLinkedDeque() @@ -52,38 +50,29 @@ class ChunkedESP private constructor( } init { - listenConcurrently { event -> - world.getWorldChunk(event.pos).renderer.notifyChunks() - } - - listenConcurrently { event -> - event.chunk.renderer.notifyChunks() - } + listen { world.getWorldChunk(it.pos).renderer.notifyChunks() } + listen { it.chunk.renderer.notifyChunks() } + listen { rendererMap.remove(it.chunk.pos.toLong())?.notifyChunks() } - listenConcurrently { event -> - rendererMap.remove(event.chunk.pos.toLong())?.notifyChunks() - } - - owner.onStaticRender { builder -> + owner.onStaticRender { if (++ticks % StyleEditor.updateFrequency == 0) { val polls = minOf(StyleEditor.rebuildsPerTick, rebuildQueue.size) - repeat(polls) { - rebuildQueue.poll()?.rebuild(builder) - } + repeat(polls) { rebuildQueue.poll()?.rebuild() } + ticks = 0 } } - owner.listen { + owner.listen { if (uploadQueue.isEmpty()) return@listen val polls = minOf(StyleEditor.uploadsPerTick, uploadQueue.size) - repeat(polls) { - uploadQueue.poll()?.invoke() - } + repeat(polls) { uploadQueue.poll()?.invoke() } } + + owner.listen { rendererMap.values.forEach { it.renderer.render() } } } companion object { @@ -93,29 +82,35 @@ class ChunkedESP private constructor( } private class EspChunk(val chunk: WorldChunk, val owner: ChunkedESP) { - val neighbors = listOf(1 to 0, 0 to 1, -1 to 0, 0 to -1).map { ChunkPos(chunk.pos.x + it.first, chunk.pos.z + it.second) } + var renderer = Treed(static = true) + private val builder: ShapeBuilder + get() = ShapeBuilder(renderer.faceBuilder, renderer.edgeBuilder) + + val neighbors = listOf(1 to 0, 0 to 1, -1 to 0, 0 to -1) + .map { ChunkPos(chunk.pos.x + it.first, chunk.pos.z + it.second) } fun notifyChunks() { neighbors.forEach { owner.rendererMap[it.toLong()]?.let { - owner.rebuildQueue.apply { - if (!contains(it)) add(it) - } + if (!owner.rebuildQueue.contains(it)) + owner.rebuildQueue.add(it) } } } - fun rebuild(builder: ShapeBuilder) = - iterateChunk { owner.update(builder, chunk.world, it) } + fun rebuild() { + renderer = Treed(static = true) + + chunkIterator { owner.update(builder, chunk.world, it) } - inline fun iterateChunk(crossinline block: (FastVector) -> Unit) = chunk.apply { - for (x in pos.startX..pos.endX) { - for (z in pos.startZ..pos.endZ) { - for (y in bottomY..height) { + owner.uploadQueue.add { renderer.upload() } + } + + inline fun chunkIterator(crossinline block: (FastVector) -> Unit) { + for (x in chunk.pos.startX..chunk.pos.endX) + for (z in chunk.pos.startZ..chunk.pos.endZ) + for (y in chunk.bottomY..chunk.height) block(fastVectorOf(x, y, z)) - } - } - } } } } diff --git a/src/main/kotlin/com/lambda/graphics/renderer/esp/ShapeDsl.kt b/src/main/kotlin/com/lambda/graphics/renderer/esp/ShapeDsl.kt index 35ba1dd02..6fecca9ce 100644 --- a/src/main/kotlin/com/lambda/graphics/renderer/esp/ShapeDsl.kt +++ b/src/main/kotlin/com/lambda/graphics/renderer/esp/ShapeDsl.kt @@ -36,8 +36,8 @@ import java.awt.Color annotation class ShapeDsl class ShapeBuilder( - val faces: VertexBuilder, - val edges: VertexBuilder, + val faces: VertexBuilder = VertexBuilder(), + val edges: VertexBuilder = VertexBuilder(), ) { @ShapeDsl fun filled( diff --git a/src/main/kotlin/com/lambda/graphics/renderer/esp/Treed.kt b/src/main/kotlin/com/lambda/graphics/renderer/esp/Treed.kt index a560c9e96..90e96ca44 100644 --- a/src/main/kotlin/com/lambda/graphics/renderer/esp/Treed.kt +++ b/src/main/kotlin/com/lambda/graphics/renderer/esp/Treed.kt @@ -27,53 +27,42 @@ import com.lambda.graphics.shader.Shader.Companion.shader import com.lambda.module.modules.client.StyleEditor import com.lambda.util.extension.partialTicks -object Treed { - val staticShader = shader("renderer/box_static") - val dynamicShader = shader("renderer/box_dynamic") +open class Treed(static: Boolean) { + val shader = if (static) staticMode.first else dynamicMode.first - val staticFaces = VertexPipeline(VertexMode.TRIANGLES, VertexAttrib.Group.STATIC_RENDERER) - val staticEdges = VertexPipeline(VertexMode.LINES, VertexAttrib.Group.STATIC_RENDERER) - val dynamicFaces = VertexPipeline(VertexMode.TRIANGLES, VertexAttrib.Group.DYNAMIC_RENDERER) - val dynamicEdges = VertexPipeline(VertexMode.LINES, VertexAttrib.Group.DYNAMIC_RENDERER) + val faces = VertexPipeline(VertexMode.TRIANGLES, if (static) staticMode.second else dynamicMode.second) + val edges = VertexPipeline(VertexMode.LINES, if (static) staticMode.second else dynamicMode.second) - // Vertex builders for shape building - var staticFaceBuilder = VertexBuilder(); private set - var dynamicFaceBuilder = VertexBuilder(); private set - var staticEdgeBuilder = VertexBuilder(); private set - var dynamicEdgeBuilder = VertexBuilder(); private set + var faceBuilder = VertexBuilder(); private set + var edgeBuilder = VertexBuilder(); private set fun upload() { - staticFaces.upload(staticFaceBuilder) - staticEdges.upload(staticEdgeBuilder) - dynamicFaces.upload(dynamicFaceBuilder) - dynamicEdges.upload(dynamicEdgeBuilder) + faces.upload(faceBuilder) + edges.upload(edgeBuilder) } fun render() { - staticShader.use() - staticShader["u_TickDelta"] = Lambda.mc.partialTicks - staticShader["u_CameraPosition"] = Lambda.mc.gameRenderer.camera.pos + shader.use() + shader["u_TickDelta"] = Lambda.mc.partialTicks + shader["u_CameraPosition"] = Lambda.mc.gameRenderer.camera.pos - GlStateUtils.withFaceCulling(staticFaces::render) - GlStateUtils.withLineWidth(StyleEditor.outlineWidth, staticEdges::render) + GlStateUtils.withFaceCulling(faces::render) + GlStateUtils.withLineWidth(StyleEditor.outlineWidth, edges::render) + } - dynamicShader.use() - dynamicShader["u_TickDelta"] = Lambda.mc.partialTicks - dynamicShader["u_CameraPosition"] = Lambda.mc.gameRenderer.camera.pos + fun clear() { + faces.clear() + edges.clear() - GlStateUtils.withFaceCulling(dynamicFaces::render) - GlStateUtils.withLineWidth(StyleEditor.outlineWidth, dynamicEdges::render) + faceBuilder = VertexBuilder() + edgeBuilder = VertexBuilder() } - fun clear() { - staticFaces.clear() - staticEdges.clear() - dynamicFaces.clear() - dynamicEdges.clear() + object Static : Treed(true) + object Dynamic : Treed(false) - staticFaceBuilder = VertexBuilder() - staticEdgeBuilder = VertexBuilder() - dynamicFaceBuilder = VertexBuilder() - dynamicEdgeBuilder = VertexBuilder() + companion object { + private val staticMode = shader("renderer/box_static") to VertexAttrib.Group.STATIC_RENDERER + private val dynamicMode = shader("renderer/box_dynamic") to VertexAttrib.Group.DYNAMIC_RENDERER } } diff --git a/src/main/kotlin/com/lambda/module/modules/combat/CrystalAura.kt b/src/main/kotlin/com/lambda/module/modules/combat/CrystalAura.kt index 9ec6177f2..3d6d2994e 100644 --- a/src/main/kotlin/com/lambda/module/modules/combat/CrystalAura.kt +++ b/src/main/kotlin/com/lambda/module/modules/combat/CrystalAura.kt @@ -180,7 +180,7 @@ object CrystalAura : Module( updatesThisFrame = 0 } - listen { + listen { if (!debug) return@listen Matrices.push { diff --git a/src/main/kotlin/com/lambda/module/modules/movement/Blink.kt b/src/main/kotlin/com/lambda/module/modules/movement/Blink.kt index 4b04a8576..bc9266d99 100644 --- a/src/main/kotlin/com/lambda/module/modules/movement/Blink.kt +++ b/src/main/kotlin/com/lambda/module/modules/movement/Blink.kt @@ -58,7 +58,7 @@ object Blink : Module( private var lastBox = Box(BlockPos.ORIGIN) init { - listen { + listen { val time = System.currentTimeMillis() if (isActive && time - lastUpdate < delay) return@listen diff --git a/src/main/kotlin/com/lambda/module/modules/network/PacketDelay.kt b/src/main/kotlin/com/lambda/module/modules/network/PacketDelay.kt index 3cf88493f..4d0d3457c 100644 --- a/src/main/kotlin/com/lambda/module/modules/network/PacketDelay.kt +++ b/src/main/kotlin/com/lambda/module/modules/network/PacketDelay.kt @@ -51,7 +51,7 @@ object PacketDelay : Module( private var inboundLastUpdate = 0L init { - listen { + listen { if (mode != Mode.STATIC) return@listen flushPools(System.currentTimeMillis()) From a25d3d6c8931dfa681f5937ec2786cd267209f70 Mon Sep 17 00:00:00 2001 From: Edouard127 <46357922+Edouard127@users.noreply.github.com> Date: Sat, 23 Aug 2025 12:23:24 -0400 Subject: [PATCH 3/9] Added back particles --- .../lambda/module/modules/render/Particles.kt | 51 ++++++++++++++++--- 1 file changed, 44 insertions(+), 7 deletions(-) diff --git a/src/main/kotlin/com/lambda/module/modules/render/Particles.kt b/src/main/kotlin/com/lambda/module/modules/render/Particles.kt index 7a7bc021b..d10e76a69 100644 --- a/src/main/kotlin/com/lambda/module/modules/render/Particles.kt +++ b/src/main/kotlin/com/lambda/module/modules/render/Particles.kt @@ -17,11 +17,50 @@ package com.lambda.module.modules.render +import com.lambda.Lambda.mc +import com.lambda.context.SafeContext +import com.lambda.event.events.MovementEvent +import com.lambda.event.events.PlayerEvent +import com.lambda.event.events.RenderEvent +import com.lambda.event.events.TickEvent +import com.lambda.event.listener.SafeListener.Companion.listen +import com.lambda.graphics.buffer.vertex.attributes.VertexAttrib +import com.lambda.graphics.buffer.vertex.attributes.VertexMode +import com.lambda.graphics.gl.GlStateUtils.withBlendFunc +import com.lambda.graphics.gl.GlStateUtils.withDepth +import com.lambda.graphics.gl.Matrices +import com.lambda.graphics.gl.Matrices.buildWorldProjection +import com.lambda.graphics.gl.Matrices.withVertexTransform +import com.lambda.graphics.pipeline.VertexBuilder +import com.lambda.graphics.pipeline.VertexPipeline +import com.lambda.graphics.shader.Shader.Companion.shader +import com.lambda.interaction.request.rotating.Rotation +import com.lambda.module.Module +import com.lambda.module.modules.client.GuiSettings +import com.lambda.module.modules.client.GuiSettings.colorSpeed +import com.lambda.module.tag.ModuleTag +import com.lambda.util.extension.partialTicks +import com.lambda.util.math.DOWN +import com.lambda.util.math.MathUtils.random +import com.lambda.util.math.UP +import com.lambda.util.math.lerp +import com.lambda.util.math.multAlpha +import com.lambda.util.math.plus +import com.lambda.util.math.times +import com.lambda.util.math.transform +import com.lambda.util.player.MovementUtils.moveDelta +import com.lambda.util.world.raycast.InteractionMask +import com.mojang.blaze3d.opengl.GlConst.GL_ONE +import com.mojang.blaze3d.opengl.GlConst.GL_SRC_ALPHA +import net.minecraft.entity.Entity +import net.minecraft.util.math.Vec3d +import kotlin.math.sin + // FixMe: Do not call render stuff in the initialization block -/*object Particles : Module( +object Particles : Module( name = "Particles", description = "Spawns fancy particles", - defaultTags = setOf(ModuleTag.RENDER) + tag = ModuleTag.RENDER, ) { // ToDo: resort, cleanup settings private val duration by setting("Duration", 5.0, 1.0..500.0, 1.0) @@ -52,12 +91,10 @@ package com.lambda.module.modules.render particles.removeIf(Particle::update) } - listen { + listen { // Todo: interpolated tickbased upload? val builder = pipeline.build() - particles.forEach { - it.build(builder) - } + particles.forEach { it.build(builder) } withBlendFunc(GL_SRC_ALPHA, GL_ONE) { shader.use() @@ -182,4 +219,4 @@ package com.lambda.module.modules.render } } } -}*/ +} From b59521af3b449979312e61dd42001913baa92cd1 Mon Sep 17 00:00:00 2001 From: Edouard127 <46357922+Edouard127@users.noreply.github.com> Date: Sat, 23 Aug 2025 16:04:51 -0400 Subject: [PATCH 4/9] BlockESP performance --- src/main/kotlin/com/lambda/Lambda.kt | 7 ++--- .../graphics/renderer/esp/ChunkedESP.kt | 22 +++++++------- .../lambda/module/modules/render/BlockESP.kt | 30 +++++++++---------- .../module/modules/render/StorageESP.kt | 4 +-- .../kotlin/com/lambda/threading/Threading.kt | 3 +- 5 files changed, 31 insertions(+), 35 deletions(-) diff --git a/src/main/kotlin/com/lambda/Lambda.kt b/src/main/kotlin/com/lambda/Lambda.kt index 4c7f6e326..56f624535 100644 --- a/src/main/kotlin/com/lambda/Lambda.kt +++ b/src/main/kotlin/com/lambda/Lambda.kt @@ -72,9 +72,6 @@ object Lambda : ClientModInitializer { .registerTypeAdapter(Text::class.java, Text.Serializer(DynamicRegistryManager.EMPTY)) .create() - override fun onInitializeClient() { - recordRenderCall { - LOG.info("$MOD_NAME $VERSION initialized in ${Loader.initialize()} ms\n") - } - } + override fun onInitializeClient() = + recordRenderCall { LOG.info("$MOD_NAME $VERSION initialized in ${Loader.initialize()} ms\n") } } diff --git a/src/main/kotlin/com/lambda/graphics/renderer/esp/ChunkedESP.kt b/src/main/kotlin/com/lambda/graphics/renderer/esp/ChunkedESP.kt index ca5c06dc8..1b0859c52 100644 --- a/src/main/kotlin/com/lambda/graphics/renderer/esp/ChunkedESP.kt +++ b/src/main/kotlin/com/lambda/graphics/renderer/esp/ChunkedESP.kt @@ -22,7 +22,9 @@ import com.lambda.event.events.TickEvent import com.lambda.event.events.WorldEvent import com.lambda.event.events.onStaticRender import com.lambda.event.listener.SafeListener.Companion.listen +import com.lambda.event.listener.SafeListener.Companion.listenConcurrently import com.lambda.module.modules.client.StyleEditor +import com.lambda.threading.awaitMainThread import com.lambda.util.world.FastVector import com.lambda.util.world.fastVectorOf import net.minecraft.util.math.ChunkPos @@ -54,7 +56,7 @@ class ChunkedESP private constructor( listen { it.chunk.renderer.notifyChunks() } listen { rendererMap.remove(it.chunk.pos.toLong())?.notifyChunks() } - owner.onStaticRender { + listenConcurrently { if (++ticks % StyleEditor.updateFrequency == 0) { val polls = minOf(StyleEditor.rebuildsPerTick, rebuildQueue.size) @@ -64,8 +66,8 @@ class ChunkedESP private constructor( } } - owner.listen { - if (uploadQueue.isEmpty()) return@listen + owner.onStaticRender { + if (uploadQueue.isEmpty()) return@onStaticRender val polls = minOf(StyleEditor.uploadsPerTick, uploadQueue.size) @@ -98,19 +100,15 @@ class ChunkedESP private constructor( } } - fun rebuild() { - renderer = Treed(static = true) - - chunkIterator { owner.update(builder, chunk.world, it) } - - owner.uploadQueue.add { renderer.upload() } - } + suspend fun rebuild() { + renderer = awaitMainThread { Treed(static = true) } - inline fun chunkIterator(crossinline block: (FastVector) -> Unit) { for (x in chunk.pos.startX..chunk.pos.endX) for (z in chunk.pos.startZ..chunk.pos.endZ) for (y in chunk.bottomY..chunk.height) - block(fastVectorOf(x, y, z)) + owner.update(builder, chunk.world, fastVectorOf(x, y, z)) + + owner.uploadQueue.add { renderer.upload() } } } } diff --git a/src/main/kotlin/com/lambda/module/modules/render/BlockESP.kt b/src/main/kotlin/com/lambda/module/modules/render/BlockESP.kt index 271363eaa..e17200b4c 100644 --- a/src/main/kotlin/com/lambda/module/modules/render/BlockESP.kt +++ b/src/main/kotlin/com/lambda/module/modules/render/BlockESP.kt @@ -18,6 +18,9 @@ package com.lambda.module.modules.render import com.lambda.Lambda.mc +import com.lambda.context.SafeContext +import com.lambda.event.events.TickEvent +import com.lambda.event.listener.SafeListener.Companion.listen import com.lambda.graphics.pipeline.VertexBuilder import com.lambda.graphics.renderer.esp.ChunkedESP.Companion.newChunkedESP import com.lambda.graphics.renderer.esp.DirectionMask @@ -26,9 +29,12 @@ import com.lambda.graphics.renderer.esp.ShapeBuilder import com.lambda.module.Module import com.lambda.module.tag.ModuleTag import com.lambda.threading.runSafe +import com.lambda.util.Communication.info import com.lambda.util.extension.blockColor import com.lambda.util.extension.getBlockState import com.lambda.util.extension.outlineShape +import com.lambda.util.world.blockSearch +import com.lambda.util.world.distSq import com.lambda.util.world.toBlockPos import net.minecraft.block.BlockState import net.minecraft.block.Blocks @@ -41,17 +47,17 @@ object BlockESP : Module( description = "Render block ESP", tag = ModuleTag.RENDER, ) { - private var drawFaces: Boolean by setting("Draw Faces", true, "Draw faces of blocks").onValueSet(::rebuildMesh).onValueSet { _, to -> if (!to) drawOutlines = true } - private var drawOutlines: Boolean by setting("Draw Outlines", true, "Draw outlines of blocks").onValueSet(::rebuildMesh).onValueSet { _, to -> if (!to) drawFaces = true } - private val mesh by setting("Mesh", true, "Connect similar adjacent blocks").onValueSet(::rebuildMesh) + private var drawFaces: Boolean by setting("Draw Faces", true, "Draw faces of blocks").onValueChange(::rebuildMesh).onValueChange { _, to -> if (!to) drawOutlines = true } + private var drawOutlines: Boolean by setting("Draw Outlines", true, "Draw outlines of blocks").onValueChange(::rebuildMesh).onValueChange { _, to -> if (!to) drawFaces = true } + private val mesh by setting("Mesh", true, "Connect similar adjacent blocks").onValueChange(::rebuildMesh) - private val useBlockColor by setting("Use Block Color", false, "Use the color of the block instead").onValueSet(::rebuildMesh) - private val faceColor by setting("Face Color", Color(100, 150, 255, 51), "Color of the surfaces") { drawFaces && !useBlockColor }.onValueSet(::rebuildMesh) - private val outlineColor by setting("Outline Color", Color(100, 150, 255, 128), "Color of the outlines") { drawOutlines && !useBlockColor }.onValueSet(::rebuildMesh) + private val useBlockColor by setting("Use Block Color", false, "Use the color of the block instead").onValueChange(::rebuildMesh) + private val faceColor by setting("Face Color", Color(100, 150, 255, 51), "Color of the surfaces") { drawFaces && !useBlockColor }.onValueChange(::rebuildMesh) + private val outlineColor by setting("Outline Color", Color(100, 150, 255, 128), "Color of the outlines") { drawOutlines && !useBlockColor }.onValueChange(::rebuildMesh) - private val outlineMode by setting("Outline Mode", DirectionMask.OutlineMode.AND, "Outline mode").onValueSet(::rebuildMesh) + private val outlineMode by setting("Outline Mode", DirectionMask.OutlineMode.AND, "Outline mode").onValueChange(::rebuildMesh) - private val blocks by setting("Blocks", setOf(Blocks.BEDROCK), setOf(Blocks.BEDROCK), "Render blocks").onValueSet(::rebuildMesh) + private val blocks by setting("Blocks", setOf(Blocks.BEDROCK), setOf(Blocks.BEDROCK), "Render blocks").onValueChange(::rebuildMesh) @JvmStatic val barrier by setting("Solid Barrier Block", true, "Render barrier blocks") @@ -63,12 +69,6 @@ object BlockESP : Module( @JvmStatic val model: BlockStateModel get() = mc.bakedModelManager.missingModel - init { - onToggle { - if (barrier) mc.worldRenderer.reload() - } - } - private val esp = newChunkedESP { world, position -> val state = world.getBlockState(position) if (state.block !in blocks) return@newChunkedESP @@ -94,5 +94,5 @@ object BlockESP : Module( if (drawOutlines) outline(shape, if (useBlockColor) blockColor else outlineColor, sides, outlineMode) } - private fun rebuildMesh(from: Any, to: Any): Unit = esp.rebuild() + private fun rebuildMesh(ctx: SafeContext, from: Any, to: Any): Unit = esp.rebuild() } diff --git a/src/main/kotlin/com/lambda/module/modules/render/StorageESP.kt b/src/main/kotlin/com/lambda/module/modules/render/StorageESP.kt index 60e164121..5a8ff3533 100644 --- a/src/main/kotlin/com/lambda/module/modules/render/StorageESP.kt +++ b/src/main/kotlin/com/lambda/module/modules/render/StorageESP.kt @@ -58,8 +58,8 @@ object StorageESP : Module( private val distance by setting("Distance", 64.0, 10.0..256.0, 1.0, "Maximum distance for rendering").group(Group.General) /* Render settings */ - private var drawFaces: Boolean by setting("Draw Faces", true, "Draw faces of blocks").onValueSet { _, to -> if (!to) drawEdges = true }.group(Group.Render) - private var drawEdges: Boolean by setting("Draw Edges", true, "Draw edges of blocks").onValueSet { _, to -> if (!to) drawFaces = true }.group(Group.Render) + private var drawFaces: Boolean by setting("Draw Faces", true, "Draw faces of blocks").onValueChange { _, to -> drawEdges = !to && !drawFaces }.group(Group.Render) + private var drawEdges: Boolean by setting("Draw Edges", true, "Draw edges of blocks").onValueChange { _, to -> drawFaces = !to && !drawEdges }.group(Group.Render) private val mode by setting("Outline Mode", DirectionMask.OutlineMode.AND, "Outline mode").group(Group.Render) private val mesh by setting("Mesh", true, "Connect similar adjacent blocks").group(Group.Render) diff --git a/src/main/kotlin/com/lambda/threading/Threading.kt b/src/main/kotlin/com/lambda/threading/Threading.kt index 08dfab0a2..b08659907 100644 --- a/src/main/kotlin/com/lambda/threading/Threading.kt +++ b/src/main/kotlin/com/lambda/threading/Threading.kt @@ -97,8 +97,9 @@ inline fun runSafeConcurrent(crossinline block: suspend SafeContext.() -> Unit) * * @param block The task to be executed on the game's main thread. */ -inline fun recordRenderCall(crossinline block: () -> Unit) = +inline fun recordRenderCall(crossinline block: () -> Unit) { mc.renderTaskQueue.add { block() } +} /** * Executes a given task on the game's main thread. From 8d3b8778c1d81960d2fc66b57aaaf1156212f1ee Mon Sep 17 00:00:00 2001 From: Edouard127 <46357922+Edouard127@users.noreply.github.com> Date: Sat, 23 Aug 2025 18:18:59 -0400 Subject: [PATCH 5/9] removed neighbor notify --- .../kotlin/com/lambda/graphics/renderer/esp/ChunkedESP.kt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/kotlin/com/lambda/graphics/renderer/esp/ChunkedESP.kt b/src/main/kotlin/com/lambda/graphics/renderer/esp/ChunkedESP.kt index 1b0859c52..2e284e8fc 100644 --- a/src/main/kotlin/com/lambda/graphics/renderer/esp/ChunkedESP.kt +++ b/src/main/kotlin/com/lambda/graphics/renderer/esp/ChunkedESP.kt @@ -52,11 +52,11 @@ class ChunkedESP private constructor( } init { - listen { world.getWorldChunk(it.pos).renderer.notifyChunks() } + //listen { rebuildQueue.add(rendererMap[ChunkPos.toLong(it.pos)] ?: return@listen) } listen { it.chunk.renderer.notifyChunks() } listen { rendererMap.remove(it.chunk.pos.toLong())?.notifyChunks() } - listenConcurrently { + listenConcurrently { if (++ticks % StyleEditor.updateFrequency == 0) { val polls = minOf(StyleEditor.rebuildsPerTick, rebuildQueue.size) From 1be7135fb7617dfdc5aed07236cf804f8e62e5af Mon Sep 17 00:00:00 2001 From: Edouard127 <46357922+Edouard127@users.noreply.github.com> Date: Sat, 23 Aug 2025 18:26:54 -0400 Subject: [PATCH 6/9] Fixed concurrent vertices access --- src/main/kotlin/com/lambda/graphics/pipeline/VertexBuilder.kt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/kotlin/com/lambda/graphics/pipeline/VertexBuilder.kt b/src/main/kotlin/com/lambda/graphics/pipeline/VertexBuilder.kt index aa4716035..e3346dca1 100644 --- a/src/main/kotlin/com/lambda/graphics/pipeline/VertexBuilder.kt +++ b/src/main/kotlin/com/lambda/graphics/pipeline/VertexBuilder.kt @@ -29,8 +29,8 @@ import org.joml.Vector4d class VertexBuilder( private val direct: VertexPipeline? = null ) { - val vertices by lazy { mutableListOf() } - val indices by lazy { mutableListOf() } + val vertices by lazy(LazyThreadSafetyMode.PUBLICATION) { mutableListOf() } + val indices by lazy(LazyThreadSafetyMode.PUBLICATION) { mutableListOf() } private var verticesCounter = 0 From 6d09bdaa81aadb6e90eab41f94e95c3fc5e6d92f Mon Sep 17 00:00:00 2001 From: Edouard127 <46357922+Edouard127@users.noreply.github.com> Date: Sat, 23 Aug 2025 19:02:09 -0400 Subject: [PATCH 7/9] Faster memory compare --- .../graphics/buffer/DynamicByteBuffer.kt | 11 +++++-- .../graphics/pipeline/PersistentBuffer.kt | 30 +------------------ 2 files changed, 10 insertions(+), 31 deletions(-) diff --git a/src/main/kotlin/com/lambda/graphics/buffer/DynamicByteBuffer.kt b/src/main/kotlin/com/lambda/graphics/buffer/DynamicByteBuffer.kt index 02ec17360..9ee396552 100644 --- a/src/main/kotlin/com/lambda/graphics/buffer/DynamicByteBuffer.kt +++ b/src/main/kotlin/com/lambda/graphics/buffer/DynamicByteBuffer.kt @@ -150,8 +150,8 @@ class DynamicByteBuffer private constructor(initialCapacity: Int) { val offset = position - pointer memCopy(pointer, newPointer, offset) - data = newBuffer + data = newBuffer pointer = newPointer position = newPointer + offset capacity = newCapacity @@ -176,6 +176,13 @@ class DynamicByteBuffer private constructor(initialCapacity: Int) { capacity = newCapacity } + /** + * Returns the relative index of the first mismatch between this and the given buffer, otherwise -1 if no mismatch. + * + * @see [ByteBuffer.mismatch] + */ + fun mismatch(other: DynamicByteBuffer) = data.mismatch(other.data) + companion object { /** * Creates a new DynamicByteBuffer with specified initial capacity @@ -184,4 +191,4 @@ class DynamicByteBuffer private constructor(initialCapacity: Int) { fun dynamicByteBuffer(initialCapacity: Int) = DynamicByteBuffer(initialCapacity) } -} \ No newline at end of file +} diff --git a/src/main/kotlin/com/lambda/graphics/pipeline/PersistentBuffer.kt b/src/main/kotlin/com/lambda/graphics/pipeline/PersistentBuffer.kt index 351e6ee0a..44ce5014e 100644 --- a/src/main/kotlin/com/lambda/graphics/pipeline/PersistentBuffer.kt +++ b/src/main/kotlin/com/lambda/graphics/pipeline/PersistentBuffer.kt @@ -18,10 +18,8 @@ package com.lambda.graphics.pipeline import com.lambda.graphics.buffer.Buffer.Companion.createPipelineBuffer -import com.lambda.graphics.buffer.DynamicByteBuffer import com.lambda.graphics.buffer.DynamicByteBuffer.Companion.dynamicByteBuffer import com.lambda.graphics.gl.kibibyte -import org.lwjgl.system.MemoryUtil import org.lwjgl.system.MemoryUtil.memCopy /** @@ -64,7 +62,7 @@ class PersistentBuffer( } if (snapshotData > 0 && snapshot.capacity >= byteBuffer.bytesPut) { - if (memcmp(snapshot, byteBuffer, uploadOffset, dataCount)) return + if (snapshot.mismatch(byteBuffer) >= 0) return } glBuffer.update(uploadOffset, dataCount, dataStart) @@ -90,30 +88,4 @@ class PersistentBuffer( } fun use(block: () -> Unit) = glBuffer.bind { block() } - - private fun memcmp(a: DynamicByteBuffer, b: DynamicByteBuffer, position: Long, size: Long): Boolean { - if (a.capacity != b.capacity) return false - - val end = position + size - var head = position - - // Process the aligned bytes in chunks of 8 until we've reached the end - while (head + 8 <= end) { - val first = MemoryUtil.memGetLong(a.pointer + head) - val second = MemoryUtil.memGetLong(b.pointer + head) - if (first != second) return false - - head += 8 - } - - while (head < end) { - val first = MemoryUtil.memGetByte(a.pointer + head) - val second = MemoryUtil.memGetByte(b.pointer + head) - if (first != second) return false - - head++ - } - - return true - } } From 5c60e438dcb68da5fb000e711c1e43fd2b6be075 Mon Sep 17 00:00:00 2001 From: Edouard127 <46357922+Edouard127@users.noreply.github.com> Date: Sun, 7 Sep 2025 15:32:35 -0400 Subject: [PATCH 8/9] Reworked the Drawable --- .../lambda/graphics/renderer/esp/ShapeDsl.kt | 64 +++++++++++++------ .../construction/context/BreakContext.kt | 9 ++- .../context/InteractionContext.kt | 13 ++-- .../construction/context/PlaceContext.kt | 7 +- .../construction/result/BreakResult.kt | 25 ++++---- .../construction/result/BuildResult.kt | 48 ++++++-------- .../construction/result/Drawable.kt | 45 +------------ .../construction/result/InteractResult.kt | 5 +- .../construction/result/PlaceResult.kt | 7 +- .../construction/simulation/Simulation.kt | 5 +- .../module/modules/client/TaskFlowModule.kt | 5 +- 11 files changed, 104 insertions(+), 129 deletions(-) diff --git a/src/main/kotlin/com/lambda/graphics/renderer/esp/ShapeDsl.kt b/src/main/kotlin/com/lambda/graphics/renderer/esp/ShapeDsl.kt index 6fecca9ce..a47e154ec 100644 --- a/src/main/kotlin/com/lambda/graphics/renderer/esp/ShapeDsl.kt +++ b/src/main/kotlin/com/lambda/graphics/renderer/esp/ShapeDsl.kt @@ -17,9 +17,9 @@ package com.lambda.graphics.renderer.esp -import com.lambda.context.SafeContext import com.lambda.graphics.pipeline.VertexBuilder import com.lambda.graphics.renderer.esp.DirectionMask.hasDirection +import com.lambda.threading.runSafe import com.lambda.util.BlockUtils.blockState import com.lambda.util.extension.max import com.lambda.util.extension.min @@ -98,33 +98,33 @@ class ShapeBuilder( } @ShapeDsl - fun SafeContext.filled( + fun filled( pos : BlockPos, state : BlockState, color : Color, sides : Int = DirectionMask.ALL, - ) = faces.apply { + ) = runSafe { faces.apply { val shape = state.getOutlineShape(world, pos) filled(shape, color, sides) - } + } } @ShapeDsl - fun SafeContext.filled( + fun filled( pos : BlockPos, color : Color, sides : Int = DirectionMask.ALL, - ) = faces.apply { + ) = runSafe { faces.apply { val shape = blockState(pos).getOutlineShape(world, pos) filled(shape, color, sides) - } + } } @ShapeDsl - fun SafeContext.filled( + fun filled( pos : BlockPos, entity : BlockEntity, color : Color, sides : Int = DirectionMask.ALL, - ) { + ) = runSafe { val shape = outlineShape(entity.cachedState, pos) filled(shape, color, sides) } @@ -236,36 +236,36 @@ class ShapeBuilder( } @ShapeDsl - fun SafeContext.outline( + fun outline( pos : BlockPos, state : BlockState, color : Color, sides : Int = DirectionMask.ALL, mode : DirectionMask.OutlineMode = DirectionMask.OutlineMode.OR, - ) { + ) = runSafe { val shape = state.getOutlineShape(world, pos) outline(shape, color, sides, mode) } @ShapeDsl - fun SafeContext.outline( + fun outline( pos : BlockPos, color : Color, sides : Int = DirectionMask.ALL, mode : DirectionMask.OutlineMode = DirectionMask.OutlineMode.OR, - ) { + ) = runSafe { val shape = blockState(pos).getOutlineShape(world, pos) outline(shape, color, sides, mode) } @ShapeDsl - fun SafeContext.outline( + fun outline( pos : BlockPos, entity : BlockEntity, color : Color, sides : Int = DirectionMask.ALL, mode : DirectionMask.OutlineMode = DirectionMask.OutlineMode.OR, - ) { + ) = runSafe { val shape = outlineShape(entity.cachedState, pos) outline(shape, color, sides, mode) } @@ -291,6 +291,32 @@ class ShapeBuilder( outline(box, color, color, sides, mode) } + @ShapeDsl + fun box( + pos : BlockPos, + state : BlockState, + filled : Color, + outline : Color, + sides : Int = DirectionMask.ALL, + mode : DirectionMask.OutlineMode = DirectionMask.OutlineMode.OR, + ) = runSafe { + val shape = state.getOutlineShape(world, pos) + filled(shape, filled, sides) + outline(shape, outline, sides, mode) + } + + @ShapeDsl + fun box( + pos : BlockPos, + filled : Color, + outline : Color, + sides : Int = DirectionMask.ALL, + mode : DirectionMask.OutlineMode = DirectionMask.OutlineMode.OR, + ) = runSafe { + filled(pos, filled, sides) + outline(pos, outline, sides, mode) + } + @ShapeDsl fun box( box : DynamicAABB, @@ -316,23 +342,23 @@ class ShapeBuilder( } @ShapeDsl - fun SafeContext.box( + fun box( entity : BlockEntity, color : Color, sides : Int = DirectionMask.ALL, mode : DirectionMask.OutlineMode = DirectionMask.OutlineMode.OR, - ) { + ) = runSafe { filled(entity.pos, entity, color, sides) outline(entity.pos, entity, color, sides, mode) } @ShapeDsl - fun SafeContext.box( + fun box( entity : Entity, color : Color, sides : Int = DirectionMask.ALL, mode : DirectionMask.OutlineMode = DirectionMask.OutlineMode.OR, - ) { + ) = runSafe { filled(entity.boundingBox, color, sides) outline(entity.boundingBox, color, sides, mode) } diff --git a/src/main/kotlin/com/lambda/interaction/construction/context/BreakContext.kt b/src/main/kotlin/com/lambda/interaction/construction/context/BreakContext.kt index 04cef97b8..9a449a891 100644 --- a/src/main/kotlin/com/lambda/interaction/construction/context/BreakContext.kt +++ b/src/main/kotlin/com/lambda/interaction/construction/context/BreakContext.kt @@ -17,9 +17,9 @@ package com.lambda.interaction.construction.context -import com.lambda.context.SafeContext import com.lambda.graphics.renderer.esp.DirectionMask import com.lambda.graphics.renderer.esp.DirectionMask.exclude +import com.lambda.graphics.renderer.esp.ShapeBuilder import com.lambda.interaction.material.StackSelection import com.lambda.interaction.request.breaking.BreakConfig import com.lambda.interaction.request.breaking.BreakRequest @@ -72,9 +72,8 @@ data class BreakContext( } } - override fun SafeContext.buildRenderer() { - withState(cachedState, blockPos, baseColor, DirectionMask.ALL.exclude(result.side)) - withState(cachedState, blockPos, sideColor, result.side) + override fun ShapeBuilder.buildRenderer() { + box(blockPos, cachedState, baseColor, sideColor, DirectionMask.ALL.exclude(result.side)) } fun requestSwap(breakRequest: BreakRequest, minKeepTicks: Int = 0): Boolean = @@ -83,4 +82,4 @@ data class BreakContext( breakRequest.hotbar, breakRequest.hotbar.keepTicks.coerceAtLeast(minKeepTicks) ).submit(false).done -} \ No newline at end of file +} diff --git a/src/main/kotlin/com/lambda/interaction/construction/context/InteractionContext.kt b/src/main/kotlin/com/lambda/interaction/construction/context/InteractionContext.kt index 33bcb966a..e61351a32 100644 --- a/src/main/kotlin/com/lambda/interaction/construction/context/InteractionContext.kt +++ b/src/main/kotlin/com/lambda/interaction/construction/context/InteractionContext.kt @@ -17,16 +17,14 @@ package com.lambda.interaction.construction.context -import com.lambda.context.SafeContext -import com.lambda.graphics.renderer.esp.DirectionMask -import com.lambda.graphics.renderer.esp.DirectionMask.exclude +import com.lambda.graphics.renderer.esp.DirectionMask.mask +import com.lambda.graphics.renderer.esp.ShapeBuilder import com.lambda.interaction.request.Request.Companion.submit import com.lambda.interaction.request.hotbar.HotbarManager import com.lambda.interaction.request.hotbar.HotbarRequest import com.lambda.interaction.request.interacting.InteractRequest import com.lambda.interaction.request.rotating.RotationRequest import com.lambda.util.BlockUtils -import com.lambda.util.BlockUtils.blockState import net.minecraft.block.BlockState import net.minecraft.util.hit.BlockHitResult import net.minecraft.util.math.BlockPos @@ -61,9 +59,8 @@ class InteractionContext( else -> 1 } - override fun SafeContext.buildRenderer() { - withState(expectedState, blockPos, baseColor, DirectionMask.ALL.exclude(result.side.opposite)) - withState(blockState(result.blockPos), result.blockPos, sideColor, result.side) + override fun ShapeBuilder.buildRenderer() { + box(blockPos, expectedState, baseColor, sideColor, result.side.mask) } fun requestDependencies(request: InteractRequest): Boolean { @@ -71,4 +68,4 @@ class InteractionContext( val validRotation = if (request.rotate) submit(rotation, false).done else true return hotbarRequest.done && validRotation } -} \ No newline at end of file +} diff --git a/src/main/kotlin/com/lambda/interaction/construction/context/PlaceContext.kt b/src/main/kotlin/com/lambda/interaction/construction/context/PlaceContext.kt index f25101867..76689dab2 100644 --- a/src/main/kotlin/com/lambda/interaction/construction/context/PlaceContext.kt +++ b/src/main/kotlin/com/lambda/interaction/construction/context/PlaceContext.kt @@ -21,6 +21,8 @@ import com.lambda.Lambda.mc import com.lambda.context.SafeContext import com.lambda.graphics.renderer.esp.DirectionMask import com.lambda.graphics.renderer.esp.DirectionMask.exclude +import com.lambda.graphics.renderer.esp.DirectionMask.mask +import com.lambda.graphics.renderer.esp.ShapeBuilder import com.lambda.interaction.request.Request.Companion.submit import com.lambda.interaction.request.hotbar.HotbarManager import com.lambda.interaction.request.hotbar.HotbarRequest @@ -70,9 +72,8 @@ data class PlaceContext( else -> 1 } - override fun SafeContext.buildRenderer() { - withState(expectedState, blockPos, baseColor, DirectionMask.ALL.exclude(result.side.opposite)) - withState(blockState(result.blockPos), result.blockPos, sideColor, result.side) + override fun ShapeBuilder.buildRenderer() { + box(blockPos, expectedState, baseColor, sideColor, result.side.mask) } fun requestDependencies(request: PlaceRequest): Boolean { diff --git a/src/main/kotlin/com/lambda/interaction/construction/result/BreakResult.kt b/src/main/kotlin/com/lambda/interaction/construction/result/BreakResult.kt index b6f032a47..58092620a 100644 --- a/src/main/kotlin/com/lambda/interaction/construction/result/BreakResult.kt +++ b/src/main/kotlin/com/lambda/interaction/construction/result/BreakResult.kt @@ -19,7 +19,8 @@ package com.lambda.interaction.construction.result import baritone.api.pathing.goals.GoalBlock import baritone.api.pathing.goals.GoalInverted -import com.lambda.context.SafeContext +import com.lambda.graphics.renderer.esp.DirectionMask.mask +import com.lambda.graphics.renderer.esp.ShapeBuilder import com.lambda.interaction.construction.context.BreakContext import com.lambda.interaction.material.StackSelection.Companion.selectStack import com.lambda.interaction.material.container.ContainerManager.transfer @@ -44,7 +45,7 @@ sealed class BreakResult : BuildResult() { ) : Drawable, Contextual, BreakResult() { override val rank = Rank.BREAK_SUCCESS - override fun SafeContext.buildRenderer() { + override fun ShapeBuilder.buildRenderer() { with(context) { buildRenderer() } } @@ -68,8 +69,8 @@ sealed class BreakResult : BuildResult() { override val rank = Rank.BREAK_NOT_EXPOSED private val color = Color(46, 0, 0, 30) - override fun SafeContext.buildRenderer() { - withPos(blockPos, color, side) + override fun ShapeBuilder.buildRenderer() { + box(blockPos, color, color, side.mask) } override fun compareTo(other: ComparableResult): Int { @@ -108,8 +109,8 @@ sealed class BreakResult : BuildResult() { ) } - override fun SafeContext.buildRenderer() { - withPos(blockPos, color) + override fun ShapeBuilder.buildRenderer() { + box(blockPos, color, color) } override fun compareTo(other: ComparableResult): Int { @@ -132,8 +133,8 @@ sealed class BreakResult : BuildResult() { override val rank = Rank.BREAK_SUBMERGE private val color = Color(114, 27, 255, 100) - override fun SafeContext.buildRenderer() { - withPos(blockPos, color) + override fun ShapeBuilder.buildRenderer() { + box(blockPos, color, color) } } @@ -147,8 +148,8 @@ sealed class BreakResult : BuildResult() { override val rank = Rank.BREAK_IS_BLOCKED_BY_FLUID private val color = Color(50, 12, 112, 100) - override fun SafeContext.buildRenderer() { - withPos(blockPos, color) + override fun ShapeBuilder.buildRenderer() { + box(blockPos, color, color) } } @@ -164,8 +165,8 @@ sealed class BreakResult : BuildResult() { override val goal = GoalInverted(GoalBlock(blockPos)) - override fun SafeContext.buildRenderer() { - withPos(blockPos, color) + override fun ShapeBuilder.buildRenderer() { + box(blockPos, color, color) } } } diff --git a/src/main/kotlin/com/lambda/interaction/construction/result/BuildResult.kt b/src/main/kotlin/com/lambda/interaction/construction/result/BuildResult.kt index 5e8d657f9..1712db18c 100644 --- a/src/main/kotlin/com/lambda/interaction/construction/result/BuildResult.kt +++ b/src/main/kotlin/com/lambda/interaction/construction/result/BuildResult.kt @@ -19,7 +19,7 @@ package com.lambda.interaction.construction.result import baritone.api.pathing.goals.GoalBlock import baritone.api.pathing.goals.GoalNear -import com.lambda.context.SafeContext +import com.lambda.graphics.renderer.esp.ShapeBuilder import com.lambda.interaction.construction.context.BuildContext import com.lambda.interaction.material.StackSelection import com.lambda.interaction.material.StackSelection.Companion.select @@ -27,12 +27,10 @@ import com.lambda.interaction.material.container.ContainerManager.transfer import com.lambda.interaction.material.container.MaterialContainer import com.lambda.interaction.material.container.containers.MainHandContainer import com.lambda.interaction.request.inventory.InventoryConfig -import com.lambda.util.BlockUtils.blockState import com.lambda.util.Nameable import net.minecraft.block.BlockState import net.minecraft.item.ItemStack import net.minecraft.util.math.BlockPos -import net.minecraft.util.math.Box import net.minecraft.util.math.Direction import net.minecraft.util.math.Vec3d import java.awt.Color @@ -81,8 +79,8 @@ abstract class BuildResult : ComparableResult, Nameable { override val goal = GoalBlock(blockPos) - override fun SafeContext.buildRenderer() { - withBox(Box(blockPos), color) + override fun ShapeBuilder.buildRenderer() { + box(blockPos, color, color) } override fun compareTo(other: ComparableResult): Int { @@ -104,8 +102,8 @@ abstract class BuildResult : ComparableResult, Nameable { override val rank = Rank.BREAK_RESTRICTED private val color = Color(255, 0, 0, 100) - override fun SafeContext.buildRenderer() { - withPos(blockPos, color) + override fun ShapeBuilder.buildRenderer() { + box(blockPos, color, color) } } @@ -122,8 +120,8 @@ abstract class BuildResult : ComparableResult, Nameable { override val rank get() = Rank.BREAK_NO_PERMISSION private val color = Color(255, 0, 0, 100) - override fun SafeContext.buildRenderer() { - withPos(blockPos, color) + override fun ShapeBuilder.buildRenderer() { + box(blockPos, color, color) } } @@ -138,8 +136,8 @@ abstract class BuildResult : ComparableResult, Nameable { override val rank = Rank.OUT_OF_WORLD private val color = Color(3, 148, 252, 100) - override fun SafeContext.buildRenderer() { - withPos(blockPos, color) + override fun ShapeBuilder.buildRenderer() { + box(blockPos, color, color) } } @@ -156,8 +154,8 @@ abstract class BuildResult : ComparableResult, Nameable { override val rank = Rank.UNBREAKABLE private val color = Color(11, 11, 11, 100) - override fun SafeContext.buildRenderer() { - withPos(blockPos, color) + override fun ShapeBuilder.buildRenderer() { + box(blockPos, color, color) } } @@ -176,8 +174,8 @@ abstract class BuildResult : ComparableResult, Nameable { override val rank = Rank.NOT_VISIBLE private val color = Color(46, 0, 0, 80) - override fun SafeContext.buildRenderer() { - withBox(Box(blockPos), color) + override fun ShapeBuilder.buildRenderer() { + box(blockPos, color, color) } override fun compareTo(other: ComparableResult): Int { @@ -215,12 +213,8 @@ abstract class BuildResult : ComparableResult, Nameable { ) } - override fun SafeContext.buildRenderer() { - if (blockState(blockPos).isAir) { - withBox(Box(blockPos), color) - } else { - withPos(blockPos, color) - } + override fun ShapeBuilder.buildRenderer() { + box(blockPos, color, color) } override fun compareTo(other: ComparableResult): Int { @@ -258,12 +252,8 @@ abstract class BuildResult : ComparableResult, Nameable { ) } - override fun SafeContext.buildRenderer() { - if (blockState(blockPos).isAir) { - withBox(Box(blockPos), color) - } else { - withPos(blockPos, color) - } + override fun ShapeBuilder.buildRenderer() { + box(blockPos, color, color) } override fun compareTo(other: ComparableResult): Int { @@ -295,8 +285,8 @@ abstract class BuildResult : ComparableResult, Nameable { override val goal = GoalNear(blockPos, 3) - override fun SafeContext.buildRenderer() { - withPos(blockPos, color) + override fun ShapeBuilder.buildRenderer() { + box(blockPos, color, color) } override fun compareTo(other: ComparableResult): Int { diff --git a/src/main/kotlin/com/lambda/interaction/construction/result/Drawable.kt b/src/main/kotlin/com/lambda/interaction/construction/result/Drawable.kt index 108e56200..84b71901e 100644 --- a/src/main/kotlin/com/lambda/interaction/construction/result/Drawable.kt +++ b/src/main/kotlin/com/lambda/interaction/construction/result/Drawable.kt @@ -17,49 +17,8 @@ package com.lambda.interaction.construction.result -import com.lambda.context.SafeContext -import com.lambda.graphics.renderer.esp.DirectionMask -import com.lambda.graphics.renderer.esp.DirectionMask.include -import com.lambda.util.BlockUtils.blockState -import net.minecraft.block.BlockState -import net.minecraft.util.math.BlockPos -import net.minecraft.util.math.Box -import net.minecraft.util.math.Direction -import net.minecraft.util.shape.VoxelShape -import java.awt.Color +import com.lambda.graphics.renderer.esp.ShapeBuilder interface Drawable { - fun SafeContext.buildRenderer() - - fun SafeContext.withBox(box: Box, color: Color, mask: Int = DirectionMask.ALL) { - //StaticESP.filled(box, color, mask) - //StaticESP.buildOutline(box, color, mask) - } - - fun SafeContext.withState(blockState: BlockState, blockPos: BlockPos, color: Color, side: Direction) { - withState(blockState, blockPos, color, DirectionMask.NONE.include(side)) - } - - fun SafeContext.withState(blockState: BlockState, blockPos: BlockPos, color: Color, mask: Int = DirectionMask.ALL) { - withShape(blockState.getOutlineShape(world, blockPos), blockPos, color, mask) - } - - fun SafeContext.withPos(blockPos: BlockPos, color: Color, side: Direction) { - withPos(blockPos, color, DirectionMask.NONE.include(side)) - } - - fun SafeContext.withPos(blockPos: BlockPos, color: Color, mask: Int = DirectionMask.ALL) { - val shape = blockState(blockPos).getOutlineShape(world, blockPos) - withShape(shape, blockPos, color, mask) - } - - fun SafeContext.withShape(shape: VoxelShape, offset: BlockPos, color: Color, mask: Int = DirectionMask.ALL) { - if (shape.isEmpty) { - withBox(Box(offset), color, mask) - return - } - shape.boundingBoxes.forEach { box -> - withBox(box.offset(offset), color, mask) - } - } + fun ShapeBuilder.buildRenderer() } diff --git a/src/main/kotlin/com/lambda/interaction/construction/result/InteractResult.kt b/src/main/kotlin/com/lambda/interaction/construction/result/InteractResult.kt index bbfcd5137..e70102e26 100644 --- a/src/main/kotlin/com/lambda/interaction/construction/result/InteractResult.kt +++ b/src/main/kotlin/com/lambda/interaction/construction/result/InteractResult.kt @@ -18,6 +18,7 @@ package com.lambda.interaction.construction.result import com.lambda.context.SafeContext +import com.lambda.graphics.renderer.esp.ShapeBuilder import com.lambda.interaction.construction.context.InteractionContext import net.minecraft.util.math.BlockPos @@ -28,7 +29,7 @@ sealed class InteractResult : BuildResult() { ) : Contextual, Drawable, InteractResult() { override val rank = Rank.INTERACT_SUCCESS - override fun SafeContext.buildRenderer() { + override fun ShapeBuilder.buildRenderer() { with(context) { buildRenderer() } } @@ -38,4 +39,4 @@ sealed class InteractResult : BuildResult() { else -> super.compareTo(other) } } -} \ No newline at end of file +} diff --git a/src/main/kotlin/com/lambda/interaction/construction/result/PlaceResult.kt b/src/main/kotlin/com/lambda/interaction/construction/result/PlaceResult.kt index 6b2dc65a0..067eb08e7 100644 --- a/src/main/kotlin/com/lambda/interaction/construction/result/PlaceResult.kt +++ b/src/main/kotlin/com/lambda/interaction/construction/result/PlaceResult.kt @@ -20,6 +20,7 @@ package com.lambda.interaction.construction.result import baritone.api.pathing.goals.GoalBlock import baritone.api.pathing.goals.GoalInverted import com.lambda.context.SafeContext +import com.lambda.graphics.renderer.esp.ShapeBuilder import com.lambda.interaction.construction.context.PlaceContext import com.lambda.task.tasks.BuildTask.Companion.breakBlock import net.minecraft.block.BlockState @@ -46,7 +47,7 @@ sealed class PlaceResult : BuildResult() { ) : Contextual, Drawable, PlaceResult() { override val rank = Rank.PLACE_SUCCESS - override fun SafeContext.buildRenderer() { + override fun ShapeBuilder.buildRenderer() { with(context) { buildRenderer() } } @@ -77,8 +78,8 @@ sealed class PlaceResult : BuildResult() { override val rank = Rank.PLACE_NO_INTEGRITY private val color = Color(252, 3, 3, 100) - override fun SafeContext.buildRenderer() { - withState(expected, blockPos, color) + override fun ShapeBuilder.buildRenderer() { + box(blockPos, expected, color, color) } } diff --git a/src/main/kotlin/com/lambda/interaction/construction/simulation/Simulation.kt b/src/main/kotlin/com/lambda/interaction/construction/simulation/Simulation.kt index 6e8b1c1fc..5bf40b099 100644 --- a/src/main/kotlin/com/lambda/interaction/construction/simulation/Simulation.kt +++ b/src/main/kotlin/com/lambda/interaction/construction/simulation/Simulation.kt @@ -20,6 +20,7 @@ package com.lambda.interaction.construction.simulation import com.lambda.config.groups.BuildConfig import com.lambda.config.groups.InteractionConfig import com.lambda.context.SafeContext +import com.lambda.graphics.renderer.esp.ShapeBuilder import com.lambda.interaction.construction.blueprint.Blueprint import com.lambda.interaction.construction.result.BuildResult import com.lambda.interaction.construction.result.Drawable @@ -71,8 +72,8 @@ data class Simulation( .map { PossiblePos(it.key.toBlockPos(), it.value.count { it.rank.ordinal < 4 }) } class PossiblePos(val pos: BlockPos, val interactions: Int) : Drawable { - override fun SafeContext.buildRenderer() { - withBox(Vec3d.ofBottomCenter(pos).playerBox(), Color(0, 255, 0, 50)) + override fun ShapeBuilder.buildRenderer() { + box(Vec3d.ofBottomCenter(pos).playerBox(), Color(0, 255, 0, 50), Color(0, 255, 0, 50)) } } diff --git a/src/main/kotlin/com/lambda/module/modules/client/TaskFlowModule.kt b/src/main/kotlin/com/lambda/module/modules/client/TaskFlowModule.kt index ed7f9287f..944b343fe 100644 --- a/src/main/kotlin/com/lambda/module/modules/client/TaskFlowModule.kt +++ b/src/main/kotlin/com/lambda/module/modules/client/TaskFlowModule.kt @@ -22,9 +22,8 @@ import com.lambda.config.groups.HotbarSettings import com.lambda.config.groups.InteractionSettings import com.lambda.config.groups.InventorySettings import com.lambda.config.groups.RotationSettings -import com.lambda.event.events.RenderEvent import com.lambda.event.events.onStaticRender -import com.lambda.event.listener.SafeListener.Companion.listen +import com.lambda.interaction.construction.result.BuildResult import com.lambda.interaction.construction.result.Drawable import com.lambda.module.Module import com.lambda.module.tag.ModuleTag @@ -60,7 +59,7 @@ object TaskFlowModule : Module( init { onStaticRender { - drawables.forEach { with(it) { buildRenderer() } } + with(it) { drawables.forEach { with(it) { buildRenderer() } } } } } } From 26f379db4b1b80f3ac6e053f725f03f172f8ce1a Mon Sep 17 00:00:00 2001 From: Edouard127 <46357922+Edouard127@users.noreply.github.com> Date: Sun, 7 Sep 2025 15:40:00 -0400 Subject: [PATCH 9/9] Update BreakManager.kt --- .../interaction/request/breaking/BreakManager.kt | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/src/main/kotlin/com/lambda/interaction/request/breaking/BreakManager.kt b/src/main/kotlin/com/lambda/interaction/request/breaking/BreakManager.kt index 7fbdc5699..b57f8ebb3 100644 --- a/src/main/kotlin/com/lambda/interaction/request/breaking/BreakManager.kt +++ b/src/main/kotlin/com/lambda/interaction/request/breaking/BreakManager.kt @@ -22,15 +22,13 @@ import com.lambda.event.Event import com.lambda.event.EventFlow.post import com.lambda.event.events.ConnectionEvent import com.lambda.event.events.EntityEvent -import com.lambda.event.events.RenderEvent import com.lambda.event.events.TickEvent import com.lambda.event.events.UpdateManagerEvent import com.lambda.event.events.WorldEvent +import com.lambda.event.events.onStaticRender import com.lambda.event.listener.SafeListener.Companion.listen import com.lambda.event.listener.UnsafeListener.Companion.listenUnsafe import com.lambda.graphics.renderer.esp.DynamicAABB -import com.lambda.graphics.renderer.esp.builders.buildFilled -import com.lambda.graphics.renderer.esp.builders.buildOutline import com.lambda.interaction.construction.blueprint.Blueprint.Companion.toStructure import com.lambda.interaction.construction.blueprint.StaticBlueprint.Companion.toBlueprint import com.lambda.interaction.construction.context.BreakContext @@ -217,16 +215,16 @@ object BreakManager : RequestHandler( ?.internalOnItemDrop(it.entity) } - listen { event -> + onStaticRender { val activeStack = breakInfos .filterNotNull() - .firstOrNull()?.swapStack ?: return@listen + .firstOrNull()?.swapStack ?: return@onStaticRender breakInfos .filterNotNull() .forEach { info -> val config = info.breakConfig - if (!config.renders) return@listen + if (!config.renders) return@onStaticRender val swapMode = info.breakConfig.swapMode val breakDelta = info.context.cachedState.calcBreakDelta( player, @@ -265,8 +263,8 @@ object BreakManager : RequestHandler( val dynamicAABB = DynamicAABB() dynamicAABB.update(interpolatedNow) dynamicAABB.update(interpolatedNext) - if (config.fill) event.renderer.buildFilled(dynamicAABB, fillColor) - if (config.outline) event.renderer.buildOutline(dynamicAABB, outlineColor) + if (config.fill) it.filled(dynamicAABB, fillColor) + if (config.outline) it.outline(dynamicAABB, outlineColor) } } }