From 81f1d1ebfc9a67574fc8abbf694ad6a6ca816495 Mon Sep 17 00:00:00 2001 From: etianl <115842502+etianl@users.noreply.github.com> Date: Thu, 6 Jul 2023 11:43:40 -0700 Subject: [PATCH] 0.6.1 Newer-NewerNewchunks Exploit (again) **Newer-NewerNewChunks Exploit** - The TickExploit option does essentially what the Lighting Exploit did. (it might even be the same thing) - The new detection exploit is based on the hasRandomTicks() tag associated with blocks. - The TickExploit option estimates possible newchunks based on the fact that when blocks generate in newchunks, they are not immediately being ticked. - When using Advanced mode if the TickExploit chunks appear infrequently and are combined with Old Chunks, then the chunks you are in are OLD. If there is alot of TickExploit chunks appearing and/or they are mixed with newchunks then the chunks are NEW. - The TickExploit option works best if you move fast, because if you hang out in an area you will recieve block tick updates that occur naturally in old chunks. - LightingExploit option has been replaced with the TickExploit option in 1.19.4. It does the same thing. - ***NOTE FOR 1.19.4 USERS*** -> finish any tracing you are doing now with the LightingExploit before updating, this new version cannot read the saved data from the LightingExploit. **Another smol BaseFinder Update** - Made Spawner Finder feature in BaseFinder dimension-specific. For example if you are in the nether and a spawner has mossy cobblestone near it but no nether brick fence or chain then it is modified. - Moved Brown Stained Glass from list1 to list3 to avoid a false positive with trail ruins. (Press the reset button on your lists to get the new default) --- README.md | 15 +- gradle.properties | 2 +- .../commands/NewChunkCounter.java | 10 +- .../trouserstreak/modules/BaseFinder.java | 8 +- .../trouserstreak/modules/NewerNewChunks.java | 133 +++++++++++++++++- 5 files changed, 147 insertions(+), 21 deletions(-) diff --git a/README.md b/README.md index be8d8f694..cfaf62557 100644 --- a/README.md +++ b/README.md @@ -75,10 +75,8 @@ This will return the lowest block placed with AutoMountain until AutoLavacast is - **LecternCrash:** Crash 1.18.X vanilla servers and possibly below. (Credits to Coderx-Gamer) - **NewerNewChunks:** NewChunks module with new newchunk estimation exploits, and the ability to save chunk data for later! Also with special options for tracing servers that have been updated from a version before the build limit updates, which throw false positives normally. (Credits to Meteor Rejects, and BleachHack from where it was ported, and etianl for updating :D.) - *NewerNewChunks Notes:* -- ***LIGHTING EXPLOIT STUFF IS ONLY AVAILABLE FOR TROUSER 1.19.4 and prior!!!*** -- Trouser-Streak for 1.20 and up does not contain the LightingExploit as part of NewerNewChunks because Mojang patched it. :P -- The LightingExploit option estimates possible newchunks based on lighting update packets. SOME OF THESE CHUNKS MAY BE OLD. Advanced Mode is needed to filter any false positives out. See Special Options notes for usage. -- The LightingExploit option works best if you move fast, because if you hang out in an area you will recieve lighting updates that occur naturally in old chunks. +- The **TickExploit** option estimates possible newchunks based on block ticking packets. SOME OF THESE CHUNKS MAY BE OLD. Advanced Mode is needed to filter any false positives out. See Special Options notes for usage. +- The **TickExploit** option can produce false positives if you are hanging around in the same location for a while. It's best to keep moving fast for it to work best. - NewerNewChunks stores your NewChunks data as text files seperately per server and per dimension in the NewChunks folder in your Minecraft folder. - Save and Load ChunkData options are for the stored files. - This enables you to chunk trace multiple different servers and dimensions without mixing NewChunks data. @@ -88,11 +86,10 @@ This will return the lowest block placed with AutoMountain until AutoLavacast is - The .newchunkcount command can tell you how many chunks have been saved in data in the dimension you are in. ------------------------------------------------------------------------------------- - ***NewerNewChunks Special Options:*** -- These are to be used when the server has two distinct diamond layers, and two distinct lava pool layers underground at spawn. -------------------------------------------------------------------------------------- -- The **"AdvancedMode"** highlights chunks that have flow only below Y0 as well as chunks that have been detected with the LightingExploit option. -- If there is nothing but FlowBelowY0 chunks and OldChunks as well as a few LightingExploit chunks**(If MC Version<=1.19.4)**, then you are updating Old Chunks to the new build limits and those are OLDCHUNKS. If the FlowIsBelowY0 are mixed with NewChunks and LightingExploit **(If MC Version<=1.19.4)** coloured chunks they are NEWCHUNKS. -- **(If MC Version<=1.19.4** When using Advanced mode if the LightingExploit chunks appear infrequently and are combined with Old Chunks, then the chunks you are in are OLD. If there is alot of LightingExploit chunks appearing and/or they are mixed with NewChunks then the chunks are NEW. +(These are to be used when the server has two distinct diamond layers, and two distinct lava pool layers underground at spawn.) +- The **"AdvancedMode"** highlights chunks that have flow only below Y0 as well as chunks that have been detected with the TickExploit option. +- If there is nothing but FlowBelowY0 chunks and OldChunks as well as a few TickExploit chunks, then you are updating Old Chunks to the new build limits and those are OLDCHUNKS. If the FlowIsBelowY0 are mixed with NewChunks and Tick Exploit coloured chunks they are NEWCHUNKS. +- When using Advanced mode if the Tick Exploit chunks appear infrequently and are combined with Old Chunks, then the chunks you are in are OLD. If there is alot of Tick Exploit chunks appearing and/or they are mixed with NewChunks then the chunks are NEW. - AdvancedMode can be confusing, do not use if you can't interpret the chunk data. ------------------------------------------------------------------------------------- - The **"IgnoreFlowBelow0"** will render as an oldchunk if liquid flow is only below Y zero, and will show as a newchunk if flow is above Y zero, or both above AND below Y zero. diff --git a/gradle.properties b/gradle.properties index c6b9b3f28..48dc565bf 100644 --- a/gradle.properties +++ b/gradle.properties @@ -6,7 +6,7 @@ yarn_mappings=1.20.1+build.9 loader_version=0.14.21 # Mod Properties -mod_version=0.6.0-1.20.1 +mod_version=0.6.1-1.20.1 maven_group=pwn.noobs archives_base_name=1trouser-streak diff --git a/src/main/java/pwn/noobs/trouserstreak/commands/NewChunkCounter.java b/src/main/java/pwn/noobs/trouserstreak/commands/NewChunkCounter.java index df7946914..175726a7f 100644 --- a/src/main/java/pwn/noobs/trouserstreak/commands/NewChunkCounter.java +++ b/src/main/java/pwn/noobs/trouserstreak/commands/NewChunkCounter.java @@ -37,13 +37,21 @@ public void build(LiteralArgumentBuilder builder) { ChatUtils.sendMsg(Text.of(chunks+" FlowBelowY0Chunk locations have been saved by NewerNewChunks in this dimension.")); return SINGLE_SUCCESS; })); + builder.then(literal("LightingExploitChunks").executes(ctx -> { + n.chunkcounterticks=0; + n.chunkcounter=true; + int chunks = n.tickexploitchunksfound; + ChatUtils.sendMsg(Text.of(chunks+" Lighting/TickExploitChunk locations have been saved by NewerNewChunks in this dimension.")); + return SINGLE_SUCCESS; + })); builder.executes(ctx -> { n.chunkcounterticks=0; n.chunkcounter=true; int chunks1 = n.newchunksfound; int chunks2 = n.olderoldchunksfound; + int chunks4 = n.tickexploitchunksfound; int chunks3 = n.oldchunksfound; - ChatUtils.sendMsg(Text.of("New: "+chunks1+" | FlowBelowY=0: "+chunks2+" | Old: "+chunks3+" | Chunk locations have been saved by NewerNewChunks in this dimension.")); + ChatUtils.sendMsg(Text.of("New: "+chunks1+" | FlowBelowY=0: "+chunks2+" | TickExploitChunk: "+chunks4+" | Old: "+chunks3+" | Chunk locations have been saved by NewerNewChunks in this dimension.")); return SINGLE_SUCCESS; }); } diff --git a/src/main/java/pwn/noobs/trouserstreak/modules/BaseFinder.java b/src/main/java/pwn/noobs/trouserstreak/modules/BaseFinder.java index fda0ffba2..2c35e8f19 100644 --- a/src/main/java/pwn/noobs/trouserstreak/modules/BaseFinder.java +++ b/src/main/java/pwn/noobs/trouserstreak/modules/BaseFinder.java @@ -28,6 +28,7 @@ import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.Box; import net.minecraft.util.math.ChunkPos; +import net.minecraft.world.World; import net.minecraft.world.chunk.WorldChunk; import pwn.noobs.trouserstreak.Trouser; @@ -83,7 +84,7 @@ public class BaseFinder extends Module { Blocks.BLACK_CONCRETE, Blocks.BLUE_CONCRETE, Blocks.CYAN_CONCRETE, Blocks.BROWN_CONCRETE, Blocks.WHITE_CONCRETE, Blocks.ORANGE_CONCRETE, Blocks.MAGENTA_CONCRETE, Blocks.LIGHT_BLUE_CONCRETE, Blocks.YELLOW_CONCRETE, Blocks.LIME_CONCRETE, Blocks.PINK_CONCRETE, Blocks.GRAY_CONCRETE, Blocks.LIGHT_GRAY_CONCRETE, Blocks.PURPLE_CONCRETE, Blocks.GREEN_CONCRETE, Blocks.RED_CONCRETE, Blocks.BLACK_CONCRETE_POWDER, Blocks.BLUE_CONCRETE_POWDER, Blocks.CYAN_CONCRETE_POWDER, Blocks.BROWN_CONCRETE_POWDER, Blocks.WHITE_CONCRETE_POWDER, Blocks.ORANGE_CONCRETE_POWDER, Blocks.MAGENTA_CONCRETE_POWDER, Blocks.LIGHT_BLUE_CONCRETE_POWDER, Blocks.YELLOW_CONCRETE_POWDER, Blocks.LIME_CONCRETE_POWDER, Blocks.PINK_CONCRETE_POWDER, Blocks.GRAY_CONCRETE_POWDER, Blocks.LIGHT_GRAY_CONCRETE_POWDER, Blocks.PURPLE_CONCRETE_POWDER, Blocks.GREEN_CONCRETE_POWDER, Blocks.RED_CONCRETE_POWDER, Blocks.COPPER_BLOCK, Blocks.EXPOSED_COPPER, Blocks.WEATHERED_COPPER, Blocks.OXIDIZED_COPPER, Blocks.SOUL_TORCH, Blocks.SOUL_WALL_TORCH, - Blocks.WHITE_STAINED_GLASS, Blocks.ORANGE_STAINED_GLASS, Blocks.LIGHT_BLUE_STAINED_GLASS, Blocks.YELLOW_STAINED_GLASS, Blocks.LIME_STAINED_GLASS, Blocks.PINK_STAINED_GLASS, Blocks.GRAY_STAINED_GLASS, Blocks.LIGHT_GRAY_STAINED_GLASS, Blocks.CYAN_STAINED_GLASS, Blocks.PURPLE_STAINED_GLASS, Blocks.BLUE_STAINED_GLASS, Blocks.BROWN_STAINED_GLASS, Blocks.GREEN_STAINED_GLASS, Blocks.RED_STAINED_GLASS, Blocks.BLACK_STAINED_GLASS, + Blocks.WHITE_STAINED_GLASS, Blocks.ORANGE_STAINED_GLASS, Blocks.LIGHT_BLUE_STAINED_GLASS, Blocks.YELLOW_STAINED_GLASS, Blocks.LIME_STAINED_GLASS, Blocks.PINK_STAINED_GLASS, Blocks.GRAY_STAINED_GLASS, Blocks.LIGHT_GRAY_STAINED_GLASS, Blocks.CYAN_STAINED_GLASS, Blocks.PURPLE_STAINED_GLASS, Blocks.BLUE_STAINED_GLASS, Blocks.GREEN_STAINED_GLASS, Blocks.RED_STAINED_GLASS, Blocks.BLACK_STAINED_GLASS, Blocks.CRIMSON_PRESSURE_PLATE, Blocks.CRIMSON_BUTTON, Blocks.CRIMSON_DOOR, Blocks.CRIMSON_FENCE, Blocks.CRIMSON_FENCE_GATE, Blocks.CRIMSON_PLANKS, Blocks.CRIMSON_SIGN, Blocks.CRIMSON_WALL_SIGN, Blocks.CRIMSON_SLAB, Blocks.CRIMSON_STAIRS, Blocks.CRIMSON_TRAPDOOR, Blocks.WARPED_PRESSURE_PLATE, Blocks.WARPED_BUTTON, Blocks.WARPED_DOOR, Blocks.WARPED_FENCE, Blocks.WARPED_FENCE_GATE, Blocks.WARPED_PLANKS, Blocks.WARPED_SIGN, Blocks.WARPED_WALL_SIGN, Blocks.WARPED_SLAB, Blocks.WARPED_STAIRS, Blocks.WARPED_TRAPDOOR, Blocks.SCAFFOLDING, Blocks.CHERRY_SIGN, Blocks.CHERRY_WALL_SIGN, Blocks.OAK_SIGN, Blocks.SPRUCE_SIGN, Blocks.ACACIA_SIGN, Blocks.ACACIA_WALL_SIGN, Blocks.BIRCH_SIGN, Blocks.BIRCH_WALL_SIGN, Blocks.DARK_OAK_SIGN, Blocks.DARK_OAK_WALL_SIGN, Blocks.JUNGLE_SIGN, Blocks.JUNGLE_WALL_SIGN, Blocks.MANGROVE_SIGN, Blocks.MANGROVE_WALL_SIGN, Blocks.SLIME_BLOCK, Blocks.SPONGE, Blocks.TINTED_GLASS, @@ -108,7 +109,7 @@ public class BaseFinder extends Module { private final Setting> Blawcks3 = sglists.add(new BlockListSetting.Builder() .name("Block List #3 (Default)") .description("If the total amount of any of these found is greater than the Number specified, throw a base location.") - .defaultValue(Blocks.CRAFTING_TABLE, Blocks.BREWING_STAND, Blocks.ENDER_CHEST, Blocks.SMOOTH_QUARTZ, Blocks.REDSTONE_BLOCK) + .defaultValue(Blocks.CRAFTING_TABLE, Blocks.BREWING_STAND, Blocks.ENDER_CHEST, Blocks.SMOOTH_QUARTZ, Blocks.REDSTONE_BLOCK, Blocks.BROWN_STAINED_GLASS) .filter(this::filterBlocks) .build() ); @@ -585,7 +586,8 @@ private void onReadPacket(PacketEvent.Receive event) { if (spawner.get()){ if (blerks.getBlock()==Blocks.SPAWNER)spawnerfound=true; //dungeon MOSSY_COBBLESTONE, mineshaft COBWEB, fortress NETHER_BRICK_FENCE, stronghold STONE_BRICK_STAIRS, bastion CHAIN - if (blerks.getBlock()==Blocks.MOSSY_COBBLESTONE || blerks.getBlock()==Blocks.COBWEB || blerks.getBlock()==Blocks.NETHER_BRICK_FENCE || blerks.getBlock()==Blocks.STONE_BRICK_STAIRS || blerks.getBlock()==Blocks.CHAIN)spawnernaturalblocks=true; + if (mc.world.getRegistryKey() == World.OVERWORLD && (blerks.getBlock()==Blocks.MOSSY_COBBLESTONE || blerks.getBlock()==Blocks.COBWEB || blerks.getBlock()==Blocks.STONE_BRICK_STAIRS))spawnernaturalblocks=true; + else if (mc.world.getRegistryKey() == World.NETHER && (blerks.getBlock()==Blocks.NETHER_BRICK_FENCE || blerks.getBlock()==Blocks.CHAIN))spawnernaturalblocks=true; } if (Blawcks1.get().size()>0){ if (Blawcks1.get().contains(blerks.getBlock())) { diff --git a/src/main/java/pwn/noobs/trouserstreak/modules/NewerNewChunks.java b/src/main/java/pwn/noobs/trouserstreak/modules/NewerNewChunks.java index d947c937a..722d25a7f 100644 --- a/src/main/java/pwn/noobs/trouserstreak/modules/NewerNewChunks.java +++ b/src/main/java/pwn/noobs/trouserstreak/modules/NewerNewChunks.java @@ -46,7 +46,7 @@ public class NewerNewChunks extends Module { public enum DetectMode { Normal, - IgnoreFlowBelow0, + IgnoreFlowBelow0AndTickExploit, Advanced } @@ -62,6 +62,12 @@ public enum DetectMode { .defaultValue(DetectMode.Normal) .build() ); + private final Setting tickexploit = sgGeneral.add(new BoolSetting.Builder() + .name("TickExploit") + .description("Estimates newchunks based on block ticking. THESE MAY POSSIBLY BE OLD. Advanced Mode needed to help determine false positives.") + .defaultValue(false) + .build() + ); private final Setting remove = sgcacheCdata.add(new BoolSetting.Builder() .name("RemoveOnModuleDisabled") .description("Removes the cached chunks when disabling the module.") @@ -152,6 +158,14 @@ public WWidget getWidget(GuiTheme theme) { .visible(() -> (shapeMode.get() == ShapeMode.Sides || shapeMode.get() == ShapeMode.Both) && detectmode.get()== DetectMode.Advanced) .build() ); + private final Setting tickexploitChunksSideColor = sgRender.add(new ColorSetting.Builder() + .name("TickExploitChunks-side-color") + .description("MAY POSSIBLY BE OLD. Color of the chunks that have been triggered via block ticking packets") + .defaultValue(new SettingColor(0, 0, 255, 75)) + .visible(() -> (shapeMode.get() == ShapeMode.Sides || shapeMode.get() == ShapeMode.Both) && detectmode.get()== DetectMode.Advanced && tickexploit.get()) + .build() + ); + private final Setting oldChunksSideColor = sgRender.add(new ColorSetting.Builder() .name("old-chunks-side-color") .description("Color of the chunks that have (most likely) been loaded before.") @@ -159,6 +173,7 @@ public WWidget getWidget(GuiTheme theme) { .visible(() -> shapeMode.get() == ShapeMode.Sides || shapeMode.get() == ShapeMode.Both) .build() ); + private final Setting newChunksLineColor = sgRender.add(new ColorSetting.Builder() .name("new-chunks-line-color") .description("Color of the chunks that are (most likely) completely new.") @@ -173,6 +188,14 @@ public WWidget getWidget(GuiTheme theme) { .visible(() -> (shapeMode.get() == ShapeMode.Lines || shapeMode.get() == ShapeMode.Both) && detectmode.get()== DetectMode.Advanced) .build() ); + private final Setting tickexploitChunksLineColor = sgRender.add(new ColorSetting.Builder() + .name("TickExploitChunks-line-color") + .description("MAY POSSIBLY BE OLD. Color of the chunks that have been triggered via block ticking packets") + .defaultValue(new SettingColor(0, 0, 255, 170)) + .visible(() -> (shapeMode.get() == ShapeMode.Lines || shapeMode.get() == ShapeMode.Both) && detectmode.get()== DetectMode.Advanced && tickexploit.get()) + .build() + ); + private final Setting oldChunksLineColor = sgRender.add(new ColorSetting.Builder() .name("old-chunks-line-color") .description("Color of the chunks that have (most likely) been loaded before.") @@ -189,7 +212,9 @@ public WWidget getWidget(GuiTheme theme) { private final Set newChunks = Collections.synchronizedSet(new HashSet<>()); private final Set oldChunks = Collections.synchronizedSet(new HashSet<>()); private final Set olderoldChunks = Collections.synchronizedSet(new HashSet<>()); + private final Set tickexploitChunks = Collections.synchronizedSet(new HashSet<>()); private static final Direction[] searchDirs = new Direction[] { Direction.EAST, Direction.NORTH, Direction.WEST, Direction.SOUTH, Direction.UP }; + private int errticks=0; private int autoreloadticks=0; private int loadingticks=0; private int reloadworld=0; @@ -198,8 +223,9 @@ public WWidget getWidget(GuiTheme theme) { public static int newchunksfound=0; public static int oldchunksfound=0; public static int olderoldchunksfound=0; + public static int tickexploitchunksfound=0; public NewerNewChunks() { - super(Trouser.Main,"NewerNewChunks", "Estimates if chunks are new or old by checking liquid flow."); + super(Trouser.Main,"NewerNewChunks", "Estimates new chunks by checking liquid flow, and by using block ticking packets."); } @Override public void onActivate() { @@ -207,6 +233,7 @@ public void onActivate() { newChunks.clear(); oldChunks.clear(); olderoldChunks.clear(); + tickexploitChunks.clear(); } if (mc.isInSingleplayer()==true){ String[] array = mc.getServer().getSavePath(WorldSavePath.ROOT).toString().replace(':', '_').split("/|\\\\"); @@ -236,6 +263,7 @@ public void onDeactivate() { newChunks.clear(); oldChunks.clear(); olderoldChunks.clear(); + tickexploitChunks.clear(); } super.onDeactivate(); } @@ -246,10 +274,12 @@ private void onScreenOpen(OpenScreenEvent event) { newchunksfound=0; oldchunksfound=0; olderoldchunksfound=0; + tickexploitchunksfound=0; if (worldleaveremove.get()) { newChunks.clear(); oldChunks.clear(); olderoldChunks.clear(); + tickexploitChunks.clear(); } } if (event.screen instanceof DownloadingTerrainScreen) { @@ -257,6 +287,7 @@ private void onScreenOpen(OpenScreenEvent event) { newchunksfound=0; oldchunksfound=0; olderoldchunksfound=0; + tickexploitchunksfound=0; reloadworld=0; } } @@ -266,10 +297,12 @@ private void onGameLeft(GameLeftEvent event) { newchunksfound=0; oldchunksfound=0; olderoldchunksfound=0; + tickexploitchunksfound=0; if (worldleaveremove.get()) { newChunks.clear(); oldChunks.clear(); olderoldChunks.clear(); + tickexploitChunks.clear(); } } @@ -281,12 +314,21 @@ private void onPreTick(TickEvent.Pre event) { newChunks.clear(); oldChunks.clear(); olderoldChunks.clear(); + tickexploitChunks.clear(); new File("NewChunks/"+serverip+"/"+world+"/NewChunkData.txt").delete(); new File("NewChunks/"+serverip+"/"+world+"/OldChunkData.txt").delete(); new File("NewChunks/"+serverip+"/"+world+"/FlowIsBelowY0ChunkData.txt").delete(); + new File("NewChunks/"+serverip+"/"+world+"/TickExploitChunkData.txt").delete(); error("Chunk Data deleted for this Dimension."); deletewarning=0; } + if (detectmode.get()== DetectMode.Normal && tickexploit.get()){ + if (errticks<6){ + errticks++;} + if (errticks==5){ + error("ADVANCED MODE RECOMMENDED. Required to determine false positives from the Tick Exploit from the OldChunks."); + } + } else errticks=0; if (load.get()){ loadingticks++; if (loadingticks<2){ @@ -302,6 +344,7 @@ private void onPreTick(TickEvent.Pre event) { newchunksfound=0; oldchunksfound=0; olderoldchunksfound=0; + tickexploitchunksfound=0; chunkcounter=false;} if (chunkcounter=true && chunkcounterticks<1){ try { @@ -331,6 +374,15 @@ private void onPreTick(TickEvent.Pre event) { } catch (IOException e) { e.printStackTrace(); } + try { + List allLines = Files.readAllLines(Paths.get("NewChunks/"+serverip+"/"+world+"/TickExploitChunkData.txt")); + + for (String line : allLines) { + tickexploitchunksfound++; + } + } catch (IOException e) { + e.printStackTrace(); + } } } @@ -348,6 +400,7 @@ private void onPreTick(TickEvent.Pre event) { newChunks.clear(); oldChunks.clear(); olderoldChunks.clear(); + tickexploitChunks.clear(); if (load.get()){ loadData(); } @@ -364,6 +417,7 @@ private void onPreTick(TickEvent.Pre event) { newChunks.clear(); oldChunks.clear(); olderoldChunks.clear(); + tickexploitChunks.clear(); } loadData(); } @@ -387,7 +441,24 @@ private void onRender(Render3DEvent event) { render(new Box(c.getStartPos().add(0, renderHeight.get(), 0), c.getStartPos().add(16, renderHeight.get(), 16)), olderoldChunksSideColor.get(), olderoldChunksLineColor.get(), shapeMode.get(), event); } else if (detectmode.get()== DetectMode.Normal) { render(new Box(c.getStartPos().add(0, renderHeight.get(), 0), c.getStartPos().add(16, renderHeight.get(), 16)), newChunksSideColor.get(), newChunksLineColor.get(), shapeMode.get(), event); - } else if (detectmode.get()== DetectMode.IgnoreFlowBelow0) { + } else if (detectmode.get()== DetectMode.IgnoreFlowBelow0AndTickExploit) { + render(new Box(c.getStartPos().add(0, renderHeight.get(), 0), c.getStartPos().add(16, renderHeight.get(), 16)), oldChunksSideColor.get(), oldChunksLineColor.get(), shapeMode.get(), event); + } + } + } + } + } + if (tickexploitChunksLineColor.get().a > 5 || tickexploitChunksSideColor.get().a > 5) { + synchronized (tickexploitChunks) { + for (ChunkPos c : tickexploitChunks) { + if (mc.getCameraEntity().getBlockPos().isWithinDistance(c.getStartPos(), renderDistance.get()*16)) { + if (detectmode.get()== DetectMode.Advanced && tickexploit.get()) { + render(new Box(c.getStartPos().add(0, renderHeight.get(), 0), c.getStartPos().add(16, renderHeight.get(), 16)), tickexploitChunksSideColor.get(), tickexploitChunksLineColor.get(), shapeMode.get(), event); + } else if ((detectmode.get()== DetectMode.Normal) && tickexploit.get()) { + render(new Box(c.getStartPos().add(0, renderHeight.get(), 0), c.getStartPos().add(16, renderHeight.get(), 16)), newChunksSideColor.get(), newChunksLineColor.get(), shapeMode.get(), event); + } else if ((detectmode.get()== DetectMode.IgnoreFlowBelow0AndTickExploit) && tickexploit.get()) { + render(new Box(c.getStartPos().add(0, renderHeight.get(), 0), c.getStartPos().add(16, renderHeight.get(), 16)), oldChunksSideColor.get(), oldChunksLineColor.get(), shapeMode.get(), event); + } else if ((detectmode.get()== DetectMode.Advanced | detectmode.get()== DetectMode.Normal | detectmode.get()== DetectMode.IgnoreFlowBelow0AndTickExploit) && !tickexploit.get()) { render(new Box(c.getStartPos().add(0, renderHeight.get(), 0), c.getStartPos().add(16, renderHeight.get(), 16)), oldChunksSideColor.get(), oldChunksLineColor.get(), shapeMode.get(), event); } } @@ -422,12 +493,14 @@ private void onReadPacket(PacketEvent.Receive event) { for (Direction dir: searchDirs) { if (pos.offset(dir).getY()>0 && mc.world.getBlockState(pos.offset(dir)).getFluidState().isStill() && (!newChunks.contains(chunkPos) && !oldChunks.contains(chunkPos))) { if (olderoldChunks.contains(chunkPos)) olderoldChunks.remove(chunkPos); + if (tickexploitChunks.contains(chunkPos)) tickexploitChunks.remove(chunkPos); newChunks.add(chunkPos); if (save.get()){ saveNewChunkData(); } return; }else if (pos.offset(dir).getY()<=0 && mc.world.getBlockState(pos.offset(dir)).getFluidState().isStill() && (!newChunks.contains(chunkPos) && !olderoldChunks.contains(chunkPos) && !oldChunks.contains(chunkPos))) { + if (tickexploitChunks.contains(chunkPos)) tickexploitChunks.remove(chunkPos); olderoldChunks.add(chunkPos); if (save.get()){ saveOlderOldChunkData(); @@ -440,18 +513,37 @@ private void onReadPacket(PacketEvent.Receive event) { } else if (event.packet instanceof BlockUpdateS2CPacket) { BlockUpdateS2CPacket packet = (BlockUpdateS2CPacket) event.packet; - + if (tickexploit.get()){ + try { + if (!packet.getState().hasRandomTicks() && !tickexploitChunks.contains(chunkPos) && !oldChunks.contains(chunkPos) && !olderoldChunks.contains(chunkPos) && !newChunks.contains(chunkPos)){ + tickexploitChunks.add(chunkPos); + if (save.get()){ + saveTickExploitChunkData(); + } + } else if (packet.getState().hasRandomTicks() && !tickexploitChunks.contains(chunkPos) && !oldChunks.contains(chunkPos) && !olderoldChunks.contains(chunkPos) && !newChunks.contains(chunkPos)){ + oldChunks.add(chunkPos); + if (save.get()){ + saveOldChunkData(); + } + } + } + catch (Exception e){ + e.printStackTrace(); + } + } if (!packet.getState().getFluidState().isEmpty() && !packet.getState().getFluidState().isStill()) { chunkPos = new ChunkPos(packet.getPos()); for (Direction dir: searchDirs) { if (packet.getPos().offset(dir).getY()>0 && mc.world.getBlockState(packet.getPos().offset(dir)).getFluidState().isStill() && (!newChunks.contains(chunkPos) && !oldChunks.contains(chunkPos))) { if (olderoldChunks.contains(chunkPos)) olderoldChunks.remove(chunkPos); + if (tickexploitChunks.contains(chunkPos)) tickexploitChunks.remove(chunkPos); newChunks.add(chunkPos); if (save.get()){ saveNewChunkData(); } return; }else if (packet.getPos().offset(dir).getY()<=0 && mc.world.getBlockState(packet.getPos().offset(dir)).getFluidState().isStill() && (!newChunks.contains(chunkPos) && !olderoldChunks.contains(chunkPos) && !oldChunks.contains(chunkPos))) { + if (tickexploitChunks.contains(chunkPos)) tickexploitChunks.remove(chunkPos); olderoldChunks.add(chunkPos); if (save.get()){ saveOlderOldChunkData(); @@ -478,7 +570,7 @@ else if (event.packet instanceof ChunkDataS2CPacket && mc.world != null) { for (int y = mc.world.getBottomY(); y < mc.world.getTopY(); y++) { for (int z = 0; z < 16; z++) { FluidState fluid = chunk.getFluidState(x, y, z); - if (!oldChunks.contains(oldpos) && !olderoldChunks.contains(oldpos) && !newChunks.contains(oldpos) && !fluid.isEmpty() && !fluid.isStill()) { + if (!oldChunks.contains(oldpos) && !tickexploitChunks.contains(oldpos) && !olderoldChunks.contains(oldpos) && !newChunks.contains(oldpos) && !fluid.isEmpty() && !fluid.isStill()) { oldChunks.add(oldpos); if (save.get()){ saveOldChunkData(); @@ -515,7 +607,7 @@ private void loadData() { int X = Integer.parseInt(array[0].replaceAll("\\[", "").replaceAll("\\]","")); int Z = Integer.parseInt(array[1].replaceAll("\\[", "").replaceAll("\\]","")); chunkPos = new ChunkPos(X,Z); - if (!newChunks.contains(chunkPos) && !olderoldChunks.contains(chunkPos) && !oldChunks.contains(chunkPos)){ + if (!tickexploitChunks.contains(chunkPos) && !newChunks.contains(chunkPos) && !olderoldChunks.contains(chunkPos) && !oldChunks.contains(chunkPos)){ newChunks.add(chunkPos);} } } catch (IOException e) { @@ -530,12 +622,28 @@ private void loadData() { int X = Integer.parseInt(array[0].replaceAll("\\[", "").replaceAll("\\]","")); int Z = Integer.parseInt(array[1].replaceAll("\\[", "").replaceAll("\\]","")); chunkPos = new ChunkPos(X,Z); - if (!newChunks.contains(chunkPos) && !olderoldChunks.contains(chunkPos) && !oldChunks.contains(chunkPos)){ + if (!tickexploitChunks.contains(chunkPos) && !newChunks.contains(chunkPos) && !olderoldChunks.contains(chunkPos) && !oldChunks.contains(chunkPos)){ olderoldChunks.add(chunkPos);} } } catch (IOException e) { e.printStackTrace(); } + try { + List allLines = Files.readAllLines(Paths.get("NewChunks/"+serverip+"/"+world+"/TickExploitChunkData.txt")); + + for (String line : allLines) { + String s = line; + String[] array = s.split(", "); + int X = Integer.parseInt(array[0].replaceAll("\\[", "").replaceAll("\\]","")); + int Z = Integer.parseInt(array[1].replaceAll("\\[", "").replaceAll("\\]","")); + chunkPos = new ChunkPos(X,Z); + if (!tickexploitChunks.contains(chunkPos) && !newChunks.contains(chunkPos) && !olderoldChunks.contains(chunkPos) && !oldChunks.contains(chunkPos)){ + tickexploitChunks.add(chunkPos ); + } + } + } catch (IOException e) { + e.printStackTrace(); + } } private void saveNewChunkData() { try { @@ -570,4 +678,15 @@ private void saveOlderOldChunkData() { e.printStackTrace(); } } + private void saveTickExploitChunkData() { + try { + new File("NewChunks/"+serverip+"/"+world).mkdirs(); + FileWriter writer = new FileWriter("NewChunks/"+serverip+"/"+world+"/TickExploitChunkData.txt", true); + writer.write(String.valueOf(chunkPos)); + writer.write("\r\n"); // write new line + writer.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } } \ No newline at end of file