diff --git a/.gitignore b/.gitignore index 69317376f..97f9d853e 100644 --- a/.gitignore +++ b/.gitignore @@ -29,3 +29,6 @@ baritone_Client.launch # Copyright Files !/.idea/copyright/Baritone.xml !/.idea/copyright/profiles_settings.xml + +.vscode/launch.json + diff --git a/README.md b/README.md index 85f3bf84e..7222e4d89 100644 --- a/README.md +++ b/README.md @@ -4,11 +4,13 @@

- Minecraft - Minecraft - Minecraft - Minecraft - Minecraft + Minecraft + Minecraft + Minecraft + Minecraft + Minecraft + Minecraft + Minecraft

@@ -48,7 +50,9 @@ A Minecraft pathfinder bot. [**Baritone Discord Server**](http://discord.gg/s6fRBAUpmr) -Baritone is the pathfinding system used in [Impact](https://impactclient.net/) since 4.4. There's a [showcase video](https://youtu.be/CZkLXWo4Fg4) made by @Adovin#0730 on Baritone which I recommend. [Here's](https://www.youtube.com/watch?v=StquF69-_wI) a (very old!) video I made showing off what it can do. [Tutorial playlist](https://www.youtube.com/playlist?list=PLnwnJ1qsS7CoQl9Si-RTluuzCo_4Oulpa) +Baritone is the pathfinding system used in [Impact](https://impactclient.net/) since 4.4. There's a [showcase video](https://youtu.be/CZkLXWo4Fg4) made by @Adovin#0730 on Baritone which I recommend. [Here's](https://www.youtube.com/watch?v=StquF69-_wI) a (very old!) video I made showing off what it can do. + +[Tutorial playlist](https://www.youtube.com/playlist?list=PLnwnJ1qsS7CoQl9Si-RTluuzCo_4Oulpa) The easiest way to install Baritone is to install [Impact](https://impactclient.net/), which comes with Baritone. The second easiest way (for 1.12.2 only) is to install the v1.2.* `api-forge` jar from [releases](https://github.com/cabaletta/baritone/releases). **For 1.12.2 Forge, just click [here](https://github.com/cabaletta/baritone/releases/download/v1.2.15/baritone-api-forge-1.2.15.jar)**. Otherwise, see [Installation & setup](SETUP.md). Once Baritone is installed, look [here](USAGE.md) for instructions on how to use it. @@ -56,8 +60,12 @@ For 1.15.2, [click here](https://www.youtube.com/watch?v=j1qKtCZFURM) and see de For 1.16.5, [click here](https://www.youtube.com/watch?v=_4eVJ9Qz2J8) and see description. If you need Forge or Fabric 1.16.5, look [here](https://github.com/cabaletta/baritone/releases/tag/v1.6.3) and get the `api-forge` or `api-fabric` jar. **For 1.16.5 Fabric, just click [here](https://github.com/cabaletta/baritone/releases/download/v1.6.3/baritone-api-fabric-1.6.3.jar)**. +If you need Forge or Fabric 1.17.1, look [here](https://github.com/cabaletta/baritone/releases/tag/v1.7.2) and get the `api-forge` or `api-fabric` jar. **For 1.17.1 Fabric, just click [here](https://github.com/cabaletta/baritone/releases/download/v1.7.2/baritone-api-fabric-1.7.2.jar)**. + +If you need Forge or Fabric 1.18.1, look [here](https://github.com/cabaletta/baritone/releases/tag/v1.8.2) and get the `api-forge` or `api-fabric` jar. **For 1.18.1 Fabric, just click [here](https://github.com/cabaletta/baritone/releases/download/v1.8.2/baritone-api-fabric-1.8.2.jar)**. + This project is an updated version of [MineBot](https://github.com/leijurv/MineBot/), -the original version of the bot for Minecraft 1.8.9, rebuilt for 1.12.2 through 1.16.5. Baritone focuses on reliability and particularly performance (it's over [30x faster](https://github.com/cabaletta/baritone/pull/180#issuecomment-423822928) than MineBot at calculating paths). +the original version of the bot for Minecraft 1.8.9, rebuilt for 1.12.2 onwards. Baritone focuses on reliability and particularly performance (it's over [30x faster](https://github.com/cabaletta/baritone/pull/180#issuecomment-423822928) than MineBot at calculating paths). Have committed at least once a day from Aug 1, 2018, to Aug 1, 2019. @@ -89,7 +97,7 @@ jar. Below is an example of basic usage for changing some settings, and then pathing to an X/Z goal. -``` +```java BaritoneAPI.getSettings().allowSprint.value = true; BaritoneAPI.getSettings().primaryTimeoutMS.value = 2000L; diff --git a/SETUP.md b/SETUP.md index 7a43faa62..57866b192 100644 --- a/SETUP.md +++ b/SETUP.md @@ -11,7 +11,7 @@ These releases are not always completely up to date with latest features, and ar 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.2 or 1.16.4 or 1.16.5 (LOL) +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 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`. @@ -22,15 +22,16 @@ The build is fully deterministic and reproducible, and you can verify Travis did 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). -**The Forge release can simply be added as a Forge mod.** +**The Forge and Fabric releases can simply be added as a Forge/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` - **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 API**: Same as API, but packaged for Forge. This should be used where another mod has a Baritone integration. +- **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 Standalone**: Same as Standalone, but packaged for Forge. This should be used when Baritone is your only Forge mod, or none of your other Forge mods integrate with Baritone. +- **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. ## Build it yourself - Clone or download Baritone @@ -42,13 +43,13 @@ If another one of your Forge mods has a Baritone integration, you want `baritone ## 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. +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, it might not work because the Java distributions above JDK 8 using may not have the needed javax classes. +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. -Open JDK 8 download: https://openjdk.java.net/install/ +Open JDK download: https://openjdk.java.net/install/ #### macOS guide In order to get JDK 8, Try running the following command: `% /usr/libexec/java_home -V` @@ -84,6 +85,12 @@ For minecraft 1.15.2+, run the following instead to include the Forge jars: $ gradlew build -Pbaritone.forge_build ``` +Do this instead for Fabric jars: + +``` +$ gradlew build -Pbaritone.fabric_build +``` + Running Baritone: ``` diff --git a/USAGE.md b/USAGE.md index f896ad012..46241e3fe 100644 --- a/USAGE.md +++ b/USAGE.md @@ -32,13 +32,13 @@ Watch this [showcase video](https://youtu.be/CZkLXWo4Fg4)! To toggle a boolean setting, just say its name in chat (for example saying `allowBreak` toggles whether Baritone will consider breaking blocks). For a numeric setting, say its name then the new value (like `primaryTimeoutMS 250`). It's case insensitive. To reset a setting to its default value, say `acceptableThrowawayItems reset`. To reset all settings, say `reset`. To see all settings that have been modified from their default values, say `modified`. -Some common examples: +Commands in Baritone: - `thisway 1000` then `path` to go in the direction you're facing for a thousand blocks - `goal x y z` or `goal x z` or `goal y`, then `path` to set a goal to a certain coordinate then path to it - `goto x y z` or `goto x z` or `goto y` to go to a certain coordinate (in a single step, starts going immediately) - `goal` to set the goal to your player's feet - `goal clear` to clear the goal -- `cancel` or `stop` to stop everything +- `cancel` or `stop` to stop everything, `forcecancel` is also an option - `goto portal` or `goto ender_chest` or `goto block_type` to go to a block. (in Impact, `.goto` is an alias for `.b goto` for the most part) - `mine diamond_ore iron_ore` to mine diamond ore or iron ore (turn on the setting `legitMine` to only mine ores that it can actually see. It will explore randomly around y=11 until it finds them.) An amount of blocks can also be specified, for example, `mine 64 diamond_ore`. - `click` to click your destination on the screen. Right click path to on top of the block, left click to path into it (either at foot level or eye level), and left click and drag to select an area (`#help sel` to see what you can do with that selection). @@ -51,11 +51,19 @@ Some common examples: - `axis` to go to an axis or diagonal axis at y=120 (`axisHeight` is a configurable setting, defaults to 120). - `explore x z` to explore the world from the origin of x,z. Leave out x and z to default to player feet. This will continually path towards the closest chunk to the origin that it's never seen before. `explorefilter filter.json` with optional invert can be used to load in a list of chunks to load. - `invert` to invert the current goal and path. This gets as far away from it as possible, instead of as close as possible. For example, do `goal` then `invert` to run as far as possible from where you're standing at the start. +- `come` tells Baritone to head towards your camera, useful when freecam doesn't move your player position. +- `blacklist` will stop baritone from going to the closest block so it won't attempt to get to it. +- `eta` to get information about the estimated time until the next segment and the goal, be aware that the ETA to your goal is really unprecise. +- `proc` to view miscellaneous information about the process currently controlling Baritone. +- `repack` to re-cache the chunks around you. +- `gc` to call `System.gc()` which may free up some memory. +- `render` to fix glitched chunk rendering without having to reload all of them. +- `reloadall` to reload Baritone's world cache or `saveall` to save Baritone's world cache. +- `find` to search through Baritone's cache and attempt to find the location of the block. +- `surface` or `top` to tell Baritone to head towards the closest surface-like area, this can be the surface or highest available air space. - `version` to get the version of Baritone you're running - `damn` daniel -For the rest of the commands, you can take a look at the code [here](https://baritone.leijurv.com/baritone/api/Settings.html). - All the settings and documentation are here. If you find HTML easier to read than Javadoc, you can look here. There are about a hundred settings, but here are some fun / interesting / important ones that you might want to look at changing in normal usage of Baritone. The documentation for each can be found at the above links. diff --git a/scripts/proguard.pro b/scripts/proguard.pro index c92a371eb..b20bebba5 100644 --- a/scripts/proguard.pro +++ b/scripts/proguard.pro @@ -24,6 +24,7 @@ -keep class baritone.api.IBaritoneProvider -keep class baritone.api.utils.MyChunkPos { *; } # even in standalone we need to keep this for gson reflect +-keepname class baritone.api.utils.BlockOptionalMeta # this name is exposed to the user, so we need to keep it in all builds # Keep any class or member annotated with @KeepName so we dont have to put everything in the script -keep,allowobfuscation @interface baritone.KeepName @@ -45,7 +46,6 @@ #proguard doesnt like it when it cant find our fake schematica classes -dontwarn baritone.utils.schematic.schematica.** - # Keep - Applications. Keep all application classes, along with their 'main' # methods. -keepclasseswithmembers public class * { diff --git a/src/api/java/baritone/api/Settings.java b/src/api/java/baritone/api/Settings.java index 20566f54b..bfcdd7b46 100644 --- a/src/api/java/baritone/api/Settings.java +++ b/src/api/java/baritone/api/Settings.java @@ -190,6 +190,13 @@ public final class Settings { /** * Blocks that Baritone is not allowed to break */ + public final Setting> blocksToDisallowBreaking = new Setting<>(new ArrayList<>( + // Leave Empty by Default + )); + + /** + * blocks that baritone shouldn't break, but can if it needs to. + */ public final Setting> blocksToAvoidBreaking = new Setting<>(new ArrayList<>(Arrays.asList( // TODO can this be a HashSet or ImmutableSet? Blocks.CRAFTING_TABLE, Blocks.FURNACE, @@ -199,6 +206,11 @@ public final class Settings { Blocks.WALL_SIGN ))); + /** + * this multiplies the break speed, if set above 1 it's "encourage breaking" instead + */ + public final Setting avoidBreakingMultiplier = new Setting<>(.1); + /** * A list of blocks to be treated as if they're air. *

@@ -245,6 +257,11 @@ public final class Settings { */ public final Setting buildIgnoreExisting = new Setting<>(false); + /** + * If this is true, the builder will ignore directionality of certain blocks like glazed terracotta. + */ + public final Setting buildIgnoreDirection = new Setting<>(false); + /** * If this setting is true, Baritone will never break a block that is adjacent to an unsupported falling block. *

@@ -372,6 +389,9 @@ public final class Settings { */ public final Setting mobSpawnerAvoidanceCoefficient = new Setting<>(2.0); + /** + * Distance to avoid mob spawners. + */ public final Setting mobSpawnerAvoidanceRadius = new Setting<>(16); /** @@ -381,6 +401,9 @@ public final class Settings { */ public final Setting mobAvoidanceCoefficient = new Setting<>(1.5); + /** + * Distance to avoid mobs. + */ public final Setting mobAvoidanceRadius = new Setting<>(8); /** @@ -547,13 +570,6 @@ public final class Settings { */ public final Setting pruneRegionsFromRAM = new Setting<>(true); - /** - * Remember the contents of containers (chests, echests, furnaces) - *

- * Really buggy since the packet stuff is multithreaded badly thanks to brady - */ - public final Setting containerMemory = new Setting<>(false); - /** * Fill in blocks behind you */ diff --git a/src/api/java/baritone/api/cache/IContainerMemory.java b/src/api/java/baritone/api/cache/IContainerMemory.java deleted file mode 100644 index 5c19d43b9..000000000 --- a/src/api/java/baritone/api/cache/IContainerMemory.java +++ /dev/null @@ -1,44 +0,0 @@ -/* - * 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.cache; - -import net.minecraft.util.math.BlockPos; - -import java.util.Map; - -/** - * @author Brady - * @since 9/23/2018 - */ -public interface IContainerMemory { - - /** - * Gets a remembered inventory by its block position. - * - * @param pos The position of the container block - * @return The remembered inventory - */ - IRememberedInventory getInventoryByPos(BlockPos pos); - - /** - * Gets the map of all block positions to their remembered inventories. - * - * @return Map of block positions to their respective remembered inventories - */ - Map getRememberedInventories(); -} diff --git a/src/api/java/baritone/api/cache/IRememberedInventory.java b/src/api/java/baritone/api/cache/IRememberedInventory.java deleted file mode 100644 index a7890fe3a..000000000 --- a/src/api/java/baritone/api/cache/IRememberedInventory.java +++ /dev/null @@ -1,39 +0,0 @@ -/* - * 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.cache; - -import net.minecraft.item.ItemStack; - -import java.util.List; - -/** - * @author Brady - * @since 9/23/2018 - */ -public interface IRememberedInventory { - - /** - * @return The contents of this inventory - */ - List getContents(); - - /** - * @return The number of slots in this inventory - */ - int getSize(); -} diff --git a/src/api/java/baritone/api/cache/IWorldData.java b/src/api/java/baritone/api/cache/IWorldData.java index 1eaade4c0..200771935 100644 --- a/src/api/java/baritone/api/cache/IWorldData.java +++ b/src/api/java/baritone/api/cache/IWorldData.java @@ -37,9 +37,4 @@ public interface IWorldData { */ IWaypointCollection getWaypoints(); - /** - * @return The {@link IContainerMemory} instance - * @see IContainerMemory - */ - IContainerMemory getContainerMemory(); } diff --git a/src/main/java/baritone/Baritone.java b/src/main/java/baritone/Baritone.java index f37252658..71d786339 100755 --- a/src/main/java/baritone/Baritone.java +++ b/src/main/java/baritone/Baritone.java @@ -68,7 +68,6 @@ public class Baritone implements IBaritone { private PathingBehavior pathingBehavior; private LookBehavior lookBehavior; - private MemoryBehavior memoryBehavior; private InventoryBehavior inventoryBehavior; private InputOverrideHandler inputOverrideHandler; @@ -100,7 +99,6 @@ public class Baritone implements IBaritone { // the Behavior constructor calls baritone.registerBehavior(this) so this populates the behaviors arraylist pathingBehavior = new PathingBehavior(this); lookBehavior = new LookBehavior(this); - memoryBehavior = new MemoryBehavior(this); inventoryBehavior = new InventoryBehavior(this); inputOverrideHandler = new InputOverrideHandler(this); } @@ -151,10 +149,6 @@ public class Baritone implements IBaritone { return this.playerContext; } - public MemoryBehavior getMemoryBehavior() { - return this.memoryBehavior; - } - @Override public FollowProcess getFollowProcess() { return this.followProcess; diff --git a/src/main/java/baritone/behavior/MemoryBehavior.java b/src/main/java/baritone/behavior/MemoryBehavior.java deleted file mode 100644 index b7d31223a..000000000 --- a/src/main/java/baritone/behavior/MemoryBehavior.java +++ /dev/null @@ -1,319 +0,0 @@ -/* - * 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.behavior; - -import baritone.Baritone; -import baritone.api.cache.Waypoint; -import baritone.api.event.events.BlockInteractEvent; -import baritone.api.event.events.PacketEvent; -import baritone.api.event.events.PlayerUpdateEvent; -import baritone.api.event.events.TickEvent; -import baritone.api.event.events.type.EventState; -import baritone.api.utils.BetterBlockPos; -import baritone.api.utils.Helper; -import baritone.cache.ContainerMemory; -import baritone.utils.BlockStateInterface; -import net.minecraft.block.Block; -import net.minecraft.block.BlockBed; -import net.minecraft.init.Blocks; -import net.minecraft.item.ItemStack; -import net.minecraft.network.Packet; -import net.minecraft.network.play.client.CPacketCloseWindow; -import net.minecraft.network.play.client.CPacketPlayerTryUseItemOnBlock; -import net.minecraft.network.play.server.SPacketCloseWindow; -import net.minecraft.network.play.server.SPacketOpenWindow; -import net.minecraft.tileentity.TileEntity; -import net.minecraft.tileentity.TileEntityLockable; -import net.minecraft.util.EnumFacing; -import net.minecraft.util.math.BlockPos; -import net.minecraft.util.text.ITextComponent; -import net.minecraft.util.text.TextComponentString; -import net.minecraft.util.text.TextComponentTranslation; -import net.minecraft.util.text.TextFormatting; -import net.minecraft.util.text.event.ClickEvent; -import net.minecraft.util.text.event.HoverEvent; - -import java.io.IOException; -import java.nio.file.Files; -import java.nio.file.Path; -import java.util.*; - -import static baritone.api.command.IBaritoneChatControl.FORCE_COMMAND_PREFIX; - -/** - * doesn't work for horse inventories :^) - * - * @author Brady - * @since 8/6/2018 - */ -public final class MemoryBehavior extends Behavior { - - private final List futureInventories = new ArrayList<>(); // this is per-bot - - private Integer enderChestWindowId; // nae nae - - public MemoryBehavior(Baritone baritone) { - super(baritone); - } - - @Override - public synchronized void onTick(TickEvent event) { - if (!Baritone.settings().containerMemory.value) { - return; - } - if (event.getType() == TickEvent.Type.OUT) { - enderChestWindowId = null; - futureInventories.clear(); - } - } - - @Override - public synchronized void onPlayerUpdate(PlayerUpdateEvent event) { - if (event.getState() == EventState.PRE) { - updateInventory(); - } - } - - @Override - public synchronized void onSendPacket(PacketEvent event) { - if (!Baritone.settings().containerMemory.value) { - return; - } - Packet p = event.getPacket(); - - if (event.getState() == EventState.PRE) { - if (p instanceof CPacketPlayerTryUseItemOnBlock) { - CPacketPlayerTryUseItemOnBlock packet = event.cast(); - - TileEntity tileEntity = ctx.world().getTileEntity(packet.getPos()); - // if tileEntity is an ender chest, we don't need to do anything. ender chests are treated the same regardless of what coordinate right clicked - - // Ensure the TileEntity is a container of some sort - if (tileEntity instanceof TileEntityLockable) { - - TileEntityLockable lockable = (TileEntityLockable) tileEntity; - int size = lockable.getSizeInventory(); - BetterBlockPos position = BetterBlockPos.from(tileEntity.getPos()); - BetterBlockPos adj = BetterBlockPos.from(neighboringConnectedBlock(position)); - System.out.println(position + " " + adj); - if (adj != null) { - size *= 2; // double chest or double trapped chest - if (adj.getX() < position.getX() || adj.getZ() < position.getZ()) { - position = adj; // standardize on the lower coordinate, regardless of which side of the large chest we right clicked - } - } - - this.futureInventories.add(new FutureInventory(System.nanoTime() / 1000000L, size, lockable.getGuiID(), position)); - } - } - - if (p instanceof CPacketCloseWindow) { - getCurrent().save(); - } - } - } - - @Override - public synchronized void onReceivePacket(PacketEvent event) { - if (!Baritone.settings().containerMemory.value) { - return; - } - Packet p = event.getPacket(); - - if (event.getState() == EventState.PRE) { - if (p instanceof SPacketOpenWindow) { - SPacketOpenWindow packet = event.cast(); - // Remove any entries that were created over a second ago, this should make up for INSANE latency - futureInventories.removeIf(i -> System.nanoTime() / 1000000L - i.time > 1000); - - System.out.println("Received packet " + packet.getGuiId() + " " + packet.getEntityId() + " " + packet.getSlotCount() + " " + packet.getWindowId()); - System.out.println(packet.getWindowTitle()); - if (packet.getWindowTitle() instanceof TextComponentTranslation && ((TextComponentTranslation) packet.getWindowTitle()).getKey().equals("container.enderchest")) { - // title is not customized (i.e. this isn't just a renamed shulker) - enderChestWindowId = packet.getWindowId(); - return; - } - futureInventories.stream() - .filter(i -> i.type.equals(packet.getGuiId()) && i.slots == packet.getSlotCount()) - .findFirst().ifPresent(matched -> { - // Remove the future inventory - futureInventories.remove(matched); - - // Setup the remembered inventory - getCurrentContainer().setup(matched.pos, packet.getWindowId(), packet.getSlotCount()); - }); - } - - if (p instanceof SPacketCloseWindow) { - getCurrent().save(); - } - } - } - - @Override - public void onBlockInteract(BlockInteractEvent event) { - if (event.getType() == BlockInteractEvent.Type.USE && BlockStateInterface.getBlock(ctx, event.getPos()) instanceof BlockBed) { - baritone.getWorldProvider().getCurrentWorld().getWaypoints().addWaypoint(new Waypoint("bed", Waypoint.Tag.BED, BetterBlockPos.from(event.getPos()))); - } - } - - @Override - public void onPlayerDeath() { - Waypoint deathWaypoint = new Waypoint("death", Waypoint.Tag.DEATH, ctx.playerFeet()); - baritone.getWorldProvider().getCurrentWorld().getWaypoints().addWaypoint(deathWaypoint); - ITextComponent component = new TextComponentString("Death position saved."); - component.getStyle() - .setColor(TextFormatting.WHITE) - .setHoverEvent(new HoverEvent( - HoverEvent.Action.SHOW_TEXT, - new TextComponentString("Click to goto death") - )) - .setClickEvent(new ClickEvent( - ClickEvent.Action.RUN_COMMAND, - String.format( - "%s%s goto %s @ %d", - FORCE_COMMAND_PREFIX, - "wp", - deathWaypoint.getTag().getName(), - deathWaypoint.getCreationTimestamp() - ) - )); - Helper.HELPER.logDirect(component); - } - - - private void updateInventory() { - if (!Baritone.settings().containerMemory.value) { - return; - } - int windowId = ctx.player().openContainer.windowId; - if (enderChestWindowId != null) { - if (windowId == enderChestWindowId) { - getCurrent().contents = ctx.player().openContainer.getInventory().subList(0, 27); - } else { - getCurrent().save(); - enderChestWindowId = null; - } - } - if (getCurrentContainer() != null) { - getCurrentContainer().getInventoryFromWindow(windowId).ifPresent(inventory -> inventory.updateFromOpenWindow(ctx)); - } - } - - private ContainerMemory getCurrentContainer() { - if (baritone.getWorldProvider().getCurrentWorld() == null) { - return null; - } - return (ContainerMemory) baritone.getWorldProvider().getCurrentWorld().getContainerMemory(); - } - - private BlockPos neighboringConnectedBlock(BlockPos in) { - BlockStateInterface bsi = baritone.bsi; - Block block = bsi.get0(in).getBlock(); - if (block != Blocks.TRAPPED_CHEST && block != Blocks.CHEST) { - return null; // other things that have contents, but can be placed adjacent without combining - } - for (int i = 0; i < 4; i++) { - BlockPos adj = in.offset(EnumFacing.byHorizontalIndex(i)); - if (bsi.get0(adj).getBlock() == block) { - return adj; - } - } - return null; - } - - /** - * An inventory that we are not yet fully aware of, but are expecting to exist at some point in the future. - */ - private static final class FutureInventory { - - /** - * The time that we initially expected the inventory to be provided, in milliseconds - */ - private final long time; - - /** - * The amount of slots in the inventory - */ - private final int slots; - - /** - * The type of inventory - */ - private final String type; - - /** - * The position of the inventory container - */ - private final BlockPos pos; - - private FutureInventory(long time, int slots, String type, BlockPos pos) { - this.time = time; - this.slots = slots; - this.type = type; - this.pos = pos; - // betterblockpos has censoring - System.out.println("Future inventory created " + time + " " + slots + " " + type + " " + BetterBlockPos.from(pos)); - } - } - - public Optional> echest() { - return Optional.ofNullable(getCurrent().contents).map(Collections::unmodifiableList); - } - - public EnderChestMemory getCurrent() { - Path path = baritone.getWorldProvider().getCurrentWorld().directory; - return EnderChestMemory.getByServerAndPlayer(path.getParent(), ctx.player().getUniqueID()); - } - - public static class EnderChestMemory { - - private static final Map memory = new HashMap<>(); - private final Path enderChest; - private List contents; - - private EnderChestMemory(Path enderChest) { - this.enderChest = enderChest; - System.out.println("Echest storing in " + enderChest); - try { - this.contents = ContainerMemory.readItemStacks(Files.readAllBytes(enderChest)); - } catch (IOException e) { - e.printStackTrace(); - System.out.println("CANNOT read echest =( =("); - this.contents = null; - } - } - - public synchronized void save() { - System.out.println("Saving"); - if (contents != null) { - try { - enderChest.getParent().toFile().mkdir(); - Files.write(enderChest, ContainerMemory.writeItemStacks(contents)); - } catch (IOException e) { - e.printStackTrace(); - System.out.println("CANNOT save echest =( =("); - } - } - } - - private static synchronized EnderChestMemory getByServerAndPlayer(Path serverStorage, UUID player) { - return memory.computeIfAbsent(serverStorage.resolve("echests").resolve(player.toString()), EnderChestMemory::new); - } - } -} diff --git a/src/main/java/baritone/cache/ContainerMemory.java b/src/main/java/baritone/cache/ContainerMemory.java deleted file mode 100644 index e79435e3a..000000000 --- a/src/main/java/baritone/cache/ContainerMemory.java +++ /dev/null @@ -1,183 +0,0 @@ -/* - * 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.cache; - -import baritone.Baritone; -import baritone.api.cache.IContainerMemory; -import baritone.api.cache.IRememberedInventory; -import baritone.api.utils.IPlayerContext; -import io.netty.buffer.ByteBuf; -import io.netty.buffer.Unpooled; -import net.minecraft.item.ItemStack; -import net.minecraft.network.PacketBuffer; -import net.minecraft.util.math.BlockPos; - -import java.io.IOException; -import java.nio.file.Files; -import java.nio.file.NoSuchFileException; -import java.nio.file.Path; -import java.util.*; - -public class ContainerMemory implements IContainerMemory { - - private final Path saveTo; - /** - * The current remembered inventories - */ - private final Map inventories = new HashMap<>(); - - - public ContainerMemory(Path saveTo) { - this.saveTo = saveTo; - try { - read(Files.readAllBytes(saveTo)); - } catch (NoSuchFileException ignored) { - inventories.clear(); - } catch (Exception ex) { - ex.printStackTrace(); - inventories.clear(); - } - } - - private void read(byte[] bytes) throws IOException { - PacketBuffer in = new PacketBuffer(Unpooled.wrappedBuffer(bytes)); - int chests = in.readInt(); - for (int i = 0; i < chests; i++) { - int x = in.readInt(); - int y = in.readInt(); - int z = in.readInt(); - RememberedInventory rem = new RememberedInventory(); - rem.items.addAll(readItemStacks(in)); - rem.size = rem.items.size(); - rem.windowId = -1; - if (rem.items.isEmpty()) { - continue; // this only happens if the list has no elements, not if the list has elements that are all empty item stacks - } - inventories.put(new BlockPos(x, y, z), rem); - } - } - - public synchronized void save() throws IOException { - if (!Baritone.settings().containerMemory.value) { - return; - } - ByteBuf buf = Unpooled.buffer(0, Integer.MAX_VALUE); - PacketBuffer out = new PacketBuffer(buf); - out.writeInt(inventories.size()); - for (Map.Entry entry : inventories.entrySet()) { - out = new PacketBuffer(out.writeInt(entry.getKey().getX())); - out = new PacketBuffer(out.writeInt(entry.getKey().getY())); - out = new PacketBuffer(out.writeInt(entry.getKey().getZ())); - out = writeItemStacks(entry.getValue().getContents(), out); - } - Files.write(saveTo, out.array()); - } - - public synchronized void setup(BlockPos pos, int windowId, int slotCount) { - RememberedInventory inventory = inventories.computeIfAbsent(pos, x -> new RememberedInventory()); - inventory.windowId = windowId; - inventory.size = slotCount; - } - - public synchronized Optional getInventoryFromWindow(int windowId) { - return inventories.values().stream().filter(i -> i.windowId == windowId).findFirst(); - } - - @Override - public final synchronized RememberedInventory getInventoryByPos(BlockPos pos) { - return inventories.get(pos); - } - - @Override - public final synchronized Map getRememberedInventories() { - // make a copy since this map is modified from the packet thread - return new HashMap<>(inventories); - } - - public static List readItemStacks(byte[] bytes) throws IOException { - PacketBuffer in = new PacketBuffer(Unpooled.wrappedBuffer(bytes)); - return readItemStacks(in); - } - - public static List readItemStacks(PacketBuffer in) throws IOException { - int count = in.readInt(); - List result = new ArrayList<>(); - for (int i = 0; i < count; i++) { - result.add(in.readItemStack()); - } - return result; - } - - public static byte[] writeItemStacks(List write) { - ByteBuf buf = Unpooled.buffer(0, Integer.MAX_VALUE); - PacketBuffer out = new PacketBuffer(buf); - out = writeItemStacks(write, out); - return out.array(); - } - - public static PacketBuffer writeItemStacks(List write, PacketBuffer out2) { - PacketBuffer out = out2; // avoid reassigning an argument LOL - out = new PacketBuffer(out.writeInt(write.size())); - for (ItemStack stack : write) { - out = out.writeItemStack(stack); - } - return out; - } - - /** - * An inventory that we are aware of. - *

- * Associated with a {@link BlockPos} in {@link ContainerMemory#inventories}. - */ - public static class RememberedInventory implements IRememberedInventory { - - /** - * The list of items in the inventory - */ - private final List items; - - /** - * The last known window ID of the inventory - */ - private int windowId; - - /** - * The size of the inventory - */ - private int size; - - private RememberedInventory() { - this.items = new ArrayList<>(); - } - - @Override - public final List getContents() { - return Collections.unmodifiableList(this.items); - } - - @Override - public final int getSize() { - return this.size; - } - - public void updateFromOpenWindow(IPlayerContext ctx) { - items.clear(); - items.addAll(ctx.player().openContainer.getInventory().subList(0, size)); - } - } -} diff --git a/src/main/java/baritone/cache/WorldData.java b/src/main/java/baritone/cache/WorldData.java index 30fe8bd0d..cbdda3687 100644 --- a/src/main/java/baritone/cache/WorldData.java +++ b/src/main/java/baritone/cache/WorldData.java @@ -19,7 +19,6 @@ package baritone.cache; import baritone.Baritone; import baritone.api.cache.ICachedWorld; -import baritone.api.cache.IContainerMemory; import baritone.api.cache.IWaypointCollection; import baritone.api.cache.IWorldData; @@ -35,7 +34,6 @@ public class WorldData implements IWorldData { public final CachedWorld cache; private final WaypointCollection waypoints; - private final ContainerMemory containerMemory; //public final MapData map; public final Path directory; public final int dimension; @@ -44,7 +42,6 @@ public class WorldData implements IWorldData { this.directory = directory; this.cache = new CachedWorld(directory.resolve("cache"), dimension); this.waypoints = new WaypointCollection(directory.resolve("waypoints")); - this.containerMemory = new ContainerMemory(directory.resolve("containers")); this.dimension = dimension; } @@ -53,15 +50,6 @@ public class WorldData implements IWorldData { System.out.println("Started saving the world in a new thread"); cache.save(); }); - Baritone.getExecutor().execute(() -> { - System.out.println("Started saving saved containers in a new thread"); - try { - containerMemory.save(); - } catch (IOException e) { - e.printStackTrace(); - System.out.println("Failed to save saved containers"); - } - }); } @Override @@ -73,9 +61,4 @@ public class WorldData implements IWorldData { public IWaypointCollection getWaypoints() { return this.waypoints; } - - @Override - public IContainerMemory getContainerMemory() { - return this.containerMemory; - } } diff --git a/src/main/java/baritone/cache/WorldProvider.java b/src/main/java/baritone/cache/WorldProvider.java index 412e16ee5..75e319ea6 100644 --- a/src/main/java/baritone/cache/WorldProvider.java +++ b/src/main/java/baritone/cache/WorldProvider.java @@ -78,7 +78,14 @@ public class WorldProvider implements IWorldProvider, Helper { directory = new File(directory, "baritone"); readme = directory; } else { // Otherwise, the server must be remote... - String folderName = mc.getCurrentServerData().serverIP; + String folderName; + if (mc.getCurrentServerData() != null) { + folderName = mc.getCurrentServerData().serverIP; + } else { + //replaymod causes null currentServerData and false singleplayer. + currentWorld = null; + return; + } if (SystemUtils.IS_OS_WINDOWS) { folderName = folderName.replace(":", "_"); } diff --git a/src/main/java/baritone/command/defaults/ChestsCommand.java b/src/main/java/baritone/command/defaults/ChestsCommand.java deleted file mode 100644 index b4dcda749..000000000 --- a/src/main/java/baritone/command/defaults/ChestsCommand.java +++ /dev/null @@ -1,83 +0,0 @@ -/* - * 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.cache.IRememberedInventory; -import baritone.api.command.Command; -import baritone.api.command.argument.IArgConsumer; -import baritone.api.command.exception.CommandException; -import baritone.api.command.exception.CommandInvalidStateException; -import baritone.api.utils.BetterBlockPos; -import net.minecraft.item.ItemStack; -import net.minecraft.util.math.BlockPos; -import net.minecraft.util.text.ITextComponent; - -import java.util.Arrays; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.stream.Stream; - -public class ChestsCommand extends Command { - - public ChestsCommand(IBaritone baritone) { - super(baritone, "chests"); - } - - @Override - public void execute(String label, IArgConsumer args) throws CommandException { - args.requireMax(0); - Set> entries = - ctx.worldData().getContainerMemory().getRememberedInventories().entrySet(); - if (entries.isEmpty()) { - throw new CommandInvalidStateException("No remembered inventories"); - } - for (Map.Entry entry : entries) { - // betterblockpos has censoring - BetterBlockPos pos = new BetterBlockPos(entry.getKey()); - IRememberedInventory inv = entry.getValue(); - logDirect(pos.toString()); - for (ItemStack item : inv.getContents()) { - ITextComponent component = item.getTextComponent(); - component.appendText(String.format(" x %d", item.getCount())); - logDirect(component); - } - } - } - - @Override - public Stream tabComplete(String label, IArgConsumer args) { - return Stream.empty(); - } - - @Override - public String getShortDesc() { - return "Display remembered inventories"; - } - - @Override - public List getLongDesc() { - return Arrays.asList( - "The chests command lists remembered inventories, I guess?", - "", - "Usage:", - "> chests" - ); - } -} diff --git a/src/main/java/baritone/command/defaults/DefaultCommands.java b/src/main/java/baritone/command/defaults/DefaultCommands.java index 17f338046..e998dcc97 100644 --- a/src/main/java/baritone/command/defaults/DefaultCommands.java +++ b/src/main/java/baritone/command/defaults/DefaultCommands.java @@ -51,7 +51,6 @@ public final class DefaultCommands { new TunnelCommand(baritone), new RenderCommand(baritone), new FarmCommand(baritone), - new ChestsCommand(baritone), new FollowCommand(baritone), new ExploreFilterCommand(baritone), new ReloadAllCommand(baritone), diff --git a/src/main/java/baritone/command/defaults/ExecutionControlCommands.java b/src/main/java/baritone/command/defaults/ExecutionControlCommands.java index 1b024c3b8..8a53e7d41 100644 --- a/src/main/java/baritone/command/defaults/ExecutionControlCommands.java +++ b/src/main/java/baritone/command/defaults/ExecutionControlCommands.java @@ -112,7 +112,7 @@ public class ExecutionControlCommands { ); } }; - resumeCommand = new Command(baritone, "resume", "r") { + resumeCommand = new Command(baritone, "resume", "r", "unpause") { @Override public void execute(String label, IArgConsumer args) throws CommandException { args.requireMax(0); diff --git a/src/main/java/baritone/command/defaults/FindCommand.java b/src/main/java/baritone/command/defaults/FindCommand.java index ce79744e7..78052a941 100644 --- a/src/main/java/baritone/command/defaults/FindCommand.java +++ b/src/main/java/baritone/command/defaults/FindCommand.java @@ -72,10 +72,10 @@ public class FindCommand extends Command { @Override public List getLongDesc() { return Arrays.asList( - "", + "The find command searches through Baritone's cache and attempts to find the location of the block.", "", "Usage:", - "> " + "> find - Find positions of a certain block" ); } } diff --git a/src/main/java/baritone/command/defaults/WaypointsCommand.java b/src/main/java/baritone/command/defaults/WaypointsCommand.java index 5d964da42..5a45686a3 100644 --- a/src/main/java/baritone/command/defaults/WaypointsCommand.java +++ b/src/main/java/baritone/command/defaults/WaypointsCommand.java @@ -17,9 +17,11 @@ package baritone.command.defaults; +import baritone.Baritone; import baritone.api.IBaritone; import baritone.api.cache.IWaypoint; import baritone.api.cache.Waypoint; +import baritone.api.cache.IWorldData; import baritone.api.command.Command; import baritone.api.command.argument.IArgConsumer; import baritone.api.command.datatypes.ForWaypoints; @@ -41,12 +43,15 @@ import net.minecraft.util.text.event.HoverEvent; import java.util.*; import java.util.function.BiFunction; import java.util.function.Function; +import java.util.stream.Collectors; import java.util.stream.Stream; import static baritone.api.command.IBaritoneChatControl.FORCE_COMMAND_PREFIX; public class WaypointsCommand extends Command { + private Map> deletedWaypoints = new HashMap<>(); + public WaypointsCommand(IBaritone baritone) { super(baritone, "waypoints", "waypoint", "wp"); } @@ -125,11 +130,13 @@ public class WaypointsCommand extends Command { ); } } else if (action == Action.SAVE) { - IWaypoint.Tag tag = IWaypoint.Tag.getByName(args.getString()); + IWaypoint.Tag tag = args.hasAny() ? IWaypoint.Tag.getByName(args.peekString()) : null; if (tag == null) { - throw new CommandInvalidStateException(String.format("'%s' is not a tag ", args.consumedString())); + tag = IWaypoint.Tag.USER; + } else { + args.get(); } - String name = args.hasAny() ? args.getString() : ""; + String name = (args.hasExactlyOne() || args.hasExactly(4)) ? args.getString() : ""; BetterBlockPos pos = args.hasAny() ? args.getDatatypePost(RelativeBlockPos.INSTANCE, ctx.playerFeet()) : ctx.playerFeet(); @@ -147,7 +154,42 @@ public class WaypointsCommand extends Command { for (IWaypoint waypoint : waypoints) { ForWaypoints.waypoints(this.baritone).removeWaypoint(waypoint); } - logDirect(String.format("Cleared %d waypoints", waypoints.length)); + deletedWaypoints.computeIfAbsent(baritone.getWorldProvider().getCurrentWorld(), k -> new ArrayList<>()).addAll(Arrays.asList(waypoints)); + ITextComponent textComponent = new TextComponentString(String.format("Cleared %d waypoints, click to restore them", waypoints.length)); + textComponent.getStyle().setClickEvent(new ClickEvent( + ClickEvent.Action.RUN_COMMAND, + String.format( + "%s%s restore @ %s", + FORCE_COMMAND_PREFIX, + label, + Stream.of(waypoints).map(wp -> Long.toString(wp.getCreationTimestamp())).collect(Collectors.joining(" ")) + ) + )); + logDirect(textComponent); + } else if (action == Action.RESTORE) { + List waypoints = new ArrayList<>(); + List deletedWaypoints = this.deletedWaypoints.getOrDefault(baritone.getWorldProvider().getCurrentWorld(), Collections.emptyList()); + if (args.peekString().equals("@")) { + args.get(); + // no args.requireMin(1) because if the user clears an empty tag there is nothing to restore + while (args.hasAny()) { + long timestamp = args.getAs(Long.class); + for (IWaypoint waypoint : deletedWaypoints) { + if (waypoint.getCreationTimestamp() == timestamp) { + waypoints.add(waypoint); + break; + } + } + } + } else { + args.requireExactly(1); + int size = deletedWaypoints.size(); + int amount = Math.min(size, args.getAs(Integer.class)); + waypoints = new ArrayList<>(deletedWaypoints.subList(size - amount, size)); + } + waypoints.forEach(ForWaypoints.waypoints(this.baritone)::addWaypoint); + deletedWaypoints.removeIf(waypoints::contains); + logDirect(String.format("Restored %d waypoints", waypoints.size())); } else { IWaypoint[] waypoints = args.getDatatypeFor(ForWaypoints.INSTANCE); IWaypoint waypoint = null; @@ -216,6 +258,20 @@ public class WaypointsCommand extends Command { waypoint.getCreationTimestamp() ) )); + ITextComponent recreateComponent = new TextComponentString("Click to show a command to recreate this waypoint"); + recreateComponent.getStyle().setClickEvent(new ClickEvent( + ClickEvent.Action.SUGGEST_COMMAND, + String.format( + "%s%s save %s %s %s %s %s", + Baritone.settings().prefix.value, // This uses the normal prefix because it is run by the user. + label, + waypoint.getTag().getName(), + waypoint.getName(), + waypoint.getLocation().x, + waypoint.getLocation().y, + waypoint.getLocation().z + ) + )); ITextComponent backComponent = new TextComponentString("Click to return to the waypoints list"); backComponent.getStyle().setClickEvent(new ClickEvent( ClickEvent.Action.RUN_COMMAND, @@ -227,10 +283,22 @@ public class WaypointsCommand extends Command { )); logDirect(deleteComponent); logDirect(goalComponent); + logDirect(recreateComponent); logDirect(backComponent); } else if (action == Action.DELETE) { ForWaypoints.waypoints(this.baritone).removeWaypoint(waypoint); - logDirect("That waypoint has successfully been deleted"); + deletedWaypoints.computeIfAbsent(baritone.getWorldProvider().getCurrentWorld(), k -> new ArrayList<>()).add(waypoint); + ITextComponent textComponent = new TextComponentString("That waypoint has successfully been deleted, click to restore it"); + textComponent.getStyle().setClickEvent(new ClickEvent( + ClickEvent.Action.RUN_COMMAND, + String.format( + "%s%s restore @ %s", + FORCE_COMMAND_PREFIX, + label, + waypoint.getCreationTimestamp() + ) + )); + logDirect(textComponent); } else if (action == Action.GOAL) { Goal goal = new GoalBlock(waypoint.getLocation()); baritone.getCustomGoalProcess().setGoal(goal); @@ -262,6 +330,8 @@ public class WaypointsCommand extends Command { .sortAlphabetically() .filterPrefix(args.getString()) .stream(); + } else if (action == Action.RESTORE) { + return Stream.empty(); } else { return args.tabCompleteDatatype(ForWaypoints.INSTANCE); } @@ -289,15 +359,19 @@ public class WaypointsCommand extends Command { "", "Note that the info, delete, and goal commands let you specify a waypoint by tag. If there is more than one waypoint with a certain tag, then they will let you select which waypoint you mean.", "", + "Missing arguments for the save command use the USER tag, creating an unnamed waypoint and your current position as defaults.", + "", "Usage:", "> wp [l/list] - List all waypoints.", - "> wp - Save your current position as an unnamed waypoint with the specified tag.", - "> wp - Save the waypoint with the specified name.", - "> wp - Save the waypoint with the specified name and position.", - "> wp - Show info on a waypoint by tag.", - "> wp - Delete a waypoint by tag.", - "> wp - Set a goal to a waypoint by tag.", - "> wp - Set a goal to a waypoint by tag and start pathing." + "> wp - List all waypoints by tag.", + "> wp - Save an unnamed USER waypoint at your current position", + "> wp [tag] [name] [pos] - Save a waypoint with the specified tag, name and position.", + "> wp - Show info on a waypoint by tag or name.", + "> wp - Delete a waypoint by tag or name.", + "> wp - Restore the last n deleted waypoints.", + "> wp - Delete all waypoints with the specified tag.", + "> wp - Set a goal to a waypoint by tag or name.", + "> wp - Set a goal to a waypoint by tag or name and start pathing." ); } @@ -307,6 +381,7 @@ public class WaypointsCommand extends Command { SAVE("save", "s"), INFO("info", "show", "i"), DELETE("delete", "d"), + RESTORE("restore"), GOAL("goal", "g"), GOTO("goto"); private final String[] names; diff --git a/src/main/java/baritone/pathing/movement/CalculationContext.java b/src/main/java/baritone/pathing/movement/CalculationContext.java index 4ad659cce..7da608750 100644 --- a/src/main/java/baritone/pathing/movement/CalculationContext.java +++ b/src/main/java/baritone/pathing/movement/CalculationContext.java @@ -143,7 +143,6 @@ public class CalculationContext { return COST_INF; } if (!worldBorder.canPlaceAt(x, z)) { - // TODO perhaps MovementHelper.canPlaceAgainst could also use this? return COST_INF; } return placeBlockCost; diff --git a/src/main/java/baritone/pathing/movement/MovementHelper.java b/src/main/java/baritone/pathing/movement/MovementHelper.java index a2f4865f5..7952dccac 100644 --- a/src/main/java/baritone/pathing/movement/MovementHelper.java +++ b/src/main/java/baritone/pathing/movement/MovementHelper.java @@ -56,8 +56,12 @@ import static baritone.pathing.movement.Movement.HORIZONTALS_BUT_ALSO_DOWN_____S public interface MovementHelper extends ActionCosts, Helper { static boolean avoidBreaking(BlockStateInterface bsi, int x, int y, int z, IBlockState state) { + if (!bsi.worldBorder.canPlaceAt(x, y)) { + return true; + } Block b = state.getBlock(); - return b == Blocks.ICE // ice becomes water, and water can mess up the path + return Baritone.settings().blocksToDisallowBreaking.value.contains(b) + || b == Blocks.ICE // ice becomes water, and water can mess up the path || b instanceof BlockSilverfish // obvious reasons // call context.get directly with x,y,z. no need to make 5 new BlockPos for no reason || avoidAdjacentBreaking(bsi, x, y + 1, z, true) @@ -141,6 +145,9 @@ public interface MovementHelper extends ActionCosts, Helper { } return true; } + if (block instanceof BlockCauldron) { + return false; + } // every block that overrides isPassable with anything more complicated than a "return true;" or "return false;" // has already been accounted for above // therefore it's safe to not construct a blockpos from our x, y, z ints and instead just pass null @@ -377,6 +384,9 @@ public interface MovementHelper extends ActionCosts, Helper { } static boolean canPlaceAgainst(BlockStateInterface bsi, int x, int y, int z, IBlockState state) { + if (!bsi.worldBorder.canPlaceAt(x, z)) { + return false; + } // can we look at the center of a side face of this block and likely be able to place? // (thats how this check is used) // therefore dont include weird things that we technically could place against (like carpet) but practically can't diff --git a/src/main/java/baritone/process/BuilderProcess.java b/src/main/java/baritone/process/BuilderProcess.java index 3847215ff..c53b97ba8 100644 --- a/src/main/java/baritone/process/BuilderProcess.java +++ b/src/main/java/baritone/process/BuilderProcess.java @@ -45,8 +45,10 @@ import baritone.utils.schematic.MapArtSchematic; import baritone.utils.schematic.SelectionSchematic; import baritone.utils.schematic.SchematicSystem; import baritone.utils.schematic.schematica.SchematicaHelper; +import com.google.common.collect.ImmutableMap; +import com.google.common.collect.ImmutableSet; import it.unimi.dsi.fastutil.longs.LongOpenHashSet; -import net.minecraft.block.BlockAir; +import net.minecraft.block.*; import net.minecraft.block.BlockFlowingFluid; import net.minecraft.block.state.IBlockState; import net.minecraft.init.Blocks; @@ -54,6 +56,7 @@ import net.minecraft.item.BlockItemUseContext; import net.minecraft.item.ItemBlock; import net.minecraft.item.ItemStack; import net.minecraft.item.ItemUseContext; +import net.minecraft.state.IProperty; import net.minecraft.util.EnumFacing; import net.minecraft.util.Tuple; import net.minecraft.util.math.*; @@ -849,6 +852,27 @@ public final class BuilderProcess extends BaritoneProcessHelper implements IBuil return result; } + public static final Set> orientationProps = + ImmutableSet.of(BlockRotatedPillar.AXIS, BlockHorizontal.HORIZONTAL_FACING, + BlockStairs.FACING, BlockStairs.HALF, BlockStairs.SHAPE, + BlockPane.NORTH, BlockPane.EAST, BlockPane.SOUTH, BlockPane.WEST, BlockVine.UP, + BlockTrapDoor.OPEN, BlockTrapDoor.HALF + ); + + private boolean sameWithoutOrientation(IBlockState first, IBlockState second) { + if (first.getBlock() != second.getBlock()) { + return false; + } + ImmutableMap, Comparable> map1 = first.getValues(); + ImmutableMap, Comparable> map2 = second.getValues(); + for (IProperty prop : map1.keySet()) { + if (map1.get(prop) != map2.get(prop) && !orientationProps.contains(prop)) { + return false; + } + } + return true; + } + private boolean valid(IBlockState current, IBlockState desired, boolean itemVerify) { if (desired == null) { return true; @@ -874,7 +898,10 @@ public final class BuilderProcess extends BaritoneProcessHelper implements IBuil if (Baritone.settings().buildValidSubstitutes.value.getOrDefault(desired.getBlock(), Collections.emptyList()).contains(current.getBlock()) && !itemVerify) { return true; } - return current.equals(desired); + if (current.equals(desired)) { + return true; + } + return Baritone.settings().buildIgnoreDirection.value && sameWithoutOrientation(current, desired); } public class BuilderCalculationContext extends CalculationContext { diff --git a/src/main/java/baritone/utils/BlockStateInterface.java b/src/main/java/baritone/utils/BlockStateInterface.java index 612cb8363..51927d263 100644 --- a/src/main/java/baritone/utils/BlockStateInterface.java +++ b/src/main/java/baritone/utils/BlockStateInterface.java @@ -22,6 +22,7 @@ import baritone.api.utils.IPlayerContext; import baritone.cache.CachedRegion; import baritone.cache.WorldData; import baritone.utils.accessor.IChunkProviderClient; +import baritone.utils.pathing.BetterWorldBorder; import it.unimi.dsi.fastutil.longs.Long2ObjectMap; import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap; import net.minecraft.block.Block; @@ -46,6 +47,7 @@ public class BlockStateInterface { protected final IBlockReader world; public final BlockPos.MutableBlockPos isPassableBlockPos; public final IBlockReader access; + public final BetterWorldBorder worldBorder; private Chunk prev = null; private CachedRegion prevCached = null; @@ -64,6 +66,7 @@ public class BlockStateInterface { public BlockStateInterface(World world, WorldData worldData, boolean copyLoadedChunks) { this.world = world; + this.worldBorder = new BetterWorldBorder(world.getWorldBorder()); this.worldData = worldData; Long2ObjectMap worldLoaded = ((IChunkProviderClient) world.getChunkProvider()).loadedChunks(); if (copyLoadedChunks) { diff --git a/src/main/java/baritone/utils/ToolSet.java b/src/main/java/baritone/utils/ToolSet.java index 79a06db58..6ef17d040 100644 --- a/src/main/java/baritone/utils/ToolSet.java +++ b/src/main/java/baritone/utils/ToolSet.java @@ -158,7 +158,7 @@ public class ToolSet { } private double avoidanceMultiplier(Block b) { - return Baritone.settings().blocksToAvoidBreaking.value.contains(b) ? 0.1 : 1; + return Baritone.settings().blocksToAvoidBreaking.value.contains(b) ? Baritone.settings().avoidBreakingMultiplier.value : 1; } /**