From 86d62a3e3158cf01128818e2703a7d92ab9236e1 Mon Sep 17 00:00:00 2001 From: etianl <115842502+etianl@users.noreply.github.com> Date: Sat, 27 Jul 2024 17:16:36 -0700 Subject: [PATCH] v1.1.3 Hole/TunnelFinder module added, other improvements - Added the **HoleAndTunnelFinder** module which can detect 1x1 holes going straight down, and horizontal tunnels of any height. It by default ignores passable blocks such as torches or water but there is an option to have it only detect Air for holes and tunnels. - Added more blocks for the Nether and Overworld old generation detectors to consider in **NewerNewChunks**. This will improve detection and reduce false positives in relation to their detections. - Reduced the amount of blocks the old generation detectors for Nether and Overworld are detecting just a little to improve performance slightly in **NewerNewChunks**. - Added a detector for **BaseFinder** for detecting Nether roof builds. If there is anything other than a red or brown mushroom at or above Y 128 in the nether it will be flagged. - Reverted the taskExecutor for loading chunkdata for **BaseFinder** and **NewerNewChunks** back to just being single threaded because multithreading it did not actually provide any benefit. - Added falling_block entity support for **Boom+**, this allows you to throw any blocks when in Creative mode at things. --- README.md | 1 + gradle.properties | 2 +- .../java/pwn/noobs/trouserstreak/Trouser.java | 1 + .../trouserstreak/modules/BaseFinder.java | 30 +- .../noobs/trouserstreak/modules/BoomPlus.java | 14 + .../modules/HoleAndTunnelFinder.java | 363 ++++++++++++++++++ .../trouserstreak/modules/NewerNewChunks.java | 31 +- src/main/resources/fabric.mod.json | 2 +- 8 files changed, 419 insertions(+), 25 deletions(-) create mode 100644 src/main/java/pwn/noobs/trouserstreak/modules/HoleAndTunnelFinder.java diff --git a/README.md b/README.md index ac3d0233..8770e843 100644 --- a/README.md +++ b/README.md @@ -85,6 +85,7 @@ In no particular order - **FlightAntikick:** Moves you down on a tick-based timer. Added in to substitute the lack of a "Normal" mode antikick for velocity flight in MeteorClient (not a great antikick it's just something). Bind it to the same key as Flight. (Credits to etianl :D) - **GarbageCleanerCommand:** Accessable by typing ".cleanram". It cleans the RAM of useless junk and may be very handy for improving performance after chunk tracing for a while and can be used to clear other lag. (credits to [ogmur](https://www.youtube.com/@Ogmur) for writing this) - **HandOfGod:** Runs the "/fill" command on the world around you or around everyone else in different ways as you move around, and as you click. Destroy and modify the world with ease! Operator status required. (Credits to etianl :D) +- **HoleAndTunnelFinder:** Detects 1x1 holes going straight down, and horizontal tunnels of any height. It by default ignores passable blocks such as torches or water but there is an option to have it only detect Air for holes and tunnels. (Thank you to Meteor Client for some code from TunnelESP, and credits to etianl for this version of it) - **Inventory Dupe (1.17):** Duplicates things in your crafting slots when the module is enabled and the Dupe button is pressed in your inventory. Only works on Minecraft servers on the version 1.17, not any version before or after.(Credit to ItsVen and Da0neDatGotAway for original creation of the dupe, and to B2H990 for making the fabric mod. Credits to etianl for porting to Meteor.) - **InstaKill:** Shoots arrows and tridents with incredible power and velocity. Enabling multiple buttons causes the amount of packets to add up. (Credits to Saturn5Vfive) - **InstaMineNuker:** Sends packets to instantly mine the blocks around you until they are gone. There is an option in it to make it only target instamineable blocks such as crops, grass, slimeblocks, and more.. (Credits to etianl and to Meteor Client, as well as Meteor Rejects for some borrowed code) diff --git a/gradle.properties b/gradle.properties index 3d00706b..5f8a85a4 100644 --- a/gradle.properties +++ b/gradle.properties @@ -6,7 +6,7 @@ yarn_mappings=1.21+build.2 loader_version=0.15.11 # Mod Properties -mod_version=1.1.2-1.21 +mod_version=1.1.3-1.21 maven_group=pwn.noobs archives_base_name=1trouser-streak diff --git a/src/main/java/pwn/noobs/trouserstreak/Trouser.java b/src/main/java/pwn/noobs/trouserstreak/Trouser.java index a8117ded..8b96db3e 100644 --- a/src/main/java/pwn/noobs/trouserstreak/Trouser.java +++ b/src/main/java/pwn/noobs/trouserstreak/Trouser.java @@ -28,6 +28,7 @@ public void onInitialize() { //Modules.get().add(new -----> Find and Grief noobs! <-----()); Modules.get().add(new NewerNewChunks()); Modules.get().add(new BaseFinder()); + Modules.get().add(new HoleAndTunnelFinder()); Modules.get().add(new StorageLooter()); Modules.get().add(new LavaAura()); Modules.get().add(new MaceKill()); diff --git a/src/main/java/pwn/noobs/trouserstreak/modules/BaseFinder.java b/src/main/java/pwn/noobs/trouserstreak/modules/BaseFinder.java index 43839f97..122a6b3a 100644 --- a/src/main/java/pwn/noobs/trouserstreak/modules/BaseFinder.java +++ b/src/main/java/pwn/noobs/trouserstreak/modules/BaseFinder.java @@ -44,7 +44,7 @@ import java.util.HashSet; import java.util.List; import java.util.Set; -import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executor; import java.util.concurrent.Executors; /* @@ -108,6 +108,11 @@ public class BaseFinder extends Module { .description("If a spawner doesn't have the proper natural companion blocks with it in the chunk, flag as possible build.") .defaultValue(true) .build()); + private final Setting roofDetector = sgDetectors.add(new BoolSetting.Builder() + .name("Nether Roof Build Finder") + .description("If anything but mushrooms on the nether roof, flag as possible build.") + .defaultValue(true) + .build()); private final Setting bsefndtickdelay = sgGeneral.add(new IntSetting.Builder() .name("Base Found Message Tick Delay") .description("Delays the allowance of Base Found messages to reduce spam.") @@ -432,7 +437,7 @@ public WWidget getWidget(GuiTheme theme) { .visible(() -> trcr.get()) .build() ); - private final ExecutorService taskExecutor = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors()); + private final Executor taskExecutor = Executors.newSingleThreadExecutor(); private int basefoundspamTicks=0; private boolean basefound=false; private int deletewarningTicks=666; @@ -677,8 +682,8 @@ private void onReadPacket(PacketEvent.Receive event) { if (mc.world.getChunkManager().getChunk(packet.getChunkX(), packet.getChunkZ()) == null) { WorldChunk chunk = new WorldChunk(mc.world, basepos); try { - taskExecutor.execute(() -> chunk.loadFromPacket(packet.getChunkData().getSectionsDataBuf(), new NbtCompound(), packet.getChunkData().getBlockEntities(packet.getChunkX(), packet.getChunkZ()))); - } catch (ArrayIndexOutOfBoundsException e) { + taskExecutor.execute(() -> chunk.loadFromPacket(packet.getChunkData().getSectionsDataBuf(), new NbtCompound(), packet.getChunkData().getBlockEntities(packet.getChunkX(), packet.getChunkZ()))); + } catch (ArrayIndexOutOfBoundsException e) { return; } @@ -689,7 +694,7 @@ private void onReadPacket(PacketEvent.Receive event) { for (int z = 0; z < 16; z++) { BlockState blerks = chunk.getBlockState(new BlockPos(x, y, z)); blockposi=new BlockPos(x, y, z); - if (!(blerks.getBlock()==Blocks.AIR)){ + if (blerks.getBlock()!=Blocks.AIR){ if (skybuildfind.get() && y>skybuildint.get()) { if (!baseChunks.contains(basepos)){ baseChunks.add(basepos); @@ -716,6 +721,19 @@ private void onReadPacket(PacketEvent.Receive event) { } } } + if (roofDetector.get() && blerks.getBlock()!=Blocks.AIR && blerks.getBlock()!=Blocks.RED_MUSHROOM && blerks.getBlock()!=Blocks.BROWN_MUSHROOM && y>=128 && mc.world.getRegistryKey() == World.NETHER){ + if (!baseChunks.contains(basepos)){ + baseChunks.add(basepos); + if (save.get()) { + saveBaseChunkData(); + } + if (basefoundspamTicks==0){ + ChatUtils.sendMsg(Text.of("(Nether Roof)Possible build located near X"+basepos.getCenterX()+", Y"+y+", Z"+basepos.getCenterZ())); + LastBaseFound= new ChunkPos(basepos.x, basepos.z); + basefound=true; + } + } + } if (!(blerks.getBlock()==Blocks.STONE)){ if (!(blerks.getBlock()==Blocks.DEEPSLATE) && !(blerks.getBlock()==Blocks.DIRT) && !(blerks.getBlock()==Blocks.GRASS_BLOCK) && !(blerks.getBlock()==Blocks.WATER) && !(blerks.getBlock()==Blocks.SAND) && !(blerks.getBlock()==Blocks.GRAVEL) && !(blerks.getBlock()==Blocks.BEDROCK)&& !(blerks.getBlock()==Blocks.NETHERRACK) && !(blerks.getBlock()==Blocks.LAVA)){ if (spawner.get()){ @@ -1025,4 +1043,4 @@ private boolean isNaturalLagCausingBlock(Block block) { !(block ==Blocks.NETHERRACK) && !(block ==Blocks.LAVA); } -} +} \ No newline at end of file diff --git a/src/main/java/pwn/noobs/trouserstreak/modules/BoomPlus.java b/src/main/java/pwn/noobs/trouserstreak/modules/BoomPlus.java index 4ec4cc6b..9e81a265 100644 --- a/src/main/java/pwn/noobs/trouserstreak/modules/BoomPlus.java +++ b/src/main/java/pwn/noobs/trouserstreak/modules/BoomPlus.java @@ -5,6 +5,8 @@ import meteordevelopment.meteorclient.settings.*; import meteordevelopment.meteorclient.systems.modules.Module; import meteordevelopment.orbit.EventHandler; +import net.minecraft.block.Block; +import net.minecraft.block.Blocks; import net.minecraft.component.ComponentChanges; import net.minecraft.component.DataComponentTypes; import net.minecraft.component.type.NbtComponent; @@ -141,6 +143,11 @@ public class BoomPlus extends Module { .min(0) .sliderRange(0, 100) .build()); + private final Setting blockstate = sgOptions.add(new BlockSetting.Builder() + .name("falling_block entity block") + .description("What is created when specifying falling_block as the entity.") + .defaultValue(Blocks.BEDROCK) + .build()); public final Setting target = sgGeneral.add(new BoolSetting.Builder() .name("OnTarget") .description("spawns on target") @@ -228,6 +235,10 @@ private void onMouseButton(MouseButtonEvent event) { } } private NbtComponent createEntityData() { + String fullString = blockstate.get().toString(); + String[] parts = fullString.split(":"); + String block = parts[1]; + String blockName = block.replace("}", ""); NbtList motion = new NbtList(); NbtList Pos = new NbtList(); HitResult hr = mc.cameraEntity.raycast(900, 0, true); @@ -254,6 +265,9 @@ private NbtComponent createEntityData() { entityTag.putInt("Age", age.get()); entityTag.putInt("ExplosionPower", exppower.get()); entityTag.putInt("ExplosionRadius", exppower.get()); + NbtCompound blockState = new NbtCompound(); + blockState.putString("Name", "minecraft:" + blockName); + entityTag.put("BlockState", blockState); if (invincible.get())entityTag.putBoolean("Invulnerable", invincible.get()); if (silence.get())entityTag.putBoolean("Silent", silence.get()); if (glow.get())entityTag.putBoolean("Glowing", glow.get()); diff --git a/src/main/java/pwn/noobs/trouserstreak/modules/HoleAndTunnelFinder.java b/src/main/java/pwn/noobs/trouserstreak/modules/HoleAndTunnelFinder.java new file mode 100644 index 00000000..a04c3085 --- /dev/null +++ b/src/main/java/pwn/noobs/trouserstreak/modules/HoleAndTunnelFinder.java @@ -0,0 +1,363 @@ +//made by etianl with "inspiration" from Meteor Client. +//Thank you to them for a bit of this code https://github.com/MeteorDevelopment/meteor-client/blob/master/src/main/java/meteordevelopment/meteorclient/systems/modules/render/TunnelESP.java + +package pwn.noobs.trouserstreak.modules; + +import it.unimi.dsi.fastutil.longs.Long2ObjectMap; +import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap; +import meteordevelopment.meteorclient.events.render.Render3DEvent; +import meteordevelopment.meteorclient.events.world.TickEvent; +import meteordevelopment.meteorclient.renderer.Renderer3D; +import meteordevelopment.meteorclient.renderer.ShapeMode; +import meteordevelopment.meteorclient.settings.*; +import meteordevelopment.meteorclient.systems.modules.Module; +import meteordevelopment.meteorclient.utils.Utils; +import meteordevelopment.meteorclient.utils.network.MeteorExecutor; +import meteordevelopment.meteorclient.utils.render.color.SettingColor; +import meteordevelopment.orbit.EventHandler; +import net.minecraft.block.BlockState; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.Box; +import net.minecraft.util.math.ChunkPos; +import net.minecraft.util.math.Direction; +import net.minecraft.world.chunk.Chunk; +import net.minecraft.world.chunk.ChunkSection; +import pwn.noobs.trouserstreak.Trouser; + +import java.util.HashSet; +import java.util.Set; + +import java.util.Queue; +import java.util.LinkedList; + +public class HoleAndTunnelFinder extends Module { + private final SettingGroup sgGeneral = settings.getDefaultGroup(); + private final SettingGroup sgParams = settings.createGroup("Parameters"); + private final SettingGroup sgRender = settings.createGroup("Rendering"); + private final Setting detectionMode = sgGeneral.add(new EnumSetting.Builder() + .name("Detection Mode") + .description("Choose what to detect: holes, tunnels, or both.") + .defaultValue(DetectionMode.HOLES_AND_TUNNELS) + .build() + ); + private final Setting maxChunks = sgGeneral.add(new IntSetting.Builder() + .name("Chunks to process/tick") + .description("Amount of Chunks to process per tick") + .defaultValue(10) + .min(1) + .sliderRange(1, 100) + .build() + ); + private final Setting airBlocks = sgGeneral.add(new BoolSetting.Builder() + .name("Detect only Air blocks as passable.") + .description("Only marks tunnels or holes if their blocks are air as oppose to if the blocks are passable.") + .defaultValue(false) + .build() + ); + private final Setting minYLevel = sgParams.add(new IntSetting.Builder() + .name("Min Y Level") + .description("Minimum Y level to scan") + .defaultValue(-64) + .min(-64) + .sliderRange(-64, 319) + .build() + ); + + private final Setting maxYLevel = sgParams.add(new IntSetting.Builder() + .name("Max Y Level") + .description("Maximum Y level to scan") + .defaultValue(256) + .min(-64) + .sliderRange(-64, 319) + .build() + ); + + private final Setting minHoleDepth = sgParams.add(new IntSetting.Builder() + .name("Min Hole Depth") + .description("Minimum depth for a hole to be detected") + .defaultValue(4) + .min(1) + .sliderMax(20) + .build() + ); + + private final Setting minTunnelLength = sgParams.add(new IntSetting.Builder() + .name("Min Tunnel Length") + .description("Minimum length for a tunnel to be detected") + .defaultValue(3) + .min(1) + .sliderMax(20) + .build() + ); + + private final Setting tunnelHeight = sgParams.add(new IntSetting.Builder() + .name("Tunnel Height") + .description("Height of the tunnels to be detected") + .defaultValue(2) + .min(1) + .sliderMax(5) + .build() + ); + + private final Setting shapeMode = sgRender.add(new EnumSetting.Builder() + .name("shape-mode") + .description("How the shapes are rendered.") + .defaultValue(ShapeMode.Both) + .build() + ); + + private final Setting holeLineColor = sgRender.add(new ColorSetting.Builder() + .name("hole-line-color") + .description("The color of the lines for the holes being rendered.") + .defaultValue(new SettingColor(255, 0, 0, 155)) // Opaque red + .build() + ); + + private final Setting holeSideColor = sgRender.add(new ColorSetting.Builder() + .name("hole-side-color") + .description("The color of the sides for the holes being rendered.") + .defaultValue(new SettingColor(255, 0, 0, 50)) // Semi-transparent red + .build() + ); + + private final Setting tunnelLineColor = sgRender.add(new ColorSetting.Builder() + .name("tunnel-line-color") + .description("The color of the lines for the tunnels being rendered.") + .defaultValue(new SettingColor(0, 0, 255, 155)) // Opaque blue + .build() + ); + + private final Setting tunnelSideColor = sgRender.add(new ColorSetting.Builder() + .name("tunnel-side-color") + .description("The color of the sides for the tunnels being rendered.") + .defaultValue(new SettingColor(0, 0, 255, 50)) // Semi-transparent blue + .build() + ); + private static final Direction[] DIRECTIONS = { Direction.EAST, Direction.WEST, Direction.NORTH, Direction.SOUTH }; + private final Long2ObjectMap chunks = new Long2ObjectOpenHashMap<>(); + private final Queue chunkQueue = new LinkedList<>(); + + public HoleAndTunnelFinder() { + super(Trouser.Main, "Hole/TunnelFinder", "Finds and highlights holes and/or tunnels."); + } + + @Override + public void onDeactivate() { + chunks.clear(); + chunkQueue.clear(); + } + + private void searchChunk(Chunk chunk, TChunk tChunk) { + Set holes = new HashSet<>(); + Set tunnels = new HashSet<>(); + + int minSectionY = Math.max(chunk.getSectionIndex(minYLevel.get()), 0); + int maxSectionY = Math.min(chunk.getSectionIndex(maxYLevel.get()), chunk.getSectionArray().length - 1); + + for (int sectionY = minSectionY; sectionY <= maxSectionY; sectionY++) { + ChunkSection section = chunk.getSectionArray()[sectionY]; + if (section == null || section.isEmpty()) continue; + + int startY = Math.max(sectionY * 16, minYLevel.get()); + int endY = Math.min((sectionY + 1) * 16 - 1, maxYLevel.get()); + + for (int y = startY; y <= endY; y++) { + for (int x = 0; x < 16; x++) { + for (int z = 0; z < 16; z++) { + BlockPos pos = chunk.getPos().getBlockPos(x, y, z); + if (isPassableBlock(pos)) { + if (detectionMode.get() == DetectionMode.HOLES || detectionMode.get() == DetectionMode.HOLES_AND_TUNNELS) { + checkHole(chunk, pos, holes); + } + if (detectionMode.get() == DetectionMode.TUNNELS || detectionMode.get() == DetectionMode.HOLES_AND_TUNNELS) { + checkTunnel(chunk, pos, tunnels); + } + } + } + } + } + } + + tChunk.holes = holes; + tChunk.tunnels = tunnels; + } + + private boolean isTunnelSection(BlockPos pos, Direction dir) { + int height = tunnelHeight.get(); + for (int i = 0; i < height; i++) { + if (!isPassableBlock(pos.up(i))) return false; + } + + // Check for solid blocks above and below + if (isPassableBlock(pos.down()) || isPassableBlock(pos.up(height))) return false; + + // Check for solid blocks on the sides perpendicular to the tunnel direction + Direction[] perpDirs = dir.getAxis() == Direction.Axis.X ? + new Direction[]{Direction.NORTH, Direction.SOUTH} : + new Direction[]{Direction.EAST, Direction.WEST}; + + for (Direction perpDir : perpDirs) { + for (int i = 0; i < height; i++) { + if (isPassableBlock(pos.up(i).offset(perpDir))) { + return false; + } + } + } + + return true; + } + + private void checkTunnel(Chunk chunk, BlockPos pos, Set tunnels) { + for (Direction dir : DIRECTIONS) { + BlockPos.Mutable currentPos = pos.mutableCopy(); + int length = 0; + + while (isTunnelSection(currentPos, dir)) { + length++; + currentPos.move(dir); + + // Check if the next position is out of the current chunk boundaries + if (!chunk.getPos().equals(mc.world.getChunk(currentPos).getPos())) { + break; + } + } + + if (length >= minTunnelLength.get()) { + BlockPos endPos = pos.offset(dir, length - 1); + Box tunnelBox = new Box( + Math.min(pos.getX(), endPos.getX()), + Math.max(pos.getY(), minYLevel.get()), + Math.min(pos.getZ(), endPos.getZ()), + Math.max(pos.getX(), endPos.getX()) + 1, + Math.min(pos.getY() + tunnelHeight.get(), maxYLevel.get()), + Math.max(pos.getZ(), endPos.getZ()) + 1 + ); + + // Check if this tunnel overlaps with any existing tunnel + if (tunnels.stream().noneMatch(existingTunnel -> existingTunnel.intersects(tunnelBox))) { + tunnels.add(tunnelBox); + } + return; // Only add one tunnel per starting position + } + } + } + + private void checkHole(Chunk chunk, BlockPos pos, Set holes) { + if (isValidHoleSection(pos) && !isValidHoleSection(pos.up())) { + BlockPos.Mutable currentPos = pos.mutableCopy(); + int depth = 0; + while (isValidHoleSection(currentPos) && currentPos.getY() >= minYLevel.get()) { + depth++; + currentPos.move(Direction.DOWN); + + // Check if the next position is out of the current chunk boundaries + if (!chunk.getPos().equals(mc.world.getChunk(currentPos).getPos())) { + break; + } + } + if (depth >= minHoleDepth.get()) { + Box holeBox = new Box( + pos.getX(), Math.max(pos.getY() - depth + 1, minYLevel.get()), pos.getZ(), + pos.getX() + 1, Math.min(pos.getY() + 1, maxYLevel.get()), pos.getZ() + 1 + ); + if (holes.stream().noneMatch(existingHole -> existingHole.intersects(holeBox))) { + holes.add(holeBox); + } + } + } + } + + private boolean isValidHoleSection(BlockPos pos) { + return isPassableBlock(pos) && + !isPassableBlock(pos.north()) && + !isPassableBlock(pos.south()) && + !isPassableBlock(pos.east()) && + !isPassableBlock(pos.west()); + } + + private boolean isPassableBlock(BlockPos pos) { + Chunk chunk = mc.world.getChunk(pos); + BlockState state = chunk.getBlockState(pos); + if (airBlocks.get()) return state.isAir(); + else return state.getCollisionShape(mc.world, pos).isEmpty() || state.getFluidState().isStill(); + } + + @EventHandler + private void onTick(TickEvent.Post event) { + synchronized (chunks) { + for (TChunk tChunk : chunks.values()) tChunk.marked = false; + + for (Chunk chunk : Utils.chunks(true)) { + long key = ChunkPos.toLong(chunk.getPos().x, chunk.getPos().z); + + if (chunks.containsKey(key)) chunks.get(key).marked = true; + else if (!chunkQueue.contains(chunk)) { + chunkQueue.add(chunk); + } + } + + processChunkQueue(); + chunks.values().removeIf(tChunk -> !tChunk.marked); + } + } + + private void processChunkQueue() { + int maxChunksPerTick = maxChunks.get(); // Adjust this value based on performance needs + int processed = 0; + + while (!chunkQueue.isEmpty() && processed < maxChunksPerTick) { + Chunk chunk = chunkQueue.poll(); + if (chunk != null) { + long key = ChunkPos.toLong(chunk.getPos().x, chunk.getPos().z); + TChunk tChunk = new TChunk(chunk.getPos().x, chunk.getPos().z); + chunks.put(tChunk.getKey(), tChunk); + + MeteorExecutor.execute(() -> searchChunk(chunk, tChunk)); + processed++; + } + } + } + + @EventHandler + private void onRender3D(Render3DEvent event) { + synchronized (chunks) { + for (TChunk chunk : chunks.values()) chunk.render(event.renderer); + } + } + + private class TChunk { + private final int x, z; + public Set holes; + public Set tunnels; + public boolean marked; + + public TChunk(int x, int z) { + this.x = x; + this.z = z; + this.marked = true; + } + + public void render(Renderer3D renderer) { + if ((detectionMode.get() == DetectionMode.HOLES || detectionMode.get() == DetectionMode.HOLES_AND_TUNNELS) && holes != null) { + for (Box box : holes) { + renderer.box(box.minX, box.minY, box.minZ, box.maxX, box.maxY, box.maxZ, holeSideColor.get(), holeLineColor.get(), shapeMode.get(), 0); + } + } + if ((detectionMode.get() == DetectionMode.TUNNELS || detectionMode.get() == DetectionMode.HOLES_AND_TUNNELS) && tunnels != null) { + for (Box box : tunnels) { + renderer.box(box.minX, box.minY, box.minZ, box.maxX, box.maxY, box.maxZ, tunnelSideColor.get(), tunnelLineColor.get(), shapeMode.get(), 0); + } + } + } + + public long getKey() { + return ChunkPos.toLong(x, z); + } + } + + public enum DetectionMode { + HOLES_AND_TUNNELS, + HOLES, + TUNNELS + } +} \ No newline at end of file diff --git a/src/main/java/pwn/noobs/trouserstreak/modules/NewerNewChunks.java b/src/main/java/pwn/noobs/trouserstreak/modules/NewerNewChunks.java index 0c739a19..bc2eea85 100644 --- a/src/main/java/pwn/noobs/trouserstreak/modules/NewerNewChunks.java +++ b/src/main/java/pwn/noobs/trouserstreak/modules/NewerNewChunks.java @@ -41,7 +41,7 @@ import java.nio.file.Files; import java.nio.file.Paths; import java.util.*; -import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executor; import java.util.concurrent.Executors; /* @@ -259,7 +259,7 @@ public WWidget getWidget(GuiTheme theme) { .visible(() -> shapeMode.get() == ShapeMode.Lines || shapeMode.get() == ShapeMode.Both) .build() ); - private final ExecutorService taskExecutor = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors()); + private final Executor taskExecutor = Executors.newSingleThreadExecutor(); private int deletewarningTicks=666; private int deletewarning=0; private String serverip; @@ -304,7 +304,9 @@ public WWidget getWidget(GuiTheme theme) { static { NEW_OVERWORLD_BLOCKS.add(Blocks.DEEPSLATE); NEW_OVERWORLD_BLOCKS.add(Blocks.AMETHYST_BLOCK); + NEW_OVERWORLD_BLOCKS.add(Blocks.BUDDING_AMETHYST); NEW_OVERWORLD_BLOCKS.add(Blocks.AZALEA); + NEW_OVERWORLD_BLOCKS.add(Blocks.FLOWERING_AZALEA); NEW_OVERWORLD_BLOCKS.add(Blocks.BIG_DRIPLEAF); NEW_OVERWORLD_BLOCKS.add(Blocks.BIG_DRIPLEAF_STEM); NEW_OVERWORLD_BLOCKS.add(Blocks.SMALL_DRIPLEAF); @@ -325,6 +327,7 @@ public WWidget getWidget(GuiTheme theme) { NEW_OVERWORLD_BLOCKS.add(Blocks.RAW_IRON_BLOCK); NEW_OVERWORLD_BLOCKS.add(Blocks.DRIPSTONE_BLOCK); NEW_OVERWORLD_BLOCKS.add(Blocks.MOSS_BLOCK); + NEW_OVERWORLD_BLOCKS.add(Blocks.MOSS_CARPET); NEW_OVERWORLD_BLOCKS.add(Blocks.POINTED_DRIPSTONE); NEW_OVERWORLD_BLOCKS.add(Blocks.SMOOTH_BASALT); NEW_OVERWORLD_BLOCKS.add(Blocks.TUFF); @@ -333,6 +336,7 @@ public WWidget getWidget(GuiTheme theme) { NEW_OVERWORLD_BLOCKS.add(Blocks.ROOTED_DIRT); NEW_OVERWORLD_BLOCKS.add(Blocks.AZALEA_LEAVES); NEW_OVERWORLD_BLOCKS.add(Blocks.FLOWERING_AZALEA_LEAVES); + NEW_OVERWORLD_BLOCKS.add(Blocks.POWDER_SNOW); } private static final Set NEW_NETHER_BLOCKS = new HashSet<>(); static { @@ -352,6 +356,10 @@ public WWidget getWidget(GuiTheme theme) { NEW_NETHER_BLOCKS.add(Blocks.WEEPING_VINES); NEW_NETHER_BLOCKS.add(Blocks.BONE_BLOCK); NEW_NETHER_BLOCKS.add(Blocks.CHAIN); + NEW_NETHER_BLOCKS.add(Blocks.OBSIDIAN); + NEW_NETHER_BLOCKS.add(Blocks.CRYING_OBSIDIAN); + NEW_NETHER_BLOCKS.add(Blocks.SOUL_SOIL); + NEW_NETHER_BLOCKS.add(Blocks.SOUL_FIRE); } Set FILE_NAMES = new HashSet<>(Set.of( "OldChunkData.txt", @@ -636,8 +644,7 @@ private void onRender(Render3DEvent event) { } private void render(Box box, Color sides, Color lines, ShapeMode shapeMode, Render3DEvent event) { - event.renderer.box( - box.minX, box.minY, box.minZ, box.maxX, box.maxY, box.maxZ, sides, lines, shapeMode, 0); + event.renderer.box(box.minX, box.minY, box.minZ, box.maxX, box.maxY, box.maxZ, sides, lines, shapeMode, 0); } @EventHandler @@ -714,7 +721,7 @@ else if (!(event.packet instanceof PlayerMoveC2SPacket) && event.packet instance if (overworldOldChunksDetector.get() && mc.world.getRegistryKey() == World.OVERWORLD) { for (int x = 0; x < 16; x++) { - for (int y = mc.world.getBottomY(); y < 260; y++) { + for (int y = mc.world.getBottomY()+3; y < 260; y++) { for (int z = 0; z < 16; z++) { if (!foundAnyOre && ORE_BLOCKS.contains(chunk.getBlockState(new BlockPos(x, y, z)).getBlock())) foundAnyOre = true; //prevent false flags in flat world if (y > 5 && !isNewOverworldGeneration && NEW_OVERWORLD_BLOCKS.contains(chunk.getBlockState(new BlockPos(x, y, z)).getBlock())) { @@ -728,7 +735,7 @@ else if (!(event.packet instanceof PlayerMoveC2SPacket) && event.packet instance } if (netherOldChunksDetector.get() && mc.world.getRegistryKey() == World.NETHER) { for (int x = 0; x < 16; x++) { - for (int y = mc.world.getBottomY(); y < 128; y++) { + for (int y = mc.world.getBottomY()+3; y < 128; y++) { for (int z = 0; z < 16; z++) { if (!isNewNetherGeneration && NEW_NETHER_BLOCKS.contains(chunk.getBlockState(new BlockPos(x, y, z)).getBlock()) && mc.world.getRegistryKey() == World.NETHER) { isNewNetherGeneration = true; @@ -745,7 +752,7 @@ else if (!(event.packet instanceof PlayerMoveC2SPacket) && event.packet instance } if (endOldChunksDetector.get() && mc.world.getRegistryKey() == World.END) { PacketByteBuf bufferCopy = new PacketByteBuf(Unpooled.copiedBuffer(buf.nioBuffer())); //copy the packetByteBuf for later use - if (bufferCopy.readableBytes() < 2) return; + if (bufferCopy.readableBytes() < 3) return; try { short blockCount = bufferCopy.readShort(); @@ -786,27 +793,17 @@ else if (!(event.packet instanceof PlayerMoveC2SPacket) && event.packet instance if (biomeBitsPerEntry == 0) { int singleBiomeValue = bufferCopy.readVarInt(); - //Registry biomeRegistry = mc.world.getRegistryManager().get(RegistryKeys.BIOME); - //Biome biome = biomeRegistry.get(singleBiomeValue); - //Identifier biomeId = biomeRegistry.getId(biome); - //System.out.println("Single Biome Value: " + singleBiomeValue + " | Biome: " + biomeId.toString()); if (singleBiomeValue == 55) { isOldGeneration = true; } bufferCopy.readVarInt(); // Data Array Length (should be 0) } else if (biomeBitsPerEntry >= 1 && biomeBitsPerEntry <= 3) { int biomePaletteLength = bufferCopy.readVarInt(); - //System.out.println("Biome palette length: " + biomePaletteLength); for (int i = 0; i < biomePaletteLength; i++) { if (bufferCopy.readableBytes() < 1) { - //System.out.println("Incomplete biome palette data"); break; } int biomePaletteEntry = bufferCopy.readVarInt(); - //Registry biomeRegistry = mc.world.getRegistryManager().get(RegistryKeys.BIOME); - //Biome biome = biomeRegistry.get(biomePaletteEntry); - //Identifier biomeId = biomeRegistry.getId(biome); - //System.out.println("Biome palette entry " + i + ": " + biomePaletteEntry + " | Biome: " + biomeId.toString()); if (biomePaletteEntry == 55) { isOldGeneration = true; break; diff --git a/src/main/resources/fabric.mod.json b/src/main/resources/fabric.mod.json index 461cfc63..54f31955 100644 --- a/src/main/resources/fabric.mod.json +++ b/src/main/resources/fabric.mod.json @@ -1,7 +1,7 @@ { "schemaVersion": 1, "id": "streak-addon", - "version": "1.1.2", + "version": "1.1.3", "name": "TrouserStreak", "description": "Trouser-Streak is a compilation of modules, updated to the latest version and optimized for maximum grief. I did not make all of these.", "authors": [