Skip to content

Commit

Permalink
Search: New Features and QOL Improvements (#498)
Browse files Browse the repository at this point in the history
* 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>
  • Loading branch information
rfresh2 and Avanatiker authored Mar 2, 2023
1 parent 90d5575 commit 77d66d9
Show file tree
Hide file tree
Showing 12 changed files with 466 additions and 90 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package com.lambda.mixin.network;

import com.lambda.client.event.LambdaEventBus;
import com.lambda.client.event.events.ChunkDataEvent;
import net.minecraft.client.multiplayer.WorldClient;
import net.minecraft.client.network.NetHandlerPlayClient;
import net.minecraft.network.play.server.SPacketChunkData;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;

@Mixin(value = NetHandlerPlayClient.class)
public class MixinNetHandlerPlayClient {

@Shadow private WorldClient world;

@Inject(method = "handleChunkData", at = @At("TAIL"))
public void handleChunkData(SPacketChunkData packetIn, CallbackInfo ci) {
LambdaEventBus.INSTANCE.post(new ChunkDataEvent(packetIn.isFullChunk(), this.world.getChunk(packetIn.getChunkX(), packetIn.getChunkZ())));
}
}
16 changes: 16 additions & 0 deletions src/main/kotlin/com/lambda/client/command/Args.kt
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import com.lambda.client.util.*
import com.lambda.client.util.threads.runSafeR
import kotlinx.coroutines.Dispatchers
import net.minecraft.block.Block
import net.minecraft.entity.EntityList
import net.minecraft.item.Item
import net.minecraft.util.math.BlockPos
import java.io.File
Expand Down Expand Up @@ -94,6 +95,21 @@ class BlockArg(
}
}

class EntityArg(
override val name: String
) : AbstractArg<String>(), AutoComplete by StaticPrefixMatch(allEntityNames) {
override suspend fun convertToType(string: String?): String? {
if (string == null) return null
// checks if a valid entity class is registered with this name
return if (EntityList.getClassFromName(string) != null) string else null
}

private companion object {
val allEntityNames = EntityList.getEntityNameList().map { it.path }
}
}


class BaritoneBlockArg(
override val name: String
) : AbstractArg<Block>(), AutoComplete by StaticPrefixMatch(baritoneBlockNames) {
Expand Down
9 changes: 8 additions & 1 deletion src/main/kotlin/com/lambda/client/command/ClientCommand.kt
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package com.lambda.client.command

import com.lambda.client.capeapi.PlayerProfile
import com.lambda.client.command.CommandBuilder
import com.lambda.client.command.args.AbstractArg
import com.lambda.client.command.utils.BuilderBlock
import com.lambda.client.command.utils.ExecuteBlock
Expand Down Expand Up @@ -51,6 +50,14 @@ abstract class ClientCommand(
arg(BlockArg(name), block)
}

@CommandBuilder
protected inline fun AbstractArg<*>.entity(
name: String,
entity: BuilderBlock<String>
) {
arg(EntityArg(name), entity)
}

@CommandBuilder
protected inline fun AbstractArg<*>.item(
name: String,
Expand Down
150 changes: 139 additions & 11 deletions src/main/kotlin/com/lambda/client/command/commands/SearchCommand.kt
Original file line number Diff line number Diff line change
Expand Up @@ -2,30 +2,59 @@ package com.lambda.client.command.commands

import com.lambda.client.command.ClientCommand
import com.lambda.client.module.modules.render.Search
import com.lambda.client.util.items.shulkerList
import com.lambda.client.util.items.signsList
import com.lambda.client.util.text.MessageSendHelper
import com.lambda.client.util.text.formatValue
import net.minecraft.init.Blocks

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

init {
literal("add", "+") {
literal("shulker_box") {
execute("Add all shulker box types to search") {
Search.blockSearchList.editValue { searchList -> shulkerList.map { it.registryName.toString() }.forEach { searchList.add(it) } }
MessageSendHelper.sendChatMessage("All shulker boxes have been added to block search")
}
}
literal("sign") {
execute("Add all signs to search") {
Search.blockSearchList.editValue { searchList -> signsList.map { it.registryName.toString() }.forEach { searchList.add(it) } }
MessageSendHelper.sendChatMessage("All signs have been added to block search")
}
}
block("block") { blockArg ->
literal("force") {
execute("Force add a block to search list") {
val blockName = blockArg.value.registryName.toString()
addBlock(blockName)
}
}

int("dimension") { dimArg ->
execute("Add a block to dimension filter") {
val blockName = blockArg.value.registryName.toString()
val dim = dimArg.value
val dims = Search.blockSearchDimensionFilter.value.find { dimFilter -> dimFilter.searchKey == blockName }?.dim
if (dims != null && !dims.contains(dim)) {
dims.add(dim)
} else {
Search.blockSearchDimensionFilter.value.add(Search.DimensionFilter(blockName, linkedSetOf(dim)))
}
MessageSendHelper.sendChatMessage("Block search filter added for $blockName in dimension ${dimArg.value}")
}
}
execute("Add a block to search list") {
val block = blockArg.value
val blockName = blockArg.value.registryName.toString()

if (warningBlocks.contains(blockName)) {
if (warningBlocks.contains(block)) {
MessageSendHelper.sendWarningMessage("Your world contains lots of ${formatValue(blockName)}, " +
"it might cause extreme lag to add it. " +
"If you are sure you want to add it run ${formatValue("$prefixName add $blockName force")}"
Expand All @@ -35,50 +64,148 @@ object SearchCommand : ClientCommand(
}
}
}
entity("entity") { entityArg ->
int("dimension") {dimArg ->
execute("Add an entity to dimension filter") {
val entityName = entityArg.value
val dim = dimArg.value
val dims = Search.entitySearchDimensionFilter.value.find { dimFilter -> dimFilter.searchKey == entityName }?.dim
if (dims != null && !dims.contains(dim)) {
dims.add(dim)
} else {
Search.entitySearchDimensionFilter.value.add(Search.DimensionFilter(entityName, linkedSetOf(dim)))
}
MessageSendHelper.sendChatMessage("Entity search filter added for $entityName in dimension ${dimArg.value}")
}
}

execute("Add an entity to search list") {
val entityName = entityArg.value
if (Search.entitySearchList.contains(entityName)) {
MessageSendHelper.sendChatMessage("$entityName is already added to search list")
return@execute
}
Search.entitySearchList.editValue { it.add(entityName) }
MessageSendHelper.sendChatMessage("$entityName has been added to search list")
}
}
}

literal("remove", "-") {
literal("shulker_box") {
execute("Remove all shulker boxes from search") {
Search.blockSearchList.editValue { searchList -> shulkerList.map { it.registryName.toString() }.forEach { searchList.remove(it) } }
MessageSendHelper.sendChatMessage("Removed all shulker boxes from block search")
}
}
literal("sign") {
execute("Remove all signs from search") {
Search.blockSearchList.editValue { searchList -> signsList.map { it.registryName.toString() }.forEach { searchList.remove(it) } }
MessageSendHelper.sendChatMessage("Removed all signs from block search")
}
}
block("block") { blockArg ->
int("dimension") {dimArg ->
execute("Remove a block from dimension filter") {
val blockName = blockArg.value.registryName.toString()
val dim = dimArg.value
val dims = Search.blockSearchDimensionFilter.value.find { dimFilter -> dimFilter.searchKey == blockName }?.dim
if (dims != null) {
dims.remove(dim)
if (dims.isEmpty()) {
Search.blockSearchDimensionFilter.value.removeIf { it.searchKey == blockName }
}
}
MessageSendHelper.sendChatMessage("Block search filter removed for $blockName in dimension ${dimArg.value}")
}
}
execute("Remove a block from search list") {
val blockName = blockArg.value.registryName.toString()

if (!Search.searchList.remove(blockName)) {
if (!Search.blockSearchList.contains(blockName)) {
MessageSendHelper.sendErrorMessage("You do not have ${formatValue(blockName)} added to search block list")
} else {
Search.blockSearchList.editValue { it.remove(blockName) }
MessageSendHelper.sendChatMessage("Removed ${formatValue(blockName)} from search block list")
}
}
}
entity("entity") {entityArg ->
int("dimension") {dimArg ->
execute("Remove an entity from dimension filter") {
val entityName = entityArg.value
val dim = dimArg.value
val dims = Search.entitySearchDimensionFilter.value.find { dimFilter -> dimFilter.searchKey == entityName }?.dim
if (dims != null) {
dims.remove(dim)
if (dims.isEmpty()) {
Search.entitySearchDimensionFilter.value.removeIf { it.searchKey == entityName }
}
}
MessageSendHelper.sendChatMessage("Entity search filter removed for $entityName in dimension ${dimArg.value}")
}
}
execute("Remove an entity from search list") {
val entityName = entityArg.value
Search.entitySearchList.editValue { it.remove(entityName) }
MessageSendHelper.sendChatMessage("Removed $entityName from search list")
}
}
}

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

Search.searchList.clear()
Search.searchList.add(blockName)
Search.blockSearchList.editValue {
it.clear()
it.add(blockName)
}
MessageSendHelper.sendChatMessage("Set the search block list to ${formatValue(blockName)}")
}
}
entity("entity") { entityArg ->
execute("Sets the search list to one entity") {
val entityName = entityArg.value
Search.entitySearchList.editValue {
it.clear()
it.add(entityName)
}
MessageSendHelper.sendChatMessage("Set the entity search list to $entityName")
}
}
}

literal("reset", "default") {
execute("Reset the search list to defaults") {
Search.searchList.resetValue()
MessageSendHelper.sendChatMessage("Reset the search block list to defaults")
Search.blockSearchList.resetValue()
Search.entitySearchList.resetValue()
Search.blockSearchDimensionFilter.resetValue()
Search.entitySearchDimensionFilter.resetValue()
MessageSendHelper.sendChatMessage("Reset the search list to defaults")
}
}

literal("list") {
execute("Print search list") {
MessageSendHelper.sendChatMessage(Search.searchList.joinToString())
MessageSendHelper.sendChatMessage("Blocks: ${Search.blockSearchList.joinToString()}")
if (Search.blockSearchDimensionFilter.value.isNotEmpty()) {
MessageSendHelper.sendChatMessage("Block dimension filter: ${Search.blockSearchDimensionFilter.value}")
}
MessageSendHelper.sendChatMessage("Entities ${Search.entitySearchList.joinToString()}")
if (Search.entitySearchDimensionFilter.value.isNotEmpty()) {
MessageSendHelper.sendChatMessage("Entity dimension filter: ${Search.entitySearchDimensionFilter.value}")
}
}
}

literal("clear") {
execute("Set the search list to nothing") {
Search.searchList.clear()
Search.blockSearchList.editValue { it.clear() }
Search.entitySearchList.editValue { it.clear() }
Search.blockSearchDimensionFilter.editValue { it.clear() }
Search.entitySearchDimensionFilter.editValue { it.clear() }
MessageSendHelper.sendChatMessage("Cleared the search block list")
}
}
Expand All @@ -97,9 +224,10 @@ object SearchCommand : ClientCommand(
return
}

if (!Search.searchList.add(blockName)) {
if (Search.blockSearchList.contains(blockName)) {
MessageSendHelper.sendErrorMessage("${formatValue(blockName)} is already added to the search block list")
} else {
Search.blockSearchList.editValue { it.add(blockName) }
MessageSendHelper.sendChatMessage("${formatValue(blockName)} has been added to the search block list")
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package com.lambda.client.event.events

import com.lambda.client.event.Event
import net.minecraft.world.chunk.Chunk

/**
* Event emitted when chunk data is read
*/
class ChunkDataEvent(val isFullChunk: Boolean, val chunk: Chunk): Event
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ object InventoryManager : Module(
private val pauseMovement by setting("Pause Movement", true)
private val delay by setting("Delay Ticks", 1, 0..20, 1, unit = " ticks")
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")
val ejectList = setting(CollectionSetting("Eject List", defaultEjectList))
val ejectList = setting(CollectionSetting("Eject List", defaultEjectList, String::class.java))

enum class State {
IDLE, SAVING_ITEM, HELPING_MEND, REFILLING_BUILDING, REFILLING, EJECTING
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,8 +67,8 @@ object Scaffold : Module(
private val thickness by setting("Outline Thickness", 2f, .25f..4f, .25f, { outline && page == Page.RENDER }, description = "Changes thickness of the outline")
private val pendingBlockColor by setting("Pending Color", ColorHolder(0, 0, 255), visibility = { page == Page.RENDER })

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

private enum class Page {
GENERAL, RENDER
Expand Down
Loading

0 comments on commit 77d66d9

Please sign in to comment.