From 163e97aad624edf0f3f7b15d64d639a4c754cba2 Mon Sep 17 00:00:00 2001 From: Jack Date: Thu, 23 Nov 2023 20:36:51 +1000 Subject: [PATCH 01/23] Add issues links and link to Discord for ModMenu --- fabric/src/main/resources/fabric.mod.json | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/fabric/src/main/resources/fabric.mod.json b/fabric/src/main/resources/fabric.mod.json index 6fd5c42df..c0a4d7169 100644 --- a/fabric/src/main/resources/fabric.mod.json +++ b/fabric/src/main/resources/fabric.mod.json @@ -11,7 +11,8 @@ ], "contact": { "homepage": "https://github.com/cabaletta/baritone", - "sources": "https://github.com/cabaletta/baritone" + "sources": "https://github.com/cabaletta/baritone", + "issues": "https://github.com/cabaletta/baritone/issues" }, "license": "LGPL-3.0", @@ -27,5 +28,12 @@ "depends": { "fabricloader": ">=0.14.22", "minecraft": "1.20.2" + }, + "custom": { + "modmenu": { + "links": { + "modmenu.discord": "https://discord.gg/s6fRBAUpmr" + } + } } } From bac24af90e2d7335f6f16a89a1d8f83c41930417 Mon Sep 17 00:00:00 2001 From: ZacSharp <68165024+ZacSharp@users.noreply.github.com> Date: Sat, 14 Dec 2024 16:29:49 +0100 Subject: [PATCH 02/23] Update SETUP.md --- SETUP.md | 81 +++++++++++++++++++++++++++++++------------------------- 1 file changed, 45 insertions(+), 36 deletions(-) diff --git a/SETUP.md b/SETUP.md index 1daeb9f89..1bf6e5dbd 100644 --- a/SETUP.md +++ b/SETUP.md @@ -1,78 +1,87 @@ # Installation -The easiest way to install Baritone is to install [Impact](https://impactclient.net/), which comes with Baritone. - -You can also use a custom version json for Minecraft, with the [1.14.4](https://www.dropbox.com/s/rkml3hjokd3qv0m/1.14.4-Baritone.zip?dl=1) version or the [1.15.2](https://www.dropbox.com/s/8rx6f0kts9hvd4f/1.15.2-Baritone.zip?dl=1) version or the [1.16.5](https://www.dropbox.com/s/i6f292o2i7o9acp/1.16.5-Baritone.zip?dl=1) version. +The easiest way to install Baritone is to install it as Forge/Neoforge/Fabric mod, but if you know how you can also use with a custom `version.json` +(Examples: [1.14.4](https://www.dropbox.com/s/rkml3hjokd3qv0m/1.14.4-Baritone.zip?dl=1), [1.15.2](https://www.dropbox.com/s/8rx6f0kts9hvd4f/1.15.2-Baritone.zip?dl=1), [1.16.5](https://www.dropbox.com/s/i6f292o2i7o9acp/1.16.5-Baritone.zip?dl=1)). Once Baritone is installed, look [here](USAGE.md) for instructions on how to use it. ## Prebuilt official releases -These releases are not always completely up to date with latest features, and are only released from `master`. (so if you want `backfill-2` branch for example, you'll have to build it yourself) +Releases are made rarely and are not always up to date with the latest features and bug fixes. Link to the releases page: [Releases](https://github.com/cabaletta/baritone/releases) -v1.2.* is for 1.12.2, v1.3.* is for 1.13.2, v1.4.* is for 1.14.4, v1.5.* is for 1.15.2, v1.6.* is for 1.16.5, v1.7.* is for 1.17.1, v1.8.* is for 1.18.1 +The mapping between major Minecraft versions and major Baritone versions is as follows +| Minecraft version | 1.12 | 1.13 | 1.14 | 1.15 | 1.16 | 1.17 | 1.18 | 1.19 | 1.20 | 1.21 | +|-------------------|------|------|------|------|------|------|------|------|-------|-------| +| Baritone version | v1.2 | v1.3 | v1.4 | v1.5 | v1.6 | v1.7 | v1.8 | v1.9 | v1.10 | v1.11 | Any official release will be GPG signed by leijurv (44A3EA646EADAC6A). Please verify that the hash of the file you download is in `checksums.txt` and that `checksums_signed.asc` is a valid signature by that public keys of `checksums.txt`. -The build is fully deterministic and reproducible, and you can verify Travis did it properly by running `docker build --no-cache -t cabaletta/baritone .` yourself and comparing the shasum. This works identically on Travis, Mac, and Linux (if you have docker on Windows, I'd be grateful if you could let me know if it works there too). +The build is fully deterministic and reproducible, and you can verify that by running `docker build --no-cache -t cabaletta/baritone .` yourself and comparing the shasum. This works identically on Travis, Mac, and Linux (if you have docker on Windows, I'd be grateful if you could let me know if it works there too). ## Artifacts -Building Baritone will result in 5 artifacts created in the ``dist`` directory. These are the same as the artifacts created in the [releases](https://github.com/cabaletta/baritone/releases). +Building Baritone will create the final artifacts in the ``dist`` directory. These are the same as the artifacts created in the [releases](https://github.com/cabaletta/baritone/releases). -**The Forge and Fabric releases can simply be added as a Forge/Fabric mods.** +**The Forge, NeoForge and Fabric releases can simply be added as a Forge/Neoforge/Fabric mods.** -If another one of your Forge mods has a Baritone integration, you want `baritone-api-forge-VERSION.jar`. Otherwise, you want `baritone-standalone-forge-VERSION.jar` +If another one of your other mods has a Baritone integration, you want `baritone-api-*-VERSION.jar`. +If you want to report a bug and spare us some effort, you want `baritone-unoptimized-*-VERSION.jar`. +Otherwise, you want `baritone-standalone-*-VERSION.jar` +Here's what the various qualifiers mean - **API**: Only the non-api packages are obfuscated. This should be used in environments where other mods would like to use Baritone's features. -- **Forge/Fabric API**: Same as API, but packaged for Forge/Fabric. This should be used where another mod has a Baritone integration. -- **Standalone**: Everything is obfuscated. This should be used in environments where there are no other mods present that would like to use Baritone's features. -- **Forge/Fabric Standalone**: Same as Standalone, but packaged for Forge/Fabric. This should be used when Baritone is your only Forge/Fabric mod, or none of your other Forge/Fabric mods integrate with Baritone. -- **Unoptimized**: Nothing is obfuscated. This shouldn't be used ever in production. -- **Forge/Fabric Unoptimized**: Same as Unoptimized, but packaged for Forge/Fabric. +- **Standalone**: Everything is obfuscated. Other mods cannot use Baritone, but you get a bit of extra performance. +- **Unoptimized**: Nothing is obfuscated. This shouldn't be used in production, but is really helpful for crash reports. + +- **No loader**: Loadable as a launchwrapper tweaker against vanilla Minecraft using a custom `version.json`. +- **Forge/Neoforge/Fabric**: Loadable as a standard mod using the respective loader. The fabric build may or may not work on Quilt. + +If you build from source you will also find mapping files in the `dist` directory. These contain the renamings done by ProGuard and are useful if you want to read obfuscated stack traces. ## Build it yourself - Clone or download Baritone ![Image](https://i.imgur.com/kbqBtoN.png) - - If you choose to download, make sure you extract the ZIP archive. + - If you choose to download, make sure you download the correct branch and extract the ZIP archive. - Follow one of the instruction sets below, based on your preference ## Command Line On Mac OSX and Linux, use `./gradlew` instead of `gradlew`. -If you have errors with a package missing please make sure you have setup your environment, and are using Oracle JDK 8 for 1.12.2-1.16.5, JDK 16+ for 1.17.1, and JDK 17+ for 1.18.1. - -To check which java you are using do -`java -version` in a command prompt or terminal. -If you are using anything above OpenJDK 8 for 1.12.2-1.16.5, it might not work because the Java distributions above JDK 8 using may not have the needed javax classes. +The recommended Java versions by Minecraft version are +| Minecraft version | Java version | +|-------------------------------|---------------| +| 1.12.2 - 1.16.5 | 8 | +| 1.17.1 | 16 | +| 1.18.2 - 1.20.4 | 17 | +| 1.20.5 - 1.21.4 | 21 | Download java: https://adoptium.net/ -#### macOS guide -In order to get JDK 8, Try running the following command: -`% /usr/libexec/java_home -V` -If it doesn't work try this guide: https://stackoverflow.com/questions/46513639/how-to-downgrade-java-from-9-to-8-on-a-macos-eclipse-is-not-running-with-java-9 -If you see something like - -`% 1.8.0_VERSION, x86_64: "Java SE 8" /Library/Java/JavaVirtualMachines/jdk1.8.0_VERSION.jdk/Contents/Home` - -in the list then you've got JDK 8 installed. -In order to get JDK 8 running in the **current terminal window** you will have to run this command: - -`% export JAVA_HOME=$(/usr/libexec/java_home -v 1.8)` - -To add OpenJDK 8 to your PATH add the export line to the end of your `.zshrc / .bashrc` if you want it to apply to each new terminal. If you're using bash change the .bachrc and if you're using zsh change the .zshrc +To check which java version you are using do `java -version` in a command prompt or terminal. ### Building Baritone These tasks depend on the minecraft version, but are (for the most part) standard for building mods. -for more details, see [the build ci action](/.github/workflows/gradle_build.yml) +For more details, see [the build ci action](/.github/workflows/gradle_build.yml) of the branch you want to build. + +For most branches `gradlew build` should build everything, but there are exceptions and this file might be out of date. + +More specifically, on older branches the setup used to be that `gradlew build` builds the tweaker jar +and `gradlew build -Pbaritone.forge_build` / `gradlew build -Pbaritone.fabric_build` are needed to build +for Forge/Fabric instead. And you might have to run `setupDecompWorkspace` first. ## IntelliJ - Open the project in IntelliJ as a Gradle project - Refresh the Gradle project (or, to be safe, just restart IntelliJ) -- depending on the minecraft version, you may need to run `setupDecompWorkspace` or `genIntellijRuns` in order to get everything working \ No newline at end of file +- Depending on the minecraft version, you may need to run `setupDecompWorkspace` or `genIntellijRuns` in order to get everything working + +## Github Actions +Most branches have a CI workflow at `.github/workflows/gradle_build.yml`. If you fork this repository and enable actions for your fork +you can push a dummy commit to trigger it and have GitHub build Baritone for you. + +If the commit you want to build is less than 90 days old, you can also find the corresponding workflow run in +[this list](https://github.com/cabaletta/baritone/actions/workflows/gradle_build.yml) and download the artifacts from there. From 64fdad424f4bed7faae1cdba79f638fa5fec8ef4 Mon Sep 17 00:00:00 2001 From: cattyn Date: Sat, 28 Dec 2024 14:29:05 +0300 Subject: [PATCH 03/23] added maximum distance setting for FollowProcess --- src/api/java/baritone/api/Settings.java | 5 +++++ src/main/java/baritone/process/FollowProcess.java | 4 ++++ 2 files changed, 9 insertions(+) diff --git a/src/api/java/baritone/api/Settings.java b/src/api/java/baritone/api/Settings.java index d9cb501ef..5ae228a93 100644 --- a/src/api/java/baritone/api/Settings.java +++ b/src/api/java/baritone/api/Settings.java @@ -1225,6 +1225,11 @@ public final class Settings { */ public final Setting followRadius = new Setting<>(3); + /** + * The maximum distance to the entity you're following + */ + public final Setting followTargetMaxDistance = new Setting<>(0); + /** * Turn this on if your exploration filter is enormous, you don't want it to check if it's done, * and you are just fine with it just hanging on completion diff --git a/src/main/java/baritone/process/FollowProcess.java b/src/main/java/baritone/process/FollowProcess.java index b123216a6..49cd5f0b8 100644 --- a/src/main/java/baritone/process/FollowProcess.java +++ b/src/main/java/baritone/process/FollowProcess.java @@ -76,6 +76,10 @@ public final class FollowProcess extends BaritoneProcessHelper implements IFollo if (entity.equals(ctx.player())) { return false; } + int maxDist = Baritone.settings().followTargetMaxDistance.value; + if (maxDist != 0 && entity.distanceToSqr(ctx.player()) > maxDist * maxDist) { + return false; + } return ctx.entitiesStream().anyMatch(entity::equals); } From cdfa86c977df3fd141c79b1f328564e4b061f47f Mon Sep 17 00:00:00 2001 From: Lyzev Date: Thu, 6 Feb 2025 18:48:51 +0100 Subject: [PATCH 04/23] add(Settings): added settings to control block placement in fluid sources and flowing fluids --- src/api/java/baritone/api/Settings.java | 10 ++++++++++ .../baritone/pathing/movement/CalculationContext.java | 6 ++++++ 2 files changed, 16 insertions(+) diff --git a/src/api/java/baritone/api/Settings.java b/src/api/java/baritone/api/Settings.java index d9cb501ef..9cb82f94b 100644 --- a/src/api/java/baritone/api/Settings.java +++ b/src/api/java/baritone/api/Settings.java @@ -77,6 +77,16 @@ public final class Settings { */ public final Setting allowPlace = new Setting<>(true); + /** + * Allow Baritone to place blocks in fluid source blocks + */ + public final Setting allowPlaceInFluidsSource = new Setting<>(true); + + /** + * Allow Baritone to place blocks in flowing fluid + */ + public final Setting allowPlaceInFluidsFlow = new Setting<>(true); + /** * Allow Baritone to move items in your inventory to your hotbar */ diff --git a/src/main/java/baritone/pathing/movement/CalculationContext.java b/src/main/java/baritone/pathing/movement/CalculationContext.java index 64aca2ceb..eeb6ccc03 100644 --- a/src/main/java/baritone/pathing/movement/CalculationContext.java +++ b/src/main/java/baritone/pathing/movement/CalculationContext.java @@ -161,6 +161,12 @@ public class CalculationContext { if (!worldBorder.canPlaceAt(x, z)) { return COST_INF; } + if (current.getFluidState().isSource() && !Baritone.settings().allowPlaceInFluidsSource.value) { + return COST_INF; + } + if (!current.getFluidState().isEmpty() && !current.getFluidState().isSource() && !Baritone.settings().allowPlaceInFluidsFlow.value) { + return COST_INF; + } return placeBlockCost; } From 59157c1ee04d84abe121ff1726e948e2ff040927 Mon Sep 17 00:00:00 2001 From: Lyzev Date: Sat, 8 Feb 2025 12:15:55 +0100 Subject: [PATCH 05/23] fix(CostOfPlacingAt): improve fluid placement checks in CalculationContext --- .../java/baritone/pathing/movement/CalculationContext.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/baritone/pathing/movement/CalculationContext.java b/src/main/java/baritone/pathing/movement/CalculationContext.java index eeb6ccc03..e84188a7f 100644 --- a/src/main/java/baritone/pathing/movement/CalculationContext.java +++ b/src/main/java/baritone/pathing/movement/CalculationContext.java @@ -161,10 +161,10 @@ public class CalculationContext { if (!worldBorder.canPlaceAt(x, z)) { return COST_INF; } - if (current.getFluidState().isSource() && !Baritone.settings().allowPlaceInFluidsSource.value) { + if (!Baritone.settings().allowPlaceInFluidsSource.value && current.getFluidState().isSource()) { return COST_INF; } - if (!current.getFluidState().isEmpty() && !current.getFluidState().isSource() && !Baritone.settings().allowPlaceInFluidsFlow.value) { + if (!Baritone.settings().allowPlaceInFluidsFlow.value && !current.getFluidState().isEmpty() && !current.getFluidState().isSource()) { return COST_INF; } return placeBlockCost; From 590f5d98ee80a853c78382d64cf0bb007ffcdcf8 Mon Sep 17 00:00:00 2001 From: rfresh2 <89827146+rfresh2@users.noreply.github.com> Date: Sun, 24 Sep 2023 15:34:59 -0700 Subject: [PATCH 06/23] fix forge mixin crash cherry-picked from 7902517663436488bc7762e7a6a68be4956b1c63 --- .../launch/mixins/MixinClientPlayerEntity.java | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/src/launch/java/baritone/launch/mixins/MixinClientPlayerEntity.java b/src/launch/java/baritone/launch/mixins/MixinClientPlayerEntity.java index 4674ffaa6..24e807f62 100644 --- a/src/launch/java/baritone/launch/mixins/MixinClientPlayerEntity.java +++ b/src/launch/java/baritone/launch/mixins/MixinClientPlayerEntity.java @@ -26,8 +26,6 @@ import baritone.behavior.LookBehavior; import net.minecraft.client.KeyMapping; import net.minecraft.client.player.LocalPlayer; import net.minecraft.world.entity.player.Abilities; -import net.minecraft.world.item.ElytraItem; -import net.minecraft.world.item.ItemStack; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; @@ -112,14 +110,14 @@ public class MixinClientPlayerEntity { method = "aiStep", at = @At( value = "INVOKE", - target = "net/minecraft/world/item/ElytraItem.isFlyEnabled(Lnet/minecraft/world/item/ItemStack;)Z" + target = "Lnet/minecraft/client/player/LocalPlayer;tryToStartFallFlying()Z" ) ) - private boolean isFlyEnabled(ItemStack stack) { - IBaritone baritone = BaritoneAPI.getProvider().getBaritoneForPlayer((LocalPlayer) (Object) this); + private boolean tryToStartFallFlying(final LocalPlayer instance) { + IBaritone baritone = BaritoneAPI.getProvider().getBaritoneForPlayer(instance); if (baritone != null && baritone.getPathingBehavior().isPathing()) { return false; } - return ElytraItem.isFlyEnabled(stack); + return instance.tryToStartFallFlying(); } } From c54d878d1c6f19908b3bde3a91f6992e190ad067 Mon Sep 17 00:00:00 2001 From: ZacSharp <68165024+ZacSharp@users.noreply.github.com> Date: Wed, 26 Feb 2025 17:05:23 +0100 Subject: [PATCH 07/23] Fix nether-pathfinder on forge --- scripts/proguard.pro | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/scripts/proguard.pro b/scripts/proguard.pro index 34b76170f..0b764e4d9 100644 --- a/scripts/proguard.pro +++ b/scripts/proguard.pro @@ -54,6 +54,11 @@ -dontwarn baritone.utils.schematic.schematica.** -dontwarn baritone.utils.schematic.litematica.** +# nether-pathfinder uses JNI to acess its own classes +# and some of our builds include it before running proguard +# conservatively keep all of it, even though only PathSegment. is needed +-keep,allowoptimization class dev.babbaj.pathfinder.** { *; } + # Keep - Applications. Keep all application classes, along with their 'main' # methods. -keepclasseswithmembers public class * { From 002415425a9e3e3a4505c1c87cb2d3ffbb19cfb7 Mon Sep 17 00:00:00 2001 From: ZacSharp <68165024+ZacSharp@users.noreply.github.com> Date: Wed, 26 Feb 2025 17:05:40 +0100 Subject: [PATCH 08/23] Slightly rephrase compatibility message We cannot distinguish between unsupported systems and failures on supported systems so strongly implying the former is potentially misleading. --- src/main/java/baritone/command/defaults/ElytraCommand.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/baritone/command/defaults/ElytraCommand.java b/src/main/java/baritone/command/defaults/ElytraCommand.java index 3f7b6bfd6..2f5eff352 100644 --- a/src/main/java/baritone/command/defaults/ElytraCommand.java +++ b/src/main/java/baritone/command/defaults/ElytraCommand.java @@ -216,7 +216,7 @@ public class ElytraCommand extends Command { final String osArch = System.getProperty("os.arch"); final String osName = System.getProperty("os.name"); return String.format( - "Legacy architectures are not supported. Your CPU is %s and your operating system is %s. " + + "Failed loading native library. Your CPU is %s and your operating system is %s. " + "Supported architectures are 64 bit x86, and 64 bit ARM. Supported operating systems are Windows, " + "Linux, and Mac", osArch, osName From f3086c2231aaae956b3f471b5d7f4afe8804f278 Mon Sep 17 00:00:00 2001 From: ZacSharp <68165024+ZacSharp@users.noreply.github.com> Date: Thu, 27 Feb 2025 15:36:59 +0100 Subject: [PATCH 09/23] Filter blocks where `avoidBreaking` returns false shaft-mining checks `avoidBreaking` so not checking it here can cause Baritone to walk to a position and then do nothing. --- src/main/java/baritone/process/MineProcess.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/main/java/baritone/process/MineProcess.java b/src/main/java/baritone/process/MineProcess.java index d1bec672f..cf16a5d36 100644 --- a/src/main/java/baritone/process/MineProcess.java +++ b/src/main/java/baritone/process/MineProcess.java @@ -486,7 +486,11 @@ public final class MineProcess extends BaritoneProcessHelper implements IMinePro public static boolean plausibleToBreak(CalculationContext ctx, BlockPos pos) { - if (MovementHelper.getMiningDurationTicks(ctx, pos.getX(), pos.getY(), pos.getZ(), ctx.bsi.get0(pos), true) >= COST_INF) { + BlockState state = ctx.bsi.get0(pos); + if (MovementHelper.getMiningDurationTicks(ctx, pos.getX(), pos.getY(), pos.getZ(), state, true) >= COST_INF) { + return false; + } + if (MovementHelper.avoidBreaking(ctx.bsi, pos.getX(), pos.getY(), pos.getZ(), state)) { return false; } From f357eb230b83cfa413ca5fbf8489076e0e9bb112 Mon Sep 17 00:00:00 2001 From: ZacSharp <68165024+ZacSharp@users.noreply.github.com> Date: Thu, 27 Feb 2025 15:55:09 +0100 Subject: [PATCH 10/23] Remove spam --- src/main/java/baritone/process/MineProcess.java | 1 - 1 file changed, 1 deletion(-) diff --git a/src/main/java/baritone/process/MineProcess.java b/src/main/java/baritone/process/MineProcess.java index cf16a5d36..0a64c98d4 100644 --- a/src/main/java/baritone/process/MineProcess.java +++ b/src/main/java/baritone/process/MineProcess.java @@ -77,7 +77,6 @@ public final class MineProcess extends BaritoneProcessHelper implements IMinePro int curr = ctx.player().getInventory().items.stream() .filter(stack -> filter.has(stack)) .mapToInt(ItemStack::getCount).sum(); - System.out.println("Currently have " + curr + " valid items"); if (curr >= desiredQuantity) { logDirect("Have " + curr + " valid items"); cancel(); From bf08c4fcf473bc072f50f3df1eca429a941784a7 Mon Sep 17 00:00:00 2001 From: ZacSharp <68165024+ZacSharp@users.noreply.github.com> Date: Thu, 27 Feb 2025 15:53:54 +0100 Subject: [PATCH 11/23] Improve error messages from `#build` --- .../baritone/command/defaults/BuildCommand.java | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/src/main/java/baritone/command/defaults/BuildCommand.java b/src/main/java/baritone/command/defaults/BuildCommand.java index bb34254ae..839210cdf 100644 --- a/src/main/java/baritone/command/defaults/BuildCommand.java +++ b/src/main/java/baritone/command/defaults/BuildCommand.java @@ -44,10 +44,21 @@ public class BuildCommand extends Command { @Override public void execute(String label, IArgConsumer args) throws CommandException { - File file = args.getDatatypePost(RelativeFile.INSTANCE, schematicsDir).getAbsoluteFile(); + final File file0 = args.getDatatypePost(RelativeFile.INSTANCE, schematicsDir).getAbsoluteFile(); + File file = file0; if (FilenameUtils.getExtension(file.getAbsolutePath()).isEmpty()) { file = new File(file.getAbsolutePath() + "." + Baritone.settings().schematicFallbackExtension.value); } + if (!file.exists()) { + if (file0.exists()) { + throw new CommandInvalidStateException(String.format( + "Cannot load %s because I do not know which schematic format" + + " that is. Please rename the file to include the correct" + + " file extension.", + file)); + } + throw new CommandInvalidStateException("Cannot find " + file); + } BetterBlockPos origin = ctx.playerFeet(); BetterBlockPos buildOrigin; if (args.hasAny()) { @@ -59,7 +70,7 @@ public class BuildCommand extends Command { } boolean success = baritone.getBuilderProcess().build(file.getName(), file, buildOrigin); if (!success) { - throw new CommandInvalidStateException("Couldn't load the schematic. Make sure to use the FULL file name, including the extension (e.g. blah.schematic)."); + throw new CommandInvalidStateException("Couldn't load the schematic. Unsupported file format, wrong file extension or a bug."); } logDirect(String.format("Successfully loaded schematic for building\nOrigin: %s", buildOrigin)); } From 3f6c87a8ed8b73ca410f40e781dd0db44b30f94f Mon Sep 17 00:00:00 2001 From: ZacSharp <68165024+ZacSharp@users.noreply.github.com> Date: Sat, 8 Mar 2025 23:35:23 +0100 Subject: [PATCH 12/23] Better error message for unsupported formats --- .../baritone/api/schematic/ISchematicSystem.java | 6 ++++++ .../api/schematic/format/ISchematicFormat.java | 6 ++++++ .../java/baritone/command/defaults/BuildCommand.java | 12 +++++++++++- .../baritone/utils/schematic/SchematicSystem.java | 6 ++++++ .../schematic/format/DefaultSchematicFormats.java | 11 +++++++++-- 5 files changed, 38 insertions(+), 3 deletions(-) diff --git a/src/api/java/baritone/api/schematic/ISchematicSystem.java b/src/api/java/baritone/api/schematic/ISchematicSystem.java index c8f039070..385cc0514 100644 --- a/src/api/java/baritone/api/schematic/ISchematicSystem.java +++ b/src/api/java/baritone/api/schematic/ISchematicSystem.java @@ -21,6 +21,7 @@ import baritone.api.command.registry.Registry; import baritone.api.schematic.format.ISchematicFormat; import java.io.File; +import java.util.List; import java.util.Optional; /** @@ -41,4 +42,9 @@ public interface ISchematicSystem { * @return The corresponding format for the file, {@link Optional#empty()} if no candidates were found. */ Optional getByFile(File file); + + /** + * @return A list of file extensions used by supported formats + */ + List getFileExtensions(); } diff --git a/src/api/java/baritone/api/schematic/format/ISchematicFormat.java b/src/api/java/baritone/api/schematic/format/ISchematicFormat.java index 3fe045bcf..0ccf059b0 100644 --- a/src/api/java/baritone/api/schematic/format/ISchematicFormat.java +++ b/src/api/java/baritone/api/schematic/format/ISchematicFormat.java @@ -23,6 +23,7 @@ import baritone.api.schematic.IStaticSchematic; import java.io.File; import java.io.IOException; import java.io.InputStream; +import java.util.List; /** * The base of a {@link ISchematic} file format @@ -42,4 +43,9 @@ public interface ISchematicFormat { * @return Whether or not the specified file matches this schematic format */ boolean isFileType(File file); + + /** + * @return A list of file extensions used by this format + */ + List getFileExtensions(); } diff --git a/src/main/java/baritone/command/defaults/BuildCommand.java b/src/main/java/baritone/command/defaults/BuildCommand.java index 839210cdf..f9ddd33ef 100644 --- a/src/main/java/baritone/command/defaults/BuildCommand.java +++ b/src/main/java/baritone/command/defaults/BuildCommand.java @@ -26,11 +26,13 @@ import baritone.api.command.datatypes.RelativeFile; import baritone.api.command.exception.CommandException; import baritone.api.command.exception.CommandInvalidStateException; import baritone.api.utils.BetterBlockPos; +import baritone.utils.schematic.SchematicSystem; import org.apache.commons.io.FilenameUtils; import java.io.File; import java.util.Arrays; import java.util.List; +import java.util.StringJoiner; import java.util.stream.Stream; public class BuildCommand extends Command { @@ -59,6 +61,14 @@ public class BuildCommand extends Command { } throw new CommandInvalidStateException("Cannot find " + file); } + if (!SchematicSystem.INSTANCE.getByFile(file).isPresent()) { + StringJoiner formats = new StringJoiner(", "); + SchematicSystem.INSTANCE.getFileExtensions().forEach(formats::add); + throw new CommandInvalidStateException(String.format( + "Unsupported schematic format. Reckognized file extensions are: %s", + formats + )); + } BetterBlockPos origin = ctx.playerFeet(); BetterBlockPos buildOrigin; if (args.hasAny()) { @@ -70,7 +80,7 @@ public class BuildCommand extends Command { } boolean success = baritone.getBuilderProcess().build(file.getName(), file, buildOrigin); if (!success) { - throw new CommandInvalidStateException("Couldn't load the schematic. Unsupported file format, wrong file extension or a bug."); + throw new CommandInvalidStateException("Couldn't load the schematic. Either your schematic is corrupt or this is a bug."); } logDirect(String.format("Successfully loaded schematic for building\nOrigin: %s", buildOrigin)); } diff --git a/src/main/java/baritone/utils/schematic/SchematicSystem.java b/src/main/java/baritone/utils/schematic/SchematicSystem.java index 8afafa8c3..ec6e7f626 100644 --- a/src/main/java/baritone/utils/schematic/SchematicSystem.java +++ b/src/main/java/baritone/utils/schematic/SchematicSystem.java @@ -24,6 +24,7 @@ import baritone.utils.schematic.format.DefaultSchematicFormats; import java.io.File; import java.util.Arrays; +import java.util.List; import java.util.Optional; /** @@ -48,4 +49,9 @@ public enum SchematicSystem implements ISchematicSystem { public Optional getByFile(File file) { return this.registry.stream().filter(format -> format.isFileType(file)).findFirst(); } + + @Override + public List getFileExtensions() { + return this.registry.stream().map(ISchematicFormat::getFileExtensions).flatMap(List::stream).toList(); + } } diff --git a/src/main/java/baritone/utils/schematic/format/DefaultSchematicFormats.java b/src/main/java/baritone/utils/schematic/format/DefaultSchematicFormats.java index 40a95b50c..25ef7b0d9 100644 --- a/src/main/java/baritone/utils/schematic/format/DefaultSchematicFormats.java +++ b/src/main/java/baritone/utils/schematic/format/DefaultSchematicFormats.java @@ -22,13 +22,15 @@ import baritone.api.schematic.format.ISchematicFormat; import baritone.utils.schematic.format.defaults.LitematicaSchematic; import baritone.utils.schematic.format.defaults.MCEditSchematic; import baritone.utils.schematic.format.defaults.SpongeSchematic; +import net.minecraft.nbt.CompoundTag; +import net.minecraft.nbt.NbtIo; import org.apache.commons.io.FilenameUtils; import java.io.File; import java.io.IOException; import java.io.InputStream; -import net.minecraft.nbt.CompoundTag; -import net.minecraft.nbt.NbtIo; +import java.util.Collections; +import java.util.List; /** * Default implementations of {@link ISchematicFormat} @@ -98,4 +100,9 @@ public enum DefaultSchematicFormats implements ISchematicFormat { public boolean isFileType(File file) { return this.extension.equalsIgnoreCase(FilenameUtils.getExtension(file.getAbsolutePath())); } + + @Override + public List getFileExtensions() { + return Collections.singletonList(this.extension); + } } From b8ac867fb920e5538aaa39a65cd7501804e43897 Mon Sep 17 00:00:00 2001 From: ZacSharp <68165024+ZacSharp@users.noreply.github.com> Date: Thu, 13 Mar 2025 19:32:35 +0100 Subject: [PATCH 13/23] Break from eye level outwards We might be standing inside passable blocks (e.g. sugar cane) so the block at foot level is occluded by the one at eye level. This does still break if we are standing inside a non-target with a target above or below. --- src/main/java/baritone/process/MineProcess.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/baritone/process/MineProcess.java b/src/main/java/baritone/process/MineProcess.java index 0a64c98d4..ff905c02f 100644 --- a/src/main/java/baritone/process/MineProcess.java +++ b/src/main/java/baritone/process/MineProcess.java @@ -118,7 +118,7 @@ public final class MineProcess extends BaritoneProcessHelper implements IMinePro .filter(pos -> pos.getX() == ctx.playerFeet().getX() && pos.getZ() == ctx.playerFeet().getZ()) .filter(pos -> pos.getY() >= ctx.playerFeet().getY()) .filter(pos -> !(BlockStateInterface.get(ctx, pos).getBlock() instanceof AirBlock)) // after breaking a block, it takes mineGoalUpdateInterval ticks for it to actually update this list =( - .min(Comparator.comparingDouble(ctx.playerFeet()::distSqr)); + .min(Comparator.comparingDouble(ctx.playerFeet().above()::distSqr)); baritone.getInputOverrideHandler().clearAllKeys(); if (shaft.isPresent() && ctx.player().isOnGround()) { BlockPos pos = shaft.get(); From bf0c47c85c66647dbaf9d15c3629b60018f55f55 Mon Sep 17 00:00:00 2001 From: ZacSharp <68165024+ZacSharp@users.noreply.github.com> Date: Tue, 2 Mar 2021 02:00:24 +0100 Subject: [PATCH 14/23] =?UTF-8?q?=E2=9C=A8=20Command=20to=20pickup=20items?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../api/command/datatypes/ItemById.java | 53 ++++++++++++ .../baritone/api/process/IFollowProcess.java | 11 ++- .../command/defaults/DefaultCommands.java | 1 + .../command/defaults/PickupCommand.java | 83 +++++++++++++++++++ .../java/baritone/process/FollowProcess.java | 21 ++++- 5 files changed, 165 insertions(+), 4 deletions(-) create mode 100644 src/api/java/baritone/api/command/datatypes/ItemById.java create mode 100644 src/main/java/baritone/command/defaults/PickupCommand.java diff --git a/src/api/java/baritone/api/command/datatypes/ItemById.java b/src/api/java/baritone/api/command/datatypes/ItemById.java new file mode 100644 index 000000000..eb4f230b4 --- /dev/null +++ b/src/api/java/baritone/api/command/datatypes/ItemById.java @@ -0,0 +1,53 @@ +/* + * This file is part of Baritone. + * + * Baritone is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Baritone is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with Baritone. If not, see . + */ + +package baritone.api.command.datatypes; + +import baritone.api.command.exception.CommandException; +import baritone.api.command.helpers.TabCompleteHelper; +import net.minecraft.core.registries.BuiltInRegistries; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.world.item.Item; + +import java.util.stream.Stream; + +public enum ItemById implements IDatatypeFor { + INSTANCE; + + @Override + public Item get(IDatatypeContext ctx) throws CommandException { + ResourceLocation id = new ResourceLocation(ctx.getConsumer().getString()); + Item item; + if ((item = BuiltInRegistries.ITEM.getOptional(id).orElse(null)) == null) { + throw new IllegalArgumentException("No item found by that id"); + } + return item; + } + + @Override + public Stream tabComplete(IDatatypeContext ctx) throws CommandException { + return new TabCompleteHelper() + .append( + BuiltInRegistries.BLOCK.keySet() + .stream() + .map(ResourceLocation::toString) + ) + .filterPrefixNamespaced(ctx.getConsumer().getString()) + .sortAlphabetically() + .stream(); + } +} diff --git a/src/api/java/baritone/api/process/IFollowProcess.java b/src/api/java/baritone/api/process/IFollowProcess.java index 6f7f0a239..e3ed73006 100644 --- a/src/api/java/baritone/api/process/IFollowProcess.java +++ b/src/api/java/baritone/api/process/IFollowProcess.java @@ -17,9 +17,11 @@ package baritone.api.process; +import net.minecraft.world.entity.Entity; +import net.minecraft.world.item.ItemStack; + import java.util.List; import java.util.function.Predicate; -import net.minecraft.world.entity.Entity; /** * @author Brady @@ -34,6 +36,13 @@ public interface IFollowProcess extends IBaritoneProcess { */ void follow(Predicate filter); + /** + * Try to pick up any items matching this predicate + * + * @param filter the predicate + */ + void pickup(Predicate filter); + /** * @return The entities that are currently being followed. null if not currently following, empty if nothing matches the predicate */ diff --git a/src/main/java/baritone/command/defaults/DefaultCommands.java b/src/main/java/baritone/command/defaults/DefaultCommands.java index c810d07c1..5228a7ae1 100644 --- a/src/main/java/baritone/command/defaults/DefaultCommands.java +++ b/src/main/java/baritone/command/defaults/DefaultCommands.java @@ -53,6 +53,7 @@ public final class DefaultCommands { new RenderCommand(baritone), new FarmCommand(baritone), new FollowCommand(baritone), + new PickupCommand(baritone), new ExploreFilterCommand(baritone), new ReloadAllCommand(baritone), new SaveAllCommand(baritone), diff --git a/src/main/java/baritone/command/defaults/PickupCommand.java b/src/main/java/baritone/command/defaults/PickupCommand.java new file mode 100644 index 000000000..e1e7014b0 --- /dev/null +++ b/src/main/java/baritone/command/defaults/PickupCommand.java @@ -0,0 +1,83 @@ +/* + * This file is part of Baritone. + * + * Baritone is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Baritone is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with Baritone. If not, see . + */ + +package baritone.command.defaults; + +import baritone.api.IBaritone; +import baritone.api.command.Command; +import baritone.api.command.argument.IArgConsumer; +import baritone.api.command.datatypes.ItemById; +import baritone.api.command.exception.CommandException; +import baritone.api.command.helpers.TabCompleteHelper; +import net.minecraft.core.registries.BuiltInRegistries; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.world.item.Item; + +import java.util.Arrays; +import java.util.HashSet; +import java.util.List; +import java.util.Set; +import java.util.stream.Stream; + +public class PickupCommand extends Command { + + public PickupCommand(IBaritone baritone) { + super(baritone, "pickup"); + } + + @Override + public void execute(String label, IArgConsumer args) throws CommandException { + Set collecting = new HashSet<>(); + while (args.hasAny()) { + Item item = args.getDatatypeFor(ItemById.INSTANCE); + collecting.add(item); + } + if (collecting.isEmpty()) { + baritone.getFollowProcess().pickup(stack -> true); + logDirect("Picking up all items"); + } else { + baritone.getFollowProcess().pickup(stack -> collecting.contains(stack.getItem())); + logDirect("Picking up these items:"); + collecting.stream().map(BuiltInRegistries.ITEM::getKey).map(ResourceLocation::toString).forEach(this::logDirect); + } + } + + @Override + public Stream tabComplete(String label, IArgConsumer args) throws CommandException { + while (args.has(2)) { + if (args.peekDatatypeOrNull(ItemById.INSTANCE) == null) { + return Stream.empty(); + } + args.get(); + } + return args.tabCompleteDatatype(ItemById.INSTANCE); + } + + @Override + public String getShortDesc() { + return "Pickup items"; + } + + @Override + public List getLongDesc() { + return Arrays.asList( + "Usage:", + "> pickup - Pickup anything", + "> pickup <...> - Pickup certain items" + ); + } +} diff --git a/src/main/java/baritone/process/FollowProcess.java b/src/main/java/baritone/process/FollowProcess.java index 49cd5f0b8..0be7a4e80 100644 --- a/src/main/java/baritone/process/FollowProcess.java +++ b/src/main/java/baritone/process/FollowProcess.java @@ -19,6 +19,7 @@ package baritone.process; import baritone.Baritone; import baritone.api.pathing.goals.Goal; +import baritone.api.pathing.goals.GoalBlock; import baritone.api.pathing.goals.GoalComposite; import baritone.api.pathing.goals.GoalNear; import baritone.api.pathing.goals.GoalXZ; @@ -27,11 +28,14 @@ import baritone.api.process.PathingCommand; import baritone.api.process.PathingCommandType; import baritone.api.utils.BetterBlockPos; import baritone.utils.BaritoneProcessHelper; +import net.minecraft.core.BlockPos; +import net.minecraft.world.entity.Entity; +import net.minecraft.world.entity.item.ItemEntity; +import net.minecraft.world.item.ItemStack; + import java.util.List; import java.util.function.Predicate; import java.util.stream.Collectors; -import net.minecraft.core.BlockPos; -import net.minecraft.world.entity.Entity; /** * Follow an entity @@ -42,6 +46,7 @@ public final class FollowProcess extends BaritoneProcessHelper implements IFollo private Predicate filter; private List cache; + private boolean into; // walk straight into the target, regardless of settings public FollowProcess(Baritone baritone) { super(baritone); @@ -56,12 +61,15 @@ public final class FollowProcess extends BaritoneProcessHelper implements IFollo private Goal towards(Entity following) { BlockPos pos; - if (Baritone.settings().followOffsetDistance.value == 0) { + if (Baritone.settings().followOffsetDistance.value == 0 || into) { pos = following.blockPosition(); } else { GoalXZ g = GoalXZ.fromDirection(following.position(), Baritone.settings().followOffsetDirection.value, Baritone.settings().followOffsetDistance.value); pos = new BetterBlockPos(g.getX(), following.position().y, g.getZ()); } + if (into) { + return new GoalBlock(pos); + } return new GoalNear(pos, Baritone.settings().followRadius.value); } @@ -114,6 +122,13 @@ public final class FollowProcess extends BaritoneProcessHelper implements IFollo @Override public void follow(Predicate filter) { this.filter = filter; + this.into = false; + } + + @Override + public void pickup(Predicate filter) { + this.filter = e -> e instanceof ItemEntity && filter.test(((ItemEntity) e).getItem()); + this.into = true; } @Override From 3fa0f34c1e6c48f7089a86fd3af93939beeece75 Mon Sep 17 00:00:00 2001 From: ZacSharp <68165024+ZacSharp@users.noreply.github.com> Date: Sat, 2 Apr 2022 22:14:49 +0200 Subject: [PATCH 15/23] Remove unused import --- src/main/java/baritone/command/defaults/PickupCommand.java | 1 - 1 file changed, 1 deletion(-) diff --git a/src/main/java/baritone/command/defaults/PickupCommand.java b/src/main/java/baritone/command/defaults/PickupCommand.java index e1e7014b0..7967dd023 100644 --- a/src/main/java/baritone/command/defaults/PickupCommand.java +++ b/src/main/java/baritone/command/defaults/PickupCommand.java @@ -22,7 +22,6 @@ import baritone.api.command.Command; import baritone.api.command.argument.IArgConsumer; import baritone.api.command.datatypes.ItemById; import baritone.api.command.exception.CommandException; -import baritone.api.command.helpers.TabCompleteHelper; import net.minecraft.core.registries.BuiltInRegistries; import net.minecraft.resources.ResourceLocation; import net.minecraft.world.item.Item; From 209b51b2536dab42abc9c06f278e822cfcebcf5f Mon Sep 17 00:00:00 2001 From: ZacSharp <68165024+ZacSharp@users.noreply.github.com> Date: Sat, 15 Mar 2025 20:16:06 +0100 Subject: [PATCH 16/23] Fix parsing invalid `ResourceLocation`s once again This is to fix `ItemById` by making `filterPrefixNamespaced` not fail on invalid prefixes --- .../java/baritone/api/command/datatypes/BlockById.java | 10 ---------- .../api/command/helpers/TabCompleteHelper.java | 7 ++++++- 2 files changed, 6 insertions(+), 11 deletions(-) diff --git a/src/api/java/baritone/api/command/datatypes/BlockById.java b/src/api/java/baritone/api/command/datatypes/BlockById.java index f92c968a2..64cf0a760 100644 --- a/src/api/java/baritone/api/command/datatypes/BlockById.java +++ b/src/api/java/baritone/api/command/datatypes/BlockById.java @@ -23,17 +23,11 @@ import net.minecraft.core.registries.BuiltInRegistries; import net.minecraft.resources.ResourceLocation; import net.minecraft.world.level.block.Block; -import java.util.regex.Pattern; import java.util.stream.Stream; public enum BlockById implements IDatatypeFor { INSTANCE; - /** - * Matches (domain:)?name? where domain and name are [a-z0-9_.-]+ and [a-z0-9/_.-]+ respectively. - */ - private static Pattern PATTERN = Pattern.compile("(?:[a-z0-9_.-]+:)?[a-z0-9/_.-]*"); - @Override public Block get(IDatatypeContext ctx) throws CommandException { ResourceLocation id = new ResourceLocation(ctx.getConsumer().getString()); @@ -48,10 +42,6 @@ public enum BlockById implements IDatatypeFor { public Stream tabComplete(IDatatypeContext ctx) throws CommandException { String arg = ctx.getConsumer().getString(); - if (!PATTERN.matcher(arg).matches()) { - return Stream.empty(); - } - return new TabCompleteHelper() .append( BuiltInRegistries.BLOCK.keySet() diff --git a/src/api/java/baritone/api/command/helpers/TabCompleteHelper.java b/src/api/java/baritone/api/command/helpers/TabCompleteHelper.java index 4f822352a..88f603205 100644 --- a/src/api/java/baritone/api/command/helpers/TabCompleteHelper.java +++ b/src/api/java/baritone/api/command/helpers/TabCompleteHelper.java @@ -212,7 +212,12 @@ public class TabCompleteHelper { * @return This {@link TabCompleteHelper} */ public TabCompleteHelper filterPrefixNamespaced(String prefix) { - return filterPrefix(new ResourceLocation(prefix).toString()); + ResourceLocation loc = ResourceLocation.tryParse(prefix); + if (loc == null) { + stream = Stream.empty(); + return this; + } + return filterPrefix(loc.toString()); } /** From fd13d5cbdc9f291b51680699010fdda6337c2586 Mon Sep 17 00:00:00 2001 From: Ic3Tank <61137113+IceTank@users.noreply.github.com> Date: Tue, 4 Feb 2025 22:04:21 +0100 Subject: [PATCH 17/23] Expose current layer in IBuilderProcess --- .../baritone/api/process/IBuilderProcess.java | 14 ++++++++++++++ .../java/baritone/process/BuilderProcess.java | 16 ++++++++++++++++ 2 files changed, 30 insertions(+) diff --git a/src/api/java/baritone/api/process/IBuilderProcess.java b/src/api/java/baritone/api/process/IBuilderProcess.java index 77250ce73..67a3ed491 100644 --- a/src/api/java/baritone/api/process/IBuilderProcess.java +++ b/src/api/java/baritone/api/process/IBuilderProcess.java @@ -24,6 +24,7 @@ import net.minecraft.core.Vec3i; import net.minecraft.world.level.block.state.BlockState; import java.io.File; import java.util.List; +import java.util.Optional; /** * @author Brady @@ -74,4 +75,17 @@ public interface IBuilderProcess extends IBaritoneProcess { * cause it to give up. This is updated every tick, but only while the builder process is active. */ List getApproxPlaceable(); + /** + * Returns the lower bound of the current mining layer if mineInLayers is true. + * If mineInLayers is false, this will return an empty optional. + * @return The lower bound of the current mining layer + */ + Optional getMinLayer(); + + /** + * Returns the upper bound of the current mining layer if mineInLayers is true. + * If mineInLayers is false, this will return an empty optional. + * @return The upper bound of the current mining layer + */ + Optional getMaxLayer(); } diff --git a/src/main/java/baritone/process/BuilderProcess.java b/src/main/java/baritone/process/BuilderProcess.java index 5a93d12ec..594b3d1da 100644 --- a/src/main/java/baritone/process/BuilderProcess.java +++ b/src/main/java/baritone/process/BuilderProcess.java @@ -999,6 +999,22 @@ public final class BuilderProcess extends BaritoneProcessHelper implements IBuil return paused ? "Builder Paused" : "Building " + name; } + @Override + public Optional getMinLayer() { + if (Baritone.settings().buildInLayers.value) { + return Optional.of(this.layer); + } + return Optional.empty(); + } + + @Override + public Optional getMaxLayer() { + if (Baritone.settings().buildInLayers.value) { + return Optional.of(this.stopAtHeight); + } + return Optional.empty(); + } + private List approxPlaceable(int size) { List result = new ArrayList<>(); for (int i = 0; i < size; i++) { From 92130f1642933628fa1db7b91e60bec084cb454e Mon Sep 17 00:00:00 2001 From: Jack Date: Thu, 23 Nov 2023 20:36:51 +1000 Subject: [PATCH 18/23] Add issues links and link to Discord for ModMenu --- fabric/src/main/resources/fabric.mod.json | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/fabric/src/main/resources/fabric.mod.json b/fabric/src/main/resources/fabric.mod.json index 0dbbe1078..8ab6ca5d2 100644 --- a/fabric/src/main/resources/fabric.mod.json +++ b/fabric/src/main/resources/fabric.mod.json @@ -11,7 +11,8 @@ ], "contact": { "homepage": "https://github.com/cabaletta/baritone", - "sources": "https://github.com/cabaletta/baritone" + "sources": "https://github.com/cabaletta/baritone", + "issues": "https://github.com/cabaletta/baritone/issues" }, "license": "LGPL-3.0", @@ -27,5 +28,12 @@ "depends": { "fabricloader": ">=0.11.0", "minecraft": "1.19.4" + }, + "custom": { + "modmenu": { + "links": { + "modmenu.discord": "https://discord.gg/s6fRBAUpmr" + } + } } } From 921822acd757c94d15c0081bcadee3af5b027d6e Mon Sep 17 00:00:00 2001 From: ZacSharp <68165024+ZacSharp@users.noreply.github.com> Date: Fri, 18 Apr 2025 00:53:44 +0200 Subject: [PATCH 19/23] Add messages to more exceptions and improve some existing ones --- .../baritone/api/pathing/goals/GoalRunAway.java | 2 +- .../baritone/pathing/calc/AStarPathFinder.java | 14 +++++++++++--- src/main/java/baritone/pathing/calc/Path.java | 9 +++++---- src/main/java/baritone/pathing/calc/PathNode.java | 2 +- .../pathing/calc/openset/BinaryHeapOpenSet.java | 2 +- src/main/java/baritone/pathing/movement/Moves.java | 4 ++-- .../java/baritone/pathing/path/PathExecutor.java | 12 +++++++++--- .../java/baritone/pathing/path/SplicedPath.java | 2 +- src/main/java/baritone/process/BuilderProcess.java | 2 +- .../java/baritone/process/CustomGoalProcess.java | 2 +- src/main/java/baritone/process/ExploreProcess.java | 4 +++- .../java/baritone/utils/BlockStateInterface.java | 2 +- .../java/baritone/utils/PathingControlManager.java | 4 ++-- 13 files changed, 39 insertions(+), 22 deletions(-) diff --git a/src/api/java/baritone/api/pathing/goals/GoalRunAway.java b/src/api/java/baritone/api/pathing/goals/GoalRunAway.java index 49b6f708d..1a1b6e50c 100644 --- a/src/api/java/baritone/api/pathing/goals/GoalRunAway.java +++ b/src/api/java/baritone/api/pathing/goals/GoalRunAway.java @@ -44,7 +44,7 @@ public class GoalRunAway implements Goal { public GoalRunAway(double distance, Integer maintainY, BlockPos... from) { if (from.length == 0) { - throw new IllegalArgumentException(); + throw new IllegalArgumentException("Positions to run away from must not be empty"); } this.from = from; this.distanceSq = (int) (distance * distance); diff --git a/src/main/java/baritone/pathing/calc/AStarPathFinder.java b/src/main/java/baritone/pathing/calc/AStarPathFinder.java index 0537eac5f..b22456584 100644 --- a/src/main/java/baritone/pathing/calc/AStarPathFinder.java +++ b/src/main/java/baritone/pathing/calc/AStarPathFinder.java @@ -122,17 +122,25 @@ public final class AStarPathFinder extends AbstractNodeCostSearch { continue; } if (actionCost <= 0 || Double.isNaN(actionCost)) { - throw new IllegalStateException(moves + " calculated implausible cost " + actionCost); + throw new IllegalStateException(String.format( + "%s from %s %s %s calculated implausible cost %s", + moves, currentNode.x, currentNode.y, currentNode.z, actionCost)); } // check destination after verifying it's not COST_INF -- some movements return a static IMPOSSIBLE object with COST_INF and destination being 0,0,0 to avoid allocating a new result for every failed calculation if (moves.dynamicXZ && !worldBorder.entirelyContains(res.x, res.z)) { // see issue #218 continue; } if (!moves.dynamicXZ && (res.x != newX || res.z != newZ)) { - throw new IllegalStateException(moves + " " + res.x + " " + newX + " " + res.z + " " + newZ); + throw new IllegalStateException(String.format( + "%s from %s %s %s ended at x z %s %s instead of %s %s", + moves, currentNode.x, currentNode.y, currentNode.z, + res.x, res.z, newX, newZ)); } if (!moves.dynamicY && res.y != currentNode.y + moves.yOffset) { - throw new IllegalStateException(moves + " " + res.y + " " + (currentNode.y + moves.yOffset)); + throw new IllegalStateException(String.format( + "%s from %s %s %s ended at y %s instead of %s", + moves, currentNode.x, currentNode.y, currentNode.z, + res.y, (currentNode.y + moves.yOffset))); } long hashCode = BetterBlockPos.longHash(res.x, res.y, res.z); if (isFavoring) { diff --git a/src/main/java/baritone/pathing/calc/Path.java b/src/main/java/baritone/pathing/calc/Path.java index 8f5dd52c2..eba408058 100644 --- a/src/main/java/baritone/pathing/calc/Path.java +++ b/src/main/java/baritone/pathing/calc/Path.java @@ -112,7 +112,7 @@ class Path extends PathBase { private boolean assembleMovements() { if (path.isEmpty() || !movements.isEmpty()) { - throw new IllegalStateException(); + throw new IllegalStateException("Path must not be empty"); } for (int i = 0; i < path.size() - 1; i++) { double cost = nodes.get(i + 1).cost - nodes.get(i).cost; @@ -145,7 +145,7 @@ class Path extends PathBase { @Override public IPath postProcess() { if (verified) { - throw new IllegalStateException(); + throw new IllegalStateException("Path must not be verified twice"); } verified = true; boolean failed = assembleMovements(); @@ -154,7 +154,7 @@ class Path extends PathBase { if (failed) { // at least one movement became impossible during calculation CutoffPath res = new CutoffPath(this, movements().size()); if (res.movements().size() != movements.size()) { - throw new IllegalStateException(); + throw new IllegalStateException("Path has wrong size after cutoff"); } return res; } @@ -166,7 +166,8 @@ class Path extends PathBase { @Override public List movements() { if (!verified) { - throw new IllegalStateException(); + // edge case note: this is called during verification + throw new IllegalStateException("Path not yet verified"); } return Collections.unmodifiableList(movements); } diff --git a/src/main/java/baritone/pathing/calc/PathNode.java b/src/main/java/baritone/pathing/calc/PathNode.java index 2b693338a..7db8f3f17 100644 --- a/src/main/java/baritone/pathing/calc/PathNode.java +++ b/src/main/java/baritone/pathing/calc/PathNode.java @@ -68,7 +68,7 @@ public final class PathNode { this.cost = ActionCosts.COST_INF; this.estimatedCostToGoal = goal.heuristic(x, y, z); if (Double.isNaN(estimatedCostToGoal)) { - throw new IllegalStateException(goal + " calculated implausible heuristic"); + throw new IllegalStateException(goal + " calculated implausible heuristic NaN at " + x + " " + y + " " + z); } this.heapPosition = -1; this.x = x; diff --git a/src/main/java/baritone/pathing/calc/openset/BinaryHeapOpenSet.java b/src/main/java/baritone/pathing/calc/openset/BinaryHeapOpenSet.java index 33f077b9d..1da8ed7e5 100644 --- a/src/main/java/baritone/pathing/calc/openset/BinaryHeapOpenSet.java +++ b/src/main/java/baritone/pathing/calc/openset/BinaryHeapOpenSet.java @@ -92,7 +92,7 @@ public final class BinaryHeapOpenSet implements IOpenSet { @Override public final PathNode removeLowest() { if (size == 0) { - throw new IllegalStateException(); + throw new IllegalStateException("Cannot remove from empty heap"); } PathNode result = array[1]; PathNode val = array[size]; diff --git a/src/main/java/baritone/pathing/movement/Moves.java b/src/main/java/baritone/pathing/movement/Moves.java index 87b5db6ac..312c8957c 100644 --- a/src/main/java/baritone/pathing/movement/Moves.java +++ b/src/main/java/baritone/pathing/movement/Moves.java @@ -347,7 +347,7 @@ public enum Moves { public void apply(CalculationContext context, int x, int y, int z, MutableMoveResult result) { if (dynamicXZ || dynamicY) { - throw new UnsupportedOperationException(); + throw new UnsupportedOperationException("Movements with dynamic offset must override `apply`"); } result.x = x + xOffset; result.y = y + yOffset; @@ -356,6 +356,6 @@ public enum Moves { } public double cost(CalculationContext context, int x, int y, int z) { - throw new UnsupportedOperationException(); + throw new UnsupportedOperationException("Movements must override `cost` or `apply`"); } } diff --git a/src/main/java/baritone/pathing/path/PathExecutor.java b/src/main/java/baritone/pathing/path/PathExecutor.java index 5c89da116..96d105208 100644 --- a/src/main/java/baritone/pathing/path/PathExecutor.java +++ b/src/main/java/baritone/pathing/path/PathExecutor.java @@ -455,7 +455,9 @@ public class PathExecutor implements IPathExecutor, Helper { if (data != null) { BetterBlockPos fallDest = new BetterBlockPos(data.getB()); if (!path.positions().contains(fallDest)) { - throw new IllegalStateException(); + throw new IllegalStateException(String.format( + "Fall override at %s %s %s returned illegal destination %s %s %s", + current.getSrc(), fallDest)); } if (ctx.playerFeet().equals(fallDest)) { pathPosition = path.positions().indexOf(fallDest); @@ -603,7 +605,9 @@ public class PathExecutor implements IPathExecutor, Helper { } return SplicedPath.trySplice(path, next.path, false).map(path -> { if (!path.getDest().equals(next.getPath().getDest())) { - throw new IllegalStateException(); + throw new IllegalStateException(String.format( + "Path has end %s instead of %s after splicing", + path.getDest(), next.getPath().getDest())); } PathExecutor ret = new PathExecutor(behavior, path); ret.pathPosition = pathPosition; @@ -619,7 +623,9 @@ public class PathExecutor implements IPathExecutor, Helper { int cutoffAmt = Baritone.settings().pathHistoryCutoffAmount.value; CutoffPath newPath = new CutoffPath(path, cutoffAmt, path.length() - 1); if (!newPath.getDest().equals(path.getDest())) { - throw new IllegalStateException(); + throw new IllegalStateException(String.format( + "Path has end %s instead of %s after trimming its start", + newPath.getDest(), path.getDest())); } logDebug("Discarding earliest segment movements, length cut from " + path.length() + " to " + newPath.length()); PathExecutor ret = new PathExecutor(behavior, newPath); diff --git a/src/main/java/baritone/pathing/path/SplicedPath.java b/src/main/java/baritone/pathing/path/SplicedPath.java index 1ba497d81..7f083a662 100644 --- a/src/main/java/baritone/pathing/path/SplicedPath.java +++ b/src/main/java/baritone/pathing/path/SplicedPath.java @@ -92,7 +92,7 @@ public class SplicedPath extends PathBase { } int positionInSecond = second.positions().indexOf(first.positions().get(firstPositionInSecond)); if (!allowOverlapCutoff && positionInSecond != 0) { - throw new IllegalStateException(); + throw new IllegalStateException("Paths to be spliced are overlapping incorrectly"); } List positions = new ArrayList<>(); List movements = new ArrayList<>(); diff --git a/src/main/java/baritone/process/BuilderProcess.java b/src/main/java/baritone/process/BuilderProcess.java index 5a93d12ec..753f33020 100644 --- a/src/main/java/baritone/process/BuilderProcess.java +++ b/src/main/java/baritone/process/BuilderProcess.java @@ -442,7 +442,7 @@ public final class BuilderProcess extends BaritoneProcessHelper implements IBuil double z = side.getStepZ() == 0 ? 0.5 : (1 + side.getStepZ()) / 2D; return new Vec3[]{new Vec3(x, 0.25, z), new Vec3(x, 0.75, z)}; default: // null - throw new IllegalStateException(); + throw new IllegalStateException("Unexpected side " + side); } } diff --git a/src/main/java/baritone/process/CustomGoalProcess.java b/src/main/java/baritone/process/CustomGoalProcess.java index d0dca9cbf..e101df74f 100644 --- a/src/main/java/baritone/process/CustomGoalProcess.java +++ b/src/main/java/baritone/process/CustomGoalProcess.java @@ -114,7 +114,7 @@ public final class CustomGoalProcess extends BaritoneProcessHelper implements IC } return new PathingCommand(this.goal, PathingCommandType.SET_GOAL_AND_PATH); default: - throw new IllegalStateException(); + throw new IllegalStateException("Unexpected state " + this.state); } } diff --git a/src/main/java/baritone/process/ExploreProcess.java b/src/main/java/baritone/process/ExploreProcess.java index 23fe7c23a..514a110e6 100644 --- a/src/main/java/baritone/process/ExploreProcess.java +++ b/src/main/java/baritone/process/ExploreProcess.java @@ -118,7 +118,9 @@ public final class ExploreProcess extends BaritoneProcessHelper implements IExpl int dz = (mult * 2 - 1) * zval; // dz can be either -zval or zval int trueDist = Math.abs(dx) + Math.abs(dz); if (trueDist != dist) { - throw new IllegalStateException(); + throw new IllegalStateException(String.format( + "Offset %s %s has distance %s, expected %s", + dx, dz, trueDist, dist)); } switch (filter.isAlreadyExplored(chunkX + dx, chunkZ + dz)) { case UNKNOWN: diff --git a/src/main/java/baritone/utils/BlockStateInterface.java b/src/main/java/baritone/utils/BlockStateInterface.java index 095694db9..19a0da57a 100644 --- a/src/main/java/baritone/utils/BlockStateInterface.java +++ b/src/main/java/baritone/utils/BlockStateInterface.java @@ -70,7 +70,7 @@ public class BlockStateInterface { } this.useTheRealWorld = !Baritone.settings().pathThroughCachedOnly.value; if (!ctx.minecraft().isSameThread()) { - throw new IllegalStateException(); + throw new IllegalStateException("BlockStateInterface must be constructed on the main thread"); } this.isPassableBlockPos = new BlockPos.MutableBlockPos(); this.access = new BlockStateInterfaceAccessWrapper(this); diff --git a/src/main/java/baritone/utils/PathingControlManager.java b/src/main/java/baritone/utils/PathingControlManager.java index 3566cd23a..2205d62e7 100644 --- a/src/main/java/baritone/utils/PathingControlManager.java +++ b/src/main/java/baritone/utils/PathingControlManager.java @@ -68,7 +68,7 @@ public class PathingControlManager implements IPathingControlManager { for (IBaritoneProcess proc : processes) { proc.onLostControl(); if (proc.isActive() && !proc.isTemporary()) { // it's okay only for a temporary thing (like combat pause) to maintain control even if you say to cancel - throw new IllegalStateException(proc.displayName()); + throw new IllegalStateException(proc.displayName() + " stayed active after being cancelled"); } } } @@ -121,7 +121,7 @@ public class PathingControlManager implements IPathingControlManager { } break; default: - throw new IllegalStateException(); + throw new IllegalStateException("Unexpected command type " + command.commandType); } } From bbaa602fe9ed4dd2aa8bb8345b711f872e04cc49 Mon Sep 17 00:00:00 2001 From: ZacSharp <68165024+ZacSharp@users.noreply.github.com> Date: Fri, 18 Apr 2025 22:49:03 +0200 Subject: [PATCH 20/23] Use minecraft method to determine sneaking eye height Co-authored-by: Matthew Herber --- src/api/java/baritone/api/utils/IPlayerContext.java | 8 ++++++++ src/api/java/baritone/api/utils/RayTraceUtils.java | 3 ++- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/src/api/java/baritone/api/utils/IPlayerContext.java b/src/api/java/baritone/api/utils/IPlayerContext.java index a97475a5b..de6d7cd58 100644 --- a/src/api/java/baritone/api/utils/IPlayerContext.java +++ b/src/api/java/baritone/api/utils/IPlayerContext.java @@ -99,6 +99,14 @@ public interface IPlayerContext { return new Rotation(player().getYRot(), player().getXRot()); } + /** + * Returns the player's eye height, taking into account whether or not the player is sneaking. + * + * @param ifSneaking Whether or not the player is sneaking + * @return The player's eye height + * @deprecated Use entity.getEyeHeight(Pose.CROUCHING) instead + */ + @Deprecated static double eyeHeight(boolean ifSneaking) { return ifSneaking ? 1.27 : 1.62; } diff --git a/src/api/java/baritone/api/utils/RayTraceUtils.java b/src/api/java/baritone/api/utils/RayTraceUtils.java index e99566863..ed544302d 100644 --- a/src/api/java/baritone/api/utils/RayTraceUtils.java +++ b/src/api/java/baritone/api/utils/RayTraceUtils.java @@ -18,6 +18,7 @@ package baritone.api.utils; import net.minecraft.world.entity.Entity; +import net.minecraft.world.entity.Pose; import net.minecraft.world.level.ClipContext; import net.minecraft.world.phys.HitResult; import net.minecraft.world.phys.Vec3; @@ -62,6 +63,6 @@ public final class RayTraceUtils { } public static Vec3 inferSneakingEyePosition(Entity entity) { - return new Vec3(entity.getX(), entity.getY() + IPlayerContext.eyeHeight(true), entity.getZ()); + return new Vec3(entity.getX(), entity.getY() + entity.getEyeHeight(Pose.CROUCHING), entity.getZ()); } } From 7c4036dfb146a3ad566f0a3609c8c00a766d98b9 Mon Sep 17 00:00:00 2001 From: ZacSharp <68165024+ZacSharp@users.noreply.github.com> Date: Fri, 18 Apr 2025 23:28:39 +0200 Subject: [PATCH 21/23] Don't leak coordinates in exceptions --- .../pathing/calc/AStarPathFinder.java | 25 +++++++++++++++---- .../java/baritone/pathing/calc/PathNode.java | 8 +++++- 2 files changed, 27 insertions(+), 6 deletions(-) diff --git a/src/main/java/baritone/pathing/calc/AStarPathFinder.java b/src/main/java/baritone/pathing/calc/AStarPathFinder.java index b22456584..41bc1ac0a 100644 --- a/src/main/java/baritone/pathing/calc/AStarPathFinder.java +++ b/src/main/java/baritone/pathing/calc/AStarPathFinder.java @@ -22,6 +22,7 @@ import baritone.api.pathing.calc.IPath; import baritone.api.pathing.goals.Goal; import baritone.api.pathing.movement.ActionCosts; import baritone.api.utils.BetterBlockPos; +import baritone.api.utils.SettingsUtil; import baritone.pathing.calc.openset.BinaryHeapOpenSet; import baritone.pathing.movement.CalculationContext; import baritone.pathing.movement.Moves; @@ -124,7 +125,11 @@ public final class AStarPathFinder extends AbstractNodeCostSearch { if (actionCost <= 0 || Double.isNaN(actionCost)) { throw new IllegalStateException(String.format( "%s from %s %s %s calculated implausible cost %s", - moves, currentNode.x, currentNode.y, currentNode.z, actionCost)); + moves, + SettingsUtil.maybeCensor(currentNode.x), + SettingsUtil.maybeCensor(currentNode.y), + SettingsUtil.maybeCensor(currentNode.z), + actionCost)); } // check destination after verifying it's not COST_INF -- some movements return a static IMPOSSIBLE object with COST_INF and destination being 0,0,0 to avoid allocating a new result for every failed calculation if (moves.dynamicXZ && !worldBorder.entirelyContains(res.x, res.z)) { // see issue #218 @@ -133,14 +138,24 @@ public final class AStarPathFinder extends AbstractNodeCostSearch { if (!moves.dynamicXZ && (res.x != newX || res.z != newZ)) { throw new IllegalStateException(String.format( "%s from %s %s %s ended at x z %s %s instead of %s %s", - moves, currentNode.x, currentNode.y, currentNode.z, - res.x, res.z, newX, newZ)); + moves, + SettingsUtil.maybeCensor(currentNode.x), + SettingsUtil.maybeCensor(currentNode.y), + SettingsUtil.maybeCensor(currentNode.z), + SettingsUtil.maybeCensor(res.x), + SettingsUtil.maybeCensor(res.z), + SettingsUtil.maybeCensor(newX), + SettingsUtil.maybeCensor(newZ))); } if (!moves.dynamicY && res.y != currentNode.y + moves.yOffset) { throw new IllegalStateException(String.format( "%s from %s %s %s ended at y %s instead of %s", - moves, currentNode.x, currentNode.y, currentNode.z, - res.y, (currentNode.y + moves.yOffset))); + moves, + SettingsUtil.maybeCensor(currentNode.x), + SettingsUtil.maybeCensor(currentNode.y), + SettingsUtil.maybeCensor(currentNode.z), + SettingsUtil.maybeCensor(res.y), + SettingsUtil.maybeCensor(currentNode.y + moves.yOffset))); } long hashCode = BetterBlockPos.longHash(res.x, res.y, res.z); if (isFavoring) { diff --git a/src/main/java/baritone/pathing/calc/PathNode.java b/src/main/java/baritone/pathing/calc/PathNode.java index 7db8f3f17..0911c6c04 100644 --- a/src/main/java/baritone/pathing/calc/PathNode.java +++ b/src/main/java/baritone/pathing/calc/PathNode.java @@ -20,6 +20,7 @@ package baritone.pathing.calc; import baritone.api.pathing.goals.Goal; import baritone.api.pathing.movement.ActionCosts; import baritone.api.utils.BetterBlockPos; +import baritone.api.utils.SettingsUtil; /** * A node in the path, containing the cost and steps to get to it. @@ -68,7 +69,12 @@ public final class PathNode { this.cost = ActionCosts.COST_INF; this.estimatedCostToGoal = goal.heuristic(x, y, z); if (Double.isNaN(estimatedCostToGoal)) { - throw new IllegalStateException(goal + " calculated implausible heuristic NaN at " + x + " " + y + " " + z); + throw new IllegalStateException(String.format( + "%s calculated implausible heuristic NaN at %s %s %s", + goal, + SettingsUtil.maybeCensor(x), + SettingsUtil.maybeCensor(y), + SettingsUtil.maybeCensor(z))); } this.heapPosition = -1; this.x = x; From 9e1e89b91fa5d402a92fd0db3d936e54e9380878 Mon Sep 17 00:00:00 2001 From: ZacSharp <68165024+ZacSharp@users.noreply.github.com> Date: Fri, 18 Apr 2025 23:34:16 +0200 Subject: [PATCH 22/23] Fix ancient comment --- src/main/java/baritone/pathing/calc/AStarPathFinder.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/baritone/pathing/calc/AStarPathFinder.java b/src/main/java/baritone/pathing/calc/AStarPathFinder.java index 41bc1ac0a..1c58cbf20 100644 --- a/src/main/java/baritone/pathing/calc/AStarPathFinder.java +++ b/src/main/java/baritone/pathing/calc/AStarPathFinder.java @@ -131,7 +131,7 @@ public final class AStarPathFinder extends AbstractNodeCostSearch { SettingsUtil.maybeCensor(currentNode.z), actionCost)); } - // check destination after verifying it's not COST_INF -- some movements return a static IMPOSSIBLE object with COST_INF and destination being 0,0,0 to avoid allocating a new result for every failed calculation + // check destination after verifying it's not COST_INF -- some movements return COST_INF without adjusting the destination if (moves.dynamicXZ && !worldBorder.entirelyContains(res.x, res.z)) { // see issue #218 continue; } From 7aab08ae0f155514eb2688b5c66e9aa513c79e33 Mon Sep 17 00:00:00 2001 From: ZacSharp <68165024+ZacSharp@users.noreply.github.com> Date: Tue, 22 Apr 2025 00:50:02 +0200 Subject: [PATCH 23/23] Don't let servers trick users into running arbitrary Baritone commands As of now there shouldn't be any exploitable commands, but better be safe --- .../java/baritone/launch/mixins/MixinScreen.java | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/src/launch/java/baritone/launch/mixins/MixinScreen.java b/src/launch/java/baritone/launch/mixins/MixinScreen.java index c99c7776c..84e72c7e0 100644 --- a/src/launch/java/baritone/launch/mixins/MixinScreen.java +++ b/src/launch/java/baritone/launch/mixins/MixinScreen.java @@ -21,17 +21,19 @@ import baritone.api.BaritoneAPI; import baritone.api.IBaritone; import baritone.api.event.events.ChatEvent; import baritone.utils.accessor.IGuiScreen; +import net.minecraft.client.gui.screens.Screen; import net.minecraft.network.chat.ClickEvent; import net.minecraft.network.chat.Style; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.gen.Invoker; - -import java.net.URI; -import net.minecraft.client.gui.screens.Screen; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; +import java.net.URI; + +import static baritone.api.command.IBaritoneChatControl.FORCE_COMMAND_PREFIX; + @Mixin(Screen.class) public abstract class MixinScreen implements IGuiScreen { @@ -47,9 +49,13 @@ public abstract class MixinScreen implements IGuiScreen { if (clickEvent == null) { return; } + String command = clickEvent.getValue(); + if (command == null || !command.startsWith(FORCE_COMMAND_PREFIX)) { + return; + } IBaritone baritone = BaritoneAPI.getProvider().getPrimaryBaritone(); if (baritone != null) { - baritone.getGameEventHandler().onSendChatMessage(new ChatEvent(clickEvent.getValue())); + baritone.getGameEventHandler().onSendChatMessage(new ChatEvent(command)); } cir.setReturnValue(true); cir.cancel();