From 2ef8ab2633dc42167956ae34cbc7ac74eb3746ac Mon Sep 17 00:00:00 2001 From: Roman Danilov Date: Sun, 5 Jan 2025 18:15:23 +0500 Subject: [PATCH 1/4] Fix --- .github/workflows/dev_build.yml | 4 ++-- gradle.properties | 2 +- .../features/commands/TrainerCommand.java | 21 +++++++++++++------ 3 files changed, 18 insertions(+), 9 deletions(-) diff --git a/.github/workflows/dev_build.yml b/.github/workflows/dev_build.yml index 30b546b..398c7f5 100644 --- a/.github/workflows/dev_build.yml +++ b/.github/workflows/dev_build.yml @@ -26,8 +26,8 @@ jobs: uses: marvinpinto/action-automatic-releases@latest with: repo_token: '${{ secrets.GITHUB_TOKEN }}' - automatic_release_tag: "1.21.1_1.0.0.1" + automatic_release_tag: "1.21.1_1.0.0.2" prerelease: true - title: "1.21.1 | 1.0.0.1" + title: "1.21.1 | 1.0.0.2" files: | ./build/libs/*.jar diff --git a/gradle.properties b/gradle.properties index 16277b4..c4cbe64 100644 --- a/gradle.properties +++ b/gradle.properties @@ -6,7 +6,7 @@ yarn_mappings=1.21+build.3 loader_version=0.15.11 # Mod Properties -mod_version=1.21.1_1.0.0.1 +mod_version=1.21.1_1.0.0.2 maven_group=nekiplay.protrainer archives_base_name=pro-trainer diff --git a/src/main/java/nekiplay/protrainer/features/commands/TrainerCommand.java b/src/main/java/nekiplay/protrainer/features/commands/TrainerCommand.java index a79bfa0..9206cad 100644 --- a/src/main/java/nekiplay/protrainer/features/commands/TrainerCommand.java +++ b/src/main/java/nekiplay/protrainer/features/commands/TrainerCommand.java @@ -6,6 +6,7 @@ import com.mojang.brigadier.builder.LiteralArgumentBuilder; import meteordevelopment.meteorclient.MeteorClient; import meteordevelopment.meteorclient.commands.Command; +import meteordevelopment.meteorclient.events.game.GameLeftEvent; import meteordevelopment.meteorclient.events.packets.PacketEvent; import meteordevelopment.orbit.EventHandler; import nekiplay.Main; @@ -29,6 +30,8 @@ import java.nio.file.Path; import java.util.ArrayList; import java.util.List; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; import java.util.stream.Collectors; public class TrainerCommand extends Command { @@ -41,6 +44,7 @@ public TrainerCommand() { public Gson gson = new Gson(); public boolean started = false; public Vec3d start_position = new Vec3d(0, 0, 0); + private final ExecutorService workerThread = Executors.newSingleThreadExecutor(); public List replaced = new ArrayList<>(); @@ -68,7 +72,8 @@ public void build(LiteralArgumentBuilder builder) { dir.mkdir(); } File dir2 = new File(dir, map + ".json"); - + start_position = mc.player.getPos(); + started = true; try { BufferedReader reader = Files.newBufferedReader(Path.of(dir2.toURI()), StandardCharsets.UTF_8); try { @@ -86,6 +91,7 @@ public void build(LiteralArgumentBuilder builder) { replaced.add(blockData); mc.world.setBlockState(pos, state); + mc.player.setPos(start_position.x, start_position.y, start_position.z); } } catch (JsonSyntaxException e) { @@ -95,9 +101,8 @@ public void build(LiteralArgumentBuilder builder) { } catch (IOException e) { ProTrainerAddon.LOG.error(Main.METEOR_LOGPREFIX + " Error in custom block: " + e); } + mc.player.setPos(start_position.x, start_position.y, start_position.z); info("Successfully loaded"); - start_position = mc.player.getPos(); - started = true; return SINGLE_SUCCESS; } else { @@ -111,13 +116,13 @@ public void build(LiteralArgumentBuilder builder) { return SINGLE_SUCCESS; } for (BlockData replace : replaced) { - mc.player.setPos(start_position.x, start_position.y, start_position.z); BlockState state = Block.getStateFromRawId(replace.blockId); BlockPos pos = new BlockPos((int) replace.blockPosition.x, (int) replace.blockPosition.y, (int) replace.blockPosition.z); mc.world.setBlockState(pos, state); mc.player.setPos(start_position.x, start_position.y, start_position.z); - started = false; } + mc.player.setPos(start_position.x, start_position.y, start_position.z); + started = false; replaced.clear(); info("Parkour has been stopped"); return SINGLE_SUCCESS; @@ -135,7 +140,6 @@ public void build(LiteralArgumentBuilder builder) { Vec3d start = mc.player.getPos(); ProTrainerMap trainerMap = new ProTrainerMap(); trainerMap.start = new BlockPosition(start); - List blocks = collectBlocksBetween(mc.world, pos1, pos2); List sortedBlocks = new ArrayList<>(); for (BlockPos pos : blocks) { @@ -208,4 +212,9 @@ private void onSendPacket(PacketEvent.Send event) { } } } + + @EventHandler + private void onGameLeft(GameLeftEvent event) { + started = false; + } } From 5a6e05c93fd78d5db8055bab3e769a4222696ffb Mon Sep 17 00:00:00 2001 From: Roman Danilov Date: Sun, 5 Jan 2025 18:54:09 +0500 Subject: [PATCH 2/4] Update ProTrainerAddon.java --- src/main/java/nekiplay/protrainer/ProTrainerAddon.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/main/java/nekiplay/protrainer/ProTrainerAddon.java b/src/main/java/nekiplay/protrainer/ProTrainerAddon.java index 79d3123..607a4ba 100644 --- a/src/main/java/nekiplay/protrainer/ProTrainerAddon.java +++ b/src/main/java/nekiplay/protrainer/ProTrainerAddon.java @@ -24,13 +24,15 @@ public static ProTrainerAddon getInstance() { public void onInitialize() { instance = this; - LOG.info(METEOR_LOGPREFIX + " Initializing..."); + LOG.info("Initializing..."); TrainerCommand command = new TrainerCommand(); Commands.add(command); MeteorClient.EVENT_BUS.subscribe(command); + LOG.info("Initializing done"); + } @Override From d0106d97c9ca4fd9ad0f48e786653259ff10f5fb Mon Sep 17 00:00:00 2001 From: Roman Danilov Date: Sun, 5 Jan 2025 20:50:25 +0500 Subject: [PATCH 3/4] Update TrainerCommand.java --- .../protrainer/features/commands/TrainerCommand.java | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/src/main/java/nekiplay/protrainer/features/commands/TrainerCommand.java b/src/main/java/nekiplay/protrainer/features/commands/TrainerCommand.java index 9206cad..c3ed3e9 100644 --- a/src/main/java/nekiplay/protrainer/features/commands/TrainerCommand.java +++ b/src/main/java/nekiplay/protrainer/features/commands/TrainerCommand.java @@ -30,8 +30,6 @@ import java.nio.file.Path; import java.util.ArrayList; import java.util.List; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; import java.util.stream.Collectors; public class TrainerCommand extends Command { @@ -44,7 +42,6 @@ public TrainerCommand() { public Gson gson = new Gson(); public boolean started = false; public Vec3d start_position = new Vec3d(0, 0, 0); - private final ExecutorService workerThread = Executors.newSingleThreadExecutor(); public List replaced = new ArrayList<>(); @@ -96,7 +93,6 @@ public void build(LiteralArgumentBuilder builder) { } catch (JsonSyntaxException e) { ProTrainerAddon.LOG.error(Main.METEOR_LOGPREFIX + " Error in custom block: " + e); - } } catch (IOException e) { ProTrainerAddon.LOG.error(Main.METEOR_LOGPREFIX + " Error in custom block: " + e); @@ -113,17 +109,18 @@ public void build(LiteralArgumentBuilder builder) { builder.then(literal("stop").executes(context -> { if (!started) { info("Parkour hasn't started"); + replaced.clear(); return SINGLE_SUCCESS; } for (BlockData replace : replaced) { BlockState state = Block.getStateFromRawId(replace.blockId); BlockPos pos = new BlockPos((int) replace.blockPosition.x, (int) replace.blockPosition.y, (int) replace.blockPosition.z); + assert mc.world != null; mc.world.setBlockState(pos, state); - mc.player.setPos(start_position.x, start_position.y, start_position.z); } mc.player.setPos(start_position.x, start_position.y, start_position.z); - started = false; replaced.clear(); + started = false; info("Parkour has been stopped"); return SINGLE_SUCCESS; })); From eac1fd0a5184708a77950a74f1232aed50dbd8cc Mon Sep 17 00:00:00 2001 From: Roman Danilov Date: Mon, 13 Jan 2025 14:48:07 +0500 Subject: [PATCH 4/4] async loading parkour --- .../nekiplay/protrainer/ProTrainerAddon.java | 5 + .../nekiplay/protrainer/data/BlockData.java | 16 ++- .../protrainer/data/BlockDataAndPosition.java | 15 +++ .../protrainer/data/BlockPosition.java | 24 ++++ .../protrainer/data/ProTrainerMap.java | 5 +- .../features/commands/TrainerCommand.java | 126 +++++++++++------- .../features/modules/ProTrainerModule.java | 15 +++ 7 files changed, 157 insertions(+), 49 deletions(-) create mode 100644 src/main/java/nekiplay/protrainer/data/BlockDataAndPosition.java diff --git a/src/main/java/nekiplay/protrainer/ProTrainerAddon.java b/src/main/java/nekiplay/protrainer/ProTrainerAddon.java index 607a4ba..2830439 100644 --- a/src/main/java/nekiplay/protrainer/ProTrainerAddon.java +++ b/src/main/java/nekiplay/protrainer/ProTrainerAddon.java @@ -3,7 +3,9 @@ import meteordevelopment.meteorclient.MeteorClient; import meteordevelopment.meteorclient.addons.GithubRepo; import meteordevelopment.meteorclient.commands.Commands; +import meteordevelopment.meteorclient.systems.modules.Modules; import nekiplay.protrainer.features.commands.TrainerCommand; +import nekiplay.protrainer.features.modules.ProTrainerModule; import net.fabricmc.loader.api.FabricLoader; import meteordevelopment.meteorclient.addons.MeteorAddon; import org.slf4j.Logger; @@ -20,12 +22,15 @@ public static ProTrainerAddon getInstance() { return instance; } + public ProTrainerModule module = new ProTrainerModule(); + @Override public void onInitialize() { instance = this; LOG.info("Initializing..."); + Modules.get().add(module); TrainerCommand command = new TrainerCommand(); Commands.add(command); diff --git a/src/main/java/nekiplay/protrainer/data/BlockData.java b/src/main/java/nekiplay/protrainer/data/BlockData.java index 09d132f..54d3bdc 100644 --- a/src/main/java/nekiplay/protrainer/data/BlockData.java +++ b/src/main/java/nekiplay/protrainer/data/BlockData.java @@ -1,6 +1,18 @@ package nekiplay.protrainer.data; +import net.minecraft.block.Block; +import net.minecraft.block.BlockState; + public class BlockData { - public int blockId; - public BlockPosition blockPosition; + public int blockId = 0; + + public BlockData() {} + + public BlockData(int rawId) { + this.blockId = rawId; + } + + public BlockState toBlockState() { + return Block.getStateFromRawId(blockId); + } } diff --git a/src/main/java/nekiplay/protrainer/data/BlockDataAndPosition.java b/src/main/java/nekiplay/protrainer/data/BlockDataAndPosition.java new file mode 100644 index 0000000..b4ff042 --- /dev/null +++ b/src/main/java/nekiplay/protrainer/data/BlockDataAndPosition.java @@ -0,0 +1,15 @@ +package nekiplay.protrainer.data; + +import net.minecraft.block.Block; +import net.minecraft.block.BlockState; +import net.minecraft.util.math.BlockPos; + +public class BlockDataAndPosition { + public int blockId = 0; + public BlockPosition blockPosition; + + @Override + public int hashCode() { + return blockPosition.hashCode(); + } +} diff --git a/src/main/java/nekiplay/protrainer/data/BlockPosition.java b/src/main/java/nekiplay/protrainer/data/BlockPosition.java index 538a5df..b82e2ba 100644 --- a/src/main/java/nekiplay/protrainer/data/BlockPosition.java +++ b/src/main/java/nekiplay/protrainer/data/BlockPosition.java @@ -1,5 +1,8 @@ package nekiplay.protrainer.data; +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import net.fabricmc.loader.impl.lib.sat4j.core.Vec; import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.Vec3d; @@ -23,4 +26,25 @@ public BlockPosition(Vec3d pos) { public BlockPosition() { } + + @Override + public int hashCode() { + return new Vec3d(x, y, z).hashCode(); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + BlockPosition other = (BlockPosition) obj; + if (x != other.x) + return false; + if (y != other.y) + return false; + return z == other.z; + } } diff --git a/src/main/java/nekiplay/protrainer/data/ProTrainerMap.java b/src/main/java/nekiplay/protrainer/data/ProTrainerMap.java index 115441c..f0e1922 100644 --- a/src/main/java/nekiplay/protrainer/data/ProTrainerMap.java +++ b/src/main/java/nekiplay/protrainer/data/ProTrainerMap.java @@ -1,9 +1,10 @@ package nekiplay.protrainer.data; import java.util.ArrayList; +import java.util.List; public class ProTrainerMap { - public ArrayList blocks = new ArrayList<>(); - public BlockPosition start = new BlockPosition(); + public List blocks = new ArrayList<>(); + } diff --git a/src/main/java/nekiplay/protrainer/features/commands/TrainerCommand.java b/src/main/java/nekiplay/protrainer/features/commands/TrainerCommand.java index c3ed3e9..c3c4539 100644 --- a/src/main/java/nekiplay/protrainer/features/commands/TrainerCommand.java +++ b/src/main/java/nekiplay/protrainer/features/commands/TrainerCommand.java @@ -6,12 +6,13 @@ import com.mojang.brigadier.builder.LiteralArgumentBuilder; import meteordevelopment.meteorclient.MeteorClient; import meteordevelopment.meteorclient.commands.Command; -import meteordevelopment.meteorclient.events.game.GameLeftEvent; import meteordevelopment.meteorclient.events.packets.PacketEvent; +import meteordevelopment.meteorclient.events.world.BlockUpdateEvent; import meteordevelopment.orbit.EventHandler; import nekiplay.Main; import nekiplay.protrainer.ProTrainerAddon; import nekiplay.protrainer.data.BlockData; +import nekiplay.protrainer.data.BlockDataAndPosition; import nekiplay.protrainer.data.BlockPosition; import nekiplay.protrainer.data.ProTrainerMap; import nekiplay.protrainer.mixin.minecraft.PlayerMoveC2SPacketAccesor; @@ -29,6 +30,7 @@ import java.nio.file.Files; import java.nio.file.Path; import java.util.ArrayList; +import java.util.HashMap; import java.util.List; import java.util.stream.Collectors; @@ -43,7 +45,8 @@ public TrainerCommand() { public boolean started = false; public Vec3d start_position = new Vec3d(0, 0, 0); - public List replaced = new ArrayList<>(); + public List replaced = new ArrayList<>(); + public HashMap map_blocks = new HashMap<>(); public void build(LiteralArgumentBuilder builder) { builder.then(literal("pos1").executes(context -> { @@ -69,36 +72,53 @@ public void build(LiteralArgumentBuilder builder) { dir.mkdir(); } File dir2 = new File(dir, map + ".json"); - start_position = mc.player.getPos(); - started = true; - try { - BufferedReader reader = Files.newBufferedReader(Path.of(dir2.toURI()), StandardCharsets.UTF_8); - try { - String json = reader.lines().collect(Collectors.joining()); - - ProTrainerMap proTrainerMap = gson.fromJson(json, ProTrainerMap.class); - for (BlockData data : proTrainerMap.blocks) { - assert mc.world != null; - BlockState state = Block.getStateFromRawId(data.blockId); - BlockPos pos = new BlockPos((int) (data.blockPosition.x + mc.player.getBlockX()), (int) (data.blockPosition.y + mc.player.getBlockY()), (int) (data.blockPosition.z + mc.player.getBlockZ())); - BlockData blockData = new BlockData(); - blockData.blockPosition = new BlockPosition(pos); - blockData.blockId = Block.getRawIdFromState(mc.world.getBlockState(pos)); - replaced.add(blockData); + start_position = mc.player.getPos(); - mc.world.setBlockState(pos, state); - mc.player.setPos(start_position.x, start_position.y, start_position.z); + new Thread(() -> { + try { + map_blocks.clear(); + BufferedReader reader = Files.newBufferedReader(Path.of(dir2.toURI()), StandardCharsets.UTF_8); + try { + String json = reader.lines().collect(Collectors.joining()); + int counter = 0; + ProTrainerMap proTrainerMap = gson.fromJson(json, ProTrainerMap.class); + for (BlockDataAndPosition data : proTrainerMap.blocks) { + assert mc.world != null; + BlockState state = Block.getStateFromRawId(data.blockId); + mc.player.setPos(start_position.x, start_position.y, start_position.z); + BlockPos pos = new BlockPos((int) (data.blockPosition.x + mc.player.getBlockX()), (int) (data.blockPosition.y + mc.player.getBlockY()), (int) (data.blockPosition.z + mc.player.getBlockZ())); + + BlockDataAndPosition blockData = new BlockDataAndPosition(); + blockData.blockPosition = new BlockPosition(pos); + blockData.blockId = Block.getRawIdFromState(mc.world.getBlockState(pos)); + replaced.add(blockData); + map_blocks.put(new BlockPosition(pos), new BlockData(data.blockId)); + + BlockState original_state = mc.world.getBlockState(pos); + if (original_state.getBlock() != state.getBlock()) { + mc.execute(() -> mc.world.setBlockState(pos, state)); + if (counter >= ProTrainerAddon.getInstance().module.loadingSpeed.get()) { + Thread.sleep(1); + counter = 0; + } else { + counter++; + } + } + } + info("Successfully loaded"); + + } catch (JsonSyntaxException e) { + ProTrainerAddon.LOG.error(Main.METEOR_LOGPREFIX + " Error in custom block: " + e); + + } catch (InterruptedException e) { + ProTrainerAddon.LOG.error(Main.METEOR_LOGPREFIX + " Error in custom block: " + e); } - - } catch (JsonSyntaxException e) { + } catch (IOException e) { ProTrainerAddon.LOG.error(Main.METEOR_LOGPREFIX + " Error in custom block: " + e); } - } catch (IOException e) { - ProTrainerAddon.LOG.error(Main.METEOR_LOGPREFIX + " Error in custom block: " + e); - } - mc.player.setPos(start_position.x, start_position.y, start_position.z); - info("Successfully loaded"); + started = true; + }).start(); return SINGLE_SUCCESS; } else { @@ -109,19 +129,31 @@ public void build(LiteralArgumentBuilder builder) { builder.then(literal("stop").executes(context -> { if (!started) { info("Parkour hasn't started"); - replaced.clear(); return SINGLE_SUCCESS; } - for (BlockData replace : replaced) { - BlockState state = Block.getStateFromRawId(replace.blockId); - BlockPos pos = new BlockPos((int) replace.blockPosition.x, (int) replace.blockPosition.y, (int) replace.blockPosition.z); - assert mc.world != null; - mc.world.setBlockState(pos, state); - } - mc.player.setPos(start_position.x, start_position.y, start_position.z); - replaced.clear(); - started = false; - info("Parkour has been stopped"); + new Thread(() -> { + int counter = 0; + map_blocks.clear(); + for (BlockDataAndPosition replace : replaced) { + BlockState state = Block.getStateFromRawId(replace.blockId); + BlockPos pos = new BlockPos((int) replace.blockPosition.x, (int) replace.blockPosition.y, (int) replace.blockPosition.z); + mc.execute(() -> mc.world.setBlockState(pos, state)); + if (counter >= ProTrainerAddon.getInstance().module.loadingSpeed.get()) { + try { + Thread.sleep(1); + } catch (InterruptedException e) { + throw new RuntimeException(e); + } + counter = 0; + } else { + counter++; + } + } + mc.player.setPos(start_position.x, start_position.y, start_position.z); + started = false; + replaced.clear(); + info("Parkour has been stopped"); + }).start(); return SINGLE_SUCCESS; })); builder.then(literal("save").then(argument("map", StringArgumentType.string()).executes(context -> { @@ -136,7 +168,7 @@ public void build(LiteralArgumentBuilder builder) { String map = context.getArgument("map", String.class); Vec3d start = mc.player.getPos(); ProTrainerMap trainerMap = new ProTrainerMap(); - trainerMap.start = new BlockPosition(start); + List blocks = collectBlocksBetween(mc.world, pos1, pos2); List sortedBlocks = new ArrayList<>(); for (BlockPos pos : blocks) { @@ -145,7 +177,7 @@ public void build(LiteralArgumentBuilder builder) { for (BlockPos sorted : sortedBlocks) { var unsorted = sorted.add(new Vec3i(mc.player.getBlockX(), mc.player.getBlockY(), mc.player.getBlockZ())); BlockState state = mc.world.getBlockState(unsorted); - BlockData blockData = new BlockData(); + BlockDataAndPosition blockData = new BlockDataAndPosition(); blockData.blockId = Block.getRawIdFromState(state); blockData.blockPosition = new BlockPosition(sorted); trainerMap.blocks.add(blockData); @@ -197,6 +229,15 @@ public List collectBlocksBetween(World world, BlockPos start, BlockPos return blocks; } + @EventHandler + private void onBlockUpdate(BlockUpdateEvent event) { + BlockPosition position = new BlockPosition(event.pos); + if (map_blocks.containsKey(position) && started) { + BlockData data = map_blocks.get(position); + mc.world.setBlockState(event.pos, Block.getStateFromRawId(data.blockId)); + } + } + @EventHandler private void onSendPacket(PacketEvent.Send event) { if (event.packet instanceof PlayerMoveC2SPacket playerMoveC2SPacket) { @@ -209,9 +250,4 @@ private void onSendPacket(PacketEvent.Send event) { } } } - - @EventHandler - private void onGameLeft(GameLeftEvent event) { - started = false; - } } diff --git a/src/main/java/nekiplay/protrainer/features/modules/ProTrainerModule.java b/src/main/java/nekiplay/protrainer/features/modules/ProTrainerModule.java index a208961..75ce6a7 100644 --- a/src/main/java/nekiplay/protrainer/features/modules/ProTrainerModule.java +++ b/src/main/java/nekiplay/protrainer/features/modules/ProTrainerModule.java @@ -1,5 +1,8 @@ package nekiplay.protrainer.features.modules; +import meteordevelopment.meteorclient.settings.IntSetting; +import meteordevelopment.meteorclient.settings.Setting; +import meteordevelopment.meteorclient.settings.SettingGroup; import meteordevelopment.meteorclient.systems.modules.Categories; import meteordevelopment.meteorclient.systems.modules.Module; @@ -8,5 +11,17 @@ public ProTrainerModule() { super(Categories.World, "pro-trainer", "Settings for trainer command"); } + private final SettingGroup defaultGroup = settings.getDefaultGroup(); + + public final Setting loadingSpeed = defaultGroup.add(new IntSetting.Builder() + .name("loading-speed") + .description("World loading speed in blocks.") + .defaultValue(8) + .min(1) + .max(64) + .sliderMin(1) + .sliderMax(64) + .build() + ); }