@@ -16,13 +16,15 @@ import com.lambda.client.util.graphics.ESPRenderer
16
16
import com.lambda.client.util.graphics.GeometryMasks
17
17
import com.lambda.client.util.graphics.LambdaTessellator
18
18
import com.lambda.client.util.graphics.ShaderHelper
19
- import com.lambda.client.util.math.VectorUtils.distanceTo
19
+ import com.lambda.client.util.items.id
20
+ import com.lambda.client.util.math.VectorUtils.manhattanDistanceTo
20
21
import com.lambda.client.util.text.MessageSendHelper
21
22
import com.lambda.client.util.text.formatValue
22
23
import com.lambda.client.util.threads.defaultScope
23
24
import com.lambda.client.util.threads.runSafe
24
25
import com.lambda.client.util.threads.safeListener
25
26
import com.lambda.client.util.world.isWater
27
+ import it.unimi.dsi.fastutil.ints.IntOpenHashSet
26
28
import kotlinx.coroutines.Job
27
29
import kotlinx.coroutines.isActive
28
30
import kotlinx.coroutines.launch
@@ -38,11 +40,13 @@ import net.minecraft.init.Blocks
38
40
import net.minecraft.network.play.server.SPacketBlockChange
39
41
import net.minecraft.network.play.server.SPacketMultiBlockChange
40
42
import net.minecraft.tileentity.TileEntitySign
43
+ import net.minecraft.util.ResourceLocation
41
44
import net.minecraft.util.math.BlockPos
42
45
import net.minecraft.util.math.ChunkPos
43
46
import net.minecraft.util.text.TextComponentString
44
47
import net.minecraft.world.chunk.Chunk
45
48
import net.minecraftforge.fml.common.gameevent.TickEvent
49
+ import net.minecraftforge.fml.common.registry.ForgeRegistries
46
50
import java.util.concurrent.ConcurrentHashMap
47
51
import java.util.concurrent.ConcurrentMap
48
52
import kotlin.collections.set
@@ -80,6 +84,7 @@ object Search : Module(
80
84
81
85
var overrideWarning by setting(" Override Warning" , false , { false })
82
86
val blockSearchList = setting(CollectionSetting (" Search List" , defaultSearchList, { false }))
87
+ private var blockSearchIdHashSet: IntOpenHashSet = IntOpenHashSet ()
83
88
val entitySearchList = setting(CollectionSetting (" Entity Search List" , linkedSetOf(EntityList .getKey((EntityItemFrame ::class .java))!! .path), { false }))
84
89
val blockSearchDimensionFilter = setting(CollectionSetting (" Block Dimension Filter" , linkedSetOf(), entryType = DimensionFilter ::class .java, visibility = { false }))
85
90
val entitySearchDimensionFilter = setting(CollectionSetting (" Entity Dimension Filter" , linkedSetOf(), entryType = DimensionFilter ::class .java, visibility = { false }))
@@ -139,6 +144,10 @@ object Search : Module(
139
144
}
140
145
141
146
safeListener<TickEvent .ClientTickEvent > {
147
+ if (blockSearchIdHashSet.size != blockSearchList.size) {
148
+ updateBlockSearchIdSet()
149
+ defaultScope.launch { searchAllLoadedChunks() }
150
+ }
142
151
if (blockRenderUpdateJob == null || blockRenderUpdateJob?.isCompleted == true ) {
143
152
blockRenderUpdateJob = defaultScope.launch {
144
153
blockRenderUpdate()
@@ -175,17 +184,28 @@ object Search : Module(
175
184
}
176
185
177
186
safeListener<ConnectionEvent .Disconnect > {
178
- blockRenderer.clear()
179
- entityRenderer.clear( )
187
+ blockRenderer.replaceAll( mutableListOf ()) // safe replace during possible iterator to prevent crashes
188
+ entityRenderer.replaceAll( mutableListOf () )
180
189
foundBlockMap.clear()
181
190
}
182
191
}
183
192
184
193
private fun blockSearchListUpdateListener (newBool : Boolean ) {
185
194
foundBlockMap.entries
186
- .filterNot { blockSearchList .contains(it.value.block.registryName.toString() ) }
195
+ .filterNot { blockSearchIdHashSet .contains(it.value.block.id ) }
187
196
.forEach { foundBlockMap.remove(it.key) }
188
- if (newBool) runSafe { searchAllLoadedChunks() }
197
+ if (newBool) runSafe {
198
+ updateBlockSearchIdSet()
199
+ searchAllLoadedChunks()
200
+ }
201
+ }
202
+
203
+ private fun updateBlockSearchIdSet () {
204
+ val idSet = IntOpenHashSet ()
205
+ blockSearchList.forEach {
206
+ idSet.add(ForgeRegistries .BLOCKS .getValue(ResourceLocation (it))?.id)
207
+ }
208
+ blockSearchIdHashSet = idSet
189
209
}
190
210
191
211
private fun SafeClientEvent.searchLoadedEntities () {
@@ -201,9 +221,9 @@ object Search : Module(
201
221
entitySearchDimensionFilter.value.find { dimFilter -> dimFilter.searchKey == entityName }?.dim
202
222
}?.contains(player.dimension) ? : true
203
223
}
204
- .sortedBy { it.distanceTo (player.getPositionEyes( 1f ) ) }
224
+ .sortedBy { it.manhattanDistanceTo (player.position ) }
205
225
.take(maximumEntities)
206
- .filter { it.distanceTo (player.getPositionEyes( 1f ) ) < range }
226
+ .filter { it.manhattanDistanceTo (player.position ) < range }
207
227
.map {
208
228
Triple (
209
229
it.renderBoundingBox.offset(EntityUtils .getInterpolatedAmount(it, LambdaTessellator .pTicks())),
@@ -252,7 +272,7 @@ object Search : Module(
252
272
// unload rendering on block pos > range
253
273
foundBlockMap
254
274
.filter {
255
- playerPos.distanceTo (it.key) > max(mc.gameSettings.renderDistanceChunks * 16 , range)
275
+ playerPos.manhattanDistanceTo (it.key) > max(mc.gameSettings.renderDistanceChunks * 16 , range)
256
276
}
257
277
.map { it.key }
258
278
.forEach { foundBlockMap.remove(it) }
@@ -261,11 +281,11 @@ object Search : Module(
261
281
.filter {
262
282
blockSearchDimensionFilter.value
263
283
.find {
264
- dimFilter -> dimFilter.searchKey == it.value.block.registryName.toString()
284
+ dimFilter -> dimFilter.getId() == it.value.block.id
265
285
}?.dim?.contains(player.dimension) ? : true
266
286
}
267
287
.map {
268
- player.getPositionEyes( 1f ).distanceTo (it.key) to it.key
288
+ player.position.manhattanDistanceTo (it.key) to it.key
269
289
}
270
290
.filter { it.first < range }
271
291
.take(maximumBlocks)
@@ -322,9 +342,9 @@ object Search : Module(
322
342
private fun SafeClientEvent.searchQuery (state : IBlockState , pos : BlockPos ): Boolean {
323
343
val block = state.block
324
344
if (block == Blocks .AIR ) return false
325
- return (blockSearchList .contains(block.registryName.toString() )
345
+ return (blockSearchIdHashSet .contains(block.id )
326
346
&& blockSearchDimensionFilter.value.find { dimFilter ->
327
- dimFilter.searchKey == block.registryName.toString()
347
+ dimFilter.getId() == block.id
328
348
}?.dim?.contains(player.dimension) ? : true )
329
349
|| isIllegalBedrock(state, pos)
330
350
|| isIllegalWater(state)
@@ -395,6 +415,17 @@ object Search : Module(
395
415
}
396
416
397
417
data class DimensionFilter (val searchKey : String , val dim : LinkedHashSet <Int >) {
418
+ private var id: Int? = null
419
+ private var idInitTried = false // need to do this whole thing because gson doesn't init this field
420
+
421
+ fun getId (): Int? {
422
+ if (id == null && ! idInitTried) {
423
+ idInitTried = true
424
+ id = ForgeRegistries .BLOCKS .getValue(ResourceLocation (searchKey))?.id
425
+ }
426
+ return id
427
+ }
428
+
398
429
override fun toString (): String {
399
430
return " $searchKey -> $dim "
400
431
}
0 commit comments