From 76e4a1a6494a2615bcc58ca981e5bdb5f03d4f69 Mon Sep 17 00:00:00 2001 From: Leijurv Date: Thu, 11 Oct 2018 21:22:46 -0700 Subject: [PATCH 1/6] brag about reproducible builds some more --- IMPACT.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/IMPACT.md b/IMPACT.md index 16673103..a6ca56f2 100644 --- a/IMPACT.md +++ b/IMPACT.md @@ -18,7 +18,7 @@ For Impact 4.3, there is no Baritone integration yet, so you will want `baritone Any official release will be GPG signed by leijurv (44A3EA646EADAC6A) and ZeroMemes (73A788379A197567). Please verify that the hash of the file you download is in `checksums.txt` and that `checksums_signed.asc` is a valid signature by those two public keys of `checksums.txt`. -The build is deterministic, and you can verify Travis did it properly by running `docker build --no-cache -t cabaletta/baritone . && docker run --rm -it cabaletta/baritone sh scripts/build.sh` yourself and comparing the shasum. Note that for some godawful reason this doesn't work on Mac, the shasums are different even though docker is supposed to work the same everywhere. I get the same shasums as Travis when the host is Linux though. +The build is fully deterministic and reproducible, and you can verify Travis did it properly by running `docker build --no-cache -t cabaletta/baritone . && docker run --rm -it cabaletta/baritone sh scripts/build.sh` 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). ### Building Baritone yourself There are a few steps to this From 8a65f43a0b7b12f735e24b814fe32bee998ee384 Mon Sep 17 00:00:00 2001 From: Leijurv Date: Fri, 12 Oct 2018 14:12:06 -0700 Subject: [PATCH 2/6] check world border, fixes #218 --- .../pathing/calc/AStarPathFinder.java | 16 ++++++-- .../utils/pathing/BetterWorldBorder.java | 39 +++++++++++++++++++ 2 files changed, 51 insertions(+), 4 deletions(-) create mode 100644 src/main/java/baritone/utils/pathing/BetterWorldBorder.java diff --git a/src/main/java/baritone/pathing/calc/AStarPathFinder.java b/src/main/java/baritone/pathing/calc/AStarPathFinder.java index f4adc7e2..a0deae58 100644 --- a/src/main/java/baritone/pathing/calc/AStarPathFinder.java +++ b/src/main/java/baritone/pathing/calc/AStarPathFinder.java @@ -18,15 +18,16 @@ package baritone.pathing.calc; import baritone.Baritone; +import baritone.api.pathing.calc.IPath; import baritone.api.pathing.goals.Goal; import baritone.api.pathing.movement.ActionCosts; -import baritone.api.pathing.calc.IPath; import baritone.api.utils.BetterBlockPos; import baritone.pathing.calc.openset.BinaryHeapOpenSet; import baritone.pathing.movement.CalculationContext; import baritone.pathing.movement.Moves; import baritone.utils.BlockStateInterface; import baritone.utils.Helper; +import baritone.utils.pathing.BetterWorldBorder; import baritone.utils.pathing.MutableMoveResult; import java.util.HashSet; @@ -63,6 +64,7 @@ public final class AStarPathFinder extends AbstractNodeCostSearch implements Hel CalculationContext calcContext = new CalculationContext(); MutableMoveResult res = new MutableMoveResult(); HashSet favored = favoredPositions.orElse(null); + BetterWorldBorder worldBorder = new BetterWorldBorder(world().getWorldBorder()); BlockStateInterface.clearCachedChunk(); long startTime = System.nanoTime() / 1000000L; boolean slowPath = Baritone.settings().slowPath.get(); @@ -106,6 +108,9 @@ public final class AStarPathFinder extends AbstractNodeCostSearch implements Hel continue; } } + if (!moves.dynamicXZ && !worldBorder.entirelyContains(newX, newZ)) { + continue; + } res.reset(); moves.apply(calcContext, currentNode.x, currentNode.y, currentNode.z, res); numMovementsConsidered++; @@ -113,6 +118,12 @@ public final class AStarPathFinder extends AbstractNodeCostSearch implements Hel if (actionCost >= ActionCosts.COST_INF) { continue; } + if (actionCost <= 0) { + throw new IllegalStateException(moves + " calculated implausible cost " + actionCost); + } + if (moves.dynamicXZ && !worldBorder.entirelyContains(res.x, res.z)) { // see issue #218 + continue; + } // check destination after verifying it's not COST_INF -- some movements return a static IMPOSSIBLE object with COST_INF and destination being 0,0,0 to avoid allocating a new result for every failed calculation if (!moves.dynamicXZ && (res.x != newX || res.z != newZ)) { throw new IllegalStateException(moves + " " + res.x + " " + newX + " " + res.z + " " + newZ); @@ -120,9 +131,6 @@ public final class AStarPathFinder extends AbstractNodeCostSearch implements Hel if (!moves.dynamicY && res.y != currentNode.y + moves.yOffset) { throw new IllegalStateException(moves + " " + res.x + " " + newX + " " + res.z + " " + newZ); } - if (actionCost <= 0) { - throw new IllegalStateException(moves + " calculated implausible cost " + actionCost); - } long hashCode = BetterBlockPos.longHash(res.x, res.y, res.z); if (favoring && favored.contains(hashCode)) { // see issue #18 diff --git a/src/main/java/baritone/utils/pathing/BetterWorldBorder.java b/src/main/java/baritone/utils/pathing/BetterWorldBorder.java new file mode 100644 index 00000000..8c105275 --- /dev/null +++ b/src/main/java/baritone/utils/pathing/BetterWorldBorder.java @@ -0,0 +1,39 @@ +/* + * 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.utils.pathing; + +import baritone.utils.Helper; +import net.minecraft.world.border.WorldBorder; + +public class BetterWorldBorder implements Helper { + double minX; + double maxX; + double minZ; + double maxZ; + + public BetterWorldBorder(WorldBorder border) { + this.minX = border.minX(); + this.maxX = border.maxX(); + this.minZ = border.minZ(); + this.maxZ = border.maxZ(); + } + + public boolean entirelyContains(int x, int z) { + return x + 1 > minX && x < maxX && z + 1 > minZ && z < maxZ; + } +} From c5f5445f4bb780a02cb984bd8c41202c2c4278ba Mon Sep 17 00:00:00 2001 From: Leijurv Date: Fri, 12 Oct 2018 14:19:11 -0700 Subject: [PATCH 3/6] fix exception when calculating descend from starting position above 256 --- src/main/java/baritone/pathing/calc/AStarPathFinder.java | 3 +++ src/main/java/baritone/pathing/movement/Moves.java | 8 ++++---- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/src/main/java/baritone/pathing/calc/AStarPathFinder.java b/src/main/java/baritone/pathing/calc/AStarPathFinder.java index a0deae58..9fbb3979 100644 --- a/src/main/java/baritone/pathing/calc/AStarPathFinder.java +++ b/src/main/java/baritone/pathing/calc/AStarPathFinder.java @@ -111,6 +111,9 @@ public final class AStarPathFinder extends AbstractNodeCostSearch implements Hel if (!moves.dynamicXZ && !worldBorder.entirelyContains(newX, newZ)) { continue; } + if ((currentNode.y == 256 && moves.yOffset > 0) || (currentNode.y == 0 && moves.yOffset < 0)) { + continue; + } res.reset(); moves.apply(calcContext, currentNode.x, currentNode.y, currentNode.z, res); numMovementsConsidered++; diff --git a/src/main/java/baritone/pathing/movement/Moves.java b/src/main/java/baritone/pathing/movement/Moves.java index 3d53ff5b..80a6c4d5 100644 --- a/src/main/java/baritone/pathing/movement/Moves.java +++ b/src/main/java/baritone/pathing/movement/Moves.java @@ -148,7 +148,7 @@ public enum Moves { } }, - DESCEND_EAST(+1, 0, 0, false, true) { + DESCEND_EAST(+1, -1, 0, false, true) { @Override public Movement apply0(BetterBlockPos src) { MutableMoveResult res = new MutableMoveResult(); @@ -166,7 +166,7 @@ public enum Moves { } }, - DESCEND_WEST(-1, 0, 0, false, true) { + DESCEND_WEST(-1, -1, 0, false, true) { @Override public Movement apply0(BetterBlockPos src) { MutableMoveResult res = new MutableMoveResult(); @@ -184,7 +184,7 @@ public enum Moves { } }, - DESCEND_NORTH(0, 0, -1, false, true) { + DESCEND_NORTH(0, -1, -1, false, true) { @Override public Movement apply0(BetterBlockPos src) { MutableMoveResult res = new MutableMoveResult(); @@ -202,7 +202,7 @@ public enum Moves { } }, - DESCEND_SOUTH(0, 0, +1, false, true) { + DESCEND_SOUTH(0, -1, +1, false, true) { @Override public Movement apply0(BetterBlockPos src) { MutableMoveResult res = new MutableMoveResult(); From 6b7a8e2bd3f7c88e081fed8d87dba976bf1739c3 Mon Sep 17 00:00:00 2001 From: Leijurv Date: Fri, 12 Oct 2018 14:34:33 -0700 Subject: [PATCH 4/6] better protection logic, fix placing outside worldborder --- .../pathing/movement/CalculationContext.java | 28 +++++++++++++++++++ .../pathing/movement/MovementHelper.java | 11 +------- .../movement/movements/MovementAscend.java | 2 +- .../movement/movements/MovementParkour.java | 4 +-- .../movement/movements/MovementPillar.java | 2 +- .../movement/movements/MovementTraverse.java | 2 +- .../utils/pathing/BetterWorldBorder.java | 7 +++++ 7 files changed, 41 insertions(+), 15 deletions(-) diff --git a/src/main/java/baritone/pathing/movement/CalculationContext.java b/src/main/java/baritone/pathing/movement/CalculationContext.java index 0b40539e..9f08d578 100644 --- a/src/main/java/baritone/pathing/movement/CalculationContext.java +++ b/src/main/java/baritone/pathing/movement/CalculationContext.java @@ -21,6 +21,7 @@ import baritone.Baritone; import baritone.api.pathing.movement.ActionCosts; import baritone.utils.Helper; import baritone.utils.ToolSet; +import baritone.utils.pathing.BetterWorldBorder; import net.minecraft.enchantment.EnchantmentHelper; import net.minecraft.entity.player.InventoryPlayer; import net.minecraft.init.Items; @@ -44,6 +45,7 @@ public class CalculationContext implements Helper { private final int maxFallHeightBucket; private final double waterWalkSpeed; private final double breakBlockAdditionalCost; + private final BetterWorldBorder worldBorder; public CalculationContext() { this(new ToolSet()); @@ -68,6 +70,32 @@ public class CalculationContext implements Helper { // why cache these things here, why not let the movements just get directly from settings? // because if some movements are calculated one way and others are calculated another way, // then you get a wildly inconsistent path that isn't optimal for either scenario. + this.worldBorder = new BetterWorldBorder(world().getWorldBorder()); + } + + public boolean canPlaceThrowawayAt(int x, int y, int z) { + if (!hasThrowaway()) { // only true if allowPlace is true, see constructor + return false; + } + if (isPossiblyProtected(x, y, z)) { + return false; + } + return worldBorder.canPlaceAt(x, z); // TODO perhaps MovementHelper.canPlaceAgainst could also use this? + } + + public boolean canBreakAt(int x, int y, int z) { + if (!allowBreak()) { + return false; + } + if (isPossiblyProtected(x, y, z)) { + return false; + } + return true; + } + + public boolean isPossiblyProtected(int x, int y, int z) { + // TODO more protection logic here; see #220 + return false; } public ToolSet getToolSet() { diff --git a/src/main/java/baritone/pathing/movement/MovementHelper.java b/src/main/java/baritone/pathing/movement/MovementHelper.java index d7cce82d..e393c92e 100644 --- a/src/main/java/baritone/pathing/movement/MovementHelper.java +++ b/src/main/java/baritone/pathing/movement/MovementHelper.java @@ -343,15 +343,6 @@ public interface MovementHelper extends ActionCosts, Helper { return state.isBlockNormalCube(); } - static double getMiningDurationTicks(CalculationContext context, BetterBlockPos position, boolean includeFalling) { - IBlockState state = BlockStateInterface.get(position); - return getMiningDurationTicks(context, position.x, position.y, position.z, state, includeFalling); - } - - static double getMiningDurationTicks(CalculationContext context, BetterBlockPos position, IBlockState state, boolean includeFalling) { - return getMiningDurationTicks(context, position.x, position.y, position.z, state, includeFalling); - } - static double getMiningDurationTicks(CalculationContext context, int x, int y, int z, boolean includeFalling) { return getMiningDurationTicks(context, x, y, z, BlockStateInterface.get(x, y, z), includeFalling); } @@ -359,7 +350,7 @@ public interface MovementHelper extends ActionCosts, Helper { static double getMiningDurationTicks(CalculationContext context, int x, int y, int z, IBlockState state, boolean includeFalling) { Block block = state.getBlock(); if (!canWalkThrough(x, y, z, state)) { - if (!context.allowBreak()) { + if (!context.canBreakAt(x, y, z)) { return COST_INF; } if (avoidBreaking(x, y, z, state)) { diff --git a/src/main/java/baritone/pathing/movement/movements/MovementAscend.java b/src/main/java/baritone/pathing/movement/movements/MovementAscend.java index 6989179b..09271779 100644 --- a/src/main/java/baritone/pathing/movement/movements/MovementAscend.java +++ b/src/main/java/baritone/pathing/movement/movements/MovementAscend.java @@ -72,7 +72,7 @@ public class MovementAscend extends Movement { } boolean hasToPlace = false; if (!MovementHelper.canWalkOn(destX, y, destZ, toPlace)) { - if (!context.hasThrowaway()) { + if (!context.canPlaceThrowawayAt(destX, y, destZ)) { return COST_INF; } if (toPlace.getBlock() != Blocks.AIR && !BlockStateInterface.isWater(toPlace.getBlock()) && !MovementHelper.isReplacable(destX, y, destZ, toPlace)) { diff --git a/src/main/java/baritone/pathing/movement/movements/MovementParkour.java b/src/main/java/baritone/pathing/movement/movements/MovementParkour.java index 94b7dfea..23348990 100644 --- a/src/main/java/baritone/pathing/movement/movements/MovementParkour.java +++ b/src/main/java/baritone/pathing/movement/movements/MovementParkour.java @@ -118,7 +118,7 @@ public class MovementParkour extends Movement { int destX = x + 4 * xDiff; int destZ = z + 4 * zDiff; IBlockState toPlace = BlockStateInterface.get(destX, y - 1, destZ); - if (!context.hasThrowaway()) { + if (!context.canPlaceThrowawayAt(destX, y - 1, destZ)) { return; } if (toPlace.getBlock() != Blocks.AIR && !BlockStateInterface.isWater(toPlace.getBlock()) && !MovementHelper.isReplacable(destX, y - 1, destZ, toPlace)) { @@ -225,7 +225,7 @@ public class MovementParkour extends Movement { } state.setInput(InputOverrideHandler.Input.JUMP, true); - } else if(!playerFeet().equals(dest.offset(direction, -1))) { + } else if (!playerFeet().equals(dest.offset(direction, -1))) { state.setInput(InputOverrideHandler.Input.SPRINT, false); if (playerFeet().equals(src.offset(direction, -1))) { MovementHelper.moveTowards(state, src); diff --git a/src/main/java/baritone/pathing/movement/movements/MovementPillar.java b/src/main/java/baritone/pathing/movement/movements/MovementPillar.java index 853b34d5..799a4e9b 100644 --- a/src/main/java/baritone/pathing/movement/movements/MovementPillar.java +++ b/src/main/java/baritone/pathing/movement/movements/MovementPillar.java @@ -76,7 +76,7 @@ public class MovementPillar extends Movement { return LADDER_UP_ONE_COST; } } - if (!context.hasThrowaway() && !ladder) { + if (!ladder && !context.canPlaceThrowawayAt(x, y, z)) { return COST_INF; } double hardness = MovementHelper.getMiningDurationTicks(context, x, y + 2, z, toBreak, true); diff --git a/src/main/java/baritone/pathing/movement/movements/MovementTraverse.java b/src/main/java/baritone/pathing/movement/movements/MovementTraverse.java index f029619a..367d2c17 100644 --- a/src/main/java/baritone/pathing/movement/movements/MovementTraverse.java +++ b/src/main/java/baritone/pathing/movement/movements/MovementTraverse.java @@ -108,7 +108,7 @@ public class MovementTraverse extends Movement { if (BlockStateInterface.isWater(destOn.getBlock()) && throughWater) { return COST_INF; } - if (!context.hasThrowaway()) { + if (!context.canPlaceThrowawayAt(destX, y - 1, destZ)) { return COST_INF; } double hardness1 = MovementHelper.getMiningDurationTicks(context, destX, y, destZ, pb0, false); diff --git a/src/main/java/baritone/utils/pathing/BetterWorldBorder.java b/src/main/java/baritone/utils/pathing/BetterWorldBorder.java index 8c105275..c9ffe5bd 100644 --- a/src/main/java/baritone/utils/pathing/BetterWorldBorder.java +++ b/src/main/java/baritone/utils/pathing/BetterWorldBorder.java @@ -36,4 +36,11 @@ public class BetterWorldBorder implements Helper { public boolean entirelyContains(int x, int z) { return x + 1 > minX && x < maxX && z + 1 > minZ && z < maxZ; } + + public boolean canPlaceAt(int x, int z) { + // move it in 1 block on all sides + // because we can't place a block at the very edge against a block outside the border + // it won't let us right click it + return x > minX && x + 1 < maxX && z > minZ && z + 1 < maxZ; + } } From 4892192c6c686b8557c0f29071218621ac3f2c40 Mon Sep 17 00:00:00 2001 From: Leijurv Date: Fri, 12 Oct 2018 15:14:39 -0700 Subject: [PATCH 5/6] remove unused functions --- .../pathing/movement/MovementHelper.java | 16 ---------------- 1 file changed, 16 deletions(-) diff --git a/src/main/java/baritone/pathing/movement/MovementHelper.java b/src/main/java/baritone/pathing/movement/MovementHelper.java index e393c92e..7517cdce 100644 --- a/src/main/java/baritone/pathing/movement/MovementHelper.java +++ b/src/main/java/baritone/pathing/movement/MovementHelper.java @@ -48,10 +48,6 @@ import java.util.Optional; */ public interface MovementHelper extends ActionCosts, Helper { - static boolean avoidBreaking(BetterBlockPos pos, IBlockState state) { - return avoidBreaking(pos.x, pos.y, pos.z, state); - } - static boolean avoidBreaking(int x, int y, int z, IBlockState state) { Block b = state.getBlock(); return b == Blocks.ICE // ice becomes water, and water can mess up the path @@ -74,10 +70,6 @@ public interface MovementHelper extends ActionCosts, Helper { return canWalkThrough(pos.x, pos.y, pos.z, BlockStateInterface.get(pos)); } - static boolean canWalkThrough(BetterBlockPos pos, IBlockState state) { - return canWalkThrough(pos.x, pos.y, pos.z, state); - } - static boolean canWalkThrough(int x, int y, int z) { return canWalkThrough(x, y, z, BlockStateInterface.get(x, y, z)); } @@ -139,10 +131,6 @@ public interface MovementHelper extends ActionCosts, Helper { * * @return */ - static boolean fullyPassable(BlockPos pos) { - return fullyPassable(BlockStateInterface.get(pos)); - } - static boolean fullyPassable(int x, int y, int z) { return fullyPassable(BlockStateInterface.get(x, y, z)); } @@ -170,10 +158,6 @@ public interface MovementHelper extends ActionCosts, Helper { return block.isPassable(null, null); } - static boolean isReplacable(BlockPos pos, IBlockState state) { - return isReplacable(pos.getX(), pos.getY(), pos.getZ(), state); - } - static boolean isReplacable(int x, int y, int z, IBlockState state) { // for MovementTraverse and MovementAscend // block double plant defaults to true when the block doesn't match, so don't need to check that case From b443be1795d0fd611e62ed3ab546dea67586ee83 Mon Sep 17 00:00:00 2001 From: Leijurv Date: Fri, 12 Oct 2018 15:29:25 -0700 Subject: [PATCH 6/6] more accurate check --- src/main/java/baritone/pathing/calc/AStarPathFinder.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/baritone/pathing/calc/AStarPathFinder.java b/src/main/java/baritone/pathing/calc/AStarPathFinder.java index 9fbb3979..020acc34 100644 --- a/src/main/java/baritone/pathing/calc/AStarPathFinder.java +++ b/src/main/java/baritone/pathing/calc/AStarPathFinder.java @@ -111,7 +111,7 @@ public final class AStarPathFinder extends AbstractNodeCostSearch implements Hel if (!moves.dynamicXZ && !worldBorder.entirelyContains(newX, newZ)) { continue; } - if ((currentNode.y == 256 && moves.yOffset > 0) || (currentNode.y == 0 && moves.yOffset < 0)) { + if (currentNode.y + moves.yOffset > 256 || currentNode.y + moves.yOffset < 0) { continue; } res.reset();