Skip to content

Commit 77d66d9

Browse files
rfresh2Avanatiker
andauthored
Search: New Features and QOL Improvements (#498)
* Search: New Features and QOL Improvements New features: 1. Entity search 2. Illegal bedrock / nether water search 3. Dimension filters: only search for blocks in a specific dimensions 4. Command shortcuts for adding/removing all shulkers and signs 5. Performance optimization: Only check new and changed blocks in their respective events. Prevents constant searching over unchanged blocks 6. Option to hide rendering on F1 7. Tweaks to certain block colors with auto coloring 8. Greatly increased max render range of found blocks: Useful while traveling at very high speeds when you can easily miss found blocks * Dynamic list type for CollectionSetting * revert CollectionSetting changes sorry but it doesn't work * Smol cleanup --------- Co-authored-by: Constructor <fractalminds@protonmail.com>
1 parent 90d5575 commit 77d66d9

File tree

12 files changed

+466
-90
lines changed

12 files changed

+466
-90
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
package com.lambda.mixin.network;
2+
3+
import com.lambda.client.event.LambdaEventBus;
4+
import com.lambda.client.event.events.ChunkDataEvent;
5+
import net.minecraft.client.multiplayer.WorldClient;
6+
import net.minecraft.client.network.NetHandlerPlayClient;
7+
import net.minecraft.network.play.server.SPacketChunkData;
8+
import org.spongepowered.asm.mixin.Mixin;
9+
import org.spongepowered.asm.mixin.Shadow;
10+
import org.spongepowered.asm.mixin.injection.At;
11+
import org.spongepowered.asm.mixin.injection.Inject;
12+
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
13+
14+
@Mixin(value = NetHandlerPlayClient.class)
15+
public class MixinNetHandlerPlayClient {
16+
17+
@Shadow private WorldClient world;
18+
19+
@Inject(method = "handleChunkData", at = @At("TAIL"))
20+
public void handleChunkData(SPacketChunkData packetIn, CallbackInfo ci) {
21+
LambdaEventBus.INSTANCE.post(new ChunkDataEvent(packetIn.isFullChunk(), this.world.getChunk(packetIn.getChunkX(), packetIn.getChunkZ())));
22+
}
23+
}

src/main/kotlin/com/lambda/client/command/Args.kt

+16
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import com.lambda.client.util.*
1414
import com.lambda.client.util.threads.runSafeR
1515
import kotlinx.coroutines.Dispatchers
1616
import net.minecraft.block.Block
17+
import net.minecraft.entity.EntityList
1718
import net.minecraft.item.Item
1819
import net.minecraft.util.math.BlockPos
1920
import java.io.File
@@ -94,6 +95,21 @@ class BlockArg(
9495
}
9596
}
9697

98+
class EntityArg(
99+
override val name: String
100+
) : AbstractArg<String>(), AutoComplete by StaticPrefixMatch(allEntityNames) {
101+
override suspend fun convertToType(string: String?): String? {
102+
if (string == null) return null
103+
// checks if a valid entity class is registered with this name
104+
return if (EntityList.getClassFromName(string) != null) string else null
105+
}
106+
107+
private companion object {
108+
val allEntityNames = EntityList.getEntityNameList().map { it.path }
109+
}
110+
}
111+
112+
97113
class BaritoneBlockArg(
98114
override val name: String
99115
) : AbstractArg<Block>(), AutoComplete by StaticPrefixMatch(baritoneBlockNames) {

src/main/kotlin/com/lambda/client/command/ClientCommand.kt

+8-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
package com.lambda.client.command
22

33
import com.lambda.client.capeapi.PlayerProfile
4-
import com.lambda.client.command.CommandBuilder
54
import com.lambda.client.command.args.AbstractArg
65
import com.lambda.client.command.utils.BuilderBlock
76
import com.lambda.client.command.utils.ExecuteBlock
@@ -51,6 +50,14 @@ abstract class ClientCommand(
5150
arg(BlockArg(name), block)
5251
}
5352

53+
@CommandBuilder
54+
protected inline fun AbstractArg<*>.entity(
55+
name: String,
56+
entity: BuilderBlock<String>
57+
) {
58+
arg(EntityArg(name), entity)
59+
}
60+
5461
@CommandBuilder
5562
protected inline fun AbstractArg<*>.item(
5663
name: String,

src/main/kotlin/com/lambda/client/command/commands/SearchCommand.kt

+139-11
Original file line numberDiff line numberDiff line change
@@ -2,30 +2,59 @@ package com.lambda.client.command.commands
22

33
import com.lambda.client.command.ClientCommand
44
import com.lambda.client.module.modules.render.Search
5+
import com.lambda.client.util.items.shulkerList
6+
import com.lambda.client.util.items.signsList
57
import com.lambda.client.util.text.MessageSendHelper
68
import com.lambda.client.util.text.formatValue
9+
import net.minecraft.init.Blocks
710

811
// TODO: Remove once GUI has List
912
object SearchCommand : ClientCommand(
1013
name = "search",
1114
description = "Manage search blocks"
1215
) {
13-
private val warningBlocks = arrayOf("minecraft:grass", "minecraft:end_stone", "minecraft:lava", "minecraft:bedrock", "minecraft:netherrack", "minecraft:dirt", "minecraft:water", "minecraft:stone")
16+
private val warningBlocks = hashSetOf(Blocks.GRASS, Blocks.END_STONE, Blocks.LAVA, Blocks.FLOWING_LAVA,
17+
Blocks.BEDROCK, Blocks.NETHERRACK, Blocks.DIRT, Blocks.WATER, Blocks.FLOWING_WATER, Blocks.STONE)
1418

1519
init {
1620
literal("add", "+") {
21+
literal("shulker_box") {
22+
execute("Add all shulker box types to search") {
23+
Search.blockSearchList.editValue { searchList -> shulkerList.map { it.registryName.toString() }.forEach { searchList.add(it) } }
24+
MessageSendHelper.sendChatMessage("All shulker boxes have been added to block search")
25+
}
26+
}
27+
literal("sign") {
28+
execute("Add all signs to search") {
29+
Search.blockSearchList.editValue { searchList -> signsList.map { it.registryName.toString() }.forEach { searchList.add(it) } }
30+
MessageSendHelper.sendChatMessage("All signs have been added to block search")
31+
}
32+
}
1733
block("block") { blockArg ->
1834
literal("force") {
1935
execute("Force add a block to search list") {
2036
val blockName = blockArg.value.registryName.toString()
2137
addBlock(blockName)
2238
}
2339
}
24-
40+
int("dimension") { dimArg ->
41+
execute("Add a block to dimension filter") {
42+
val blockName = blockArg.value.registryName.toString()
43+
val dim = dimArg.value
44+
val dims = Search.blockSearchDimensionFilter.value.find { dimFilter -> dimFilter.searchKey == blockName }?.dim
45+
if (dims != null && !dims.contains(dim)) {
46+
dims.add(dim)
47+
} else {
48+
Search.blockSearchDimensionFilter.value.add(Search.DimensionFilter(blockName, linkedSetOf(dim)))
49+
}
50+
MessageSendHelper.sendChatMessage("Block search filter added for $blockName in dimension ${dimArg.value}")
51+
}
52+
}
2553
execute("Add a block to search list") {
54+
val block = blockArg.value
2655
val blockName = blockArg.value.registryName.toString()
2756

28-
if (warningBlocks.contains(blockName)) {
57+
if (warningBlocks.contains(block)) {
2958
MessageSendHelper.sendWarningMessage("Your world contains lots of ${formatValue(blockName)}, " +
3059
"it might cause extreme lag to add it. " +
3160
"If you are sure you want to add it run ${formatValue("$prefixName add $blockName force")}"
@@ -35,50 +64,148 @@ object SearchCommand : ClientCommand(
3564
}
3665
}
3766
}
67+
entity("entity") { entityArg ->
68+
int("dimension") {dimArg ->
69+
execute("Add an entity to dimension filter") {
70+
val entityName = entityArg.value
71+
val dim = dimArg.value
72+
val dims = Search.entitySearchDimensionFilter.value.find { dimFilter -> dimFilter.searchKey == entityName }?.dim
73+
if (dims != null && !dims.contains(dim)) {
74+
dims.add(dim)
75+
} else {
76+
Search.entitySearchDimensionFilter.value.add(Search.DimensionFilter(entityName, linkedSetOf(dim)))
77+
}
78+
MessageSendHelper.sendChatMessage("Entity search filter added for $entityName in dimension ${dimArg.value}")
79+
}
80+
}
81+
82+
execute("Add an entity to search list") {
83+
val entityName = entityArg.value
84+
if (Search.entitySearchList.contains(entityName)) {
85+
MessageSendHelper.sendChatMessage("$entityName is already added to search list")
86+
return@execute
87+
}
88+
Search.entitySearchList.editValue { it.add(entityName) }
89+
MessageSendHelper.sendChatMessage("$entityName has been added to search list")
90+
}
91+
}
3892
}
3993

4094
literal("remove", "-") {
95+
literal("shulker_box") {
96+
execute("Remove all shulker boxes from search") {
97+
Search.blockSearchList.editValue { searchList -> shulkerList.map { it.registryName.toString() }.forEach { searchList.remove(it) } }
98+
MessageSendHelper.sendChatMessage("Removed all shulker boxes from block search")
99+
}
100+
}
101+
literal("sign") {
102+
execute("Remove all signs from search") {
103+
Search.blockSearchList.editValue { searchList -> signsList.map { it.registryName.toString() }.forEach { searchList.remove(it) } }
104+
MessageSendHelper.sendChatMessage("Removed all signs from block search")
105+
}
106+
}
41107
block("block") { blockArg ->
108+
int("dimension") {dimArg ->
109+
execute("Remove a block from dimension filter") {
110+
val blockName = blockArg.value.registryName.toString()
111+
val dim = dimArg.value
112+
val dims = Search.blockSearchDimensionFilter.value.find { dimFilter -> dimFilter.searchKey == blockName }?.dim
113+
if (dims != null) {
114+
dims.remove(dim)
115+
if (dims.isEmpty()) {
116+
Search.blockSearchDimensionFilter.value.removeIf { it.searchKey == blockName }
117+
}
118+
}
119+
MessageSendHelper.sendChatMessage("Block search filter removed for $blockName in dimension ${dimArg.value}")
120+
}
121+
}
42122
execute("Remove a block from search list") {
43123
val blockName = blockArg.value.registryName.toString()
44124

45-
if (!Search.searchList.remove(blockName)) {
125+
if (!Search.blockSearchList.contains(blockName)) {
46126
MessageSendHelper.sendErrorMessage("You do not have ${formatValue(blockName)} added to search block list")
47127
} else {
128+
Search.blockSearchList.editValue { it.remove(blockName) }
48129
MessageSendHelper.sendChatMessage("Removed ${formatValue(blockName)} from search block list")
49130
}
50131
}
51132
}
133+
entity("entity") {entityArg ->
134+
int("dimension") {dimArg ->
135+
execute("Remove an entity from dimension filter") {
136+
val entityName = entityArg.value
137+
val dim = dimArg.value
138+
val dims = Search.entitySearchDimensionFilter.value.find { dimFilter -> dimFilter.searchKey == entityName }?.dim
139+
if (dims != null) {
140+
dims.remove(dim)
141+
if (dims.isEmpty()) {
142+
Search.entitySearchDimensionFilter.value.removeIf { it.searchKey == entityName }
143+
}
144+
}
145+
MessageSendHelper.sendChatMessage("Entity search filter removed for $entityName in dimension ${dimArg.value}")
146+
}
147+
}
148+
execute("Remove an entity from search list") {
149+
val entityName = entityArg.value
150+
Search.entitySearchList.editValue { it.remove(entityName) }
151+
MessageSendHelper.sendChatMessage("Removed $entityName from search list")
152+
}
153+
}
52154
}
53155

54156
literal("set", "=") {
55157
block("block") { blockArg ->
56158
execute("Set the search list to one block") {
57159
val blockName = blockArg.value.registryName.toString()
58160

59-
Search.searchList.clear()
60-
Search.searchList.add(blockName)
161+
Search.blockSearchList.editValue {
162+
it.clear()
163+
it.add(blockName)
164+
}
61165
MessageSendHelper.sendChatMessage("Set the search block list to ${formatValue(blockName)}")
62166
}
63167
}
168+
entity("entity") { entityArg ->
169+
execute("Sets the search list to one entity") {
170+
val entityName = entityArg.value
171+
Search.entitySearchList.editValue {
172+
it.clear()
173+
it.add(entityName)
174+
}
175+
MessageSendHelper.sendChatMessage("Set the entity search list to $entityName")
176+
}
177+
}
64178
}
65179

66180
literal("reset", "default") {
67181
execute("Reset the search list to defaults") {
68-
Search.searchList.resetValue()
69-
MessageSendHelper.sendChatMessage("Reset the search block list to defaults")
182+
Search.blockSearchList.resetValue()
183+
Search.entitySearchList.resetValue()
184+
Search.blockSearchDimensionFilter.resetValue()
185+
Search.entitySearchDimensionFilter.resetValue()
186+
MessageSendHelper.sendChatMessage("Reset the search list to defaults")
70187
}
71188
}
72189

73190
literal("list") {
74191
execute("Print search list") {
75-
MessageSendHelper.sendChatMessage(Search.searchList.joinToString())
192+
MessageSendHelper.sendChatMessage("Blocks: ${Search.blockSearchList.joinToString()}")
193+
if (Search.blockSearchDimensionFilter.value.isNotEmpty()) {
194+
MessageSendHelper.sendChatMessage("Block dimension filter: ${Search.blockSearchDimensionFilter.value}")
195+
}
196+
MessageSendHelper.sendChatMessage("Entities ${Search.entitySearchList.joinToString()}")
197+
if (Search.entitySearchDimensionFilter.value.isNotEmpty()) {
198+
MessageSendHelper.sendChatMessage("Entity dimension filter: ${Search.entitySearchDimensionFilter.value}")
199+
}
76200
}
77201
}
78202

79203
literal("clear") {
80204
execute("Set the search list to nothing") {
81-
Search.searchList.clear()
205+
Search.blockSearchList.editValue { it.clear() }
206+
Search.entitySearchList.editValue { it.clear() }
207+
Search.blockSearchDimensionFilter.editValue { it.clear() }
208+
Search.entitySearchDimensionFilter.editValue { it.clear() }
82209
MessageSendHelper.sendChatMessage("Cleared the search block list")
83210
}
84211
}
@@ -97,9 +224,10 @@ object SearchCommand : ClientCommand(
97224
return
98225
}
99226

100-
if (!Search.searchList.add(blockName)) {
227+
if (Search.blockSearchList.contains(blockName)) {
101228
MessageSendHelper.sendErrorMessage("${formatValue(blockName)} is already added to the search block list")
102229
} else {
230+
Search.blockSearchList.editValue { it.add(blockName) }
103231
MessageSendHelper.sendChatMessage("${formatValue(blockName)} has been added to the search block list")
104232
}
105233
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
package com.lambda.client.event.events
2+
3+
import com.lambda.client.event.Event
4+
import net.minecraft.world.chunk.Chunk
5+
6+
/**
7+
* Event emitted when chunk data is read
8+
*/
9+
class ChunkDataEvent(val isFullChunk: Boolean, val chunk: Chunk): Event

src/main/kotlin/com/lambda/client/module/modules/player/InventoryManager.kt

+1-1
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ object InventoryManager : Module(
4747
private val pauseMovement by setting("Pause Movement", true)
4848
private val delay by setting("Delay Ticks", 1, 0..20, 1, unit = " ticks")
4949
private val helpMend by setting("Help Mend", false, description = "Helps mending items by replacing the offhand item with low HP items of the same type")
50-
val ejectList = setting(CollectionSetting("Eject List", defaultEjectList))
50+
val ejectList = setting(CollectionSetting("Eject List", defaultEjectList, String::class.java))
5151

5252
enum class State {
5353
IDLE, SAVING_ITEM, HELPING_MEND, REFILLING_BUILDING, REFILLING, EJECTING

src/main/kotlin/com/lambda/client/module/modules/player/Scaffold.kt

+2-2
Original file line numberDiff line numberDiff line change
@@ -67,8 +67,8 @@ object Scaffold : Module(
6767
private val thickness by setting("Outline Thickness", 2f, .25f..4f, .25f, { outline && page == Page.RENDER }, description = "Changes thickness of the outline")
6868
private val pendingBlockColor by setting("Pending Color", ColorHolder(0, 0, 255), visibility = { page == Page.RENDER })
6969

70-
val blockSelectionWhitelist = setting(CollectionSetting("BlockWhitelist", linkedSetOf("minecraft:obsidian"), { false }))
71-
val blockSelectionBlacklist = setting(CollectionSetting("BlockBlacklist", blockBlacklist.map { it.registryName.toString() }.toMutableSet(), { false }))
70+
val blockSelectionWhitelist = setting(CollectionSetting("BlockWhitelist", linkedSetOf("minecraft:obsidian"), String::class.java, { false }))
71+
val blockSelectionBlacklist = setting(CollectionSetting("BlockBlacklist", blockBlacklist.map { it.registryName.toString() }.toMutableSet(), String::class.java, { false }))
7272

7373
private enum class Page {
7474
GENERAL, RENDER

0 commit comments

Comments
 (0)