Skip to content

Commit 20e4777

Browse files
committed
Smol refactors
1 parent d75461c commit 20e4777

File tree

11 files changed

+154
-113
lines changed

11 files changed

+154
-113
lines changed

common/src/main/kotlin/com/lambda/Lambda.kt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,10 @@ import com.lambda.core.Loader
1010
import com.lambda.gui.impl.clickgui.windows.tag.CustomModuleWindow
1111
import com.lambda.gui.impl.clickgui.windows.tag.TagWindow
1212
import com.lambda.module.tag.ModuleTag
13+
import com.lambda.threading.runGameScheduled
1314
import com.lambda.util.KeyCode
1415
import com.mojang.authlib.GameProfile
16+
import com.mojang.blaze3d.systems.RenderSystem.recordRenderCall
1517
import net.minecraft.block.Block
1618
import net.minecraft.client.MinecraftClient
1719
import net.minecraft.util.math.BlockPos

common/src/main/kotlin/com/lambda/config/Configuration.kt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,7 @@ abstract class Configuration : Jsonable {
131131
}
132132
.onFailure {
133133
val message = "Failed to save ${configName.capitalize()} config"
134+
LOG.error(message, it)
134135
logError(message)
135136
}
136137
}

common/src/main/kotlin/com/lambda/event/EventFlow.kt

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -159,9 +159,7 @@ object EventFlow {
159159
private fun Event.executeListenerConcurrently() {
160160
concurrentListeners[this::class]?.forEach { listener ->
161161
if (shouldNotNotify(listener, this)) return@forEach
162-
runConcurrent {
163-
listener.execute(this)
164-
}
162+
listener.execute(this)
165163
}
166164
}
167165

common/src/main/kotlin/com/lambda/event/listener/SafeListener.kt

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import com.lambda.event.Event
55
import com.lambda.event.EventFlow
66
import com.lambda.event.Muteable
77
import com.lambda.task.Task
8+
import com.lambda.threading.runConcurrent
89
import com.lambda.threading.runSafe
910

1011

@@ -162,10 +163,12 @@ class SafeListener(
162163
inline fun <reified T : Event> Any.concurrentListener(
163164
priority: Int = 0,
164165
alwaysListen: Boolean = false,
165-
noinline function: SafeContext.(T) -> Unit,
166+
noinline function: suspend SafeContext.(T) -> Unit,
166167
): SafeListener {
167168
val listener = SafeListener(priority, this, alwaysListen) { event ->
168-
function(event as T)
169+
runConcurrent {
170+
function(event as T)
171+
}
169172
}
170173

171174
EventFlow.concurrentListeners.subscribe<T>(listener)

common/src/main/kotlin/com/lambda/graphics/buffer/vao/VAO.kt

Lines changed: 31 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -21,15 +21,15 @@ import com.lambda.graphics.gl.VaoUtils.unbindIndexBuffer
2121
import com.lambda.graphics.gl.VaoUtils.unbindVertexArray
2222
import com.lambda.graphics.gl.VaoUtils.unbindVertexBuffer
2323
import com.lambda.threading.runGameScheduled
24-
import com.mojang.blaze3d.systems.RenderSystem.drawElements
2524
import org.lwjgl.opengl.GL30C.*
2625
import java.awt.Color
2726
import java.nio.ByteBuffer
2827

2928
class VAO(
3029
private val vertexMode: VertexMode,
3130
attribGroup: VertexAttrib.Group,
32-
private val bufferUsage: BufferUsage = BufferUsage.DYNAMIC
31+
private val bufferUsage: BufferUsage = BufferUsage.DYNAMIC,
32+
initializeInstantly: Boolean = false
3333
) : IRenderContext {
3434
private var vao = 0
3535
private var vbo = 0
@@ -52,34 +52,42 @@ class VAO(
5252
val stride = attribGroup.stride
5353
objectSize = stride * vertexMode.indicesCount
5454

55-
runGameScheduled {
56-
vertices = byteBuffer(objectSize * 256 * 4)
57-
verticesPointer = address(vertices)
58-
verticesPosition = verticesPointer
55+
if (initializeInstantly) {
56+
initialize(attribGroup, stride)
57+
} else {
58+
runGameScheduled {
59+
initialize(attribGroup, stride)
60+
}
61+
}
62+
}
5963

60-
indices = byteBuffer(vertexMode.indicesCount * 512 * 4)
61-
indicesPointer = address(indices)
64+
private fun initialize(attribGroup: VertexAttrib.Group, stride: Int) {
65+
vertices = byteBuffer(objectSize * 256 * 4)
66+
verticesPointer = address(vertices)
67+
verticesPosition = verticesPointer
6268

63-
vao = glGenVertexArrays()
64-
bindVertexArray(vao)
69+
indices = byteBuffer(vertexMode.indicesCount * 512 * 4)
70+
indicesPointer = address(indices)
6571

66-
vbo = glGenBuffers()
67-
bindVertexBuffer(vbo)
72+
vao = glGenVertexArrays()
73+
bindVertexArray(vao)
6874

69-
ibo = glGenBuffers()
70-
bindIndexBuffer(ibo)
75+
vbo = glGenBuffers()
76+
bindVertexBuffer(vbo)
7177

72-
var pointer = 0L
73-
attribGroup.attributes.forEachIndexed { index, attrib ->
74-
VaoUtils.enableVertexAttribute(index)
75-
VaoUtils.vertexAttribute(index, attrib.componentCount, attrib.gl, attrib.normalized, stride, pointer)
76-
pointer += attrib.size
77-
}
78+
ibo = glGenBuffers()
79+
bindIndexBuffer(ibo)
7880

79-
unbindVertexArray()
80-
unbindVertexBuffer()
81-
unbindIndexBuffer()
81+
var pointer = 0L
82+
attribGroup.attributes.forEachIndexed { index, attrib ->
83+
VaoUtils.enableVertexAttribute(index)
84+
VaoUtils.vertexAttribute(index, attrib.componentCount, attrib.gl, attrib.normalized, stride, pointer)
85+
pointer += attrib.size
8286
}
87+
88+
unbindVertexArray()
89+
unbindVertexBuffer()
90+
unbindIndexBuffer()
8391
}
8492

8593
override fun vec3(x: Double, y: Double, z: Double): VAO {

common/src/main/kotlin/com/lambda/graphics/renderer/esp/ChunkedESP.kt

Lines changed: 67 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -1,75 +1,82 @@
11
package com.lambda.graphics.renderer.esp
22

3-
import com.lambda.event.Muteable
43
import com.lambda.event.events.RenderEvent
54
import com.lambda.event.events.TickEvent
65
import com.lambda.event.events.WorldEvent
6+
import com.lambda.event.listener.SafeListener.Companion.concurrentListener
77
import com.lambda.event.listener.SafeListener.Companion.listener
88
import com.lambda.graphics.renderer.esp.DirectionMask.exclude
99
import com.lambda.graphics.renderer.esp.DirectionMask.mask
1010
import com.lambda.module.modules.client.RenderSettings
11+
import com.lambda.threading.runGameBlocking
1112
import com.mojang.blaze3d.systems.RenderSystem.recordRenderCall
1213
import kotlinx.coroutines.*
1314
import net.minecraft.util.math.BlockPos
1415
import net.minecraft.util.math.Box
16+
import net.minecraft.util.math.ChunkPos
1517
import net.minecraft.util.math.Direction
1618
import net.minecraft.world.BlockView
1719
import net.minecraft.world.chunk.WorldChunk
1820
import java.awt.Color
1921
import java.util.concurrent.ConcurrentHashMap
2022
import java.util.concurrent.ConcurrentLinkedDeque
21-
import java.util.concurrent.Executors.newSingleThreadExecutor
2223

2324
class ChunkedESP private constructor(
24-
private val owner: Any,
25+
owner: Any,
2526
private val filter: (BlockView, BlockPos) -> Boolean,
2627
private val painter: (BlockView, BlockPos) -> Pair<Color, Color>
2728
) {
28-
private val rendererMap = ConcurrentHashMap<WorldChunk, EspChunk>()
29-
private val WorldChunk.renderer get() = rendererMap.getOrPut(this) {
29+
private val rendererMap = ConcurrentHashMap<ChunkPos, EspChunk>()
30+
private val WorldChunk.renderer get() = rendererMap.getOrPut(pos) {
3031
EspChunk(this, this@ChunkedESP)
3132
}
33+
private var ticks = 0
3234

3335
private val uploadPool = ConcurrentLinkedDeque<() -> Unit>()
36+
private val rebuildPool = ConcurrentLinkedDeque<() -> Unit>()
37+
38+
fun clear() {
39+
rendererMap.clear()
40+
}
3441

3542
init {
36-
listener<WorldEvent.BlockUpdate> { event ->
43+
owner.concurrentListener<WorldEvent.BlockUpdate> { event ->
3744
world.getWorldChunk(event.pos).renderer.apply {
38-
update = true
39-
updateNeighbors()
45+
markOutdated()
46+
notifyNeighbors()
4047
}
4148
}
4249

43-
listener<WorldEvent.ChunkEvent.Load> { event ->
44-
event.chunk.renderer.updateNeighbors()
50+
owner.concurrentListener<WorldEvent.ChunkEvent.Load> { event ->
51+
event.chunk.renderer.notifyNeighbors()
4552
}
4653

47-
listener<WorldEvent.ChunkEvent.Unload> { event ->
48-
rendererMap.remove(event.chunk)?.updateNeighbors()
54+
owner.concurrentListener<WorldEvent.ChunkEvent.Unload> { event ->
55+
rendererMap.remove(event.chunk.pos)?.notifyNeighbors()
4956
}
5057

51-
owner.listener<TickEvent.Pre> {
52-
repeat(RenderSettings.chunksPerTick) {
53-
uploadPool.poll()?.invoke()
58+
owner.concurrentListener<TickEvent.Pre> {
59+
if (++ticks % RenderSettings.updateFrequency == 0) {
60+
rendererMap.values
61+
.filter { it.outdated && it.neighborsLoaded }
62+
.forEach { it.rebuild() }
63+
ticks = 0
5464
}
5565
}
5666

67+
owner.listener<TickEvent.Pre> {
68+
if (uploadPool.isEmpty()) return@listener
69+
70+
uploadPool
71+
.take(RenderSettings.uploadsPerTick)
72+
.forEach { it() }
73+
}
74+
5775
owner.listener<RenderEvent.World> {
5876
rendererMap.values.forEach {
5977
it.renderer?.render()
6078
}
6179
}
62-
63-
CoroutineScope(newSingleThreadExecutor().asCoroutineDispatcher()).launch {
64-
while (true) {
65-
delay(100)
66-
67-
if ((owner as? Muteable)?.isMuted == true) continue
68-
rendererMap.values.forEach {
69-
it.tick()
70-
}
71-
}
72-
}
7380
}
7481

7582
companion object {
@@ -80,59 +87,52 @@ class ChunkedESP private constructor(
8087
}
8188

8289
private class EspChunk(val chunk: WorldChunk, val owner: ChunkedESP) {
83-
private val scope = CoroutineScope(newSingleThreadExecutor().asCoroutineDispatcher())
84-
8590
var renderer: EspRenderer? = null
91+
var outdated = true
8692

87-
var update = true
8893
private val chunkOffsets = listOf(1 to 0, 0 to 1, -1 to 0, 0 to -1)
94+
val neighbors = chunkOffsets.map {
95+
ChunkPos(chunk.pos.x + it.first, chunk.pos.z + it.second)
96+
}.toTypedArray()
97+
val neighborsLoaded get() = neighbors.all { it.isLoaded() }
8998

90-
fun updateNeighbors() {
91-
scope.launch {
92-
chunkOffsets.forEach { ofs ->
93-
chunk.world.chunkManager.getWorldChunk(
94-
chunk.pos.x + ofs.first,
95-
chunk.pos.z + ofs.second
96-
)?.let {
97-
owner.rendererMap[it]?.update = true
98-
}
99-
}
100-
}
101-
}
99+
fun ChunkPos.isLoaded() = chunk.world.chunkManager.isChunkLoaded(x, z)
102100

103-
fun tick() {
104-
if (!update) return
101+
fun markOutdated() {
102+
outdated = true
103+
}
105104

106-
// Chunk could only be drawn when all neighbors are loaded
107-
if (chunkOffsets.count {
108-
chunk.world.isChunkLoaded(
109-
chunk.pos.x + it.first,
110-
chunk.pos.z + it.second
111-
)
112-
} < 4) return
105+
fun notifyNeighbors() {
106+
neighbors.forEach {
107+
owner.rendererMap[it]?.markOutdated()
108+
}
109+
}
113110

114-
update = false
111+
suspend fun rebuild() {
112+
outdated = false
115113

116-
scope.launch {
117-
val newRenderer = runOnMainThreadAndWait(::EspRenderer)
114+
val newRenderer = runGameBlocking {
115+
EspRenderer()
116+
}
118117

119-
iterateChunk { x, y, z ->
120-
checkAndDraw(newRenderer, BlockPos(x, y, z))
121-
}
118+
iterateChunk { x, y, z ->
119+
checkAndDraw(newRenderer, BlockPos(x, y, z))
120+
}
122121

123-
val upload = {
124-
newRenderer.upload()
125-
renderer = newRenderer
126-
}
122+
val upload = {
123+
newRenderer.upload()
124+
renderer = newRenderer
125+
}
127126

128-
when (RenderSettings.uploadScheduler) {
129-
RenderSettings.UploadScheduler.Instant -> {
130-
runOnMainThreadAndWait(upload)
131-
}
132-
RenderSettings.UploadScheduler.Delayed -> {
133-
owner.uploadPool.add(upload)
127+
when (RenderSettings.uploadScheduler) {
128+
RenderSettings.UploadScheduler.Instant -> {
129+
runGameBlocking {
130+
upload()
134131
}
135132
}
133+
RenderSettings.UploadScheduler.Delayed -> {
134+
owner.uploadPool.add(upload)
135+
}
136136
}
137137
}
138138

@@ -145,7 +145,7 @@ class ChunkedESP private constructor(
145145

146146
while (result == null) delay(1)
147147
return result as R
148-
}
148+
}
149149

150150
private fun checkAndDraw(renderer: EspRenderer, blockPos: BlockPos): Boolean {
151151
if (!owner.filter(chunk, blockPos)) return false

common/src/main/kotlin/com/lambda/graphics/renderer/esp/EspRenderer.kt

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -23,18 +23,18 @@ import net.minecraft.util.math.Box
2323
import java.awt.Color
2424
import java.util.concurrent.ConcurrentHashMap
2525

26-
class EspRenderer(usage: BufferUsage = BufferUsage.STATIC) {
27-
private val filled = VAO(VertexMode.TRIANGLES, VertexAttrib.Group.STATIC_RENDERER, usage)
26+
class EspRenderer(
27+
usage: BufferUsage = BufferUsage.STATIC
28+
) {
29+
private val filled = VAO(VertexMode.TRIANGLES, VertexAttrib.Group.STATIC_RENDERER, usage, true)
2830
private val filledVertices = ConcurrentHashMap<Vertex, Int>()
2931

30-
private val outline = VAO(VertexMode.LINES, VertexAttrib.Group.STATIC_RENDERER, usage)
32+
private val outline = VAO(VertexMode.LINES, VertexAttrib.Group.STATIC_RENDERER, usage, true)
3133
private val outlineVertices = ConcurrentHashMap<Vertex, Int>()
3234

3335
private var updateFilled = false
3436
private var updateOutline = false
3537

36-
var outlineWidth = 1.0
37-
3838
fun build(box: Box, filledColor: Color, outlineColor: Color, sides: Int = DirectionMask.ALL, outlineMode: DirectionMask.OutlineMode = DirectionMask.OutlineMode.OR) {
3939
buildFilled(box, filledColor, sides)
4040
buildOutline(box, outlineColor, sides, outlineMode)
@@ -120,7 +120,7 @@ class EspRenderer(usage: BufferUsage = BufferUsage.STATIC) {
120120
shader["u_CameraPosition"] = mc.gameRenderer.camera.pos
121121

122122
withFaceCulling(filled::render)
123-
withLineWidth(outlineWidth, outline::render)
123+
withLineWidth(RenderSettings.outlineWidth, outline::render)
124124
}
125125

126126
fun clear() {

common/src/main/kotlin/com/lambda/module/modules/client/RenderSettings.kt

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,10 @@ object RenderSettings : Module(
2020

2121
// ESP
2222
val uploadScheduler by setting("Upload Scheduler", UploadScheduler.Instant) { page == Page.ESP }
23-
val chunksPerTick by setting("Chunks", 8, 1..32, 1, unit = " / tick") { page == Page.ESP && uploadScheduler == UploadScheduler.Delayed }
23+
val uploadsPerTick by setting("Uploads", 8, 1..32, 1, unit = " chunk/tick") { page == Page.ESP && uploadScheduler == UploadScheduler.Delayed }
2424
val vertexMapping by setting("Vertex Mapping", true) { page == Page.ESP }
25+
val updateFrequency by setting("Update Frequency", 2, 1..10, 1, "Frequency of block updates", unit = " ticks") { page == Page.ESP }
26+
val outlineWidth by setting("Outline Width", 1.0, 0.1..5.0, 0.1, "Width of block outlines", unit = "px") { page == Page.ESP }
2527

2628
val lodBias get() = lodBiasSetting * 0.25f - 0.75f
2729

0 commit comments

Comments
 (0)