From e49549117bbd29f7349194432184821e436aa247 Mon Sep 17 00:00:00 2001 From: Leijurv Date: Fri, 11 Oct 2019 17:08:28 -0700 Subject: [PATCH 01/39] v1.2.10 --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index d0ba4720a..117f1d63d 100755 --- a/build.gradle +++ b/build.gradle @@ -16,7 +16,7 @@ */ group 'baritone' -version '1.2.9' +version '1.2.10' buildscript { repositories { From 105c7d438a45bf81cfc3acee2b74bf0219608c06 Mon Sep 17 00:00:00 2001 From: Leijurv Date: Fri, 11 Oct 2019 17:29:27 -0700 Subject: [PATCH 02/39] v1.3.5 --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index 641d910ef..25be6d665 100755 --- a/build.gradle +++ b/build.gradle @@ -16,7 +16,7 @@ */ group 'baritone' -version '1.3.4' +version '1.3.5' buildscript { repositories { From 6a8807b0fa1dfe102e13d1dc857a2226164b4412 Mon Sep 17 00:00:00 2001 From: Leijurv Date: Sat, 12 Oct 2019 10:43:01 -0700 Subject: [PATCH 03/39] documentation stuff --- README.md | 2 +- USAGE.md | 12 ++++++------ 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index 19ec0e879..90173889d 100644 --- a/README.md +++ b/README.md @@ -19,7 +19,7 @@ ![Lines of Code](https://tokei.rs/b1/github/cabaletta/baritone?category=code) [![GitHub contributors](https://img.shields.io/github/contributors/cabaletta/baritone.svg)](https://github.com/cabaletta/baritone/graphs/contributors/) [![GitHub commits](https://img.shields.io/github/commits-since/cabaletta/baritone/v1.0.0.svg)](https://github.com/cabaletta/baritone/commit/) -[![Impact integration](https://img.shields.io/badge/Impact%20integration-v1.2.8%20/%20v1.3.4%20/%20v1.4.1-brightgreen.svg)](https://impactclient.net/) +[![Impact integration](https://img.shields.io/badge/Impact%20integration-v1.2.10%20/%20v1.3.5%20/%20v1.4.2-brightgreen.svg)](https://impactclient.net/) [![ForgeHax integration](https://img.shields.io/badge/ForgeHax%20%22integration%22-scuffed-yellow.svg)](https://github.com/fr1kin/ForgeHax/) [![Aristois add-on integration](https://img.shields.io/badge/Aristois%20add--on%20integration-v1.3.4%20/%20v1.4.1-green.svg)](https://gitlab.com/emc-mods-indrit/baritone_api) [![WWE integration](https://img.shields.io/badge/WWE%20%22integration%22-master%3F-green.svg)](https://wweclient.com/) diff --git a/USAGE.md b/USAGE.md index 25fef11e8..3bca1e769 100644 --- a/USAGE.md +++ b/USAGE.md @@ -8,6 +8,12 @@ Baritone commands can also by default be typed in the chatbox. However if you ma To disable direct chat control (with no prefix), turn off the `chatControl` setting. To disable chat control with the `#` prefix, turn off the `prefixControl` setting. In Impact, `.b` cannot be disabled. Be careful that you don't leave yourself with all control methods disabled (if you do, reset your settings by deleting the file `minecraft/baritone/settings.txt` and relaunching). +# For Baritone 1.2.10+, 1.3.5+, 1.4.2+ + +Lots of the commands have changed, BUT `#help` is improved vastly (its clickable!). + +Try `#help` I promise it won't just send you back here =) + # Commands **All** of these commands may need a prefix before them, as above ^. @@ -38,12 +44,6 @@ Some common examples: - `version` to get the version of Baritone you're running - `damn` daniel - -New commands: -- `sel` to manage selections -- some others - - For the rest of the commands, you can take a look at the code [here](https://github.com/cabaletta/baritone/blob/master/src/api/java/baritone/api/utils/ExampleBaritoneControl.java). All the settings and documentation are here. If you find HTML easier to read than Javadoc, you can look here. From 69bceb43f8c7ed09f22dde7ca67a3632e4006739 Mon Sep 17 00:00:00 2001 From: Leijurv Date: Sat, 12 Oct 2019 13:07:12 -0700 Subject: [PATCH 04/39] Update USAGE.md --- USAGE.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/USAGE.md b/USAGE.md index 3bca1e769..45dfab571 100644 --- a/USAGE.md +++ b/USAGE.md @@ -10,7 +10,7 @@ To disable direct chat control (with no prefix), turn off the `chatControl` sett # For Baritone 1.2.10+, 1.3.5+, 1.4.2+ -Lots of the commands have changed, BUT `#help` is improved vastly (its clickable!). +Lots of the commands have changed, BUT `#help` is improved vastly (its clickable! commands have tab completion! oh my!). Try `#help` I promise it won't just send you back here =) From 4eca960a4ca0b94b6c2065e7c989af43fecaf70b Mon Sep 17 00:00:00 2001 From: Brady Date: Mon, 14 Oct 2019 15:45:41 -0500 Subject: [PATCH 05/39] Specify range in IWorldScanner#repack --- .../java/baritone/api/cache/ICachedWorld.java | 2 - .../baritone/api/cache/IWorldScanner.java | 16 +++++- .../java/baritone/cache/WorldScanner.java | 57 ++++++++++++------- 3 files changed, 48 insertions(+), 27 deletions(-) diff --git a/src/api/java/baritone/api/cache/ICachedWorld.java b/src/api/java/baritone/api/cache/ICachedWorld.java index 837ae076c..e681ce51c 100644 --- a/src/api/java/baritone/api/cache/ICachedWorld.java +++ b/src/api/java/baritone/api/cache/ICachedWorld.java @@ -81,6 +81,4 @@ public interface ICachedWorld { * in a new thread by default. */ void save(); - - } diff --git a/src/api/java/baritone/api/cache/IWorldScanner.java b/src/api/java/baritone/api/cache/IWorldScanner.java index 325d4bd0e..224f64c76 100644 --- a/src/api/java/baritone/api/cache/IWorldScanner.java +++ b/src/api/java/baritone/api/cache/IWorldScanner.java @@ -77,10 +77,20 @@ public interface IWorldScanner { } /** - * Repacks 40 chunks around the player. + * Overload of {@link #repack(IPlayerContext, int)} where the value of the {@code range} parameter is {@code 40}. * - * @param ctx The player context for that player. - * @return The number of chunks queued for repacking. + * @param ctx The player, describing the origin + * @return The amount of chunks successfully queued for repacking */ int repack(IPlayerContext ctx); + + /** + * Queues the chunks in a square formation around the specified player, using the specified + * range, which represents 1/2 the square's dimensions, where the player is in the center. + * + * @param ctx The player, describing the origin + * @param range The range to repack + * @return The amount of chunks successfully queued for repacking + */ + int repack(IPlayerContext ctx, int range); } diff --git a/src/main/java/baritone/cache/WorldScanner.java b/src/main/java/baritone/cache/WorldScanner.java index d31c17ab3..362506298 100644 --- a/src/main/java/baritone/cache/WorldScanner.java +++ b/src/main/java/baritone/cache/WorldScanner.java @@ -111,6 +111,41 @@ public enum WorldScanner implements IWorldScanner { return res; } + @Override + public int repack(IPlayerContext ctx) { + return this.repack(ctx, 40); + } + + @Override + public int repack(IPlayerContext ctx, int range) { + IChunkProvider chunkProvider = ctx.world().getChunkProvider(); + ICachedWorld cachedWorld = ctx.worldData().getCachedWorld(); + + BetterBlockPos playerPos = ctx.playerFeet(); + + int playerChunkX = playerPos.getX() >> 4; + int playerChunkZ = playerPos.getZ() >> 4; + + int minX = playerChunkX - range; + int minZ = playerChunkZ - range; + int maxX = playerChunkX + range; + int maxZ = playerChunkZ + range; + + int queued = 0; + for (int x = minX; x <= maxX; x++) { + for (int z = minZ; z <= maxZ; z++) { + Chunk chunk = chunkProvider.getLoadedChunk(x, z); + + if (chunk != null && !chunk.isEmpty()) { + queued++; + cachedWorld.queueForPacking(chunk); + } + } + } + + return queued; + } + private boolean scanChunkInto(int chunkX, int chunkZ, Chunk chunk, BlockOptionalMetaLookup filter, Collection result, int max, int yLevelThreshold, int playerY, int[] coordinateIterationOrder) { ExtendedBlockStorage[] chunkInternalStorageArray = chunk.getBlockStorageArray(); boolean foundWithinY = false; @@ -147,26 +182,4 @@ public enum WorldScanner implements IWorldScanner { } return foundWithinY; } - - public int repack(IPlayerContext ctx) { - IChunkProvider chunkProvider = ctx.world().getChunkProvider(); - ICachedWorld cachedWorld = ctx.worldData().getCachedWorld(); - - BetterBlockPos playerPos = ctx.playerFeet(); - int playerChunkX = playerPos.getX() >> 4; - int playerChunkZ = playerPos.getZ() >> 4; - int queued = 0; - for (int x = playerChunkX - 40; x <= playerChunkX + 40; x++) { - for (int z = playerChunkZ - 40; z <= playerChunkZ + 40; z++) { - Chunk chunk = chunkProvider.getLoadedChunk(x, z); - - if (chunk != null && !chunk.isEmpty()) { - queued++; - cachedWorld.queueForPacking(chunk); - } - } - } - - return queued; - } } From e65c854e6a0822dbc2559620e602beb6920b561d Mon Sep 17 00:00:00 2001 From: Leijurv Date: Tue, 15 Oct 2019 11:25:35 -0700 Subject: [PATCH 06/39] Update USAGE.md --- USAGE.md | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/USAGE.md b/USAGE.md index 45dfab571..118104993 100644 --- a/USAGE.md +++ b/USAGE.md @@ -14,11 +14,17 @@ Lots of the commands have changed, BUT `#help` is improved vastly (its clickable Try `#help` I promise it won't just send you back here =) +"wtf where is cleararea" -> look at `#help sel` + +"wtf where is goto death, goto waypoint" -> look at `#help wp` + +just look at `#help` lmao + # Commands **All** of these commands may need a prefix before them, as above ^. -`help` for (rudimentary) help. You can see what it says [here](https://github.com/cabaletta/baritone/blob/master/src/api/java/baritone/api/utils/ExampleBaritoneControl.java#L47). +`help` 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`. From 66ffd1e0d9acb68b5b3b13a112522cd88b6d76db Mon Sep 17 00:00:00 2001 From: 0x22 <0x22@futureclient.net> Date: Thu, 17 Oct 2019 14:35:28 -0400 Subject: [PATCH 07/39] Disable harmful mob spawning in Travis auto test. --- .../java/baritone/utils/BaritoneAutoTest.java | 24 +++++++++++-------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/src/main/java/baritone/utils/BaritoneAutoTest.java b/src/main/java/baritone/utils/BaritoneAutoTest.java index a723ebc53..7fe913ac4 100644 --- a/src/main/java/baritone/utils/BaritoneAutoTest.java +++ b/src/main/java/baritone/utils/BaritoneAutoTest.java @@ -29,9 +29,7 @@ import net.minecraft.client.gui.GuiMainMenu; import net.minecraft.client.settings.GameSettings; import net.minecraft.client.tutorial.TutorialSteps; import net.minecraft.util.math.BlockPos; -import net.minecraft.world.GameType; -import net.minecraft.world.WorldSettings; -import net.minecraft.world.WorldType; +import net.minecraft.world.*; /** * Responsible for automatically testing Baritone's pathing algorithm by automatically creating a world with a specific @@ -85,15 +83,21 @@ public class BaritoneAutoTest implements AbstractGameEventListener, Helper { if (mc.currentScreen instanceof GuiMainMenu) { System.out.println("Beginning Baritone automatic test routine"); mc.displayGuiScreen(null); - WorldSettings worldsettings = new WorldSettings(TEST_SEED, GameType.getByName("survival"), true, false, WorldType.DEFAULT); + WorldSettings worldsettings = new WorldSettings(TEST_SEED, GameType.SURVIVAL, true, false, WorldType.DEFAULT); mc.launchIntegratedServer("BaritoneAutoTest", "BaritoneAutoTest", worldsettings); } - // If the integrated server is launched and the world has initialized, set the spawn point - // to our defined starting position - if (mc.getIntegratedServer() != null && mc.getIntegratedServer().worlds[0] != null) { - mc.getIntegratedServer().worlds[0].setSpawnPoint(STARTING_POSITION); - mc.getIntegratedServer().worlds[0].getGameRules().setOrCreateGameRule("spawnRadius", "0"); + // If the integrated server is running, set the difficulty to peaceful + if (mc.getIntegratedServer() != null) { + mc.getIntegratedServer().setDifficultyForAllWorlds(EnumDifficulty.PEACEFUL); + + for (final WorldServer world : mc.getIntegratedServer().worlds) { + // If the world has initialized, set the spawn point to our defined starting position + if (world != null) { + world.setSpawnPoint(STARTING_POSITION); + world.getGameRules().setOrCreateGameRule("spawnRadius", "0"); + } + } } if (event.getType() == TickEvent.Type.IN) { // If we're in-game @@ -101,7 +105,7 @@ public class BaritoneAutoTest implements AbstractGameEventListener, Helper { // Force the integrated server to share the world to LAN so that // the ingame pause menu gui doesn't actually pause our game if (mc.isSingleplayer() && !mc.getIntegratedServer().getPublic()) { - mc.getIntegratedServer().shareToLAN(GameType.getByName("survival"), false); + mc.getIntegratedServer().shareToLAN(GameType.SURVIVAL, false); } // For the first 200 ticks, wait for the world to generate From 43ab4f7d3b114748aec18be299f78e7404c76c64 Mon Sep 17 00:00:00 2001 From: Brady Date: Tue, 22 Oct 2019 15:58:10 -0500 Subject: [PATCH 08/39] Fix isPassable crash --- .../pathing/movement/MovementHelper.java | 27 ++++++++++--------- .../movement/movements/MovementParkour.java | 16 +++++------ .../baritone/pathing/path/PathExecutor.java | 6 ++--- .../baritone/utils/BlockStateInterface.java | 5 ++++ 4 files changed, 31 insertions(+), 23 deletions(-) diff --git a/src/main/java/baritone/pathing/movement/MovementHelper.java b/src/main/java/baritone/pathing/movement/MovementHelper.java index 725a0876d..9fd1c75f1 100644 --- a/src/main/java/baritone/pathing/movement/MovementHelper.java +++ b/src/main/java/baritone/pathing/movement/MovementHelper.java @@ -35,6 +35,7 @@ import net.minecraft.util.EnumFacing; import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.RayTraceResult; import net.minecraft.util.math.Vec3d; +import net.minecraft.world.IBlockAccess; import java.util.Optional; @@ -132,27 +133,29 @@ public interface MovementHelper extends ActionCosts, Helper { } return block == Blocks.WATER || block == Blocks.FLOWING_WATER; } - // 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 - return block.isPassable(null, BlockPos.ORIGIN); + + return block.isPassable(bsi.world, bsi.isPassableBlockPos.setPos(x, y, z)); } /** * canWalkThrough but also won't impede movement at all. so not including doors or fence gates (we'd have to right click), * not including water, and not including ladders or vines or cobwebs (they slow us down) * - * @param context Calculation context to provide block state lookup - * @param x The block's x position - * @param y The block's y position - * @param z The block's z position + * @param bsi Block State Interface to provide block state lookup + * @param x The block's x position + * @param y The block's y position + * @param z The block's z position * @return Whether or not the block at the specified position */ - static boolean fullyPassable(CalculationContext context, int x, int y, int z) { - return fullyPassable(context.get(x, y, z)); + static boolean fullyPassable(BlockStateInterface bsi, int x, int y, int z) { + return fullyPassable(bsi.world, bsi.isPassableBlockPos.setPos(x, y, z), bsi.get0(x, y, z)); } - static boolean fullyPassable(IBlockState state) { + static boolean fullyPassable(IPlayerContext ctx, BlockPos pos) { + return fullyPassable(ctx.world(), pos, ctx.world().getBlockState(pos)); + } + + static boolean fullyPassable(IBlockAccess world, BlockPos pos, IBlockState state) { Block block = state.getBlock(); if (block == Blocks.AIR) { // early return for most common case return true; @@ -174,7 +177,7 @@ public interface MovementHelper extends ActionCosts, Helper { return false; } // door, fence gate, liquid, trapdoor have been accounted for, nothing else uses the world or pos parameters - return block.isPassable(null, null); + return block.isPassable(world, pos); } static boolean isReplaceable(int x, int y, int z, IBlockState state, BlockStateInterface bsi) { diff --git a/src/main/java/baritone/pathing/movement/movements/MovementParkour.java b/src/main/java/baritone/pathing/movement/movements/MovementParkour.java index eb0322102..7475182c9 100644 --- a/src/main/java/baritone/pathing/movement/movements/MovementParkour.java +++ b/src/main/java/baritone/pathing/movement/movements/MovementParkour.java @@ -69,7 +69,7 @@ public class MovementParkour extends Movement { int xDiff = dir.getXOffset(); int zDiff = dir.getZOffset(); - if (!MovementHelper.fullyPassable(context, x + xDiff, y, z + zDiff)) { + if (!MovementHelper.fullyPassable(context.bsi, x + xDiff, y, z + zDiff)) { // most common case at the top -- the adjacent block isn't air return; } @@ -81,13 +81,13 @@ public class MovementParkour extends Movement { if (MovementHelper.avoidWalkingInto(adj.getBlock()) && adj.getBlock() != Blocks.WATER && adj.getBlock() != Blocks.FLOWING_WATER) { // magma sucks return; } - if (!MovementHelper.fullyPassable(context, x + xDiff, y + 1, z + zDiff)) { + if (!MovementHelper.fullyPassable(context.bsi, x + xDiff, y + 1, z + zDiff)) { return; } - if (!MovementHelper.fullyPassable(context, x + xDiff, y + 2, z + zDiff)) { + if (!MovementHelper.fullyPassable(context.bsi, x + xDiff, y + 2, z + zDiff)) { return; } - if (!MovementHelper.fullyPassable(context, x, y + 2, z)) { + if (!MovementHelper.fullyPassable(context.bsi, x, y + 2, z)) { return; } IBlockState standingOn = context.get(x, y - 1, z); @@ -107,14 +107,14 @@ public class MovementParkour extends Movement { for (int i = 2; i <= maxJump; i++) { int destX = x + xDiff * i; int destZ = z + zDiff * i; - if (!MovementHelper.fullyPassable(context, destX, y + 1, destZ)) { + if (!MovementHelper.fullyPassable(context.bsi, destX, y + 1, destZ)) { return; } - if (!MovementHelper.fullyPassable(context, destX, y + 2, destZ)) { + if (!MovementHelper.fullyPassable(context.bsi, destX, y + 2, destZ)) { return; } IBlockState destInto = context.bsi.get0(destX, y, destZ); - if (!MovementHelper.fullyPassable(destInto)) { + if (!MovementHelper.fullyPassable(context.bsi.world, context.bsi.isPassableBlockPos.setPos(destX, y, destZ), destInto)) { if (i <= 3 && context.allowParkourAscend && context.canSprint && MovementHelper.canWalkOn(context.bsi, destX, y, destZ, destInto) && checkOvershootSafety(context.bsi, destX + xDiff, y + 1, destZ + zDiff)) { res.x = destX; res.y = y + 1; @@ -134,7 +134,7 @@ public class MovementParkour extends Movement { } return; } - if (!MovementHelper.fullyPassable(context, destX, y + 3, destZ)) { + if (!MovementHelper.fullyPassable(context.bsi, destX, y + 3, destZ)) { return; } } diff --git a/src/main/java/baritone/pathing/path/PathExecutor.java b/src/main/java/baritone/pathing/path/PathExecutor.java index 97bee4245..7e4f76a3b 100644 --- a/src/main/java/baritone/pathing/path/PathExecutor.java +++ b/src/main/java/baritone/pathing/path/PathExecutor.java @@ -466,7 +466,7 @@ public class PathExecutor implements IPathExecutor, Helper { } for (int y = next.getDest().y; y <= movement.getSrc().y + 1; y++) { BlockPos chk = new BlockPos(next.getDest().x, y, next.getDest().z); - if (!MovementHelper.fullyPassable(ctx.world().getBlockState(chk))) { + if (!MovementHelper.fullyPassable(ctx, chk)) { break outer; } } @@ -491,7 +491,7 @@ public class PathExecutor implements IPathExecutor, Helper { } // we are centered BlockPos headBonk = current.getSrc().subtract(current.getDirection()).up(2); - if (MovementHelper.fullyPassable(ctx.world().getBlockState(headBonk))) { + if (MovementHelper.fullyPassable(ctx, headBonk)) { return true; } // wait 0.3 @@ -524,7 +524,7 @@ public class PathExecutor implements IPathExecutor, Helper { if (x == 1) { chk = chk.add(current.getDirection()); } - if (!MovementHelper.fullyPassable(ctx.world().getBlockState(chk))) { + if (!MovementHelper.fullyPassable(ctx, chk)) { return false; } } diff --git a/src/main/java/baritone/utils/BlockStateInterface.java b/src/main/java/baritone/utils/BlockStateInterface.java index 84bdce5fe..bbe5a17ee 100644 --- a/src/main/java/baritone/utils/BlockStateInterface.java +++ b/src/main/java/baritone/utils/BlockStateInterface.java @@ -30,6 +30,7 @@ import net.minecraft.client.Minecraft; import net.minecraft.init.Blocks; import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.ChunkPos; +import net.minecraft.world.IBlockAccess; import net.minecraft.world.World; import net.minecraft.world.chunk.Chunk; @@ -42,6 +43,8 @@ public class BlockStateInterface { private final Long2ObjectMap loadedChunks; private final WorldData worldData; + public final IBlockAccess world; + public final BlockPos.MutableBlockPos isPassableBlockPos; private Chunk prev = null; private CachedRegion prevCached = null; @@ -59,6 +62,7 @@ public class BlockStateInterface { } public BlockStateInterface(World world, WorldData worldData, boolean copyLoadedChunks) { + this.world = world; this.worldData = worldData; Long2ObjectMap worldLoaded = ((IChunkProviderClient) world.getChunkProvider()).loadedChunks(); if (copyLoadedChunks) { @@ -70,6 +74,7 @@ public class BlockStateInterface { if (!Minecraft.getMinecraft().isCallingFromMinecraftThread()) { throw new IllegalStateException(); } + this.isPassableBlockPos = new BlockPos.MutableBlockPos(); } public boolean worldContainsLoadedChunk(int blockX, int blockZ) { From f02c33d95a7563a497b04195f661d754babc82db Mon Sep 17 00:00:00 2001 From: Brady Date: Wed, 23 Oct 2019 17:47:20 -0500 Subject: [PATCH 09/39] Fix improper tick count incrementation --- .../baritone/api/event/events/TickEvent.java | 18 ++++++++++-------- .../baritone/launch/mixins/MixinMinecraft.java | 10 +++++++--- 2 files changed, 17 insertions(+), 11 deletions(-) diff --git a/src/api/java/baritone/api/event/events/TickEvent.java b/src/api/java/baritone/api/event/events/TickEvent.java index da8f8878a..5c484ae49 100644 --- a/src/api/java/baritone/api/event/events/TickEvent.java +++ b/src/api/java/baritone/api/event/events/TickEvent.java @@ -19,22 +19,20 @@ package baritone.api.event.events; import baritone.api.event.events.type.EventState; +import java.util.function.BiFunction; + public final class TickEvent { + private static int overallTickCount; + private final EventState state; private final Type type; private final int count; - private static int overallTickCount; - - public TickEvent(EventState state, Type type) { + public TickEvent(EventState state, Type type, int count) { this.state = state; this.type = type; - this.count = incrementCount(); - } - - private static synchronized int incrementCount() { - return overallTickCount++; + this.count = count; } public int getCount() { @@ -49,6 +47,10 @@ public final class TickEvent { return state; } + public static synchronized BiFunction createNextProvider() { + final int count = overallTickCount++; + return (state, type) -> new TickEvent(state, type, count); + } public enum Type { /** diff --git a/src/launch/java/baritone/launch/mixins/MixinMinecraft.java b/src/launch/java/baritone/launch/mixins/MixinMinecraft.java index 9dc835cd1..3de4a0f54 100644 --- a/src/launch/java/baritone/launch/mixins/MixinMinecraft.java +++ b/src/launch/java/baritone/launch/mixins/MixinMinecraft.java @@ -41,6 +41,8 @@ import org.spongepowered.asm.mixin.injection.Redirect; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; import org.spongepowered.asm.mixin.injection.callback.LocalCapture; +import java.util.function.BiFunction; + /** * @author Brady * @since 7/31/2018 @@ -84,13 +86,15 @@ public class MixinMinecraft { ) ) private void runTick(CallbackInfo ci) { - for (IBaritone ibaritone : BaritoneAPI.getProvider().getAllBaritones()) { + final BiFunction tickProvider = TickEvent.createNextProvider(); - TickEvent.Type type = ibaritone.getPlayerContext().player() != null && ibaritone.getPlayerContext().world() != null + for (IBaritone baritone : BaritoneAPI.getProvider().getAllBaritones()) { + + TickEvent.Type type = baritone.getPlayerContext().player() != null && baritone.getPlayerContext().world() != null ? TickEvent.Type.IN : TickEvent.Type.OUT; - ibaritone.getGameEventHandler().onTick(new TickEvent(EventState.PRE, type)); + baritone.getGameEventHandler().onTick(tickProvider.apply(EventState.PRE, type)); } } From 5201d39adf1ef1709ed35f3d61245b6364f7cf6f Mon Sep 17 00:00:00 2001 From: Brady Date: Thu, 24 Oct 2019 15:20:23 -0500 Subject: [PATCH 10/39] Retain old method signature --- .../pathing/movement/MovementHelper.java | 16 ++++++++++------ .../movement/movements/MovementParkour.java | 14 +++++++------- 2 files changed, 17 insertions(+), 13 deletions(-) diff --git a/src/main/java/baritone/pathing/movement/MovementHelper.java b/src/main/java/baritone/pathing/movement/MovementHelper.java index 9fd1c75f1..62a96a181 100644 --- a/src/main/java/baritone/pathing/movement/MovementHelper.java +++ b/src/main/java/baritone/pathing/movement/MovementHelper.java @@ -141,14 +141,18 @@ public interface MovementHelper extends ActionCosts, Helper { * canWalkThrough but also won't impede movement at all. so not including doors or fence gates (we'd have to right click), * not including water, and not including ladders or vines or cobwebs (they slow us down) * - * @param bsi Block State Interface to provide block state lookup - * @param x The block's x position - * @param y The block's y position - * @param z The block's z position + * @param context Calculation context to provide block state lookup + * @param x The block's x position + * @param y The block's y position + * @param z The block's z position * @return Whether or not the block at the specified position */ - static boolean fullyPassable(BlockStateInterface bsi, int x, int y, int z) { - return fullyPassable(bsi.world, bsi.isPassableBlockPos.setPos(x, y, z), bsi.get0(x, y, z)); + static boolean fullyPassable(CalculationContext context, int x, int y, int z) { + return fullyPassable( + context.bsi.world, + context.bsi.isPassableBlockPos.setPos(x, y, z), + context.bsi.get0(x, y, z) + ); } static boolean fullyPassable(IPlayerContext ctx, BlockPos pos) { diff --git a/src/main/java/baritone/pathing/movement/movements/MovementParkour.java b/src/main/java/baritone/pathing/movement/movements/MovementParkour.java index 7475182c9..0477c85c0 100644 --- a/src/main/java/baritone/pathing/movement/movements/MovementParkour.java +++ b/src/main/java/baritone/pathing/movement/movements/MovementParkour.java @@ -69,7 +69,7 @@ public class MovementParkour extends Movement { int xDiff = dir.getXOffset(); int zDiff = dir.getZOffset(); - if (!MovementHelper.fullyPassable(context.bsi, x + xDiff, y, z + zDiff)) { + if (!MovementHelper.fullyPassable(context, x + xDiff, y, z + zDiff)) { // most common case at the top -- the adjacent block isn't air return; } @@ -81,13 +81,13 @@ public class MovementParkour extends Movement { if (MovementHelper.avoidWalkingInto(adj.getBlock()) && adj.getBlock() != Blocks.WATER && adj.getBlock() != Blocks.FLOWING_WATER) { // magma sucks return; } - if (!MovementHelper.fullyPassable(context.bsi, x + xDiff, y + 1, z + zDiff)) { + if (!MovementHelper.fullyPassable(context, x + xDiff, y + 1, z + zDiff)) { return; } - if (!MovementHelper.fullyPassable(context.bsi, x + xDiff, y + 2, z + zDiff)) { + if (!MovementHelper.fullyPassable(context, x + xDiff, y + 2, z + zDiff)) { return; } - if (!MovementHelper.fullyPassable(context.bsi, x, y + 2, z)) { + if (!MovementHelper.fullyPassable(context, x, y + 2, z)) { return; } IBlockState standingOn = context.get(x, y - 1, z); @@ -107,10 +107,10 @@ public class MovementParkour extends Movement { for (int i = 2; i <= maxJump; i++) { int destX = x + xDiff * i; int destZ = z + zDiff * i; - if (!MovementHelper.fullyPassable(context.bsi, destX, y + 1, destZ)) { + if (!MovementHelper.fullyPassable(context, destX, y + 1, destZ)) { return; } - if (!MovementHelper.fullyPassable(context.bsi, destX, y + 2, destZ)) { + if (!MovementHelper.fullyPassable(context, destX, y + 2, destZ)) { return; } IBlockState destInto = context.bsi.get0(destX, y, destZ); @@ -134,7 +134,7 @@ public class MovementParkour extends Movement { } return; } - if (!MovementHelper.fullyPassable(context.bsi, destX, y + 3, destZ)) { + if (!MovementHelper.fullyPassable(context, destX, y + 3, destZ)) { return; } } From 82d520d8081a0189fddd31be9329b2910defc77a Mon Sep 17 00:00:00 2001 From: Greg Depoire--Ferrer Date: Fri, 25 Oct 2019 14:42:36 +0200 Subject: [PATCH 11/39] Don't print invalid type error to stderr --- .../CommandErrorMessageException.java | 4 ++++ .../command/exception/CommandException.java | 4 ++++ .../CommandInvalidArgumentException.java | 21 +++++++++++++------ .../CommandInvalidTypeException.java | 4 ++-- .../command/argument/ArgConsumer.java | 5 ++--- 5 files changed, 27 insertions(+), 11 deletions(-) diff --git a/src/api/java/baritone/api/command/exception/CommandErrorMessageException.java b/src/api/java/baritone/api/command/exception/CommandErrorMessageException.java index 4a21bede7..b31615163 100644 --- a/src/api/java/baritone/api/command/exception/CommandErrorMessageException.java +++ b/src/api/java/baritone/api/command/exception/CommandErrorMessageException.java @@ -22,4 +22,8 @@ public abstract class CommandErrorMessageException extends CommandException { protected CommandErrorMessageException(String reason) { super(reason); } + + protected CommandErrorMessageException(String reason, Throwable cause) { + super(reason, cause); + } } diff --git a/src/api/java/baritone/api/command/exception/CommandException.java b/src/api/java/baritone/api/command/exception/CommandException.java index b8962c159..53b8e6023 100644 --- a/src/api/java/baritone/api/command/exception/CommandException.java +++ b/src/api/java/baritone/api/command/exception/CommandException.java @@ -22,4 +22,8 @@ public abstract class CommandException extends Exception implements ICommandExce protected CommandException(String reason) { super(reason); } + + protected CommandException(String reason, Throwable cause) { + super(reason, cause); + } } diff --git a/src/api/java/baritone/api/command/exception/CommandInvalidArgumentException.java b/src/api/java/baritone/api/command/exception/CommandInvalidArgumentException.java index 1902d7355..6997d6d69 100644 --- a/src/api/java/baritone/api/command/exception/CommandInvalidArgumentException.java +++ b/src/api/java/baritone/api/command/exception/CommandInvalidArgumentException.java @@ -23,12 +23,21 @@ public abstract class CommandInvalidArgumentException extends CommandErrorMessag public final ICommandArgument arg; - protected CommandInvalidArgumentException(ICommandArgument arg, String reason) { - super(String.format( - "Error at argument #%s: %s", - arg.getIndex() == -1 ? "" : Integer.toString(arg.getIndex() + 1), - reason - )); + protected CommandInvalidArgumentException(ICommandArgument arg, String message) { + super(formatMessage(arg, message)); this.arg = arg; } + + protected CommandInvalidArgumentException(ICommandArgument arg, String message, Throwable cause) { + super(formatMessage(arg, message), cause); + this.arg = arg; + } + + private static String formatMessage(ICommandArgument arg, String message) { + return String.format( + "Error at argument #%s: %s", + arg.getIndex() == -1 ? "" : Integer.toString(arg.getIndex() + 1), + message + ); + } } diff --git a/src/api/java/baritone/api/command/exception/CommandInvalidTypeException.java b/src/api/java/baritone/api/command/exception/CommandInvalidTypeException.java index 516fd308f..06658c3a0 100644 --- a/src/api/java/baritone/api/command/exception/CommandInvalidTypeException.java +++ b/src/api/java/baritone/api/command/exception/CommandInvalidTypeException.java @@ -26,7 +26,7 @@ public class CommandInvalidTypeException extends CommandInvalidArgumentException } public CommandInvalidTypeException(ICommandArgument arg, String expected, Throwable cause) { - super(arg, String.format("Expected %s.\nMore details: %s", expected, cause.getMessage())); + super(arg, String.format("Expected %s", expected), cause); } public CommandInvalidTypeException(ICommandArgument arg, String expected, String got) { @@ -34,6 +34,6 @@ public class CommandInvalidTypeException extends CommandInvalidArgumentException } public CommandInvalidTypeException(ICommandArgument arg, String expected, String got, Throwable cause) { - super(arg, String.format("Expected %s, but got %s instead.\nMore details: %s", expected, got, cause.getMessage())); + super(arg, String.format("Expected %s, but got %s instead", expected, got), cause); } } diff --git a/src/main/java/baritone/command/argument/ArgConsumer.java b/src/main/java/baritone/command/argument/ArgConsumer.java index 651ca50bc..f4e7dd524 100644 --- a/src/main/java/baritone/command/argument/ArgConsumer.java +++ b/src/main/java/baritone/command/argument/ArgConsumer.java @@ -316,8 +316,7 @@ public class ArgConsumer implements IArgConsumer { try { return datatype.apply(this.context, original); } catch (Exception e) { - e.printStackTrace(); - throw new CommandInvalidTypeException(hasAny() ? peek() : consumed(), datatype.getClass().getSimpleName()); + throw new CommandInvalidTypeException(hasAny() ? peek() : consumed(), datatype.getClass().getSimpleName(), e); } } @@ -346,7 +345,7 @@ public class ArgConsumer implements IArgConsumer { try { return datatype.get(this.context); } catch (Exception e) { - throw new CommandInvalidTypeException(hasAny() ? peek() : consumed(), datatype.getClass().getSimpleName()); + throw new CommandInvalidTypeException(hasAny() ? peek() : consumed(), datatype.getClass().getSimpleName(), e); } } From 0db4b193e14b5df0990b5c65c512a72399da534c Mon Sep 17 00:00:00 2001 From: Greg Depoire--Ferrer Date: Fri, 25 Oct 2019 14:48:53 +0200 Subject: [PATCH 12/39] Remove hack, add comment, don't use default when arg is required --- .../api/command/datatypes/RelativeGoal.java | 42 +++++++------------ .../command/defaults/GotoCommand.java | 8 +++- 2 files changed, 21 insertions(+), 29 deletions(-) diff --git a/src/api/java/baritone/api/command/datatypes/RelativeGoal.java b/src/api/java/baritone/api/command/datatypes/RelativeGoal.java index cda0ad665..19312907e 100644 --- a/src/api/java/baritone/api/command/datatypes/RelativeGoal.java +++ b/src/api/java/baritone/api/command/datatypes/RelativeGoal.java @@ -38,38 +38,26 @@ public enum RelativeGoal implements IDatatypePost { if (origin == null) { origin = BetterBlockPos.ORIGIN; } + final IArgConsumer consumer = ctx.getConsumer(); - List> coords = new ArrayList<>(); - final IArgConsumer copy = consumer.copy(); // This is a hack and should be fixed in the future probably - for (int i = 0; i < 3; i++) { - if (copy.peekDatatypeOrNull(RelativeCoordinate.INSTANCE) != null) { - coords.add(o -> consumer.getDatatypePost(RelativeCoordinate.INSTANCE, o)); - copy.get(); // Consume so we actually decrement the remaining arguments - } + GoalBlock goalBlock = consumer.peekDatatypePostOrNull(RelativeGoalBlock.INSTANCE, origin); + if (goalBlock != null) { + return goalBlock; } - switch (coords.size()) { - case 0: - return new GoalBlock(origin); - case 1: - return new GoalYLevel( - MathHelper.floor(coords.get(0).apply((double) origin.y)) - ); - case 2: - return new GoalXZ( - MathHelper.floor(coords.get(0).apply((double) origin.x)), - MathHelper.floor(coords.get(1).apply((double) origin.z)) - ); - case 3: - return new GoalBlock( - MathHelper.floor(coords.get(0).apply((double) origin.x)), - MathHelper.floor(coords.get(1).apply((double) origin.y)), - MathHelper.floor(coords.get(2).apply((double) origin.z)) - ); - default: - throw new IllegalStateException("Unexpected coords size: " + coords.size()); + GoalXZ goalXZ = consumer.peekDatatypePostOrNull(RelativeGoalXZ.INSTANCE, origin); + if (goalXZ != null) { + return goalXZ; } + + GoalYLevel goalYLevel = consumer.peekDatatypePostOrNull(RelativeGoalYLevel.INSTANCE, origin); + if (goalYLevel != null) { + return goalYLevel; + } + + // when the user doesn't input anything, default to the origin + return new GoalBlock(origin); } @Override diff --git a/src/main/java/baritone/command/defaults/GotoCommand.java b/src/main/java/baritone/command/defaults/GotoCommand.java index 427e67b2a..28e768296 100644 --- a/src/main/java/baritone/command/defaults/GotoCommand.java +++ b/src/main/java/baritone/command/defaults/GotoCommand.java @@ -41,9 +41,13 @@ public class GotoCommand extends Command { @Override public void execute(String label, IArgConsumer args) throws CommandException { - if (args.peekDatatypeOrNull(RelativeCoordinate.INSTANCE) != null) { // if we have a numeric first argument... + // If we have a numeric first argument, then parse arguments as coordinates. + // Note: There is no reason to want to go where you're already at so there + // is no need to handle the case of empty arguments. + if (args.peekDatatypeOrNull(RelativeCoordinate.INSTANCE) != null) { + args.requireMax(3); BetterBlockPos origin = baritone.getPlayerContext().playerFeet(); - Goal goal = args.getDatatypePostOrNull(RelativeGoal.INSTANCE, origin); + Goal goal = args.getDatatypePost(RelativeGoal.INSTANCE, origin); logDirect(String.format("Going to: %s", goal.toString())); baritone.getCustomGoalProcess().setGoalAndPath(goal); return; From 23fc6c8b494cc523a6278696da6d34c2156c49be Mon Sep 17 00:00:00 2001 From: Greg Depoire--Ferrer Date: Fri, 25 Oct 2019 14:49:49 +0200 Subject: [PATCH 13/39] Add a space between sentences in error message --- .../api/command/exception/CommandUnhandledException.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/api/java/baritone/api/command/exception/CommandUnhandledException.java b/src/api/java/baritone/api/command/exception/CommandUnhandledException.java index fe0b09fad..02987d4ee 100644 --- a/src/api/java/baritone/api/command/exception/CommandUnhandledException.java +++ b/src/api/java/baritone/api/command/exception/CommandUnhandledException.java @@ -37,7 +37,7 @@ public class CommandUnhandledException extends RuntimeException implements IComm @Override public void handle(ICommand command, List args) { - HELPER.logDirect("An unhandled exception occurred." + + HELPER.logDirect("An unhandled exception occurred. " + "The error is in your game's log, please report this at https://github.com/cabaletta/baritone/issues", TextFormatting.RED); From 2ae16d8bb1cd6bed87fe2a4858ac2e5458911079 Mon Sep 17 00:00:00 2001 From: Leijurv Date: Sat, 26 Oct 2019 16:01:08 -0700 Subject: [PATCH 14/39] configurable block reach distance --- src/api/java/baritone/api/Settings.java | 5 +++++ src/api/java/baritone/api/utils/IPlayerController.java | 3 ++- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/src/api/java/baritone/api/Settings.java b/src/api/java/baritone/api/Settings.java index 776d8e61e..3ca6dd9a6 100644 --- a/src/api/java/baritone/api/Settings.java +++ b/src/api/java/baritone/api/Settings.java @@ -248,6 +248,11 @@ public final class Settings { */ public final Setting rightClickSpeed = new Setting<>(4); + /** + * Block reach distance + */ + public final Setting blockReachDistance = new Setting<>(4.5f); + /** * How many degrees to randomize the pitch and yaw every tick. Set to 0 to disable */ diff --git a/src/api/java/baritone/api/utils/IPlayerController.java b/src/api/java/baritone/api/utils/IPlayerController.java index 05199fcac..d6fa1837a 100644 --- a/src/api/java/baritone/api/utils/IPlayerController.java +++ b/src/api/java/baritone/api/utils/IPlayerController.java @@ -17,6 +17,7 @@ package baritone.api.utils; +import baritone.api.BaritoneAPI; import net.minecraft.client.entity.EntityPlayerSP; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.inventory.ClickType; @@ -56,6 +57,6 @@ public interface IPlayerController { void setHittingBlock(boolean hittingBlock); default double getBlockReachDistance() { - return this.getGameType().isCreative() ? 5.0F : 4.5F; + return this.getGameType().isCreative() ? 5.0F : BaritoneAPI.getSettings().blockReachDistance.value; } } From 45ea776090cf5d17aa660bcfe1a81116f3a64453 Mon Sep 17 00:00:00 2001 From: Leijurv Date: Mon, 28 Oct 2019 10:47:20 -0700 Subject: [PATCH 15/39] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 90173889d..043aed085 100644 --- a/README.md +++ b/README.md @@ -19,7 +19,7 @@ ![Lines of Code](https://tokei.rs/b1/github/cabaletta/baritone?category=code) [![GitHub contributors](https://img.shields.io/github/contributors/cabaletta/baritone.svg)](https://github.com/cabaletta/baritone/graphs/contributors/) [![GitHub commits](https://img.shields.io/github/commits-since/cabaletta/baritone/v1.0.0.svg)](https://github.com/cabaletta/baritone/commit/) -[![Impact integration](https://img.shields.io/badge/Impact%20integration-v1.2.10%20/%20v1.3.5%20/%20v1.4.2-brightgreen.svg)](https://impactclient.net/) +[![Impact integration](https://img.shields.io/badge/Impact%20integration-v1.2.10%20/%20v1.3.5%20/%20v1.4.3-brightgreen.svg)](https://impactclient.net/) [![ForgeHax integration](https://img.shields.io/badge/ForgeHax%20%22integration%22-scuffed-yellow.svg)](https://github.com/fr1kin/ForgeHax/) [![Aristois add-on integration](https://img.shields.io/badge/Aristois%20add--on%20integration-v1.3.4%20/%20v1.4.1-green.svg)](https://gitlab.com/emc-mods-indrit/baritone_api) [![WWE integration](https://img.shields.io/badge/WWE%20%22integration%22-master%3F-green.svg)](https://wweclient.com/) From 152285043d89a49931a1ea9db7563d7e96c56908 Mon Sep 17 00:00:00 2001 From: Leijurv Date: Tue, 5 Nov 2019 11:50:27 -0800 Subject: [PATCH 16/39] Update USAGE.md --- USAGE.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/USAGE.md b/USAGE.md index 118104993..0f911efaa 100644 --- a/USAGE.md +++ b/USAGE.md @@ -16,7 +16,7 @@ Try `#help` I promise it won't just send you back here =) "wtf where is cleararea" -> look at `#help sel` -"wtf where is goto death, goto waypoint" -> look at `#help wp` +"wtf where is goto death, goto waypoint" -> look at `#help wp` (a "tag" is like "home" (created automatically on right clicking a bed) or "death" (created automatically on death) or "user" (has to be created manually)). So you might want `#wp save user coolbiome` then, to set the goal `#wp goal coolbiome` then `#path` to path to it. For death, `#wp goal death` (remember stuff is clickable!). just look at `#help` lmao From 7e3a2d3c0a676ef955c1b345b1a789d51e8c6834 Mon Sep 17 00:00:00 2001 From: Brady Date: Tue, 5 Nov 2019 18:17:10 -0600 Subject: [PATCH 17/39] Create a BlockStateInterface specialized IBlockAccess wrapper --- .../pathing/movement/MovementHelper.java | 8 +- .../movement/movements/MovementParkour.java | 2 +- .../baritone/utils/BlockStateInterface.java | 4 +- .../BlockStateInterfaceAccessWrapper.java | 80 +++++++++++++++++++ 4 files changed, 88 insertions(+), 6 deletions(-) create mode 100644 src/main/java/baritone/utils/BlockStateInterfaceAccessWrapper.java diff --git a/src/main/java/baritone/pathing/movement/MovementHelper.java b/src/main/java/baritone/pathing/movement/MovementHelper.java index 62a96a181..31a1de7a6 100644 --- a/src/main/java/baritone/pathing/movement/MovementHelper.java +++ b/src/main/java/baritone/pathing/movement/MovementHelper.java @@ -134,7 +134,7 @@ public interface MovementHelper extends ActionCosts, Helper { return block == Blocks.WATER || block == Blocks.FLOWING_WATER; } - return block.isPassable(bsi.world, bsi.isPassableBlockPos.setPos(x, y, z)); + return block.isPassable(bsi.access, bsi.isPassableBlockPos.setPos(x, y, z)); } /** @@ -149,7 +149,7 @@ public interface MovementHelper extends ActionCosts, Helper { */ static boolean fullyPassable(CalculationContext context, int x, int y, int z) { return fullyPassable( - context.bsi.world, + context.bsi.access, context.bsi.isPassableBlockPos.setPos(x, y, z), context.bsi.get0(x, y, z) ); @@ -159,7 +159,7 @@ public interface MovementHelper extends ActionCosts, Helper { return fullyPassable(ctx.world(), pos, ctx.world().getBlockState(pos)); } - static boolean fullyPassable(IBlockAccess world, BlockPos pos, IBlockState state) { + static boolean fullyPassable(IBlockAccess access, BlockPos pos, IBlockState state) { Block block = state.getBlock(); if (block == Blocks.AIR) { // early return for most common case return true; @@ -181,7 +181,7 @@ public interface MovementHelper extends ActionCosts, Helper { return false; } // door, fence gate, liquid, trapdoor have been accounted for, nothing else uses the world or pos parameters - return block.isPassable(world, pos); + return block.isPassable(access, pos); } static boolean isReplaceable(int x, int y, int z, IBlockState state, BlockStateInterface bsi) { diff --git a/src/main/java/baritone/pathing/movement/movements/MovementParkour.java b/src/main/java/baritone/pathing/movement/movements/MovementParkour.java index 0477c85c0..3d3426da2 100644 --- a/src/main/java/baritone/pathing/movement/movements/MovementParkour.java +++ b/src/main/java/baritone/pathing/movement/movements/MovementParkour.java @@ -114,7 +114,7 @@ public class MovementParkour extends Movement { return; } IBlockState destInto = context.bsi.get0(destX, y, destZ); - if (!MovementHelper.fullyPassable(context.bsi.world, context.bsi.isPassableBlockPos.setPos(destX, y, destZ), destInto)) { + if (!MovementHelper.fullyPassable(context.bsi.access, context.bsi.isPassableBlockPos.setPos(destX, y, destZ), destInto)) { if (i <= 3 && context.allowParkourAscend && context.canSprint && MovementHelper.canWalkOn(context.bsi, destX, y, destZ, destInto) && checkOvershootSafety(context.bsi, destX + xDiff, y + 1, destZ + zDiff)) { res.x = destX; res.y = y + 1; diff --git a/src/main/java/baritone/utils/BlockStateInterface.java b/src/main/java/baritone/utils/BlockStateInterface.java index bbe5a17ee..4f5f26899 100644 --- a/src/main/java/baritone/utils/BlockStateInterface.java +++ b/src/main/java/baritone/utils/BlockStateInterface.java @@ -43,8 +43,9 @@ public class BlockStateInterface { private final Long2ObjectMap loadedChunks; private final WorldData worldData; - public final IBlockAccess world; + protected final IBlockAccess world; public final BlockPos.MutableBlockPos isPassableBlockPos; + public final IBlockAccess access; private Chunk prev = null; private CachedRegion prevCached = null; @@ -75,6 +76,7 @@ public class BlockStateInterface { throw new IllegalStateException(); } this.isPassableBlockPos = new BlockPos.MutableBlockPos(); + this.access = new BlockStateInterfaceAccessWrapper(this); } public boolean worldContainsLoadedChunk(int blockX, int blockZ) { diff --git a/src/main/java/baritone/utils/BlockStateInterfaceAccessWrapper.java b/src/main/java/baritone/utils/BlockStateInterfaceAccessWrapper.java new file mode 100644 index 000000000..6ce70193f --- /dev/null +++ b/src/main/java/baritone/utils/BlockStateInterfaceAccessWrapper.java @@ -0,0 +1,80 @@ +/* + * 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; + +import net.minecraft.block.material.Material; +import net.minecraft.block.state.IBlockState; +import net.minecraft.tileentity.TileEntity; +import net.minecraft.util.EnumFacing; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.IBlockAccess; +import net.minecraft.world.WorldType; +import net.minecraft.world.biome.Biome; + +import javax.annotation.Nullable; + +/** + * @author Brady + * @since 11/5/2019 + */ +@SuppressWarnings("NullableProblems") +public final class BlockStateInterfaceAccessWrapper implements IBlockAccess { + + private final BlockStateInterface bsi; + + BlockStateInterfaceAccessWrapper(BlockStateInterface bsi) { + this.bsi = bsi; + } + + @Nullable + @Override + public TileEntity getTileEntity(BlockPos pos) { + throw new UnsupportedOperationException("getTileEntity not supported by BlockStateInterfaceAccessWrapper"); + } + + @Override + public int getCombinedLight(BlockPos pos, int lightValue) { + throw new UnsupportedOperationException("getCombinedLight not supported by BlockStateInterfaceAccessWrapper"); + } + + @Override + public IBlockState getBlockState(BlockPos pos) { + // BlockStateInterface#get0(BlockPos) btfo! + return this.bsi.get0(pos.getX(), pos.getY(), pos.getZ()); + } + + @Override + public boolean isAirBlock(BlockPos pos) { + return this.bsi.get0(pos.getX(), pos.getY(), pos.getZ()).getMaterial() == Material.AIR; + } + + @Override + public Biome getBiome(BlockPos pos) { + throw new UnsupportedOperationException("getBiome not supported by BlockStateInterfaceAccessWrapper"); + } + + @Override + public int getStrongPower(BlockPos pos, EnumFacing direction) { + throw new UnsupportedOperationException("getStrongPower not supported by BlockStateInterfaceAccessWrapper"); + } + + @Override + public WorldType getWorldType() { + return this.bsi.world.getWorldType(); + } +} From ed144e995bc51430f0d665924a7d3193a78b2466 Mon Sep 17 00:00:00 2001 From: Leijurv Date: Sun, 10 Nov 2019 14:04:27 -0800 Subject: [PATCH 18/39] apparently this usage of > was an invalid javadoc command lol --- src/api/java/baritone/api/Settings.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/api/java/baritone/api/Settings.java b/src/api/java/baritone/api/Settings.java index 3ca6dd9a6..22b5d187d 100644 --- a/src/api/java/baritone/api/Settings.java +++ b/src/api/java/baritone/api/Settings.java @@ -234,7 +234,7 @@ public final class Settings { /** * If we overshoot a traverse and end up one block beyond the destination, mark it as successful anyway. *

- * This helps with speed at >=20m/s + * This helps with speed exceeding 20m/s */ public final Setting overshootTraverse = new Setting<>(true); From ddc681fe772a4a8a3550d4f34a963bc1cc163b61 Mon Sep 17 00:00:00 2001 From: Leijurv Date: Sun, 24 Nov 2019 11:11:21 -0800 Subject: [PATCH 19/39] build repeat count --- src/api/java/baritone/api/Settings.java | 5 +++++ src/main/java/baritone/process/BuilderProcess.java | 12 ++++++++++-- 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/src/api/java/baritone/api/Settings.java b/src/api/java/baritone/api/Settings.java index 22b5d187d..14a131831 100644 --- a/src/api/java/baritone/api/Settings.java +++ b/src/api/java/baritone/api/Settings.java @@ -743,6 +743,11 @@ public final class Settings { */ public final Setting buildRepeat = new Setting<>(new Vec3i(0, 0, 0)); + /** + * How many times to buildrepeat. -1 for infinite. + */ + public final Setting buildRepeatCount = new Setting<>(-1); + /** * Allow standing above a block while mining it, in BuilderProcess *

diff --git a/src/main/java/baritone/process/BuilderProcess.java b/src/main/java/baritone/process/BuilderProcess.java index 4300ce53f..17cbe110e 100644 --- a/src/main/java/baritone/process/BuilderProcess.java +++ b/src/main/java/baritone/process/BuilderProcess.java @@ -26,7 +26,10 @@ import baritone.api.process.IBuilderProcess; import baritone.api.process.PathingCommand; import baritone.api.process.PathingCommandType; import baritone.api.schematic.ISchematic; -import baritone.api.utils.*; +import baritone.api.utils.BetterBlockPos; +import baritone.api.utils.RayTraceUtils; +import baritone.api.utils.Rotation; +import baritone.api.utils.RotationUtils; import baritone.api.utils.input.Input; import baritone.pathing.movement.CalculationContext; import baritone.pathing.movement.Movement; @@ -69,6 +72,7 @@ public final class BuilderProcess extends BaritoneProcessHelper implements IBuil private int ticks; private boolean paused; private int layer; + private int numRepeats; private List approxPlaceable; public BuilderProcess(Baritone baritone) { @@ -95,6 +99,7 @@ public final class BuilderProcess extends BaritoneProcessHelper implements IBuil this.origin = new Vec3i(x, y, z); this.paused = false; this.layer = 0; + this.numRepeats = 0; this.observedCompleted = new LongOpenHashSet(); } @@ -391,7 +396,9 @@ public final class BuilderProcess extends BaritoneProcessHelper implements IBuil return onTick(calcFailed, isSafeToCancel); } Vec3i repeat = Baritone.settings().buildRepeat.value; - if (repeat.equals(new Vec3i(0, 0, 0))) { + int max = Baritone.settings().buildRepeatCount.value; + numRepeats++; + if (repeat.equals(new Vec3i(0, 0, 0)) || (max != -1 && numRepeats >= max)) { logDirect("Done building"); onLostControl(); return null; @@ -731,6 +738,7 @@ public final class BuilderProcess extends BaritoneProcessHelper implements IBuil schematic = null; realSchematic = null; layer = 0; + numRepeats = 0; paused = false; observedCompleted = null; } From 2c3e1f42321fd65c2d3d1e7fd41e936adde94aae Mon Sep 17 00:00:00 2001 From: Leijurv Date: Fri, 13 Dec 2019 20:09:04 -0800 Subject: [PATCH 20/39] builder stuff, fixes #1059 --- src/api/java/baritone/api/Settings.java | 14 ++++++++++++++ src/main/java/baritone/process/BuilderProcess.java | 11 ++++++++++- 2 files changed, 24 insertions(+), 1 deletion(-) diff --git a/src/api/java/baritone/api/Settings.java b/src/api/java/baritone/api/Settings.java index 14a131831..dac1ae55c 100644 --- a/src/api/java/baritone/api/Settings.java +++ b/src/api/java/baritone/api/Settings.java @@ -184,6 +184,20 @@ public final class Settings { Blocks.WALL_SIGN ))); + /** + * A list of blocks to be treated as if they're air. + *

+ * If a schematic asks for air at a certain position, and that position currently contains a block on this list, it will be treated as correct. + */ + public final Setting> buildIgnoreBlocks = new Setting<>(new ArrayList<>(Arrays.asList( + + ))); + + /** + * If this is true, the builder will treat all non-air blocks as correct. It will only place new blocks. + */ + public final Setting buildIgnoreExisting = new Setting<>(true); + /** * If this setting is true, Baritone will never break a block that is adjacent to an unsupported falling block. *

diff --git a/src/main/java/baritone/process/BuilderProcess.java b/src/main/java/baritone/process/BuilderProcess.java index 17cbe110e..4d66a7645 100644 --- a/src/main/java/baritone/process/BuilderProcess.java +++ b/src/main/java/baritone/process/BuilderProcess.java @@ -764,11 +764,20 @@ public final class BuilderProcess extends BaritoneProcessHelper implements IBuil } private boolean valid(IBlockState current, IBlockState desired) { + if (desired == null) { + return true; + } // TODO more complicated comparison logic I guess if (current.getBlock() instanceof BlockLiquid && Baritone.settings().okIfWater.value) { return true; } - return desired == null || current.equals(desired); + if (desired.getBlock() instanceof BlockAir && Baritone.settings().buildIgnoreBlocks.value.contains(current.getBlock())) { + return true; + } + if (!(current.getBlock() instanceof BlockAir) && Baritone.settings().buildIgnoreExisting.value) { + return true; + } + return current.equals(desired); } public class BuilderCalculationContext extends CalculationContext { From 937d4cc8847a2cbd59ecc0e1f1d7f5f354c09107 Mon Sep 17 00:00:00 2001 From: Leijurv Date: Fri, 13 Dec 2019 20:46:12 -0800 Subject: [PATCH 21/39] whoops --- src/api/java/baritone/api/Settings.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/api/java/baritone/api/Settings.java b/src/api/java/baritone/api/Settings.java index dac1ae55c..bf077f1a0 100644 --- a/src/api/java/baritone/api/Settings.java +++ b/src/api/java/baritone/api/Settings.java @@ -196,7 +196,7 @@ public final class Settings { /** * If this is true, the builder will treat all non-air blocks as correct. It will only place new blocks. */ - public final Setting buildIgnoreExisting = new Setting<>(true); + public final Setting buildIgnoreExisting = new Setting<>(false); /** * If this setting is true, Baritone will never break a block that is adjacent to an unsupported falling block. From 5c9f02810347ec8e5bc0c98d0938eefbbd1f4330 Mon Sep 17 00:00:00 2001 From: Brady Date: Wed, 18 Dec 2019 10:24:43 -0600 Subject: [PATCH 22/39] Initial sponge support --- .../api/schematic/AbstractSchematic.java | 4 + .../baritone/api/utils/BlockOptionalMeta.java | 8 +- .../java/baritone/process/BuilderProcess.java | 31 ++- .../utils/schematic/MapArtSchematic.java | 42 +++- .../baritone/utils/schematic/Schematic.java | 92 -------- .../schematic/format/SchematicFormat.java | 70 ++++++ .../schematic/parse/ISchematicParser.java | 32 +++ .../utils/schematic/parse/MCEditParser.java | 94 ++++++++ .../utils/schematic/parse/SpongeParser.java | 202 ++++++++++++++++++ 9 files changed, 456 insertions(+), 119 deletions(-) delete mode 100644 src/main/java/baritone/utils/schematic/Schematic.java create mode 100644 src/main/java/baritone/utils/schematic/format/SchematicFormat.java create mode 100644 src/main/java/baritone/utils/schematic/parse/ISchematicParser.java create mode 100644 src/main/java/baritone/utils/schematic/parse/MCEditParser.java create mode 100644 src/main/java/baritone/utils/schematic/parse/SpongeParser.java diff --git a/src/api/java/baritone/api/schematic/AbstractSchematic.java b/src/api/java/baritone/api/schematic/AbstractSchematic.java index 3cd14747d..cca6bc966 100644 --- a/src/api/java/baritone/api/schematic/AbstractSchematic.java +++ b/src/api/java/baritone/api/schematic/AbstractSchematic.java @@ -23,6 +23,10 @@ public abstract class AbstractSchematic implements ISchematic { protected int y; protected int z; + public AbstractSchematic() { + this(0, 0, 0); + } + public AbstractSchematic(int x, int y, int z) { this.x = x; this.y = y; diff --git a/src/api/java/baritone/api/utils/BlockOptionalMeta.java b/src/api/java/baritone/api/utils/BlockOptionalMeta.java index 3ab76dd20..451d95eb2 100644 --- a/src/api/java/baritone/api/utils/BlockOptionalMeta.java +++ b/src/api/java/baritone/api/utils/BlockOptionalMeta.java @@ -178,12 +178,12 @@ public final class BlockOptionalMeta { normalizations = Collections.unmodifiableMap(_normalizations); } - private static , P extends IProperty> P castToIProperty(Object value) { + public static , P extends IProperty> P castToIProperty(Object value) { //noinspection unchecked return (P) value; } - private static , P extends IProperty> C castToIPropertyValue(P iproperty, Object value) { + public static , P extends IProperty> C castToIPropertyValue(P iproperty, Object value) { //noinspection unchecked return (C) value; } @@ -191,6 +191,10 @@ public final class BlockOptionalMeta { public static IBlockState normalize(IBlockState state) { IBlockState newState = state; + // TODO: Can the state not be normalized by simply doing...? + // return state.getBlock().getDefaultState(); + // ??? + for (IProperty property : state.getProperties().keySet()) { Class valueClass = property.getValueClass(); if (normalizations.containsKey(property)) { diff --git a/src/main/java/baritone/process/BuilderProcess.java b/src/main/java/baritone/process/BuilderProcess.java index 4d66a7645..1dfd6c82f 100644 --- a/src/main/java/baritone/process/BuilderProcess.java +++ b/src/main/java/baritone/process/BuilderProcess.java @@ -39,7 +39,7 @@ import baritone.utils.BlockStateInterface; import baritone.utils.PathingCommandContext; import baritone.utils.schematic.FillSchematic; import baritone.utils.schematic.MapArtSchematic; -import baritone.utils.schematic.Schematic; +import baritone.utils.schematic.format.SchematicFormat; import baritone.utils.schematic.schematica.SchematicaHelper; import it.unimi.dsi.fastutil.longs.LongOpenHashSet; import net.minecraft.block.BlockAir; @@ -48,15 +48,12 @@ import net.minecraft.block.state.IBlockState; import net.minecraft.init.Blocks; import net.minecraft.item.ItemBlock; import net.minecraft.item.ItemStack; -import net.minecraft.nbt.CompressedStreamTools; -import net.minecraft.nbt.NBTTagCompound; import net.minecraft.util.EnumFacing; import net.minecraft.util.Tuple; import net.minecraft.util.math.*; import java.io.File; import java.io.FileInputStream; -import java.io.IOException; import java.util.*; import static baritone.api.pathing.movement.ActionCosts.COST_INF; @@ -118,18 +115,24 @@ public final class BuilderProcess extends BaritoneProcessHelper implements IBuil @Override public boolean build(String name, File schematic, Vec3i origin) { - NBTTagCompound tag; - try (FileInputStream fileIn = new FileInputStream(schematic)) { - tag = CompressedStreamTools.readCompressed(fileIn); - } catch (IOException e) { + Optional format = SchematicFormat.getByFile(schematic); + if (!format.isPresent()) { + return false; + } + + ISchematic parsed; + try { + parsed = format.get().getParser().parse(new FileInputStream(schematic)); + } catch (Exception e) { e.printStackTrace(); return false; } - //noinspection ConstantConditions - if (tag == null) { - return false; + + if (Baritone.settings().mapArtMode.value) { + parsed = new MapArtSchematic(parsed); } - build(name, parse(tag), origin); + + build(name, parsed, origin); return true; } @@ -160,10 +163,6 @@ public final class BuilderProcess extends BaritoneProcessHelper implements IBuil return new ArrayList<>(approxPlaceable); } - private static ISchematic parse(NBTTagCompound schematic) { - return Baritone.settings().mapArtMode.value ? new MapArtSchematic(schematic) : new Schematic(schematic); - } - @Override public boolean isActive() { return schematic != null; diff --git a/src/main/java/baritone/utils/schematic/MapArtSchematic.java b/src/main/java/baritone/utils/schematic/MapArtSchematic.java index 32b3292ca..33ec3a152 100644 --- a/src/main/java/baritone/utils/schematic/MapArtSchematic.java +++ b/src/main/java/baritone/utils/schematic/MapArtSchematic.java @@ -17,24 +17,29 @@ package baritone.utils.schematic; +import baritone.api.schematic.AbstractSchematic; +import baritone.api.schematic.ISchematic; import net.minecraft.block.BlockAir; import net.minecraft.block.state.IBlockState; -import net.minecraft.nbt.NBTTagCompound; +import java.util.List; import java.util.OptionalInt; import java.util.function.Predicate; -public class MapArtSchematic extends Schematic { +public class MapArtSchematic extends AbstractSchematic { + private final ISchematic child; private final int[][] heightMap; - public MapArtSchematic(NBTTagCompound schematic) { - super(schematic); - heightMap = new int[widthX][lengthZ]; + public MapArtSchematic(ISchematic schematic) { + super(schematic.widthX(), schematic.heightY(), schematic.lengthZ()); + this.child = schematic; - for (int x = 0; x < widthX; x++) { - for (int z = 0; z < lengthZ; z++) { - IBlockState[] column = states[x][z]; + heightMap = new int[schematic.widthX()][schematic.lengthZ()]; + + for (int x = 0; x < schematic.widthX(); x++) { + for (int z = 0; z < schematic.lengthZ(); z++) { + IBlockState[] column = /*states[x][z]*/null; OptionalInt lowestBlockY = lastIndexMatching(column, state -> !(state.getBlock() instanceof BlockAir)); if (lowestBlockY.isPresent()) { @@ -44,7 +49,6 @@ public class MapArtSchematic extends Schematic { System.out.println("Letting it be whatever"); heightMap[x][z] = 256; } - } } } @@ -63,4 +67,24 @@ public class MapArtSchematic extends Schematic { // in map art, we only care about coordinates in or above the art return super.inSchematic(x, y, z, currentState) && y >= heightMap[x][z]; } + + @Override + public IBlockState desiredState(int x, int y, int z, IBlockState current, List approxPlaceable) { + return this.child.desiredState(x, y, z, current, approxPlaceable); + } + + @Override + public int widthX() { + return this.child.widthX(); + } + + @Override + public int heightY() { + return this.child.heightY(); + } + + @Override + public int lengthZ() { + return this.child.lengthZ(); + } } diff --git a/src/main/java/baritone/utils/schematic/Schematic.java b/src/main/java/baritone/utils/schematic/Schematic.java deleted file mode 100644 index 1169578a6..000000000 --- a/src/main/java/baritone/utils/schematic/Schematic.java +++ /dev/null @@ -1,92 +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.utils.schematic; - -import baritone.api.schematic.ISchematic; -import net.minecraft.block.Block; -import net.minecraft.block.state.IBlockState; -import net.minecraft.nbt.NBTTagCompound; - -import java.util.List; - -public class Schematic implements ISchematic { - - public final int widthX; - public final int heightY; - public final int lengthZ; - protected final IBlockState[][][] states; - - public Schematic(NBTTagCompound schematic) { - String type = schematic.getString("Materials"); - if (!type.equals("Alpha")) { - throw new IllegalStateException("bad schematic " + type); - } - widthX = schematic.getInteger("Width"); - heightY = schematic.getInteger("Height"); - lengthZ = schematic.getInteger("Length"); - byte[] blocks = schematic.getByteArray("Blocks"); - byte[] metadata = schematic.getByteArray("Data"); - - byte[] additional = null; - if (schematic.hasKey("AddBlocks")) { - byte[] addBlocks = schematic.getByteArray("AddBlocks"); - additional = new byte[addBlocks.length * 2]; - for (int i = 0; i < addBlocks.length; i++) { - additional[i * 2 + 0] = (byte) ((addBlocks[i] >> 4) & 0xF); // lower nibble - additional[i * 2 + 1] = (byte) ((addBlocks[i] >> 0) & 0xF); // upper nibble - } - } - states = new IBlockState[widthX][lengthZ][heightY]; - for (int y = 0; y < heightY; y++) { - for (int z = 0; z < lengthZ; z++) { - for (int x = 0; x < widthX; x++) { - int blockInd = (y * lengthZ + z) * widthX + x; - - int blockID = blocks[blockInd] & 0xFF; - if (additional != null) { - // additional is 0 through 15 inclusive since it's & 0xF above - blockID |= additional[blockInd] << 8; - } - Block block = Block.REGISTRY.getObjectById(blockID); - int meta = metadata[blockInd] & 0xFF; - states[x][z][y] = block.getStateFromMeta(meta); - } - } - } - } - - @Override - public IBlockState desiredState(int x, int y, int z, IBlockState current, List approxPlaceable) { - return states[x][z][y]; - } - - @Override - public int widthX() { - return widthX; - } - - @Override - public int heightY() { - return heightY; - } - - @Override - public int lengthZ() { - return lengthZ; - } -} diff --git a/src/main/java/baritone/utils/schematic/format/SchematicFormat.java b/src/main/java/baritone/utils/schematic/format/SchematicFormat.java new file mode 100644 index 000000000..5f103d9a1 --- /dev/null +++ b/src/main/java/baritone/utils/schematic/format/SchematicFormat.java @@ -0,0 +1,70 @@ +/* + * 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.schematic.format; + +import baritone.utils.schematic.parse.ISchematicParser; +import baritone.utils.schematic.parse.MCEditParser; +import baritone.utils.schematic.parse.SpongeParser; +import org.apache.commons.io.FilenameUtils; + +import java.io.File; +import java.util.Optional; +import java.util.stream.Stream; + +/** + * @author Brady + * @since 12/13/2019 + */ +public enum SchematicFormat { + + /** + * The MCEdit schematic specification. Commonly denoted by the ".schematic" file extension. + */ + MCEDIT("schematic", MCEditParser.INSTANCE), + + /** + * The SpongePowered Schematic Specification. Commonly denoted by the ".schem" file extension. + * + * @see Sponge Schematic Specification + */ + SPONGE("schem", SpongeParser.INSTANCE); + + private final String extension; + private final ISchematicParser parser; + + SchematicFormat(String extension, ISchematicParser parser) { + this.extension = extension; + this.parser = parser; + } + + public final ISchematicParser getParser() { + return this.parser; + } + + public static Optional getByFile(File schematic) { + // TODO: Better identification + // Maybe peek file contents and make a safe determination? + return getByExtension(FilenameUtils.getExtension(schematic.getAbsolutePath())); + } + + public static Optional getByExtension(String extension) { + return extension == null || extension.isEmpty() + ? Optional.empty() + : Stream.of(values()).filter(format -> format.extension.equals(extension)).findFirst(); + } +} diff --git a/src/main/java/baritone/utils/schematic/parse/ISchematicParser.java b/src/main/java/baritone/utils/schematic/parse/ISchematicParser.java new file mode 100644 index 000000000..040addc19 --- /dev/null +++ b/src/main/java/baritone/utils/schematic/parse/ISchematicParser.java @@ -0,0 +1,32 @@ +/* + * 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.schematic.parse; + +import baritone.api.schematic.ISchematic; + +import java.io.IOException; +import java.io.InputStream; + +/** + * @author Brady + * @since 12/13/2019 + */ +public interface ISchematicParser { + + ISchematic parse(InputStream input) throws IOException; +} diff --git a/src/main/java/baritone/utils/schematic/parse/MCEditParser.java b/src/main/java/baritone/utils/schematic/parse/MCEditParser.java new file mode 100644 index 000000000..dce2c856e --- /dev/null +++ b/src/main/java/baritone/utils/schematic/parse/MCEditParser.java @@ -0,0 +1,94 @@ +/* + * 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.schematic.parse; + +import baritone.api.schematic.AbstractSchematic; +import baritone.api.schematic.ISchematic; +import baritone.utils.schematic.format.SchematicFormat; +import net.minecraft.block.Block; +import net.minecraft.block.state.IBlockState; +import net.minecraft.nbt.CompressedStreamTools; +import net.minecraft.nbt.NBTTagCompound; + +import java.io.IOException; +import java.io.InputStream; +import java.util.List; + +/** + * An implementation of {@link ISchematicParser} for {@link SchematicFormat#MCEDIT} + * + * @author Brady + * @since 12/16/2019 + */ +public enum MCEditParser implements ISchematicParser { + INSTANCE; + + @Override + public ISchematic parse(InputStream input) throws IOException { + return new MCEditSchematic(CompressedStreamTools.readCompressed(input)); + } + + private static final class MCEditSchematic extends AbstractSchematic { + + private final IBlockState[][][] states; + + MCEditSchematic(NBTTagCompound schematic) { + String type = schematic.getString("Materials"); + if (!type.equals("Alpha")) { + throw new IllegalStateException("bad schematic " + type); + } + this.x = schematic.getInteger("Width"); + this.y = schematic.getInteger("Height"); + this.z = schematic.getInteger("Length"); + byte[] blocks = schematic.getByteArray("Blocks"); + byte[] metadata = schematic.getByteArray("Data"); + + byte[] additional = null; + if (schematic.hasKey("AddBlocks")) { + byte[] addBlocks = schematic.getByteArray("AddBlocks"); + additional = new byte[addBlocks.length * 2]; + for (int i = 0; i < addBlocks.length; i++) { + additional[i * 2 + 0] = (byte) ((addBlocks[i] >> 4) & 0xF); // lower nibble + additional[i * 2 + 1] = (byte) ((addBlocks[i] >> 0) & 0xF); // upper nibble + } + } + this.states = new IBlockState[this.x][this.z][this.y]; + for (int y = 0; y < this.y; y++) { + for (int z = 0; z < this.z; z++) { + for (int x = 0; x < this.x; x++) { + int blockInd = (y * this.z + z) * this.x + x; + + int blockID = blocks[blockInd] & 0xFF; + if (additional != null) { + // additional is 0 through 15 inclusive since it's & 0xF above + blockID |= additional[blockInd] << 8; + } + Block block = Block.REGISTRY.getObjectById(blockID); + int meta = metadata[blockInd] & 0xFF; + this.states[x][z][y] = block.getStateFromMeta(meta); + } + } + } + } + + @Override + public final IBlockState desiredState(int x, int y, int z, IBlockState current, List approxPlaceable) { + return this.states[x][z][y]; + } + } +} diff --git a/src/main/java/baritone/utils/schematic/parse/SpongeParser.java b/src/main/java/baritone/utils/schematic/parse/SpongeParser.java new file mode 100644 index 000000000..71984f915 --- /dev/null +++ b/src/main/java/baritone/utils/schematic/parse/SpongeParser.java @@ -0,0 +1,202 @@ +/* + * 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.schematic.parse; + +import baritone.api.schematic.AbstractSchematic; +import baritone.api.schematic.ISchematic; +import baritone.api.utils.BlockOptionalMeta; +import baritone.utils.schematic.format.SchematicFormat; +import io.netty.buffer.Unpooled; +import it.unimi.dsi.fastutil.ints.Int2ObjectArrayMap; +import net.minecraft.block.Block; +import net.minecraft.block.properties.IProperty; +import net.minecraft.block.state.IBlockState; +import net.minecraft.nbt.CompressedStreamTools; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.network.PacketBuffer; +import net.minecraft.util.ResourceLocation; + +import java.io.IOException; +import java.io.InputStream; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Optional; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +/** + * An implementation of {@link ISchematicParser} for {@link SchematicFormat#SPONGE} + * + * @author Brady + * @since 12/16/2019 + */ +public enum SpongeParser implements ISchematicParser { + INSTANCE; + + @Override + public ISchematic parse(InputStream input) throws IOException { + NBTTagCompound nbt = CompressedStreamTools.readCompressed(input); + int version = nbt.getInteger("Version"); + switch (version) { + case 1: + case 2: + return new SpongeSchematic(nbt); + default: + throw new UnsupportedOperationException("Unsupported Version of the a Sponge Schematic"); + } + } + + /** + * Implementation of the Sponge Schematic Format supporting both V1 and V2. (For the current + * use case, there is no difference between reading a V1 and V2 schematic). + */ + private static final class SpongeSchematic extends AbstractSchematic { + + /** + * Block states for this schematic stored in [x, z, y] indexing order + */ + private IBlockState[][][] states; + + SpongeSchematic(NBTTagCompound nbt) { + this.x = nbt.getInteger("Width"); + this.y = nbt.getInteger("Height"); + this.z = nbt.getInteger("Length"); + this.states = new IBlockState[this.x][this.z][this.y]; + + Int2ObjectArrayMap palette = new Int2ObjectArrayMap<>(); + NBTTagCompound paletteTag = nbt.getCompoundTag("Palette"); + for (String tag : paletteTag.getKeySet()) { + int index = paletteTag.getInteger(tag); + + SerializedBlockState serializedState = SerializedBlockState.getFromString(tag); + if (serializedState == null) { + throw new IllegalArgumentException("Unable to parse palette tag"); + } + + IBlockState state = serializedState.deserialize(); + if (state == null) { + throw new IllegalArgumentException("Unable to deserialize palette tag"); + } + + palette.put(index, state); + } + + // BlockData is stored as an NBT byte[], however, the actual data that is represented is a varint[]. + // This is kind of a hacky approach but it works /shrug + byte[] rawBlockData = nbt.getByteArray("BlockData"); + int[] blockData = new int[this.x * this.y * this.z]; + PacketBuffer buffer = new PacketBuffer(Unpooled.wrappedBuffer(rawBlockData)); + for (int i = 0; i < blockData.length; i++) { + if (buffer.readableBytes() > 0) { + blockData[i] = buffer.readVarInt(); + } else { + throw new IllegalArgumentException("Not enough"); + } + } + + for (int y = 0; y < this.y; y++) { + for (int z = 0; z < this.z; z++) { + for (int x = 0; x < this.x; x++) { + int index = (y * this.z + z) * this.x + x; + this.states[x][z][y] = palette.get(blockData[index]); + } + } + } + } + + @Override + public IBlockState desiredState(int x, int y, int z, IBlockState current, List approxPlaceable) { + return this.states[x][z][y]; + } + } + + private static final class SerializedBlockState { + + private static final Pattern REGEX = Pattern.compile("(?(\\w+:)?\\w+)(\\[(?(\\w+=\\w+,?)+)])?"); + + private final ResourceLocation resourceLocation; + private final Map properties; + private IBlockState blockState; + + private SerializedBlockState(ResourceLocation resourceLocation, Map properties) { + this.resourceLocation = resourceLocation; + this.properties = properties; + } + + ResourceLocation getResourceLocation() { + return this.resourceLocation; + } + + Map getProperties() { + return this.properties; + } + + IBlockState deserialize() { + if (this.blockState == null) { + // Get the base state for the block specified + this.blockState = Block.REGISTRY.getObject(this.resourceLocation).getDefaultState(); + + // AFAIK it is best to order the property keys so that Minecraft caches the Block States ideally + this.properties.keySet().stream().sorted(String::compareTo).forEachOrdered(key -> { + // getProperty(String) when lol + IProperty property = this.blockState.getPropertyKeys().stream() + .filter(p -> p.getName().equals(key)) + .findFirst().orElseThrow(IllegalArgumentException::new); + + Optional value = property.parseValue(this.properties.get(key)).toJavaUtil(); + if (value.isPresent()) { + this.blockState = this.blockState.withProperty( + BlockOptionalMeta.castToIProperty(property), + BlockOptionalMeta.castToIPropertyValue(property, value) + ); + } else { + throw new IllegalArgumentException(); + } + }); + } + return this.blockState; + } + + static SerializedBlockState getFromString(String s) { + Matcher m = REGEX.matcher(s); + if (!m.matches()) { + return null; + } + + try { + String location = m.group("location"); + String properties = m.group("properties"); + + ResourceLocation resourceLocation = new ResourceLocation(location); + Map propertiesMap = new HashMap<>(); + if (properties != null) { + for (String property : properties.split(",")) { + String[] split = property.split("="); + propertiesMap.put(split[0], split[1]); + } + } + + return new SerializedBlockState(resourceLocation, propertiesMap); + } catch (Exception e) { + e.printStackTrace(); + return null; + } + } + } +} From b4ddf381162aca4122fc7969c613e2aa6bf772f6 Mon Sep 17 00:00:00 2001 From: Brady Date: Wed, 18 Dec 2019 10:27:34 -0600 Subject: [PATCH 23/39] Check if state is null --- .../baritone/utils/schematic/parse/SpongeParser.java | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/main/java/baritone/utils/schematic/parse/SpongeParser.java b/src/main/java/baritone/utils/schematic/parse/SpongeParser.java index 71984f915..1b6cb5e06 100644 --- a/src/main/java/baritone/utils/schematic/parse/SpongeParser.java +++ b/src/main/java/baritone/utils/schematic/parse/SpongeParser.java @@ -106,7 +106,7 @@ public enum SpongeParser implements ISchematicParser { if (buffer.readableBytes() > 0) { blockData[i] = buffer.readVarInt(); } else { - throw new IllegalArgumentException("Not enough"); + throw new IllegalArgumentException("Buffer has no remaining bytes"); } } @@ -114,7 +114,12 @@ public enum SpongeParser implements ISchematicParser { for (int z = 0; z < this.z; z++) { for (int x = 0; x < this.x; x++) { int index = (y * this.z + z) * this.x + x; - this.states[x][z][y] = palette.get(blockData[index]); + IBlockState state = palette.get(blockData[index]); + if (state == null) { + throw new IllegalArgumentException("Invalid Palette Index " + index); + } + + this.states[x][z][y] = state; } } } From ea8d7fb3b9bfbe93e0c7415a4fdc1f37d26f5dc0 Mon Sep 17 00:00:00 2001 From: Brady Date: Wed, 18 Dec 2019 15:19:58 -0600 Subject: [PATCH 24/39] Improve file extension fallback mechanism --- src/api/java/baritone/api/Settings.java | 6 ++++++ src/main/java/baritone/command/defaults/BuildCommand.java | 7 ++++--- .../baritone/utils/schematic/format/SchematicFormat.java | 2 +- 3 files changed, 11 insertions(+), 4 deletions(-) diff --git a/src/api/java/baritone/api/Settings.java b/src/api/java/baritone/api/Settings.java index bf077f1a0..69bcabcb6 100644 --- a/src/api/java/baritone/api/Settings.java +++ b/src/api/java/baritone/api/Settings.java @@ -811,6 +811,12 @@ public final class Settings { */ public final Setting schematicOrientationZ = new Setting<>(false); + /** + * The fallback used by the build command when no extension is specified. This may be useful if schematics of a + * particular format are used often, and the user does not wish to have to specify the extension with every usage. + */ + public final Setting schematicFallbackExtension = new Setting<>("schematic"); + /** * Distance to scan every tick for updates. Expanding this beyond player reach distance (i.e. setting it to 6 or above) * is only necessary in very large schematics where rescanning the whole thing is costly. diff --git a/src/main/java/baritone/command/defaults/BuildCommand.java b/src/main/java/baritone/command/defaults/BuildCommand.java index 39bf0d3fd..3d5495874 100644 --- a/src/main/java/baritone/command/defaults/BuildCommand.java +++ b/src/main/java/baritone/command/defaults/BuildCommand.java @@ -17,6 +17,7 @@ package baritone.command.defaults; +import baritone.Baritone; import baritone.api.IBaritone; import baritone.api.utils.BetterBlockPos; import baritone.api.command.Command; @@ -26,11 +27,11 @@ import baritone.api.command.exception.CommandException; import baritone.api.command.exception.CommandInvalidStateException; import baritone.api.command.argument.IArgConsumer; import net.minecraft.client.Minecraft; +import org.apache.commons.io.FilenameUtils; import java.io.File; import java.util.Arrays; import java.util.List; -import java.util.Locale; import java.util.stream.Stream; public class BuildCommand extends Command { @@ -44,8 +45,8 @@ public class BuildCommand extends Command { @Override public void execute(String label, IArgConsumer args) throws CommandException { File file = args.getDatatypePost(RelativeFile.INSTANCE, schematicsDir).getAbsoluteFile(); - if (!file.getName().toLowerCase(Locale.US).endsWith(".schematic")) { - file = new File(file.getAbsolutePath() + ".schematic"); + if (FilenameUtils.getExtension(file.getAbsolutePath()).isEmpty()) { + file = new File(file.getAbsolutePath() + "." + Baritone.settings().schematicFallbackExtension); } BetterBlockPos origin = ctx.playerFeet(); BetterBlockPos buildOrigin; diff --git a/src/main/java/baritone/utils/schematic/format/SchematicFormat.java b/src/main/java/baritone/utils/schematic/format/SchematicFormat.java index 5f103d9a1..6c84273e4 100644 --- a/src/main/java/baritone/utils/schematic/format/SchematicFormat.java +++ b/src/main/java/baritone/utils/schematic/format/SchematicFormat.java @@ -65,6 +65,6 @@ public enum SchematicFormat { public static Optional getByExtension(String extension) { return extension == null || extension.isEmpty() ? Optional.empty() - : Stream.of(values()).filter(format -> format.extension.equals(extension)).findFirst(); + : Stream.of(values()).filter(format -> format.extension.equalsIgnoreCase(extension)).findFirst(); } } From aa3bd80ab2066dc30452cc68de4265924ac18d9a Mon Sep 17 00:00:00 2001 From: Brady Date: Thu, 19 Dec 2019 11:40:38 -0600 Subject: [PATCH 25/39] Clean ups --- .../utils/schematic/MapArtSchematic.java | 2 +- .../utils/schematic/parse/SpongeParser.java | 59 +++++------- src/main/java/baritone/utils/type/VarInt.java | 94 +++++++++++++++++++ 3 files changed, 120 insertions(+), 35 deletions(-) create mode 100644 src/main/java/baritone/utils/type/VarInt.java diff --git a/src/main/java/baritone/utils/schematic/MapArtSchematic.java b/src/main/java/baritone/utils/schematic/MapArtSchematic.java index 33ec3a152..ec477b57d 100644 --- a/src/main/java/baritone/utils/schematic/MapArtSchematic.java +++ b/src/main/java/baritone/utils/schematic/MapArtSchematic.java @@ -65,7 +65,7 @@ public class MapArtSchematic extends AbstractSchematic { @Override public boolean inSchematic(int x, int y, int z, IBlockState currentState) { // in map art, we only care about coordinates in or above the art - return super.inSchematic(x, y, z, currentState) && y >= heightMap[x][z]; + return this.child.inSchematic(x, y, z, currentState) && y >= heightMap[x][z]; } @Override diff --git a/src/main/java/baritone/utils/schematic/parse/SpongeParser.java b/src/main/java/baritone/utils/schematic/parse/SpongeParser.java index 1b6cb5e06..6219f1480 100644 --- a/src/main/java/baritone/utils/schematic/parse/SpongeParser.java +++ b/src/main/java/baritone/utils/schematic/parse/SpongeParser.java @@ -19,16 +19,14 @@ package baritone.utils.schematic.parse; import baritone.api.schematic.AbstractSchematic; import baritone.api.schematic.ISchematic; -import baritone.api.utils.BlockOptionalMeta; import baritone.utils.schematic.format.SchematicFormat; -import io.netty.buffer.Unpooled; +import baritone.utils.type.VarInt; import it.unimi.dsi.fastutil.ints.Int2ObjectArrayMap; import net.minecraft.block.Block; import net.minecraft.block.properties.IProperty; import net.minecraft.block.state.IBlockState; import net.minecraft.nbt.CompressedStreamTools; import net.minecraft.nbt.NBTTagCompound; -import net.minecraft.network.PacketBuffer; import net.minecraft.util.ResourceLocation; import java.io.IOException; @@ -97,17 +95,18 @@ public enum SpongeParser implements ISchematicParser { palette.put(index, state); } - // BlockData is stored as an NBT byte[], however, the actual data that is represented is a varint[]. - // This is kind of a hacky approach but it works /shrug + // BlockData is stored as an NBT byte[], however, the actual data that is represented is a varint[] byte[] rawBlockData = nbt.getByteArray("BlockData"); int[] blockData = new int[this.x * this.y * this.z]; - PacketBuffer buffer = new PacketBuffer(Unpooled.wrappedBuffer(rawBlockData)); + int offset = 0; for (int i = 0; i < blockData.length; i++) { - if (buffer.readableBytes() > 0) { - blockData[i] = buffer.readVarInt(); - } else { - throw new IllegalArgumentException("Buffer has no remaining bytes"); + if (offset >= blockData.length) { + throw new IllegalArgumentException("No remaining bytes in BlockData for complete schematic"); } + + VarInt varInt = VarInt.read(rawBlockData, offset); + blockData[i] = varInt.getValue(); + offset += varInt.getSize(); } for (int y = 0; y < this.y; y++) { @@ -144,35 +143,18 @@ public enum SpongeParser implements ISchematicParser { this.properties = properties; } - ResourceLocation getResourceLocation() { - return this.resourceLocation; - } - - Map getProperties() { - return this.properties; - } - IBlockState deserialize() { if (this.blockState == null) { - // Get the base state for the block specified - this.blockState = Block.REGISTRY.getObject(this.resourceLocation).getDefaultState(); + Block block = Block.REGISTRY.getObject(this.resourceLocation); + this.blockState = block.getDefaultState(); - // AFAIK it is best to order the property keys so that Minecraft caches the Block States ideally this.properties.keySet().stream().sorted(String::compareTo).forEachOrdered(key -> { - // getProperty(String) when lol - IProperty property = this.blockState.getPropertyKeys().stream() - .filter(p -> p.getName().equals(key)) - .findFirst().orElseThrow(IllegalArgumentException::new); - - Optional value = property.parseValue(this.properties.get(key)).toJavaUtil(); - if (value.isPresent()) { - this.blockState = this.blockState.withProperty( - BlockOptionalMeta.castToIProperty(property), - BlockOptionalMeta.castToIPropertyValue(property, value) - ); - } else { - throw new IllegalArgumentException(); + IProperty property = block.getBlockState().getProperty(key); + if (property == null) { + throw new IllegalArgumentException("Invalid property"); } + + this.blockState = setPropertyValue(this.blockState, property, this.properties.get(key)); }); } return this.blockState; @@ -203,5 +185,14 @@ public enum SpongeParser implements ISchematicParser { return null; } } + + private static > IBlockState setPropertyValue(IBlockState state, IProperty property, String value) { + Optional parsed = property.parseValue(value).toJavaUtil(); + if (parsed.isPresent()) { + return state.withProperty(property, parsed.get()); + } else { + throw new IllegalArgumentException("Invalid value for property " + property); + } + } } } diff --git a/src/main/java/baritone/utils/type/VarInt.java b/src/main/java/baritone/utils/type/VarInt.java new file mode 100644 index 000000000..8eb31e7f5 --- /dev/null +++ b/src/main/java/baritone/utils/type/VarInt.java @@ -0,0 +1,94 @@ +/* + * 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.type; + +import it.unimi.dsi.fastutil.bytes.ByteArrayList; +import it.unimi.dsi.fastutil.bytes.ByteList; + +/** + * @author Brady + * @since 12/19/2019 + */ +public final class VarInt { + + private final int value; + private final byte[] serialized; + private final int size; + + public VarInt(int value) { + this.value = value; + this.serialized = serialize0(this.value); + this.size = this.serialized.length; + } + + /** + * @return The integer value that is represented by this {@link VarInt}. + */ + public final int getValue() { + return this.value; + } + + /** + * @return The size of this {@link VarInt}, in bytes, once serialized. + */ + public final int getSize() { + return this.size; + } + + public final byte[] serialize() { + return this.serialized; + } + + private static byte[] serialize0(int value) { + ByteList bytes = new ByteArrayList(); + + while ((value & 0xFF) != 0) { + bytes.add((byte) (value & 0x7F | 0x80)); + value >>>= 7; + } + bytes.add((byte) (value & 0xFF)); + + return bytes.toByteArray(); + } + + public static VarInt read(byte[] bytes) { + return read(bytes, 0); + } + + public static VarInt read(byte[] bytes, int start) { + int value = 0; + int size = 0; + int index = start; + + while (true) { + byte b = bytes[index++]; + value |= (b & 0x7F) << size++ * 7; + + if (size > 5) { + throw new IllegalArgumentException("VarInt size cannot exceed 5 bytes"); + } + + // Most significant bit denotes another byte is to be read. + if ((b & 0x80) != 0x80) { + break; + } + } + + return new VarInt(value); + } +} From 6759917a2fbab523edd4532ebbd1f575ffcac24b Mon Sep 17 00:00:00 2001 From: Brady Date: Thu, 19 Dec 2019 11:58:47 -0600 Subject: [PATCH 26/39] Additional clean up --- .../baritone/api/schematic/FillSchematic.java | 3 ++ .../utils/schematic/FillSchematic.java | 26 ++------------ .../utils/schematic/MapArtSchematic.java | 34 +++---------------- 3 files changed, 11 insertions(+), 52 deletions(-) diff --git a/src/api/java/baritone/api/schematic/FillSchematic.java b/src/api/java/baritone/api/schematic/FillSchematic.java index aaaeb5dd1..fbf16fb47 100644 --- a/src/api/java/baritone/api/schematic/FillSchematic.java +++ b/src/api/java/baritone/api/schematic/FillSchematic.java @@ -38,6 +38,9 @@ public class FillSchematic extends AbstractSchematic { @Override public IBlockState desiredState(int x, int y, int z, IBlockState current, List approxPlaceable) { + // TODO: is this even necessary??? + // Builder will already handle logic that requires breaking blocks before replacing them, and non-api Fill Schematic + // is used for clear area and doesn't have any issues. if (bom.matches(current)) { return current; } else if (current.getBlock() != Blocks.AIR) { diff --git a/src/main/java/baritone/utils/schematic/FillSchematic.java b/src/main/java/baritone/utils/schematic/FillSchematic.java index 2e67b121f..67e5c7342 100644 --- a/src/main/java/baritone/utils/schematic/FillSchematic.java +++ b/src/main/java/baritone/utils/schematic/FillSchematic.java @@ -17,22 +17,17 @@ package baritone.utils.schematic; -import baritone.api.schematic.ISchematic; +import baritone.api.schematic.AbstractSchematic; import net.minecraft.block.state.IBlockState; import java.util.List; -public class FillSchematic implements ISchematic { +public class FillSchematic extends AbstractSchematic { - private final int widthX; - private final int heightY; - private final int lengthZ; private final IBlockState state; public FillSchematic(int widthX, int heightY, int lengthZ, IBlockState state) { - this.widthX = widthX; - this.heightY = heightY; - this.lengthZ = lengthZ; + super(widthX, heightY, lengthZ); this.state = state; } @@ -40,19 +35,4 @@ public class FillSchematic implements ISchematic { public IBlockState desiredState(int x, int y, int z, IBlockState current, List approxPlaceable) { return state; } - - @Override - public int widthX() { - return widthX; - } - - @Override - public int heightY() { - return heightY; - } - - @Override - public int lengthZ() { - return lengthZ; - } } diff --git a/src/main/java/baritone/utils/schematic/MapArtSchematic.java b/src/main/java/baritone/utils/schematic/MapArtSchematic.java index ec477b57d..a6bd20218 100644 --- a/src/main/java/baritone/utils/schematic/MapArtSchematic.java +++ b/src/main/java/baritone/utils/schematic/MapArtSchematic.java @@ -17,23 +17,20 @@ package baritone.utils.schematic; -import baritone.api.schematic.AbstractSchematic; import baritone.api.schematic.ISchematic; +import baritone.api.schematic.MaskSchematic; import net.minecraft.block.BlockAir; import net.minecraft.block.state.IBlockState; -import java.util.List; import java.util.OptionalInt; import java.util.function.Predicate; -public class MapArtSchematic extends AbstractSchematic { +public class MapArtSchematic extends MaskSchematic { - private final ISchematic child; private final int[][] heightMap; public MapArtSchematic(ISchematic schematic) { - super(schematic.widthX(), schematic.heightY(), schematic.lengthZ()); - this.child = schematic; + super(schematic); heightMap = new int[schematic.widthX()][schematic.lengthZ()]; @@ -63,28 +60,7 @@ public class MapArtSchematic extends AbstractSchematic { } @Override - public boolean inSchematic(int x, int y, int z, IBlockState currentState) { - // in map art, we only care about coordinates in or above the art - return this.child.inSchematic(x, y, z, currentState) && y >= heightMap[x][z]; - } - - @Override - public IBlockState desiredState(int x, int y, int z, IBlockState current, List approxPlaceable) { - return this.child.desiredState(x, y, z, current, approxPlaceable); - } - - @Override - public int widthX() { - return this.child.widthX(); - } - - @Override - public int heightY() { - return this.child.heightY(); - } - - @Override - public int lengthZ() { - return this.child.lengthZ(); + protected boolean partOfMask(int x, int y, int z, IBlockState currentState) { + return y >= heightMap[x][z]; } } From eea5b69b6cd8090afdb736d858a6dd16d8ecc28b Mon Sep 17 00:00:00 2001 From: Brady Date: Thu, 19 Dec 2019 12:03:02 -0600 Subject: [PATCH 27/39] Utilize new FillSchematic --- .../baritone/api/schematic/FillSchematic.java | 7 ++-- .../java/baritone/process/BuilderProcess.java | 2 +- .../utils/schematic/FillSchematic.java | 38 ------------------- 3 files changed, 5 insertions(+), 42 deletions(-) delete mode 100644 src/main/java/baritone/utils/schematic/FillSchematic.java diff --git a/src/api/java/baritone/api/schematic/FillSchematic.java b/src/api/java/baritone/api/schematic/FillSchematic.java index fbf16fb47..de9ccf970 100644 --- a/src/api/java/baritone/api/schematic/FillSchematic.java +++ b/src/api/java/baritone/api/schematic/FillSchematic.java @@ -32,15 +32,16 @@ public class FillSchematic extends AbstractSchematic { this.bom = bom; } + public FillSchematic(int x, int y, int z, IBlockState state) { + this(x, y, z, new BlockOptionalMeta(state.getBlock(), state.getBlock().getMetaFromState(state))); + } + public BlockOptionalMeta getBom() { return bom; } @Override public IBlockState desiredState(int x, int y, int z, IBlockState current, List approxPlaceable) { - // TODO: is this even necessary??? - // Builder will already handle logic that requires breaking blocks before replacing them, and non-api Fill Schematic - // is used for clear area and doesn't have any issues. if (bom.matches(current)) { return current; } else if (current.getBlock() != Blocks.AIR) { diff --git a/src/main/java/baritone/process/BuilderProcess.java b/src/main/java/baritone/process/BuilderProcess.java index 1dfd6c82f..88338a014 100644 --- a/src/main/java/baritone/process/BuilderProcess.java +++ b/src/main/java/baritone/process/BuilderProcess.java @@ -25,6 +25,7 @@ import baritone.api.pathing.goals.GoalGetToBlock; import baritone.api.process.IBuilderProcess; import baritone.api.process.PathingCommand; import baritone.api.process.PathingCommandType; +import baritone.api.schematic.FillSchematic; import baritone.api.schematic.ISchematic; import baritone.api.utils.BetterBlockPos; import baritone.api.utils.RayTraceUtils; @@ -37,7 +38,6 @@ import baritone.pathing.movement.MovementHelper; import baritone.utils.BaritoneProcessHelper; import baritone.utils.BlockStateInterface; import baritone.utils.PathingCommandContext; -import baritone.utils.schematic.FillSchematic; import baritone.utils.schematic.MapArtSchematic; import baritone.utils.schematic.format.SchematicFormat; import baritone.utils.schematic.schematica.SchematicaHelper; diff --git a/src/main/java/baritone/utils/schematic/FillSchematic.java b/src/main/java/baritone/utils/schematic/FillSchematic.java deleted file mode 100644 index 67e5c7342..000000000 --- a/src/main/java/baritone/utils/schematic/FillSchematic.java +++ /dev/null @@ -1,38 +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.utils.schematic; - -import baritone.api.schematic.AbstractSchematic; -import net.minecraft.block.state.IBlockState; - -import java.util.List; - -public class FillSchematic extends AbstractSchematic { - - private final IBlockState state; - - public FillSchematic(int widthX, int heightY, int lengthZ, IBlockState state) { - super(widthX, heightY, lengthZ); - this.state = state; - } - - @Override - public IBlockState desiredState(int x, int y, int z, IBlockState current, List approxPlaceable) { - return state; - } -} From 0a858c040c981337ae1fd82eeda6befe62622c24 Mon Sep 17 00:00:00 2001 From: Brady Date: Thu, 19 Dec 2019 22:15:14 -0600 Subject: [PATCH 28/39] Working --- .../java/baritone/utils/schematic/parse/SpongeParser.java | 8 +++----- src/main/java/baritone/utils/type/VarInt.java | 2 +- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/src/main/java/baritone/utils/schematic/parse/SpongeParser.java b/src/main/java/baritone/utils/schematic/parse/SpongeParser.java index 6219f1480..190c6d48f 100644 --- a/src/main/java/baritone/utils/schematic/parse/SpongeParser.java +++ b/src/main/java/baritone/utils/schematic/parse/SpongeParser.java @@ -100,7 +100,7 @@ public enum SpongeParser implements ISchematicParser { int[] blockData = new int[this.x * this.y * this.z]; int offset = 0; for (int i = 0; i < blockData.length; i++) { - if (offset >= blockData.length) { + if (offset >= rawBlockData.length) { throw new IllegalArgumentException("No remaining bytes in BlockData for complete schematic"); } @@ -150,11 +150,9 @@ public enum SpongeParser implements ISchematicParser { this.properties.keySet().stream().sorted(String::compareTo).forEachOrdered(key -> { IProperty property = block.getBlockState().getProperty(key); - if (property == null) { - throw new IllegalArgumentException("Invalid property"); + if (property != null) { + this.blockState = setPropertyValue(this.blockState, property, this.properties.get(key)); } - - this.blockState = setPropertyValue(this.blockState, property, this.properties.get(key)); }); } return this.blockState; diff --git a/src/main/java/baritone/utils/type/VarInt.java b/src/main/java/baritone/utils/type/VarInt.java index 8eb31e7f5..45f83dda1 100644 --- a/src/main/java/baritone/utils/type/VarInt.java +++ b/src/main/java/baritone/utils/type/VarInt.java @@ -57,7 +57,7 @@ public final class VarInt { private static byte[] serialize0(int value) { ByteList bytes = new ByteArrayList(); - while ((value & 0xFF) != 0) { + while ((value & 0x80) != 0) { bytes.add((byte) (value & 0x7F | 0x80)); value >>>= 7; } From 77bdf6e444d338d993f80efeae6e9a0e3cd3a3fb Mon Sep 17 00:00:00 2001 From: Brady Date: Mon, 23 Dec 2019 18:05:50 -0600 Subject: [PATCH 29/39] Fix MapSchematic --- .../java/baritone/process/BuilderProcess.java | 3 +- .../utils/schematic/MapArtSchematic.java | 34 +------ .../utils/schematic/StaticSchematic.java | 88 +++++++++++++++++++ .../schematic/parse/ISchematicParser.java | 4 +- .../utils/schematic/parse/MCEditParser.java | 15 +--- .../utils/schematic/parse/SpongeParser.java | 19 +--- 6 files changed, 101 insertions(+), 62 deletions(-) create mode 100644 src/main/java/baritone/utils/schematic/StaticSchematic.java diff --git a/src/main/java/baritone/process/BuilderProcess.java b/src/main/java/baritone/process/BuilderProcess.java index 88338a014..a7a17160a 100644 --- a/src/main/java/baritone/process/BuilderProcess.java +++ b/src/main/java/baritone/process/BuilderProcess.java @@ -39,6 +39,7 @@ import baritone.utils.BaritoneProcessHelper; import baritone.utils.BlockStateInterface; import baritone.utils.PathingCommandContext; import baritone.utils.schematic.MapArtSchematic; +import baritone.utils.schematic.StaticSchematic; import baritone.utils.schematic.format.SchematicFormat; import baritone.utils.schematic.schematica.SchematicaHelper; import it.unimi.dsi.fastutil.longs.LongOpenHashSet; @@ -129,7 +130,7 @@ public final class BuilderProcess extends BaritoneProcessHelper implements IBuil } if (Baritone.settings().mapArtMode.value) { - parsed = new MapArtSchematic(parsed); + parsed = new MapArtSchematic((StaticSchematic) parsed); } build(name, parsed, origin); diff --git a/src/main/java/baritone/utils/schematic/MapArtSchematic.java b/src/main/java/baritone/utils/schematic/MapArtSchematic.java index a6bd20218..dc2edf2cc 100644 --- a/src/main/java/baritone/utils/schematic/MapArtSchematic.java +++ b/src/main/java/baritone/utils/schematic/MapArtSchematic.java @@ -17,46 +17,16 @@ package baritone.utils.schematic; -import baritone.api.schematic.ISchematic; import baritone.api.schematic.MaskSchematic; -import net.minecraft.block.BlockAir; import net.minecraft.block.state.IBlockState; -import java.util.OptionalInt; -import java.util.function.Predicate; - public class MapArtSchematic extends MaskSchematic { private final int[][] heightMap; - public MapArtSchematic(ISchematic schematic) { + public MapArtSchematic(StaticSchematic schematic) { super(schematic); - - heightMap = new int[schematic.widthX()][schematic.lengthZ()]; - - for (int x = 0; x < schematic.widthX(); x++) { - for (int z = 0; z < schematic.lengthZ(); z++) { - IBlockState[] column = /*states[x][z]*/null; - - OptionalInt lowestBlockY = lastIndexMatching(column, state -> !(state.getBlock() instanceof BlockAir)); - if (lowestBlockY.isPresent()) { - heightMap[x][z] = lowestBlockY.getAsInt(); - } else { - System.out.println("Column " + x + "," + z + " has no blocks, but it's apparently map art? wtf"); - System.out.println("Letting it be whatever"); - heightMap[x][z] = 256; - } - } - } - } - - private static OptionalInt lastIndexMatching(T[] arr, Predicate predicate) { - for (int y = arr.length - 1; y >= 0; y--) { - if (predicate.test(arr[y])) { - return OptionalInt.of(y); - } - } - return OptionalInt.empty(); + this.heightMap = schematic.getHeightMap(); } @Override diff --git a/src/main/java/baritone/utils/schematic/StaticSchematic.java b/src/main/java/baritone/utils/schematic/StaticSchematic.java new file mode 100644 index 000000000..97fc91cd7 --- /dev/null +++ b/src/main/java/baritone/utils/schematic/StaticSchematic.java @@ -0,0 +1,88 @@ +/* + * 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.schematic; + +import baritone.api.schematic.AbstractSchematic; +import net.minecraft.block.BlockAir; +import net.minecraft.block.state.IBlockState; + +import java.util.List; +import java.util.OptionalInt; +import java.util.function.Predicate; + +/** + * @author Brady + * @since 12/23/2019 + */ +public abstract class StaticSchematic extends AbstractSchematic { + + /** + * Block states for this schematic stored in [x, z, y] indexing order + */ + protected IBlockState[][][] states; + + /** + * The maximum height of a given block in this schematic, indexed as [x, z]. + * This is lazily initialized by {@link #getHeightMap()}. + */ + protected int[][] heightMap; + + public StaticSchematic() { + super(); + } + + public StaticSchematic(int x, int y, int z) { + super(x, y, z); + } + + @Override + public IBlockState desiredState(int x, int y, int z, IBlockState current, List approxPlaceable) { + return this.states[x][z][y]; + } + + public final int[][] getHeightMap() { + if (this.heightMap == null) { + this.heightMap = new int[this.x][this.z]; + + for (int x = 0; x < this.x; x++) { + for (int z = 0; z < this.z; z++) { + IBlockState[] column = states[x][z]; + + OptionalInt lowestBlockY = lastIndexMatching(column, state -> !(state.getBlock() instanceof BlockAir)); + if (lowestBlockY.isPresent()) { + this.heightMap[x][z] = lowestBlockY.getAsInt(); + } else { + System.out.println("Column " + x + "," + z + " has no blocks, but it's apparently map art? wtf"); + System.out.println("Letting it be whatever"); + this.heightMap[x][z] = 256; + } + } + } + } + return this.heightMap; + } + + private static OptionalInt lastIndexMatching(T[] arr, Predicate predicate) { + for (int y = arr.length - 1; y >= 0; y--) { + if (predicate.test(arr[y])) { + return OptionalInt.of(y); + } + } + return OptionalInt.empty(); + } +} diff --git a/src/main/java/baritone/utils/schematic/parse/ISchematicParser.java b/src/main/java/baritone/utils/schematic/parse/ISchematicParser.java index 040addc19..8bc716f16 100644 --- a/src/main/java/baritone/utils/schematic/parse/ISchematicParser.java +++ b/src/main/java/baritone/utils/schematic/parse/ISchematicParser.java @@ -17,7 +17,7 @@ package baritone.utils.schematic.parse; -import baritone.api.schematic.ISchematic; +import baritone.utils.schematic.StaticSchematic; import java.io.IOException; import java.io.InputStream; @@ -28,5 +28,5 @@ import java.io.InputStream; */ public interface ISchematicParser { - ISchematic parse(InputStream input) throws IOException; + StaticSchematic parse(InputStream input) throws IOException; } diff --git a/src/main/java/baritone/utils/schematic/parse/MCEditParser.java b/src/main/java/baritone/utils/schematic/parse/MCEditParser.java index dce2c856e..54d78201e 100644 --- a/src/main/java/baritone/utils/schematic/parse/MCEditParser.java +++ b/src/main/java/baritone/utils/schematic/parse/MCEditParser.java @@ -17,8 +17,7 @@ package baritone.utils.schematic.parse; -import baritone.api.schematic.AbstractSchematic; -import baritone.api.schematic.ISchematic; +import baritone.utils.schematic.StaticSchematic; import baritone.utils.schematic.format.SchematicFormat; import net.minecraft.block.Block; import net.minecraft.block.state.IBlockState; @@ -27,7 +26,6 @@ import net.minecraft.nbt.NBTTagCompound; import java.io.IOException; import java.io.InputStream; -import java.util.List; /** * An implementation of {@link ISchematicParser} for {@link SchematicFormat#MCEDIT} @@ -39,13 +37,11 @@ public enum MCEditParser implements ISchematicParser { INSTANCE; @Override - public ISchematic parse(InputStream input) throws IOException { + public StaticSchematic parse(InputStream input) throws IOException { return new MCEditSchematic(CompressedStreamTools.readCompressed(input)); } - private static final class MCEditSchematic extends AbstractSchematic { - - private final IBlockState[][][] states; + private static final class MCEditSchematic extends StaticSchematic { MCEditSchematic(NBTTagCompound schematic) { String type = schematic.getString("Materials"); @@ -85,10 +81,5 @@ public enum MCEditParser implements ISchematicParser { } } } - - @Override - public final IBlockState desiredState(int x, int y, int z, IBlockState current, List approxPlaceable) { - return this.states[x][z][y]; - } } } diff --git a/src/main/java/baritone/utils/schematic/parse/SpongeParser.java b/src/main/java/baritone/utils/schematic/parse/SpongeParser.java index 190c6d48f..48cc60aac 100644 --- a/src/main/java/baritone/utils/schematic/parse/SpongeParser.java +++ b/src/main/java/baritone/utils/schematic/parse/SpongeParser.java @@ -17,8 +17,7 @@ package baritone.utils.schematic.parse; -import baritone.api.schematic.AbstractSchematic; -import baritone.api.schematic.ISchematic; +import baritone.utils.schematic.StaticSchematic; import baritone.utils.schematic.format.SchematicFormat; import baritone.utils.type.VarInt; import it.unimi.dsi.fastutil.ints.Int2ObjectArrayMap; @@ -32,7 +31,6 @@ import net.minecraft.util.ResourceLocation; import java.io.IOException; import java.io.InputStream; import java.util.HashMap; -import java.util.List; import java.util.Map; import java.util.Optional; import java.util.regex.Matcher; @@ -48,7 +46,7 @@ public enum SpongeParser implements ISchematicParser { INSTANCE; @Override - public ISchematic parse(InputStream input) throws IOException { + public StaticSchematic parse(InputStream input) throws IOException { NBTTagCompound nbt = CompressedStreamTools.readCompressed(input); int version = nbt.getInteger("Version"); switch (version) { @@ -56,7 +54,7 @@ public enum SpongeParser implements ISchematicParser { case 2: return new SpongeSchematic(nbt); default: - throw new UnsupportedOperationException("Unsupported Version of the a Sponge Schematic"); + throw new UnsupportedOperationException("Unsupported Version of a Sponge Schematic"); } } @@ -64,12 +62,8 @@ public enum SpongeParser implements ISchematicParser { * Implementation of the Sponge Schematic Format supporting both V1 and V2. (For the current * use case, there is no difference between reading a V1 and V2 schematic). */ - private static final class SpongeSchematic extends AbstractSchematic { + private static final class SpongeSchematic extends StaticSchematic { - /** - * Block states for this schematic stored in [x, z, y] indexing order - */ - private IBlockState[][][] states; SpongeSchematic(NBTTagCompound nbt) { this.x = nbt.getInteger("Width"); @@ -123,11 +117,6 @@ public enum SpongeParser implements ISchematicParser { } } } - - @Override - public IBlockState desiredState(int x, int y, int z, IBlockState current, List approxPlaceable) { - return this.states[x][z][y]; - } } private static final class SerializedBlockState { From eee705b371d27bf7f797ffa3d578c797cf046395 Mon Sep 17 00:00:00 2001 From: Brady Date: Tue, 24 Dec 2019 17:20:00 -0600 Subject: [PATCH 30/39] Schematic Format API support --- .../java/baritone/api/IBaritoneProvider.java | 6 ++ .../api/schematic/ISchematicSystem.java | 44 ++++++++++++++ .../api/schematic/IStaticSchematic.java | 60 +++++++++++++++++++ .../schematic/format/ISchematicFormat.java | 43 +++++++++++++ .../schematic/parse/ISchematicParser.java | 6 +- src/main/java/baritone/BaritoneProvider.java | 7 +++ .../java/baritone/process/BuilderProcess.java | 9 +-- .../utils/schematic/MapArtSchematic.java | 40 ++++++++++++- .../utils/schematic/SchematicSystem.java | 51 ++++++++++++++++ .../utils/schematic/StaticSchematic.java | 58 ++++-------------- ...rmat.java => DefaultSchematicFormats.java} | 25 ++++---- .../utils/schematic/parse/MCEditParser.java | 5 +- .../utils/schematic/parse/SpongeParser.java | 5 +- 13 files changed, 282 insertions(+), 77 deletions(-) create mode 100644 src/api/java/baritone/api/schematic/ISchematicSystem.java create mode 100644 src/api/java/baritone/api/schematic/IStaticSchematic.java create mode 100644 src/api/java/baritone/api/schematic/format/ISchematicFormat.java rename src/{main/java/baritone/utils => api/java/baritone/api}/schematic/parse/ISchematicParser.java (84%) create mode 100644 src/main/java/baritone/utils/schematic/SchematicSystem.java rename src/main/java/baritone/utils/schematic/format/{SchematicFormat.java => DefaultSchematicFormats.java} (68%) diff --git a/src/api/java/baritone/api/IBaritoneProvider.java b/src/api/java/baritone/api/IBaritoneProvider.java index b7228e33b..84a8abbbd 100644 --- a/src/api/java/baritone/api/IBaritoneProvider.java +++ b/src/api/java/baritone/api/IBaritoneProvider.java @@ -20,6 +20,7 @@ package baritone.api; import baritone.api.cache.IWorldScanner; import baritone.api.command.ICommand; import baritone.api.command.ICommandSystem; +import baritone.api.schematic.ISchematicSystem; import net.minecraft.client.entity.EntityPlayerSP; import java.util.List; @@ -82,4 +83,9 @@ public interface IBaritoneProvider { * @return The {@link ICommandSystem} instance. */ ICommandSystem getCommandSystem(); + + /** + * @return The {@link ISchematicSystem} instance. + */ + ISchematicSystem getSchematicSystem(); } diff --git a/src/api/java/baritone/api/schematic/ISchematicSystem.java b/src/api/java/baritone/api/schematic/ISchematicSystem.java new file mode 100644 index 000000000..c8f039070 --- /dev/null +++ b/src/api/java/baritone/api/schematic/ISchematicSystem.java @@ -0,0 +1,44 @@ +/* + * 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.schematic; + +import baritone.api.command.registry.Registry; +import baritone.api.schematic.format.ISchematicFormat; + +import java.io.File; +import java.util.Optional; + +/** + * @author Brady + * @since 12/23/2019 + */ +public interface ISchematicSystem { + + /** + * @return The registry of supported schematic formats + */ + Registry getRegistry(); + + /** + * Attempts to find an {@link ISchematicFormat} that supports the specified schematic file. + * + * @param file A schematic file + * @return The corresponding format for the file, {@link Optional#empty()} if no candidates were found. + */ + Optional getByFile(File file); +} diff --git a/src/api/java/baritone/api/schematic/IStaticSchematic.java b/src/api/java/baritone/api/schematic/IStaticSchematic.java new file mode 100644 index 000000000..268b1b1f4 --- /dev/null +++ b/src/api/java/baritone/api/schematic/IStaticSchematic.java @@ -0,0 +1,60 @@ +/* + * 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.schematic; + +import net.minecraft.block.state.IBlockState; + +/** + * A static schematic is capable of providing the desired state at a given position without + * additional context. Schematics of this type are expected to have non-varying contents. + * + * @see #getDirect(int, int, int) + * + * @author Brady + * @since 12/24/2019 + */ +public interface IStaticSchematic extends ISchematic { + + /** + * Gets the {@link IBlockState} for a given position in this schematic. It should be guaranteed + * that the return value of this method will not change given that the parameters are the same. + * + * @param x The X block position + * @param y The Y block position + * @param z The Z block position + * @return The desired state at the specified position. + */ + IBlockState getDirect(int x, int y, int z); + + /** + * Returns an {@link IBlockState} array of size {@link #heightY()} which contains all + * desired block states in the specified vertical column. The index of {@link IBlockState}s + * in the array are equivalent to their Y position in the schematic. + * + * @param x The X column position + * @param z The Z column position + * @return An {@link IBlockState} array + */ + default IBlockState[] getColumn(int x, int z) { + IBlockState[] column = new IBlockState[this.heightY()]; + for (int i = 0; i < this.heightY(); i++) { + column[i] = getDirect(x, i, z); + } + return column; + } +} diff --git a/src/api/java/baritone/api/schematic/format/ISchematicFormat.java b/src/api/java/baritone/api/schematic/format/ISchematicFormat.java new file mode 100644 index 000000000..260ab4536 --- /dev/null +++ b/src/api/java/baritone/api/schematic/format/ISchematicFormat.java @@ -0,0 +1,43 @@ +/* + * 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.schematic.format; + +import baritone.api.schematic.ISchematic; +import baritone.api.schematic.parse.ISchematicParser; + +import java.io.File; + +/** + * The base of a {@link ISchematic} file format + * + * @author Brady + * @since 12/23/2019 + */ +public interface ISchematicFormat { + + /** + * @return The parser for creating schematics of this format + */ + ISchematicParser getParser(); + + /** + * @param file The file to check against + * @return Whether or not the specified file matches this schematic format + */ + boolean isFileType(File file); +} diff --git a/src/main/java/baritone/utils/schematic/parse/ISchematicParser.java b/src/api/java/baritone/api/schematic/parse/ISchematicParser.java similarity index 84% rename from src/main/java/baritone/utils/schematic/parse/ISchematicParser.java rename to src/api/java/baritone/api/schematic/parse/ISchematicParser.java index 8bc716f16..ab0f12f49 100644 --- a/src/main/java/baritone/utils/schematic/parse/ISchematicParser.java +++ b/src/api/java/baritone/api/schematic/parse/ISchematicParser.java @@ -15,9 +15,9 @@ * along with Baritone. If not, see . */ -package baritone.utils.schematic.parse; +package baritone.api.schematic.parse; -import baritone.utils.schematic.StaticSchematic; +import baritone.api.schematic.IStaticSchematic; import java.io.IOException; import java.io.InputStream; @@ -28,5 +28,5 @@ import java.io.InputStream; */ public interface ISchematicParser { - StaticSchematic parse(InputStream input) throws IOException; + IStaticSchematic parse(InputStream input) throws IOException; } diff --git a/src/main/java/baritone/BaritoneProvider.java b/src/main/java/baritone/BaritoneProvider.java index cb24dfe21..84034ef33 100644 --- a/src/main/java/baritone/BaritoneProvider.java +++ b/src/main/java/baritone/BaritoneProvider.java @@ -21,9 +21,11 @@ import baritone.api.IBaritone; import baritone.api.IBaritoneProvider; import baritone.api.cache.IWorldScanner; import baritone.api.command.ICommandSystem; +import baritone.api.schematic.ISchematicSystem; import baritone.command.BaritoneChatControl; import baritone.cache.WorldScanner; import baritone.command.CommandSystem; +import baritone.utils.schematic.SchematicSystem; import java.util.Collections; import java.util.List; @@ -64,4 +66,9 @@ public final class BaritoneProvider implements IBaritoneProvider { public ICommandSystem getCommandSystem() { return CommandSystem.INSTANCE; } + + @Override + public ISchematicSystem getSchematicSystem() { + return SchematicSystem.INSTANCE; + } } diff --git a/src/main/java/baritone/process/BuilderProcess.java b/src/main/java/baritone/process/BuilderProcess.java index a7a17160a..553616020 100644 --- a/src/main/java/baritone/process/BuilderProcess.java +++ b/src/main/java/baritone/process/BuilderProcess.java @@ -27,6 +27,8 @@ import baritone.api.process.PathingCommand; import baritone.api.process.PathingCommandType; import baritone.api.schematic.FillSchematic; import baritone.api.schematic.ISchematic; +import baritone.api.schematic.IStaticSchematic; +import baritone.api.schematic.format.ISchematicFormat; import baritone.api.utils.BetterBlockPos; import baritone.api.utils.RayTraceUtils; import baritone.api.utils.Rotation; @@ -39,8 +41,7 @@ import baritone.utils.BaritoneProcessHelper; import baritone.utils.BlockStateInterface; import baritone.utils.PathingCommandContext; import baritone.utils.schematic.MapArtSchematic; -import baritone.utils.schematic.StaticSchematic; -import baritone.utils.schematic.format.SchematicFormat; +import baritone.utils.schematic.SchematicSystem; import baritone.utils.schematic.schematica.SchematicaHelper; import it.unimi.dsi.fastutil.longs.LongOpenHashSet; import net.minecraft.block.BlockAir; @@ -116,7 +117,7 @@ public final class BuilderProcess extends BaritoneProcessHelper implements IBuil @Override public boolean build(String name, File schematic, Vec3i origin) { - Optional format = SchematicFormat.getByFile(schematic); + Optional format = SchematicSystem.INSTANCE.getByFile(schematic); if (!format.isPresent()) { return false; } @@ -130,7 +131,7 @@ public final class BuilderProcess extends BaritoneProcessHelper implements IBuil } if (Baritone.settings().mapArtMode.value) { - parsed = new MapArtSchematic((StaticSchematic) parsed); + parsed = new MapArtSchematic((IStaticSchematic) parsed); } build(name, parsed, origin); diff --git a/src/main/java/baritone/utils/schematic/MapArtSchematic.java b/src/main/java/baritone/utils/schematic/MapArtSchematic.java index dc2edf2cc..314422613 100644 --- a/src/main/java/baritone/utils/schematic/MapArtSchematic.java +++ b/src/main/java/baritone/utils/schematic/MapArtSchematic.java @@ -17,20 +17,54 @@ package baritone.utils.schematic; +import baritone.api.schematic.IStaticSchematic; import baritone.api.schematic.MaskSchematic; +import net.minecraft.block.BlockAir; import net.minecraft.block.state.IBlockState; +import java.util.OptionalInt; +import java.util.function.Predicate; + public class MapArtSchematic extends MaskSchematic { private final int[][] heightMap; - public MapArtSchematic(StaticSchematic schematic) { + public MapArtSchematic(IStaticSchematic schematic) { super(schematic); - this.heightMap = schematic.getHeightMap(); + this.heightMap = generateHeightMap(schematic); } @Override protected boolean partOfMask(int x, int y, int z, IBlockState currentState) { - return y >= heightMap[x][z]; + return y >= this.heightMap[x][z]; + } + + private static int[][] generateHeightMap(IStaticSchematic schematic) { + int[][] heightMap = new int[schematic.widthX()][schematic.lengthZ()]; + + for (int x = 0; x < schematic.widthX(); x++) { + for (int z = 0; z < schematic.lengthZ(); z++) { + IBlockState[] column = schematic.getColumn(x, z); + + OptionalInt lowestBlockY = lastIndexMatching(column, state -> !(state.getBlock() instanceof BlockAir)); + if (lowestBlockY.isPresent()) { + heightMap[x][z] = lowestBlockY.getAsInt(); + } else { + System.out.println("Column " + x + "," + z + " has no blocks, but it's apparently map art? wtf"); + System.out.println("Letting it be whatever"); + heightMap[x][z] = 256; + } + } + } + return heightMap; + } + + private static OptionalInt lastIndexMatching(T[] arr, Predicate predicate) { + for (int y = arr.length - 1; y >= 0; y--) { + if (predicate.test(arr[y])) { + return OptionalInt.of(y); + } + } + return OptionalInt.empty(); } } diff --git a/src/main/java/baritone/utils/schematic/SchematicSystem.java b/src/main/java/baritone/utils/schematic/SchematicSystem.java new file mode 100644 index 000000000..8afafa8c3 --- /dev/null +++ b/src/main/java/baritone/utils/schematic/SchematicSystem.java @@ -0,0 +1,51 @@ +/* + * 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.schematic; + +import baritone.api.command.registry.Registry; +import baritone.api.schematic.ISchematicSystem; +import baritone.api.schematic.format.ISchematicFormat; +import baritone.utils.schematic.format.DefaultSchematicFormats; + +import java.io.File; +import java.util.Arrays; +import java.util.Optional; + +/** + * @author Brady + * @since 12/24/2019 + */ +public enum SchematicSystem implements ISchematicSystem { + INSTANCE; + + private final Registry registry = new Registry<>(); + + SchematicSystem() { + Arrays.stream(DefaultSchematicFormats.values()).forEach(this.registry::register); + } + + @Override + public Registry getRegistry() { + return this.registry; + } + + @Override + public Optional getByFile(File file) { + return this.registry.stream().filter(format -> format.isFileType(file)).findFirst(); + } +} diff --git a/src/main/java/baritone/utils/schematic/StaticSchematic.java b/src/main/java/baritone/utils/schematic/StaticSchematic.java index 97fc91cd7..2251450a3 100644 --- a/src/main/java/baritone/utils/schematic/StaticSchematic.java +++ b/src/main/java/baritone/utils/schematic/StaticSchematic.java @@ -18,71 +18,33 @@ package baritone.utils.schematic; import baritone.api.schematic.AbstractSchematic; -import net.minecraft.block.BlockAir; +import baritone.api.schematic.IStaticSchematic; import net.minecraft.block.state.IBlockState; import java.util.List; -import java.util.OptionalInt; -import java.util.function.Predicate; /** + * Default implementation of {@link IStaticSchematic} + * * @author Brady * @since 12/23/2019 */ -public abstract class StaticSchematic extends AbstractSchematic { +public class StaticSchematic extends AbstractSchematic implements IStaticSchematic { - /** - * Block states for this schematic stored in [x, z, y] indexing order - */ protected IBlockState[][][] states; - /** - * The maximum height of a given block in this schematic, indexed as [x, z]. - * This is lazily initialized by {@link #getHeightMap()}. - */ - protected int[][] heightMap; - - public StaticSchematic() { - super(); - } - - public StaticSchematic(int x, int y, int z) { - super(x, y, z); - } - @Override public IBlockState desiredState(int x, int y, int z, IBlockState current, List approxPlaceable) { return this.states[x][z][y]; } - public final int[][] getHeightMap() { - if (this.heightMap == null) { - this.heightMap = new int[this.x][this.z]; - - for (int x = 0; x < this.x; x++) { - for (int z = 0; z < this.z; z++) { - IBlockState[] column = states[x][z]; - - OptionalInt lowestBlockY = lastIndexMatching(column, state -> !(state.getBlock() instanceof BlockAir)); - if (lowestBlockY.isPresent()) { - this.heightMap[x][z] = lowestBlockY.getAsInt(); - } else { - System.out.println("Column " + x + "," + z + " has no blocks, but it's apparently map art? wtf"); - System.out.println("Letting it be whatever"); - this.heightMap[x][z] = 256; - } - } - } - } - return this.heightMap; + @Override + public IBlockState getDirect(int x, int y, int z) { + return this.states[x][z][y]; } - private static OptionalInt lastIndexMatching(T[] arr, Predicate predicate) { - for (int y = arr.length - 1; y >= 0; y--) { - if (predicate.test(arr[y])) { - return OptionalInt.of(y); - } - } - return OptionalInt.empty(); + @Override + public IBlockState[] getColumn(int x, int z) { + return this.states[x][z]; } } diff --git a/src/main/java/baritone/utils/schematic/format/SchematicFormat.java b/src/main/java/baritone/utils/schematic/format/DefaultSchematicFormats.java similarity index 68% rename from src/main/java/baritone/utils/schematic/format/SchematicFormat.java rename to src/main/java/baritone/utils/schematic/format/DefaultSchematicFormats.java index 6c84273e4..494d6ec8d 100644 --- a/src/main/java/baritone/utils/schematic/format/SchematicFormat.java +++ b/src/main/java/baritone/utils/schematic/format/DefaultSchematicFormats.java @@ -17,20 +17,21 @@ package baritone.utils.schematic.format; -import baritone.utils.schematic.parse.ISchematicParser; +import baritone.api.schematic.format.ISchematicFormat; +import baritone.api.schematic.parse.ISchematicParser; import baritone.utils.schematic.parse.MCEditParser; import baritone.utils.schematic.parse.SpongeParser; import org.apache.commons.io.FilenameUtils; import java.io.File; -import java.util.Optional; -import java.util.stream.Stream; /** + * Default implementations of {@link ISchematicFormat} + * * @author Brady * @since 12/13/2019 */ -public enum SchematicFormat { +public enum DefaultSchematicFormats implements ISchematicFormat { /** * The MCEdit schematic specification. Commonly denoted by the ".schematic" file extension. @@ -47,24 +48,18 @@ public enum SchematicFormat { private final String extension; private final ISchematicParser parser; - SchematicFormat(String extension, ISchematicParser parser) { + DefaultSchematicFormats(String extension, ISchematicParser parser) { this.extension = extension; this.parser = parser; } + @Override public final ISchematicParser getParser() { return this.parser; } - public static Optional getByFile(File schematic) { - // TODO: Better identification - // Maybe peek file contents and make a safe determination? - return getByExtension(FilenameUtils.getExtension(schematic.getAbsolutePath())); - } - - public static Optional getByExtension(String extension) { - return extension == null || extension.isEmpty() - ? Optional.empty() - : Stream.of(values()).filter(format -> format.extension.equalsIgnoreCase(extension)).findFirst(); + @Override + public boolean isFileType(File file) { + return this.extension.equalsIgnoreCase(FilenameUtils.getExtension(file.getAbsolutePath())); } } diff --git a/src/main/java/baritone/utils/schematic/parse/MCEditParser.java b/src/main/java/baritone/utils/schematic/parse/MCEditParser.java index 54d78201e..3599b824b 100644 --- a/src/main/java/baritone/utils/schematic/parse/MCEditParser.java +++ b/src/main/java/baritone/utils/schematic/parse/MCEditParser.java @@ -17,8 +17,9 @@ package baritone.utils.schematic.parse; +import baritone.api.schematic.parse.ISchematicParser; import baritone.utils.schematic.StaticSchematic; -import baritone.utils.schematic.format.SchematicFormat; +import baritone.utils.schematic.format.DefaultSchematicFormats; import net.minecraft.block.Block; import net.minecraft.block.state.IBlockState; import net.minecraft.nbt.CompressedStreamTools; @@ -28,7 +29,7 @@ import java.io.IOException; import java.io.InputStream; /** - * An implementation of {@link ISchematicParser} for {@link SchematicFormat#MCEDIT} + * An implementation of {@link ISchematicParser} for {@link DefaultSchematicFormats#MCEDIT} * * @author Brady * @since 12/16/2019 diff --git a/src/main/java/baritone/utils/schematic/parse/SpongeParser.java b/src/main/java/baritone/utils/schematic/parse/SpongeParser.java index 48cc60aac..255916d18 100644 --- a/src/main/java/baritone/utils/schematic/parse/SpongeParser.java +++ b/src/main/java/baritone/utils/schematic/parse/SpongeParser.java @@ -17,8 +17,9 @@ package baritone.utils.schematic.parse; +import baritone.api.schematic.parse.ISchematicParser; import baritone.utils.schematic.StaticSchematic; -import baritone.utils.schematic.format.SchematicFormat; +import baritone.utils.schematic.format.DefaultSchematicFormats; import baritone.utils.type.VarInt; import it.unimi.dsi.fastutil.ints.Int2ObjectArrayMap; import net.minecraft.block.Block; @@ -37,7 +38,7 @@ import java.util.regex.Matcher; import java.util.regex.Pattern; /** - * An implementation of {@link ISchematicParser} for {@link SchematicFormat#SPONGE} + * An implementation of {@link ISchematicParser} for {@link DefaultSchematicFormats#SPONGE} * * @author Brady * @since 12/16/2019 From d712839c259a3be2df801e366140e0ae25ba73f0 Mon Sep 17 00:00:00 2001 From: Brady Date: Wed, 25 Dec 2019 01:35:10 -0600 Subject: [PATCH 31/39] Make Schematica respect mapArtMode setting --- src/main/java/baritone/process/BuilderProcess.java | 9 +++++++-- .../utils/schematic/schematica/SchematicAdapter.java | 11 ++++++++--- .../utils/schematic/schematica/SchematicaHelper.java | 4 ++-- 3 files changed, 17 insertions(+), 7 deletions(-) diff --git a/src/main/java/baritone/process/BuilderProcess.java b/src/main/java/baritone/process/BuilderProcess.java index 553616020..5cbc3da70 100644 --- a/src/main/java/baritone/process/BuilderProcess.java +++ b/src/main/java/baritone/process/BuilderProcess.java @@ -141,9 +141,14 @@ public final class BuilderProcess extends BaritoneProcessHelper implements IBuil @Override public void buildOpenSchematic() { if (SchematicaHelper.isSchematicaPresent()) { - Optional> schematic = SchematicaHelper.getOpenSchematic(); + Optional> schematic = SchematicaHelper.getOpenSchematic(); if (schematic.isPresent()) { - this.build(schematic.get().getFirst().toString(), schematic.get().getFirst(), schematic.get().getSecond()); + IStaticSchematic s = schematic.get().getFirst(); + this.build( + schematic.get().getFirst().toString(), + Baritone.settings().mapArtMode.value ? new MapArtSchematic(s) : s, + schematic.get().getSecond() + ); } else { logDirect("No schematic currently open"); } diff --git a/src/main/java/baritone/utils/schematic/schematica/SchematicAdapter.java b/src/main/java/baritone/utils/schematic/schematica/SchematicAdapter.java index cd1e789f3..0ae3edabf 100644 --- a/src/main/java/baritone/utils/schematic/schematica/SchematicAdapter.java +++ b/src/main/java/baritone/utils/schematic/schematica/SchematicAdapter.java @@ -17,14 +17,14 @@ package baritone.utils.schematic.schematica; -import baritone.api.schematic.ISchematic; +import baritone.api.schematic.IStaticSchematic; import com.github.lunatrius.schematica.client.world.SchematicWorld; import net.minecraft.block.state.IBlockState; import net.minecraft.util.math.BlockPos; import java.util.List; -public final class SchematicAdapter implements ISchematic { +public final class SchematicAdapter implements IStaticSchematic { private final SchematicWorld schematic; @@ -34,7 +34,12 @@ public final class SchematicAdapter implements ISchematic { @Override public IBlockState desiredState(int x, int y, int z, IBlockState current, List approxPlaceable) { - return schematic.getSchematic().getBlockState(new BlockPos(x, y, z)); + return this.getDirect(x, y, z); + } + + @Override + public IBlockState getDirect(int x, int y, int z) { + return this.schematic.getSchematic().getBlockState(new BlockPos(x, y, z)); } @Override diff --git a/src/main/java/baritone/utils/schematic/schematica/SchematicaHelper.java b/src/main/java/baritone/utils/schematic/schematica/SchematicaHelper.java index 85b3967f5..fab688455 100644 --- a/src/main/java/baritone/utils/schematic/schematica/SchematicaHelper.java +++ b/src/main/java/baritone/utils/schematic/schematica/SchematicaHelper.java @@ -17,7 +17,7 @@ package baritone.utils.schematic.schematica; -import baritone.api.schematic.ISchematic; +import baritone.api.schematic.IStaticSchematic; import com.github.lunatrius.schematica.Schematica; import com.github.lunatrius.schematica.proxy.ClientProxy; import net.minecraft.util.Tuple; @@ -37,7 +37,7 @@ public enum SchematicaHelper { } } - public static Optional> getOpenSchematic() { + public static Optional> getOpenSchematic() { return Optional.ofNullable(ClientProxy.schematic) .map(world -> new Tuple<>(new SchematicAdapter(world), world.position)); } From 812bc0d8c40ebe56cd637280e0d412190d1f4f7d Mon Sep 17 00:00:00 2001 From: Brady Date: Fri, 27 Dec 2019 01:14:31 -0600 Subject: [PATCH 32/39] Remove redundant parser layer --- .../schematic/format/ISchematicFormat.java | 6 +- .../api/schematic/parse/ISchematicParser.java | 32 ----- .../java/baritone/process/BuilderProcess.java | 2 +- .../format/DefaultSchematicFormats.java | 43 +++++-- .../format/defaults/MCEditSchematic.java | 69 ++++++++++ .../defaults/SpongeSchematic.java} | 119 +++++++----------- .../utils/schematic/parse/MCEditParser.java | 86 ------------- 7 files changed, 149 insertions(+), 208 deletions(-) delete mode 100644 src/api/java/baritone/api/schematic/parse/ISchematicParser.java create mode 100644 src/main/java/baritone/utils/schematic/format/defaults/MCEditSchematic.java rename src/main/java/baritone/utils/schematic/{parse/SpongeParser.java => format/defaults/SpongeSchematic.java} (53%) delete mode 100644 src/main/java/baritone/utils/schematic/parse/MCEditParser.java diff --git a/src/api/java/baritone/api/schematic/format/ISchematicFormat.java b/src/api/java/baritone/api/schematic/format/ISchematicFormat.java index 260ab4536..3fe045bcf 100644 --- a/src/api/java/baritone/api/schematic/format/ISchematicFormat.java +++ b/src/api/java/baritone/api/schematic/format/ISchematicFormat.java @@ -18,9 +18,11 @@ package baritone.api.schematic.format; import baritone.api.schematic.ISchematic; -import baritone.api.schematic.parse.ISchematicParser; +import baritone.api.schematic.IStaticSchematic; import java.io.File; +import java.io.IOException; +import java.io.InputStream; /** * The base of a {@link ISchematic} file format @@ -33,7 +35,7 @@ public interface ISchematicFormat { /** * @return The parser for creating schematics of this format */ - ISchematicParser getParser(); + IStaticSchematic parse(InputStream input) throws IOException; /** * @param file The file to check against diff --git a/src/api/java/baritone/api/schematic/parse/ISchematicParser.java b/src/api/java/baritone/api/schematic/parse/ISchematicParser.java deleted file mode 100644 index ab0f12f49..000000000 --- a/src/api/java/baritone/api/schematic/parse/ISchematicParser.java +++ /dev/null @@ -1,32 +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.schematic.parse; - -import baritone.api.schematic.IStaticSchematic; - -import java.io.IOException; -import java.io.InputStream; - -/** - * @author Brady - * @since 12/13/2019 - */ -public interface ISchematicParser { - - IStaticSchematic parse(InputStream input) throws IOException; -} diff --git a/src/main/java/baritone/process/BuilderProcess.java b/src/main/java/baritone/process/BuilderProcess.java index 5cbc3da70..4efa2c954 100644 --- a/src/main/java/baritone/process/BuilderProcess.java +++ b/src/main/java/baritone/process/BuilderProcess.java @@ -124,7 +124,7 @@ public final class BuilderProcess extends BaritoneProcessHelper implements IBuil ISchematic parsed; try { - parsed = format.get().getParser().parse(new FileInputStream(schematic)); + parsed = format.get().parse(new FileInputStream(schematic)); } catch (Exception e) { e.printStackTrace(); return false; diff --git a/src/main/java/baritone/utils/schematic/format/DefaultSchematicFormats.java b/src/main/java/baritone/utils/schematic/format/DefaultSchematicFormats.java index 494d6ec8d..942bd72a3 100644 --- a/src/main/java/baritone/utils/schematic/format/DefaultSchematicFormats.java +++ b/src/main/java/baritone/utils/schematic/format/DefaultSchematicFormats.java @@ -17,13 +17,17 @@ package baritone.utils.schematic.format; +import baritone.api.schematic.IStaticSchematic; import baritone.api.schematic.format.ISchematicFormat; -import baritone.api.schematic.parse.ISchematicParser; -import baritone.utils.schematic.parse.MCEditParser; -import baritone.utils.schematic.parse.SpongeParser; +import baritone.utils.schematic.format.defaults.MCEditSchematic; +import baritone.utils.schematic.format.defaults.SpongeSchematic; +import net.minecraft.nbt.CompressedStreamTools; +import net.minecraft.nbt.NBTTagCompound; import org.apache.commons.io.FilenameUtils; import java.io.File; +import java.io.IOException; +import java.io.InputStream; /** * Default implementations of {@link ISchematicFormat} @@ -36,26 +40,39 @@ public enum DefaultSchematicFormats implements ISchematicFormat { /** * The MCEdit schematic specification. Commonly denoted by the ".schematic" file extension. */ - MCEDIT("schematic", MCEditParser.INSTANCE), + MCEDIT("schematic") { + + @Override + public IStaticSchematic parse(InputStream input) throws IOException { + return new MCEditSchematic(CompressedStreamTools.readCompressed(input)); + } + }, /** * The SpongePowered Schematic Specification. Commonly denoted by the ".schem" file extension. * * @see Sponge Schematic Specification */ - SPONGE("schem", SpongeParser.INSTANCE); + SPONGE("schem") { + + @Override + public IStaticSchematic parse(InputStream input) throws IOException { + NBTTagCompound nbt = CompressedStreamTools.readCompressed(input); + int version = nbt.getInteger("Version"); + switch (version) { + case 1: + case 2: + return new SpongeSchematic(nbt); + default: + throw new UnsupportedOperationException("Unsupported Version of a Sponge Schematic"); + } + } + }; private final String extension; - private final ISchematicParser parser; - DefaultSchematicFormats(String extension, ISchematicParser parser) { + DefaultSchematicFormats(String extension) { this.extension = extension; - this.parser = parser; - } - - @Override - public final ISchematicParser getParser() { - return this.parser; } @Override diff --git a/src/main/java/baritone/utils/schematic/format/defaults/MCEditSchematic.java b/src/main/java/baritone/utils/schematic/format/defaults/MCEditSchematic.java new file mode 100644 index 000000000..08e571c96 --- /dev/null +++ b/src/main/java/baritone/utils/schematic/format/defaults/MCEditSchematic.java @@ -0,0 +1,69 @@ +/* + * 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.schematic.format.defaults; + +import baritone.utils.schematic.StaticSchematic; +import net.minecraft.block.Block; +import net.minecraft.block.state.IBlockState; +import net.minecraft.nbt.NBTTagCompound; + +/** + * @author Brady + * @since 12/27/2019 + */ +public final class MCEditSchematic extends StaticSchematic { + + public MCEditSchematic(NBTTagCompound schematic) { + String type = schematic.getString("Materials"); + if (!type.equals("Alpha")) { + throw new IllegalStateException("bad schematic " + type); + } + this.x = schematic.getInteger("Width"); + this.y = schematic.getInteger("Height"); + this.z = schematic.getInteger("Length"); + byte[] blocks = schematic.getByteArray("Blocks"); + byte[] metadata = schematic.getByteArray("Data"); + + byte[] additional = null; + if (schematic.hasKey("AddBlocks")) { + byte[] addBlocks = schematic.getByteArray("AddBlocks"); + additional = new byte[addBlocks.length * 2]; + for (int i = 0; i < addBlocks.length; i++) { + additional[i * 2 + 0] = (byte) ((addBlocks[i] >> 4) & 0xF); // lower nibble + additional[i * 2 + 1] = (byte) ((addBlocks[i] >> 0) & 0xF); // upper nibble + } + } + this.states = new IBlockState[this.x][this.z][this.y]; + for (int y = 0; y < this.y; y++) { + for (int z = 0; z < this.z; z++) { + for (int x = 0; x < this.x; x++) { + int blockInd = (y * this.z + z) * this.x + x; + + int blockID = blocks[blockInd] & 0xFF; + if (additional != null) { + // additional is 0 through 15 inclusive since it's & 0xF above + blockID |= additional[blockInd] << 8; + } + Block block = Block.REGISTRY.getObjectById(blockID); + int meta = metadata[blockInd] & 0xFF; + this.states[x][z][y] = block.getStateFromMeta(meta); + } + } + } + } +} diff --git a/src/main/java/baritone/utils/schematic/parse/SpongeParser.java b/src/main/java/baritone/utils/schematic/format/defaults/SpongeSchematic.java similarity index 53% rename from src/main/java/baritone/utils/schematic/parse/SpongeParser.java rename to src/main/java/baritone/utils/schematic/format/defaults/SpongeSchematic.java index 255916d18..0d03e5d87 100644 --- a/src/main/java/baritone/utils/schematic/parse/SpongeParser.java +++ b/src/main/java/baritone/utils/schematic/format/defaults/SpongeSchematic.java @@ -15,22 +15,17 @@ * along with Baritone. If not, see . */ -package baritone.utils.schematic.parse; +package baritone.utils.schematic.format.defaults; -import baritone.api.schematic.parse.ISchematicParser; import baritone.utils.schematic.StaticSchematic; -import baritone.utils.schematic.format.DefaultSchematicFormats; import baritone.utils.type.VarInt; import it.unimi.dsi.fastutil.ints.Int2ObjectArrayMap; import net.minecraft.block.Block; import net.minecraft.block.properties.IProperty; import net.minecraft.block.state.IBlockState; -import net.minecraft.nbt.CompressedStreamTools; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.util.ResourceLocation; -import java.io.IOException; -import java.io.InputStream; import java.util.HashMap; import java.util.Map; import java.util.Optional; @@ -38,83 +33,59 @@ import java.util.regex.Matcher; import java.util.regex.Pattern; /** - * An implementation of {@link ISchematicParser} for {@link DefaultSchematicFormats#SPONGE} - * * @author Brady - * @since 12/16/2019 + * @since 12/27/2019 */ -public enum SpongeParser implements ISchematicParser { - INSTANCE; +public final class SpongeSchematic extends StaticSchematic { - @Override - public StaticSchematic parse(InputStream input) throws IOException { - NBTTagCompound nbt = CompressedStreamTools.readCompressed(input); - int version = nbt.getInteger("Version"); - switch (version) { - case 1: - case 2: - return new SpongeSchematic(nbt); - default: - throw new UnsupportedOperationException("Unsupported Version of a Sponge Schematic"); + public SpongeSchematic(NBTTagCompound nbt) { + this.x = nbt.getInteger("Width"); + this.y = nbt.getInteger("Height"); + this.z = nbt.getInteger("Length"); + this.states = new IBlockState[this.x][this.z][this.y]; + + Int2ObjectArrayMap palette = new Int2ObjectArrayMap<>(); + NBTTagCompound paletteTag = nbt.getCompoundTag("Palette"); + for (String tag : paletteTag.getKeySet()) { + int index = paletteTag.getInteger(tag); + + SerializedBlockState serializedState = SerializedBlockState.getFromString(tag); + if (serializedState == null) { + throw new IllegalArgumentException("Unable to parse palette tag"); + } + + IBlockState state = serializedState.deserialize(); + if (state == null) { + throw new IllegalArgumentException("Unable to deserialize palette tag"); + } + + palette.put(index, state); } - } - /** - * Implementation of the Sponge Schematic Format supporting both V1 and V2. (For the current - * use case, there is no difference between reading a V1 and V2 schematic). - */ - private static final class SpongeSchematic extends StaticSchematic { - - - SpongeSchematic(NBTTagCompound nbt) { - this.x = nbt.getInteger("Width"); - this.y = nbt.getInteger("Height"); - this.z = nbt.getInteger("Length"); - this.states = new IBlockState[this.x][this.z][this.y]; - - Int2ObjectArrayMap palette = new Int2ObjectArrayMap<>(); - NBTTagCompound paletteTag = nbt.getCompoundTag("Palette"); - for (String tag : paletteTag.getKeySet()) { - int index = paletteTag.getInteger(tag); - - SerializedBlockState serializedState = SerializedBlockState.getFromString(tag); - if (serializedState == null) { - throw new IllegalArgumentException("Unable to parse palette tag"); - } - - IBlockState state = serializedState.deserialize(); - if (state == null) { - throw new IllegalArgumentException("Unable to deserialize palette tag"); - } - - palette.put(index, state); + // BlockData is stored as an NBT byte[], however, the actual data that is represented is a varint[] + byte[] rawBlockData = nbt.getByteArray("BlockData"); + int[] blockData = new int[this.x * this.y * this.z]; + int offset = 0; + for (int i = 0; i < blockData.length; i++) { + if (offset >= rawBlockData.length) { + throw new IllegalArgumentException("No remaining bytes in BlockData for complete schematic"); } - // BlockData is stored as an NBT byte[], however, the actual data that is represented is a varint[] - byte[] rawBlockData = nbt.getByteArray("BlockData"); - int[] blockData = new int[this.x * this.y * this.z]; - int offset = 0; - for (int i = 0; i < blockData.length; i++) { - if (offset >= rawBlockData.length) { - throw new IllegalArgumentException("No remaining bytes in BlockData for complete schematic"); - } + VarInt varInt = VarInt.read(rawBlockData, offset); + blockData[i] = varInt.getValue(); + offset += varInt.getSize(); + } - VarInt varInt = VarInt.read(rawBlockData, offset); - blockData[i] = varInt.getValue(); - offset += varInt.getSize(); - } - - for (int y = 0; y < this.y; y++) { - for (int z = 0; z < this.z; z++) { - for (int x = 0; x < this.x; x++) { - int index = (y * this.z + z) * this.x + x; - IBlockState state = palette.get(blockData[index]); - if (state == null) { - throw new IllegalArgumentException("Invalid Palette Index " + index); - } - - this.states[x][z][y] = state; + for (int y = 0; y < this.y; y++) { + for (int z = 0; z < this.z; z++) { + for (int x = 0; x < this.x; x++) { + int index = (y * this.z + z) * this.x + x; + IBlockState state = palette.get(blockData[index]); + if (state == null) { + throw new IllegalArgumentException("Invalid Palette Index " + index); } + + this.states[x][z][y] = state; } } } diff --git a/src/main/java/baritone/utils/schematic/parse/MCEditParser.java b/src/main/java/baritone/utils/schematic/parse/MCEditParser.java deleted file mode 100644 index 3599b824b..000000000 --- a/src/main/java/baritone/utils/schematic/parse/MCEditParser.java +++ /dev/null @@ -1,86 +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.utils.schematic.parse; - -import baritone.api.schematic.parse.ISchematicParser; -import baritone.utils.schematic.StaticSchematic; -import baritone.utils.schematic.format.DefaultSchematicFormats; -import net.minecraft.block.Block; -import net.minecraft.block.state.IBlockState; -import net.minecraft.nbt.CompressedStreamTools; -import net.minecraft.nbt.NBTTagCompound; - -import java.io.IOException; -import java.io.InputStream; - -/** - * An implementation of {@link ISchematicParser} for {@link DefaultSchematicFormats#MCEDIT} - * - * @author Brady - * @since 12/16/2019 - */ -public enum MCEditParser implements ISchematicParser { - INSTANCE; - - @Override - public StaticSchematic parse(InputStream input) throws IOException { - return new MCEditSchematic(CompressedStreamTools.readCompressed(input)); - } - - private static final class MCEditSchematic extends StaticSchematic { - - MCEditSchematic(NBTTagCompound schematic) { - String type = schematic.getString("Materials"); - if (!type.equals("Alpha")) { - throw new IllegalStateException("bad schematic " + type); - } - this.x = schematic.getInteger("Width"); - this.y = schematic.getInteger("Height"); - this.z = schematic.getInteger("Length"); - byte[] blocks = schematic.getByteArray("Blocks"); - byte[] metadata = schematic.getByteArray("Data"); - - byte[] additional = null; - if (schematic.hasKey("AddBlocks")) { - byte[] addBlocks = schematic.getByteArray("AddBlocks"); - additional = new byte[addBlocks.length * 2]; - for (int i = 0; i < addBlocks.length; i++) { - additional[i * 2 + 0] = (byte) ((addBlocks[i] >> 4) & 0xF); // lower nibble - additional[i * 2 + 1] = (byte) ((addBlocks[i] >> 0) & 0xF); // upper nibble - } - } - this.states = new IBlockState[this.x][this.z][this.y]; - for (int y = 0; y < this.y; y++) { - for (int z = 0; z < this.z; z++) { - for (int x = 0; x < this.x; x++) { - int blockInd = (y * this.z + z) * this.x + x; - - int blockID = blocks[blockInd] & 0xFF; - if (additional != null) { - // additional is 0 through 15 inclusive since it's & 0xF above - blockID |= additional[blockInd] << 8; - } - Block block = Block.REGISTRY.getObjectById(blockID); - int meta = metadata[blockInd] & 0xFF; - this.states[x][z][y] = block.getStateFromMeta(meta); - } - } - } - } - } -} From 220ee30d35c8a5f9851903e7b4d791ae5253ffc3 Mon Sep 17 00:00:00 2001 From: Brady Date: Fri, 27 Dec 2019 21:28:05 -0600 Subject: [PATCH 33/39] Appease Codacy --- .../utils/schematic/format/defaults/SpongeSchematic.java | 4 ++-- src/main/java/baritone/utils/type/VarInt.java | 3 ++- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/main/java/baritone/utils/schematic/format/defaults/SpongeSchematic.java b/src/main/java/baritone/utils/schematic/format/defaults/SpongeSchematic.java index 0d03e5d87..8de038f5a 100644 --- a/src/main/java/baritone/utils/schematic/format/defaults/SpongeSchematic.java +++ b/src/main/java/baritone/utils/schematic/format/defaults/SpongeSchematic.java @@ -104,7 +104,7 @@ public final class SpongeSchematic extends StaticSchematic { this.properties = properties; } - IBlockState deserialize() { + private IBlockState deserialize() { if (this.blockState == null) { Block block = Block.REGISTRY.getObject(this.resourceLocation); this.blockState = block.getDefaultState(); @@ -119,7 +119,7 @@ public final class SpongeSchematic extends StaticSchematic { return this.blockState; } - static SerializedBlockState getFromString(String s) { + private static SerializedBlockState getFromString(String s) { Matcher m = REGEX.matcher(s); if (!m.matches()) { return null; diff --git a/src/main/java/baritone/utils/type/VarInt.java b/src/main/java/baritone/utils/type/VarInt.java index 45f83dda1..93b3e4252 100644 --- a/src/main/java/baritone/utils/type/VarInt.java +++ b/src/main/java/baritone/utils/type/VarInt.java @@ -54,9 +54,10 @@ public final class VarInt { return this.serialized; } - private static byte[] serialize0(int value) { + private static byte[] serialize0(int valueIn) { ByteList bytes = new ByteArrayList(); + int value = valueIn; while ((value & 0x80) != 0) { bytes.add((byte) (value & 0x7F | 0x80)); value >>>= 7; From fcfa022232f28627b9aebc78a8b3ddac63ea76aa Mon Sep 17 00:00:00 2001 From: Brady Date: Mon, 30 Dec 2019 02:27:20 -0600 Subject: [PATCH 34/39] Clean up BlockOptionalMeta comment and add behavioral clarification --- .../baritone/api/utils/BlockOptionalMeta.java | 24 +++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) diff --git a/src/api/java/baritone/api/utils/BlockOptionalMeta.java b/src/api/java/baritone/api/utils/BlockOptionalMeta.java index 451d95eb2..020df8146 100644 --- a/src/api/java/baritone/api/utils/BlockOptionalMeta.java +++ b/src/api/java/baritone/api/utils/BlockOptionalMeta.java @@ -188,13 +188,20 @@ public final class BlockOptionalMeta { return (C) value; } + /** + * Normalizes the specified blockstate by setting meta-affecting properties which + * are not being targeted by the meta parameter to their default values. + *

+ * For example, block variant/color is the primary target for the meta value, so properties + * such as rotation/facing direction will be set to default values in order to nullify + * the effect that they have on the state's meta value. + * + * @param state The state to normalize + * @return The normalized block state + */ public static IBlockState normalize(IBlockState state) { IBlockState newState = state; - // TODO: Can the state not be normalized by simply doing...? - // return state.getBlock().getDefaultState(); - // ??? - for (IProperty property : state.getProperties().keySet()) { Class valueClass = property.getValueClass(); if (normalizations.containsKey(property)) { @@ -224,6 +231,15 @@ public final class BlockOptionalMeta { return newState; } + /** + * Evaluate the target meta value for the specified state. The target meta value is + * most often that which is influenced by the variant/color property of the block state. + * + * @see #normalize(IBlockState) + * + * @param state The state to check + * @return The target meta of the state + */ public static int stateMeta(IBlockState state) { return state.getBlock().getMetaFromState(normalize(state)); } From bbb25acff3b8c118ae9853ab5ac35ebd5a29ed77 Mon Sep 17 00:00:00 2001 From: FTC55 Date: Tue, 31 Dec 2019 19:16:31 +0100 Subject: [PATCH 35/39] Fixed the bug, merged CancelCommand into ExecutionControlCommands --- .../command/defaults/CancelCommand.java | 61 ------------------- ...nds.java => ExecutionControlCommands.java} | 32 ++++++++++ 2 files changed, 32 insertions(+), 61 deletions(-) delete mode 100644 src/main/java/baritone/command/defaults/CancelCommand.java rename src/main/java/baritone/command/defaults/{PauseResumeCommands.java => ExecutionControlCommands.java} (84%) diff --git a/src/main/java/baritone/command/defaults/CancelCommand.java b/src/main/java/baritone/command/defaults/CancelCommand.java deleted file mode 100644 index 3b4c63670..000000000 --- a/src/main/java/baritone/command/defaults/CancelCommand.java +++ /dev/null @@ -1,61 +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.command.Command; -import baritone.api.command.exception.CommandException; -import baritone.api.command.argument.IArgConsumer; - -import java.util.Arrays; -import java.util.List; -import java.util.stream.Stream; - -public class CancelCommand extends Command { - - public CancelCommand(IBaritone baritone) { - super(baritone, "cancel", "stop"); - } - - @Override - public void execute(String label, IArgConsumer args) throws CommandException { - args.requireMax(0); - baritone.getPathingBehavior().cancelEverything(); - logDirect("ok canceled"); - } - - @Override - public Stream tabComplete(String label, IArgConsumer args) { - return Stream.empty(); - } - - @Override - public String getShortDesc() { - return "Cancel what Baritone is currently doing"; - } - - @Override - public List getLongDesc() { - return Arrays.asList( - "The cancel command tells Baritone to stop whatever it's currently doing.", - "", - "Usage:", - "> cancel" - ); - } -} diff --git a/src/main/java/baritone/command/defaults/PauseResumeCommands.java b/src/main/java/baritone/command/defaults/ExecutionControlCommands.java similarity index 84% rename from src/main/java/baritone/command/defaults/PauseResumeCommands.java rename to src/main/java/baritone/command/defaults/ExecutionControlCommands.java index 54718e9b7..376b8f433 100644 --- a/src/main/java/baritone/command/defaults/PauseResumeCommands.java +++ b/src/main/java/baritone/command/defaults/ExecutionControlCommands.java @@ -42,6 +42,7 @@ public class PauseResumeCommands { Command pauseCommand; Command resumeCommand; Command pausedCommand; + Command cancelCommand; public PauseResumeCommands(IBaritone baritone) { // array for mutability, non-field so reflection can't touch it @@ -169,5 +170,36 @@ public class PauseResumeCommands { ); } }; + cancelCommand = new Command(baritone, "cancel", "stop") { + @Override + public void execute(String label, IArgConsumer args) throws CommandException { + args.requireMax(0); + if (paused[0]) { + paused[0] = false; + } + baritone.getPathingBehavior().cancelEverything(); + logDirect("ok canceled"); + } + + @Override + public Stream tabComplete(String label, IArgConsumer args) { + return Stream.empty(); + } + + @Override + public String getShortDesc() { + return "Cancel what Baritone is currently doing"; + } + + @Override + public List getLongDesc() { + return Arrays.asList( + "The cancel command tells Baritone to stop whatever it's currently doing.", + "", + "Usage:", + "> cancel" + ); + } + }; } } From 4b10904b97ea5cc0c36f4d33559f93db2ffa13b3 Mon Sep 17 00:00:00 2001 From: FTC55 Date: Tue, 31 Dec 2019 19:43:54 +0100 Subject: [PATCH 36/39] Git missed some changes. Autoreformatted files. --- .../command/defaults/DefaultCommands.java | 77 ++++++++++--------- 1 file changed, 39 insertions(+), 38 deletions(-) diff --git a/src/main/java/baritone/command/defaults/DefaultCommands.java b/src/main/java/baritone/command/defaults/DefaultCommands.java index c48644e3b..67555ed51 100644 --- a/src/main/java/baritone/command/defaults/DefaultCommands.java +++ b/src/main/java/baritone/command/defaults/DefaultCommands.java @@ -24,52 +24,53 @@ import java.util.*; public final class DefaultCommands { - private DefaultCommands() {} + private DefaultCommands() { + } public static List createAll(IBaritone baritone) { Objects.requireNonNull(baritone); List commands = new ArrayList<>(Arrays.asList( - new HelpCommand(baritone), - new SetCommand(baritone), - new CommandAlias(baritone, Arrays.asList("modified", "mod", "baritone", "modifiedsettings"), "List modified settings", "set modified"), - new CommandAlias(baritone, "reset", "Reset all settings or just one", "set reset"), - new GoalCommand(baritone), - new GotoCommand(baritone), - new PathCommand(baritone), - new ProcCommand(baritone), - new VersionCommand(baritone), - new RepackCommand(baritone), - new BuildCommand(baritone), - new SchematicaCommand(baritone), - new ComeCommand(baritone), - new AxisCommand(baritone), - new CancelCommand(baritone), - new ForceCancelCommand(baritone), - new GcCommand(baritone), - new InvertCommand(baritone), - new TunnelCommand(baritone), - new RenderCommand(baritone), - new FarmCommand(baritone), - new ChestsCommand(baritone), - new FollowCommand(baritone), - new ExploreFilterCommand(baritone), - new ReloadAllCommand(baritone), - new SaveAllCommand(baritone), - new ExploreCommand(baritone), - new BlacklistCommand(baritone), - new FindCommand(baritone), - new MineCommand(baritone), - new ClickCommand(baritone), - new ThisWayCommand(baritone), - new WaypointsCommand(baritone), - new CommandAlias(baritone, "sethome", "Sets your home waypoint", "waypoints save home"), - new CommandAlias(baritone, "home", "Set goal to your home waypoint", "waypoints goal home"), - new SelCommand(baritone) + new HelpCommand(baritone), + new SetCommand(baritone), + new CommandAlias(baritone, Arrays.asList("modified", "mod", "baritone", "modifiedsettings"), "List modified settings", "set modified"), + new CommandAlias(baritone, "reset", "Reset all settings or just one", "set reset"), + new GoalCommand(baritone), + new GotoCommand(baritone), + new PathCommand(baritone), + new ProcCommand(baritone), + new VersionCommand(baritone), + new RepackCommand(baritone), + new BuildCommand(baritone), + new SchematicaCommand(baritone), + new ComeCommand(baritone), + new AxisCommand(baritone), + new ForceCancelCommand(baritone), + new GcCommand(baritone), + new InvertCommand(baritone), + new TunnelCommand(baritone), + new RenderCommand(baritone), + new FarmCommand(baritone), + new ChestsCommand(baritone), + new FollowCommand(baritone), + new ExploreFilterCommand(baritone), + new ReloadAllCommand(baritone), + new SaveAllCommand(baritone), + new ExploreCommand(baritone), + new BlacklistCommand(baritone), + new FindCommand(baritone), + new MineCommand(baritone), + new ClickCommand(baritone), + new ThisWayCommand(baritone), + new WaypointsCommand(baritone), + new CommandAlias(baritone, "sethome", "Sets your home waypoint", "waypoints save home"), + new CommandAlias(baritone, "home", "Set goal to your home waypoint", "waypoints goal home"), + new SelCommand(baritone) )); - PauseResumeCommands prc = new PauseResumeCommands(baritone); + ExecutionControlCommands prc = new ExecutionControlCommands(baritone); commands.add(prc.pauseCommand); commands.add(prc.resumeCommand); commands.add(prc.pausedCommand); + commands.add(prc.cancelCommand); return Collections.unmodifiableList(commands); } } From 04190af34049495bbaef5f9230d0cf3f9f5c7a05 Mon Sep 17 00:00:00 2001 From: FTC55 Date: Tue, 31 Dec 2019 19:45:08 +0100 Subject: [PATCH 37/39] ...more than I thought. Autoreformatted file x2 --- .../defaults/ExecutionControlCommands.java | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/src/main/java/baritone/command/defaults/ExecutionControlCommands.java b/src/main/java/baritone/command/defaults/ExecutionControlCommands.java index 376b8f433..4a04b9e09 100644 --- a/src/main/java/baritone/command/defaults/ExecutionControlCommands.java +++ b/src/main/java/baritone/command/defaults/ExecutionControlCommands.java @@ -18,13 +18,13 @@ package baritone.command.defaults; import baritone.api.IBaritone; +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.process.IBaritoneProcess; import baritone.api.process.PathingCommand; import baritone.api.process.PathingCommandType; -import baritone.api.command.Command; -import baritone.api.command.exception.CommandException; -import baritone.api.command.exception.CommandInvalidStateException; -import baritone.api.command.argument.IArgConsumer; import java.util.Arrays; import java.util.List; @@ -37,14 +37,14 @@ import java.util.stream.Stream; * TO USE THIS to pause and resume Baritone. Make your own process that returns {@link PathingCommandType#REQUEST_PAUSE * REQUEST_PAUSE} as needed. */ -public class PauseResumeCommands { +public class ExecutionControlCommands { Command pauseCommand; Command resumeCommand; Command pausedCommand; Command cancelCommand; - public PauseResumeCommands(IBaritone baritone) { + public ExecutionControlCommands(IBaritone baritone) { // array for mutability, non-field so reflection can't touch it final boolean[] paused = {false}; baritone.getPathingControlManager().registerProcess( @@ -65,7 +65,8 @@ public class PauseResumeCommands { } @Override - public void onLostControl() {} + public void onLostControl() { + } @Override public double priority() { From 4a05837b01cb04e28a73b114f6c035033d218454 Mon Sep 17 00:00:00 2001 From: Brady Date: Tue, 31 Dec 2019 17:44:20 -0600 Subject: [PATCH 38/39] Requested changes --- src/main/java/baritone/utils/type/VarInt.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/baritone/utils/type/VarInt.java b/src/main/java/baritone/utils/type/VarInt.java index 93b3e4252..7cc005bdb 100644 --- a/src/main/java/baritone/utils/type/VarInt.java +++ b/src/main/java/baritone/utils/type/VarInt.java @@ -85,7 +85,7 @@ public final class VarInt { } // Most significant bit denotes another byte is to be read. - if ((b & 0x80) != 0x80) { + if ((b & 0x80) == 0) { break; } } From e3d3407de5b1f2dfda8d3a476fdd4a13e1fa6e43 Mon Sep 17 00:00:00 2001 From: Brady Date: Tue, 31 Dec 2019 19:44:44 -0600 Subject: [PATCH 39/39] Remove normalizations from BlockOptionalMeta --- .../baritone/api/utils/BlockOptionalMeta.java | 157 ------------------ 1 file changed, 157 deletions(-) diff --git a/src/api/java/baritone/api/utils/BlockOptionalMeta.java b/src/api/java/baritone/api/utils/BlockOptionalMeta.java index 936b56e12..d5ecb395d 100644 --- a/src/api/java/baritone/api/utils/BlockOptionalMeta.java +++ b/src/api/java/baritone/api/utils/BlockOptionalMeta.java @@ -42,7 +42,6 @@ public final class BlockOptionalMeta { private final ImmutableSet stateHashes; private final ImmutableSet stackHashes; private static final Pattern pattern = Pattern.compile("^(.+?)(?::(\\d+))?$"); - private static final Map normalizations; public BlockOptionalMeta(@Nonnull Block block) { this.block = block; @@ -72,162 +71,6 @@ public final class BlockOptionalMeta { stackHashes = getStackHashes(blockstates); } - static { - Map _normalizations = new HashMap<>(); - Consumer put = instance -> _normalizations.put(instance.getClass(), instance); - put.accept(EnumFacing.NORTH); - put.accept(EnumFacing.Axis.Y); - put.accept(Half.BOTTOM); - put.accept(StairsShape.STRAIGHT); - put.accept(AttachFace.FLOOR); - put.accept(DoubleBlockHalf.UPPER); - put.accept(SlabType.BOTTOM); - put.accept(DoorHingeSide.LEFT); - put.accept(BedPart.HEAD); - put.accept(RailShape.NORTH_SOUTH); - _normalizations.put(BlockBanner.ROTATION, 0); - _normalizations.put(BlockBed.OCCUPIED, false); - _normalizations.put(BlockBrewingStand.HAS_BOTTLE[0], false); - _normalizations.put(BlockBrewingStand.HAS_BOTTLE[1], false); - _normalizations.put(BlockBrewingStand.HAS_BOTTLE[2], false); - _normalizations.put(BlockButton.POWERED, false); - // _normalizations.put(BlockCactus.AGE, 0); - // _normalizations.put(BlockCauldron.LEVEL, 0); - // _normalizations.put(BlockChorusFlower.AGE, 0); - _normalizations.put(BlockChorusPlant.NORTH, false); - _normalizations.put(BlockChorusPlant.EAST, false); - _normalizations.put(BlockChorusPlant.SOUTH, false); - _normalizations.put(BlockChorusPlant.WEST, false); - _normalizations.put(BlockChorusPlant.UP, false); - _normalizations.put(BlockChorusPlant.DOWN, false); - // _normalizations.put(BlockCocoa.AGE, 0); - // _normalizations.put(BlockCrops.AGE, 0); - _normalizations.put(BlockDirtSnowy.SNOWY, false); - _normalizations.put(BlockDoor.OPEN, false); - _normalizations.put(BlockDoor.POWERED, false); - // _normalizations.put(BlockFarmland.MOISTURE, 0); - _normalizations.put(BlockFence.NORTH, false); - _normalizations.put(BlockFence.EAST, false); - _normalizations.put(BlockFence.WEST, false); - _normalizations.put(BlockFence.SOUTH, false); - // _normalizations.put(BlockFenceGate.POWERED, false); - // _normalizations.put(BlockFenceGate.IN_WALL, false); - _normalizations.put(BlockFire.AGE, 0); - _normalizations.put(BlockFire.NORTH, false); - _normalizations.put(BlockFire.EAST, false); - _normalizations.put(BlockFire.SOUTH, false); - _normalizations.put(BlockFire.WEST, false); - _normalizations.put(BlockFire.UP, false); - // _normalizations.put(BlockFrostedIce.AGE, 0); - _normalizations.put(BlockGrass.SNOWY, false); - // _normalizations.put(BlockHopper.ENABLED, true); - // _normalizations.put(BlockLever.POWERED, false); - // _normalizations.put(BlockLiquid.LEVEL, 0); - // _normalizations.put(BlockMycelium.SNOWY, false); - // _normalizations.put(BlockNetherWart.AGE, false); - _normalizations.put(BlockLeaves.DISTANCE, false); - // _normalizations.put(BlockLeaves.DECAYABLE, false); - // _normalizations.put(BlockObserver.POWERED, false); - _normalizations.put(BlockPane.NORTH, false); - _normalizations.put(BlockPane.EAST, false); - _normalizations.put(BlockPane.WEST, false); - _normalizations.put(BlockPane.SOUTH, false); - // _normalizations.put(BlockPistonBase.EXTENDED, false); - // _normalizations.put(BlockPressurePlate.POWERED, false); - // _normalizations.put(BlockPressurePlateWeighted.POWER, false); - // _normalizations.put(BlockRailDetector.POWERED, false); - // _normalizations.put(BlockRailPowered.POWERED, false); - _normalizations.put(BlockRedstoneWire.NORTH, false); - _normalizations.put(BlockRedstoneWire.EAST, false); - _normalizations.put(BlockRedstoneWire.SOUTH, false); - _normalizations.put(BlockRedstoneWire.WEST, false); - // _normalizations.put(BlockReed.AGE, false); - _normalizations.put(BlockSapling.STAGE, 0); - _normalizations.put(BlockStandingSign.ROTATION, 0); - _normalizations.put(BlockStem.AGE, 0); - _normalizations.put(BlockTripWire.NORTH, false); - _normalizations.put(BlockTripWire.EAST, false); - _normalizations.put(BlockTripWire.WEST, false); - _normalizations.put(BlockTripWire.SOUTH, false); - _normalizations.put(BlockVine.NORTH, false); - _normalizations.put(BlockVine.EAST, false); - _normalizations.put(BlockVine.SOUTH, false); - _normalizations.put(BlockVine.WEST, false); - _normalizations.put(BlockVine.UP, false); - _normalizations.put(BlockWall.UP, false); - _normalizations.put(BlockWall.NORTH, false); - _normalizations.put(BlockWall.EAST, false); - _normalizations.put(BlockWall.WEST, false); - _normalizations.put(BlockWall.SOUTH, false); - normalizations = Collections.unmodifiableMap(_normalizations); - } - - public static , P extends IProperty> P castToIProperty(Object value) { - //noinspection unchecked - return (P) value; - } - - public static , P extends IProperty> C castToIPropertyValue(P iproperty, Object value) { - //noinspection unchecked - return (C) value; - } - - /** - * Normalizes the specified blockstate by setting meta-affecting properties which - * are not being targeted by the meta parameter to their default values. - *

- * For example, block variant/color is the primary target for the meta value, so properties - * such as rotation/facing direction will be set to default values in order to nullify - * the effect that they have on the state's meta value. - * - * @param state The state to normalize - * @return The normalized block state - */ - public static IBlockState normalize(IBlockState state) { - IBlockState newState = state; - - for (IProperty property : state.getProperties()) { - Class valueClass = property.getValueClass(); - if (normalizations.containsKey(property)) { - try { - newState = newState.with( - castToIProperty(property), - castToIPropertyValue(property, normalizations.get(property)) - ); - } catch (IllegalArgumentException ignored) {} - } else if (normalizations.containsKey(state.get(property))) { - try { - newState = newState.with( - castToIProperty(property), - castToIPropertyValue(property, normalizations.get(state.get(property))) - ); - } catch (IllegalArgumentException ignored) {} - } else if (normalizations.containsKey(valueClass)) { - try { - newState = newState.with( - castToIProperty(property), - castToIPropertyValue(property, normalizations.get(valueClass)) - ); - } catch (IllegalArgumentException ignored) {} - } - } - - return newState; - } - - /** - * Evaluate the target meta value for the specified state. The target meta value is - * most often that which is influenced by the variant/color property of the block state. - * - * @see #normalize(IBlockState) - * - * @param state The state to check - * @return The target meta of the state - */ - public static int stateMeta(IBlockState state) { - return state.hashCode(); - } - private static Set getStates(@Nonnull Block block) { return new HashSet<>(block.getStateContainer().getValidStates()); }