diff --git a/src/main/java/me/zeroeightsix/kami/command/commands/SearchCommand.java b/src/main/java/me/zeroeightsix/kami/command/commands/SearchCommand.java new file mode 100644 index 00000000..b1c3a45b --- /dev/null +++ b/src/main/java/me/zeroeightsix/kami/command/commands/SearchCommand.java @@ -0,0 +1,84 @@ +package me.zeroeightsix.kami.command.commands; + +import me.zeroeightsix.kami.command.Command; +import me.zeroeightsix.kami.command.syntax.ChunkBuilder; +import me.zeroeightsix.kami.module.modules.render.Search; +import net.minecraft.block.Block; + +import static me.zeroeightsix.kami.KamiMod.MODULE_MANAGER; +import static me.zeroeightsix.kami.util.MessageSendHelper.*; + +/** + * Created by 20kdc on 17/02/2020. + * Updated by S-B99 on 17/02/20 + * Modified for use with search module by wnuke on 20/04/2020 + */ +public class SearchCommand extends Command { + public SearchCommand() { + super("search", new ChunkBuilder().append("help").append("+block|-block|=block").append("list|defaults|clear").build()); + setDescription("Allows you to add or remove blocks from the &fSearch &7module"); + } + + private static final String ESP_BANNED_BLOCKS = "minecraft:air, minecraft:netherrack, minecraft:dirt, minecraft:water"; + + @Override + public void call(String[] args) { + Search search = MODULE_MANAGER.getModuleT(Search.class); + if (search == null) { + sendErrorMessage("&cThe module is not available for some reason. Make sure the name you're calling is correct and that you have the module installed!!"); + return; + } + if (!search.isEnabled()) { + sendWarningMessage("&6Warning: The " + search.getName() + " module is not enabled!"); + sendWarningMessage("These commands will still have effect, but will not visibly do anything."); + } + for (String s : args) { + if (s == null) + continue; + if (s.equalsIgnoreCase("help")) { + sendChatMessage("The " + search.getName() + " module has a list of blocks"); + sendChatMessage("Normally, the " + search.getName() + " module highlights these blocks"); + sendChatMessage("This command is a convenient way to quickly edit the list"); + sendChatMessage("Available options: \n" + + "+block: Adds a block to the list\n" + + "-block: Removes a block from the list\n" + + "=block: Changes the list to only that block\n" + + "list: Prints the list of selected blocks\n" + + "defaults: Resets the list to the default list\n" + + "clear: Removes all blocks from the " + search.getName() + " block list"); + } else if (s.equalsIgnoreCase("clear")) { + search.extClear(); + sendWarningMessage("Cleared the " + search.getName() + " block list"); + } else if (s.equalsIgnoreCase("defaults")) { + search.extDefaults(); + sendChatMessage("Reset the " + search.getName() + " block list to default"); + } else if (s.equalsIgnoreCase("list")) { + sendChatMessage("\n" + search.extGet()); + } else if (s.startsWith("=")) { + String sT = s.replace("=" ,""); + search.extSet(sT); + sendChatMessage("Set the " + search.getName() + " block list to " + sT); + } else if (s.startsWith("+") || s.startsWith("-")) { + String name = s.substring(1); + Block b = Block.getBlockFromName(name); + if (b == null) { + sendChatMessage("&cInvalid block name <" + name + ">"); + } else { + if (s.startsWith("+")) { + if (!ESP_BANNED_BLOCKS.contains(name)) { + sendChatMessage("Added <" + name + "> to the " + search.getName() + " block list"); + search.extAdd(name); + } else { + sendChatMessage("You can't add <" + name + "> to the " + search.getName() + " block list"); + } + } else { + sendChatMessage("Removed <" + name + "> from the " + search.getName() + " block list"); + search.extRemove(name); + } + } + } else { + sendChatMessage("&cInvalid subcommand <" + s + ">"); + } + } + } +} diff --git a/src/main/java/me/zeroeightsix/kami/module/modules/render/Search.java b/src/main/java/me/zeroeightsix/kami/module/modules/render/Search.java new file mode 100644 index 00000000..41e9e8c7 --- /dev/null +++ b/src/main/java/me/zeroeightsix/kami/module/modules/render/Search.java @@ -0,0 +1,181 @@ +package me.zeroeightsix.kami.module.modules.render; + +import me.zeroeightsix.kami.event.events.RenderEvent; +import me.zeroeightsix.kami.module.Module; +import me.zeroeightsix.kami.setting.Setting; +import me.zeroeightsix.kami.setting.Settings; +import me.zeroeightsix.kami.util.GeometryMasks; +import me.zeroeightsix.kami.util.KamiTessellator; +import net.minecraft.block.Block; +import net.minecraft.client.Minecraft; +import net.minecraft.client.renderer.GlStateManager; +import net.minecraft.util.math.BlockPos; +import org.lwjgl.opengl.GL11; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashSet; +import java.util.Set; + +import static me.zeroeightsix.kami.util.ColourUtils.toRGBA; +import static me.zeroeightsix.kami.util.LogUtil.getCurrentCoord; + +@Module.Info(name = "Search", description = "Highlights blocks in the world", category = Module.Category.RENDER) +public class Search extends Module { + Minecraft mc = Minecraft.getMinecraft(); + private Set espBlocks; + private static final String DEFAULT_BLOCK_ESP_CONFIG = "minecraft:portal, minecraft:end_portal_frame, minecraft:bed"; + private Setting espBlockNames = register(Settings.stringBuilder("HiddenBlocks").withValue(DEFAULT_BLOCK_ESP_CONFIG).withConsumer((old, value) -> refreshESPBlocksSet(value)).build()); + + public String extGet() { + return extGetInternal(null); + } + // Add entry by arbitrary user-provided string + public void extAdd(String s) { + espBlockNames.setValue(extGetInternal(null) + ", " + s); + } + // Remove entry by arbitrary user-provided string + public void extRemove(String s) { + espBlockNames.setValue(extGetInternal(Block.getBlockFromName(s))); + } + // Clears the list. + public void extClear() { + espBlockNames.setValue(""); + } + // Resets the list to default + public void extDefaults() { extClear(); extAdd(DEFAULT_BLOCK_ESP_CONFIG); } + // Set the list to 1 value + public void extSet(String s) { extClear(); extAdd(s); } + + private String extGetInternal(Block filter) { + StringBuilder sb = new StringBuilder(); + boolean notFirst = false; + for (Block b : espBlocks) { + if (b == filter) + continue; + if (notFirst) + sb.append(", "); + notFirst = true; + sb.append(Block.REGISTRY.getNameForObject(b)); + } + return sb.toString(); + } + + @Override + public void onUpdate() { + if (espBlocks == null) { + refreshESPBlocksSet(espBlockNames.getValue()); + } + if (mc.player == null) return; + if (shouldRun()) new Thread(this::makeChunks).start(); + } + + public void onEnable() { + refreshESPBlocksSet(espBlockNames.getValue()); + } + + private void refreshESPBlocksSet(String v) { + espBlocks = Collections.synchronizedSet(new HashSet<>()); + for (String s : v.split(",")) { + String s2 = s.trim(); + if (!s2.equals("minecraft:air")) { + Block block = Block.getBlockFromName(s2); + if (block != null) + espBlocks.add(block); + } + } + } + + private long startTime = 0; + private ArrayList>> a; + + private boolean shouldRun() { + if (startTime == 0) + startTime = System.currentTimeMillis(); + if (startTime + 500 <= System.currentTimeMillis()) { // 1 timeout = 1 second = 1000 ms + startTime = System.currentTimeMillis(); + return true; + } + return false; + } + + boolean doneList = false; + + private void makeChunks() { + doneList = false; + int[] pcoords = getCurrentCoord(false); + int renderdist = mc.gameSettings.renderDistanceChunks * 16; + if (renderdist > 80) { + renderdist = 80; + } + BlockPos pos1 = new BlockPos(pcoords[0] - renderdist, 0, pcoords[2] - renderdist); + BlockPos pos2 = new BlockPos(pcoords[0] + renderdist, 256, pcoords[2] + renderdist); + ArrayList>> foundBlocks = new ArrayList<>(); + foundBlocks.add(findBlocksInCoords(pos1, pos2, espBlocks)); + a = foundBlocks; + doneList = true; + } + + private ArrayList> findBlocksInCoords(BlockPos pos1, BlockPos pos2, Set blocksToFind) { + Iterable blocks = BlockPos.getAllInBox(pos1, pos2); + ArrayList> foundBlocks = new ArrayList<>(); + for (BlockPos blockPos : blocks) { + int side = GeometryMasks.Quad.ALL; + Block block = mc.world.getBlockState(blockPos).getBlock(); + for (Block b : blocksToFind) { + if (block == b) { + int c = block.blockMapColor.colorValue; + int[] cia = {c>>16,c>>8&255,c&255}; + int blockColor = toRGBA(cia[0], cia[1], cia[2], 100); + foundBlocks.add(new Triplet<>(blockPos, blockColor, side)); + } + } + } + return foundBlocks; + } + + ArrayList>> blocksToShow; + @Override + public void onWorldRender(RenderEvent event) { + if (doneList && a != null) { + blocksToShow = a; + } + if (blocksToShow != null) { + GlStateManager.pushMatrix(); + KamiTessellator.prepare(GL11.GL_QUADS); + for (ArrayList> blockList : blocksToShow) { + for (Triplet pair : blockList) + KamiTessellator.drawBox(pair.getFirst(), pair.getSecond(), pair.getThird()); + } + KamiTessellator.release(); + GlStateManager.popMatrix(); + GlStateManager.enableTexture2D(); + } + } + + public static class Triplet { + + private final T first; + private final U second; + private final V third; + + public Triplet(T first, U second, V third) { + this.first = first; + this.second = second; + this.third = third; + } + + public T getFirst() { + return first; + } + + public U getSecond() { + return second; + } + + public V getThird() { + return third; + } + } +} +