Merge branch '1.20.4' into 1.20.6

This commit is contained in:
ZacSharp
2025-04-23 00:00:53 +02:00
38 changed files with 424 additions and 89 deletions

View File

@@ -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
- 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.

View File

@@ -38,7 +38,7 @@ allprojects {
group = rootProject.maven_group
sourceCompatibility = targetCompatibility = JavaVersion.toVersion(project.java_version)
java {
toolchain {
languageVersion.set(JavaLanguageVersion.of(sourceCompatibility.majorVersion.toInteger()))

View File

@@ -10,7 +10,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",
@@ -26,5 +27,12 @@
"depends": {
"fabricloader": ">=0.14.22",
"minecraft": ["1.20.5", "1.20.6"]
},
"custom": {
"modmenu": {
"links": {
"modmenu.discord": "https://discord.gg/s6fRBAUpmr"
}
}
}
}

View File

@@ -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.<init> is needed
-keep,allowoptimization class dev.babbaj.pathfinder.** { *; }
# Keep - Applications. Keep all application classes, along with their 'main'
# methods.
-keepclasseswithmembers public class * {

View File

@@ -77,6 +77,16 @@ public final class Settings {
*/
public final Setting<Boolean> allowPlace = new Setting<>(true);
/**
* Allow Baritone to place blocks in fluid source blocks
*/
public final Setting<Boolean> allowPlaceInFluidsSource = new Setting<>(true);
/**
* Allow Baritone to place blocks in flowing fluid
*/
public final Setting<Boolean> allowPlaceInFluidsFlow = new Setting<>(true);
/**
* Allow Baritone to move items in your inventory to your hotbar
*/
@@ -1225,6 +1235,11 @@ public final class Settings {
*/
public final Setting<Integer> followRadius = new Setting<>(3);
/**
* The maximum distance to the entity you're following
*/
public final Setting<Integer> 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

View File

@@ -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<Block> {
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<Block> {
public Stream<String> 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()

View File

@@ -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 <https://www.gnu.org/licenses/>.
*/
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<Item> {
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<String> tabComplete(IDatatypeContext ctx) throws CommandException {
return new TabCompleteHelper()
.append(
BuiltInRegistries.BLOCK.keySet()
.stream()
.map(ResourceLocation::toString)
)
.filterPrefixNamespaced(ctx.getConsumer().getString())
.sortAlphabetically()
.stream();
}
}

View File

@@ -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());
}
/**

View File

@@ -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);

View File

@@ -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<BlockState> 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<Integer> 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<Integer> getMaxLayer();
}

View File

@@ -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<Entity> filter);
/**
* Try to pick up any items matching this predicate
*
* @param filter the predicate
*/
void pickup(Predicate<ItemStack> filter);
/**
* @return The entities that are currently being followed. null if not currently following, empty if nothing matches the predicate
*/

View File

@@ -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<ISchematicFormat> getByFile(File file);
/**
* @return A list of file extensions used by supported formats
*/
List<String> getFileExtensions();
}

View File

@@ -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<String> getFileExtensions();
}

View File

@@ -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;
}

View File

@@ -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());
}
}

View File

@@ -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();

View File

@@ -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 {
@@ -44,10 +46,29 @@ 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);
}
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()) {
@@ -59,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. Make sure to use the FULL file name, including the extension (e.g. blah.schematic).");
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));
}

View File

@@ -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),

View File

@@ -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

View File

@@ -0,0 +1,82 @@
/*
* 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 <https://www.gnu.org/licenses/>.
*/
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 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<Item> 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<String> 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<String> getLongDesc() {
return Arrays.asList(
"Usage:",
"> pickup - Pickup anything",
"> pickup <item1> <item2> <...> - Pickup certain items"
);
}
}

View File

@@ -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;
@@ -122,17 +123,39 @@ 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,
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
// 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;
}
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,
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(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,
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) {

View File

@@ -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<IMovement> 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);
}

View File

@@ -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");
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;

View File

@@ -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];

View File

@@ -161,6 +161,12 @@ public class CalculationContext {
if (!worldBorder.canPlaceAt(x, z)) {
return COST_INF;
}
if (!Baritone.settings().allowPlaceInFluidsSource.value && current.getFluidState().isSource()) {
return COST_INF;
}
if (!Baritone.settings().allowPlaceInFluidsFlow.value && !current.getFluidState().isEmpty() && !current.getFluidState().isSource()) {
return COST_INF;
}
return placeBlockCost;
}

View File

@@ -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`");
}
}

View File

@@ -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);

View File

@@ -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<BetterBlockPos> positions = new ArrayList<>();
List<IMovement> movements = new ArrayList<>();

View File

@@ -441,7 +441,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);
}
}
@@ -998,6 +998,22 @@ public final class BuilderProcess extends BaritoneProcessHelper implements IBuil
return paused ? "Builder Paused" : "Building " + name;
}
@Override
public Optional<Integer> getMinLayer() {
if (Baritone.settings().buildInLayers.value) {
return Optional.of(this.layer);
}
return Optional.empty();
}
@Override
public Optional<Integer> getMaxLayer() {
if (Baritone.settings().buildInLayers.value) {
return Optional.of(this.stopAtHeight);
}
return Optional.empty();
}
private List<BlockState> approxPlaceable(int size) {
List<BlockState> result = new ArrayList<>();
for (int i = 0; i < size; i++) {

View File

@@ -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);
}
}

View File

@@ -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:

View File

@@ -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<Entity> filter;
private List<Entity> 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);
}
@@ -76,6 +84,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);
}
@@ -110,6 +122,13 @@ public final class FollowProcess extends BaritoneProcessHelper implements IFollo
@Override
public void follow(Predicate<Entity> filter) {
this.filter = filter;
this.into = false;
}
@Override
public void pickup(Predicate<ItemStack> filter) {
this.filter = e -> e instanceof ItemEntity && filter.test(((ItemEntity) e).getItem());
this.into = true;
}
@Override

View File

@@ -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();
@@ -119,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().onGround()) {
BlockPos pos = shaft.get();
@@ -486,7 +485,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;
}

View File

@@ -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);

View File

@@ -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);
}
}

View File

@@ -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<ISchematicFormat> getByFile(File file) {
return this.registry.stream().filter(format -> format.isFileType(file)).findFirst();
}
@Override
public List<String> getFileExtensions() {
return this.registry.stream().map(ISchematicFormat::getFileExtensions).flatMap(List::stream).toList();
}
}

View File

@@ -22,14 +22,16 @@ 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.NbtAccounter;
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}
@@ -99,4 +101,9 @@ public enum DefaultSchematicFormats implements ISchematicFormat {
public boolean isFileType(File file) {
return this.extension.equalsIgnoreCase(FilenameUtils.getExtension(file.getAbsolutePath()));
}
@Override
public List<String> getFileExtensions() {
return Collections.singletonList(this.extension);
}
}

View File

@@ -47,6 +47,7 @@ dependencies {
implementation "org.ow2.asm:asm-util:${project.asm_version}"
implementation "org.ow2.asm:asm-analysis:${project.asm_version}"
implementation 'com.github.ImpactDevelopment:SimpleTweaker:1.2'
implementation('net.minecraft:launchwrapper:of-2.3') {
exclude module: 'lwjgl'