From a64e07685b1eb83471846e3dd07ee172bd1cd5d8 Mon Sep 17 00:00:00 2001 From: Leijurv Date: Tue, 21 Aug 2018 11:54:55 -0700 Subject: [PATCH 01/10] lazy chunk loading --- .../java/baritone/bot/chunk/CachedWorld.java | 2 +- .../bot/chunk/CachedWorldProvider.java | 19 ------------------- 2 files changed, 1 insertion(+), 20 deletions(-) diff --git a/src/main/java/baritone/bot/chunk/CachedWorld.java b/src/main/java/baritone/bot/chunk/CachedWorld.java index f8b2c216..d5c5c04a 100644 --- a/src/main/java/baritone/bot/chunk/CachedWorld.java +++ b/src/main/java/baritone/bot/chunk/CachedWorld.java @@ -53,7 +53,7 @@ public final class CachedWorld implements ICachedChunkAccess { @Override public final PathingBlockType getBlockType(int x, int y, int z) { - CachedRegion region = getRegion(x >> 9, z >> 9); + CachedRegion region = getOrCreateRegion(x >> 9, z >> 9); if (region != null) { return region.getBlockType(x & 511, y, z & 511); } diff --git a/src/main/java/baritone/bot/chunk/CachedWorldProvider.java b/src/main/java/baritone/bot/chunk/CachedWorldProvider.java index e5ff7509..e6062d6d 100644 --- a/src/main/java/baritone/bot/chunk/CachedWorldProvider.java +++ b/src/main/java/baritone/bot/chunk/CachedWorldProvider.java @@ -31,8 +31,6 @@ import java.nio.file.Path; import java.util.HashMap; import java.util.Map; import java.util.function.Consumer; -import java.util.regex.Matcher; -import java.util.regex.Pattern; /** * @author Brady @@ -42,8 +40,6 @@ public enum CachedWorldProvider implements Helper { INSTANCE; - private static final Pattern REGION_REGEX = Pattern.compile("r\\.(-?[0-9]+)\\.(-?[0-9]+)\\.bcr"); - private final Map singlePlayerWorldCache = new HashMap<>(); private CachedWorld currentWorld; @@ -68,21 +64,6 @@ public enum CachedWorldProvider implements Helper { } this.currentWorld = this.singlePlayerWorldCache.computeIfAbsent(dir.toString(), CachedWorld::new); - - try { - Files.list(dir).forEach(path -> { - String file = path.getFileName().toString(); - Matcher matcher = REGION_REGEX.matcher(file); - if (matcher.matches()) { - int rx = Integer.parseInt(matcher.group(1)); - int ry = Integer.parseInt(matcher.group(2)); - // Recognize the region for when we load from file - this.currentWorld.getOrCreateRegion(rx, ry); - } - }); - } catch (Exception ignored) {} - - this.currentWorld.load(); } // TODO: Store server worlds } From 800078a75cfda321d1aebb6250af272e23e91cc7 Mon Sep 17 00:00:00 2001 From: Leijurv Date: Tue, 21 Aug 2018 12:18:54 -0700 Subject: [PATCH 02/10] only gzip changed regions --- .../java/baritone/bot/chunk/CachedRegion.java | 14 +++++++++++++- .../java/baritone/bot/chunk/CachedWorld.java | 16 ++-------------- 2 files changed, 15 insertions(+), 15 deletions(-) diff --git a/src/main/java/baritone/bot/chunk/CachedRegion.java b/src/main/java/baritone/bot/chunk/CachedRegion.java index b7bc3580..b0cda611 100644 --- a/src/main/java/baritone/bot/chunk/CachedRegion.java +++ b/src/main/java/baritone/bot/chunk/CachedRegion.java @@ -17,8 +17,8 @@ package baritone.bot.chunk; -import baritone.bot.utils.pathing.PathingBlockType; import baritone.bot.utils.GZIPUtils; +import baritone.bot.utils.pathing.PathingBlockType; import java.io.FileInputStream; import java.io.FileOutputStream; @@ -52,9 +52,15 @@ public final class CachedRegion implements ICachedChunkAccess { */ private final int z; + /** + * Has this region been modified since its most recent load or save + */ + private boolean hasUnsavedChanges; + CachedRegion(int x, int z) { this.x = x; this.z = z; + this.hasUnsavedChanges = false; } @Override @@ -74,6 +80,7 @@ public final class CachedRegion implements ICachedChunkAccess { } else { chunk.updateContents(data); } + hasUnsavedChanges = true; } private CachedChunk getChunk(int chunkX, int chunkZ) { @@ -92,6 +99,9 @@ public final class CachedRegion implements ICachedChunkAccess { } public final void save(String directory) { + if (!hasUnsavedChanges) { + return; + } try { Path path = Paths.get(directory); if (!Files.exists(path)) @@ -115,6 +125,7 @@ public final class CachedRegion implements ICachedChunkAccess { } } } + hasUnsavedChanges = false; } catch (IOException ignored) {} } @@ -148,6 +159,7 @@ public final class CachedRegion implements ICachedChunkAccess { } } } + hasUnsavedChanges = false; } catch (IOException ignored) {} } diff --git a/src/main/java/baritone/bot/chunk/CachedWorld.java b/src/main/java/baritone/bot/chunk/CachedWorld.java index d5c5c04a..eb7513a3 100644 --- a/src/main/java/baritone/bot/chunk/CachedWorld.java +++ b/src/main/java/baritone/bot/chunk/CachedWorld.java @@ -54,18 +54,13 @@ public final class CachedWorld implements ICachedChunkAccess { @Override public final PathingBlockType getBlockType(int x, int y, int z) { CachedRegion region = getOrCreateRegion(x >> 9, z >> 9); - if (region != null) { - return region.getBlockType(x & 511, y, z & 511); - } - return null; + return region.getBlockType(x & 511, y, z & 511); } @Override public final void updateCachedChunk(int chunkX, int chunkZ, BitSet data) { CachedRegion region = getOrCreateRegion(chunkX >> 5, chunkZ >> 5); - if (region != null) { - region.updateCachedChunk(chunkX & 31, chunkZ & 31, data); - } + region.updateCachedChunk(chunkX & 31, chunkZ & 31, data); } public final void save() { @@ -75,13 +70,6 @@ public final class CachedWorld implements ICachedChunkAccess { }); } - public final void load() { - this.cachedRegions.values().forEach(region -> { - if (region != null) - region.load(this.directory); - }); - } - /** * Returns the region at the specified region coordinates * From 5bc8adc7771aaedb01f456fd1e560be3b927ed20 Mon Sep 17 00:00:00 2001 From: Leijurv Date: Tue, 21 Aug 2018 12:22:45 -0700 Subject: [PATCH 03/10] debug --- src/main/java/baritone/bot/chunk/CachedRegion.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/main/java/baritone/bot/chunk/CachedRegion.java b/src/main/java/baritone/bot/chunk/CachedRegion.java index b0cda611..1853bf44 100644 --- a/src/main/java/baritone/bot/chunk/CachedRegion.java +++ b/src/main/java/baritone/bot/chunk/CachedRegion.java @@ -107,6 +107,7 @@ public final class CachedRegion implements ICachedChunkAccess { if (!Files.exists(path)) Files.createDirectories(path); + System.out.println("Saving region " + x + "," + z + " to disk"); Path regionFile = getRegionFile(path, this.x, this.z); if (!Files.exists(regionFile)) Files.createFile(regionFile); @@ -139,6 +140,8 @@ public final class CachedRegion implements ICachedChunkAccess { if (!Files.exists(regionFile)) return; + System.out.println("Loading region " + x + "," + z + " from disk"); + byte[] decompressed; try (FileInputStream in = new FileInputStream(regionFile.toFile())) { decompressed = GZIPUtils.decompress(in); From 7623b8b386e5d46bdfd71adaee07daece77b0fac Mon Sep 17 00:00:00 2001 From: Leijurv Date: Tue, 21 Aug 2018 13:06:36 -0700 Subject: [PATCH 04/10] reworked saving --- .../java/baritone/bot/chunk/CachedChunk.java | 5 -- .../java/baritone/bot/chunk/CachedRegion.java | 65 ++++++++++++------- .../java/baritone/bot/utils/GZIPUtils.java | 56 ---------------- 3 files changed, 41 insertions(+), 85 deletions(-) delete mode 100644 src/main/java/baritone/bot/utils/GZIPUtils.java diff --git a/src/main/java/baritone/bot/chunk/CachedChunk.java b/src/main/java/baritone/bot/chunk/CachedChunk.java index c85cc88c..8316345f 100644 --- a/src/main/java/baritone/bot/chunk/CachedChunk.java +++ b/src/main/java/baritone/bot/chunk/CachedChunk.java @@ -40,11 +40,6 @@ public final class CachedChunk implements IBlockTypeAccess { */ public static final int SIZE_IN_BYTES = SIZE / 8; - /** - * An array of just 0s with the length of {@link CachedChunk#SIZE_IN_BYTES} - */ - public static final byte[] EMPTY_CHUNK = new byte[SIZE_IN_BYTES]; - /** * The chunk x coordinate */ diff --git a/src/main/java/baritone/bot/chunk/CachedRegion.java b/src/main/java/baritone/bot/chunk/CachedRegion.java index 1853bf44..cbdcc9ed 100644 --- a/src/main/java/baritone/bot/chunk/CachedRegion.java +++ b/src/main/java/baritone/bot/chunk/CachedRegion.java @@ -17,18 +17,15 @@ package baritone.bot.chunk; -import baritone.bot.utils.GZIPUtils; import baritone.bot.utils.pathing.PathingBlockType; -import java.io.FileInputStream; -import java.io.FileOutputStream; -import java.io.IOException; +import java.io.*; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; -import java.util.Arrays; import java.util.BitSet; import java.util.function.Consumer; +import java.util.zip.GZIPInputStream; import java.util.zip.GZIPOutputStream; /** @@ -36,6 +33,13 @@ import java.util.zip.GZIPOutputStream; * @since 8/3/2018 9:35 PM */ public final class CachedRegion implements ICachedChunkAccess { + private static final byte CHUNK_NOT_PRESENT = 0; + private static final byte CHUNK_PRESENT = 1; + + /** + * Magic value to detect invalid cache files, or incompatible cache files saved in an old version of Baritone + */ + private static final int CACHED_REGION_MAGIC = 456022910; /** * All of the chunks in this region: A 32x32 array of them. @@ -111,13 +115,19 @@ public final class CachedRegion implements ICachedChunkAccess { Path regionFile = getRegionFile(path, this.x, this.z); if (!Files.exists(regionFile)) Files.createFile(regionFile); - try (FileOutputStream fileOut = new FileOutputStream(regionFile.toFile()); GZIPOutputStream out = new GZIPOutputStream(fileOut)) { + try ( + FileOutputStream fileOut = new FileOutputStream(regionFile.toFile()); + GZIPOutputStream gzipOut = new GZIPOutputStream(fileOut); + DataOutputStream out = new DataOutputStream(gzipOut); + ) { + out.writeInt(CACHED_REGION_MAGIC); for (int z = 0; z < 32; z++) { for (int x = 0; x < 32; x++) { CachedChunk chunk = this.chunks[x][z]; if (chunk == null) { - out.write(CachedChunk.EMPTY_CHUNK); + out.write(CHUNK_NOT_PRESENT); } else { + out.write(CHUNK_PRESENT); byte[] chunkBytes = chunk.toByteArray(); out.write(chunkBytes); // Messy, but fills the empty 0s that should be trailing to fill up the space. @@ -142,23 +152,30 @@ public final class CachedRegion implements ICachedChunkAccess { System.out.println("Loading region " + x + "," + z + " from disk"); - byte[] decompressed; - try (FileInputStream in = new FileInputStream(regionFile.toFile())) { - decompressed = GZIPUtils.decompress(in); - } - - if (decompressed == null) - return; - - for (int z = 0; z < 32; z++) { - for (int x = 0; x < 32; x++) { - int index = (x + (z << 5)) * CachedChunk.SIZE_IN_BYTES; - byte[] bytes = Arrays.copyOfRange(decompressed, index, index + CachedChunk.SIZE_IN_BYTES); - if (isAllZeros(bytes)) { - this.chunks[x][z] = null; - } else { - BitSet bits = BitSet.valueOf(bytes); - updateCachedChunk(x, z, bits); + try ( + FileInputStream fileIn = new FileInputStream(regionFile.toFile()); + GZIPInputStream gzipIn = new GZIPInputStream(fileIn); + DataInputStream in = new DataInputStream(gzipIn); + ) { + int magic = in.readInt(); + if (magic != CACHED_REGION_MAGIC) { + throw new IOException("Bad magic value " + magic); + } + for (int z = 0; z < 32; z++) { + for (int x = 0; x < 32; x++) { + int isChunkPresent = in.read(); + switch (isChunkPresent) { + case CHUNK_PRESENT: + byte[] bytes = new byte[CachedChunk.SIZE_IN_BYTES]; + in.readFully(bytes); + BitSet bits = BitSet.valueOf(bytes); + updateCachedChunk(x, z, bits); + case CHUNK_NOT_PRESENT: + this.chunks[x][z] = null; + break; + default: + throw new IOException("Malformed stream"); + } } } } diff --git a/src/main/java/baritone/bot/utils/GZIPUtils.java b/src/main/java/baritone/bot/utils/GZIPUtils.java deleted file mode 100644 index 7b15e580..00000000 --- a/src/main/java/baritone/bot/utils/GZIPUtils.java +++ /dev/null @@ -1,56 +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 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Baritone. If not, see . - */ - -package baritone.bot.utils; - -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.util.zip.GZIPInputStream; -import java.util.zip.GZIPOutputStream; - -/** - * @author Brady - * @since 8/3/2018 10:18 PM - */ -public final class GZIPUtils { - - private GZIPUtils() { - } - - public static byte[] compress(byte[] in) throws IOException { - ByteArrayOutputStream byteStream = new ByteArrayOutputStream(in.length); - - try (GZIPOutputStream gzipStream = new GZIPOutputStream(byteStream)) { - gzipStream.write(in); - } - return byteStream.toByteArray(); - } - - public static byte[] decompress(InputStream in) throws IOException { - ByteArrayOutputStream outStream = new ByteArrayOutputStream(); - - try (GZIPInputStream gzipStream = new GZIPInputStream(in)) { - byte[] buffer = new byte[1024]; - int len; - while ((len = gzipStream.read(buffer)) > 0) { - outStream.write(buffer, 0, len); - } - } - return outStream.toByteArray(); - } -} From 05cc63f4ffc4d16d1024c8f7f4806f8679f6f929 Mon Sep 17 00:00:00 2001 From: Leijurv Date: Tue, 21 Aug 2018 13:10:00 -0700 Subject: [PATCH 05/10] comment --- src/main/java/baritone/bot/chunk/CachedRegion.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/main/java/baritone/bot/chunk/CachedRegion.java b/src/main/java/baritone/bot/chunk/CachedRegion.java index cbdcc9ed..6fe78009 100644 --- a/src/main/java/baritone/bot/chunk/CachedRegion.java +++ b/src/main/java/baritone/bot/chunk/CachedRegion.java @@ -159,6 +159,9 @@ public final class CachedRegion implements ICachedChunkAccess { ) { int magic = in.readInt(); if (magic != CACHED_REGION_MAGIC) { + // in the future, if we change the format on disk + // we can keep converters for the old format + // by switching on the magic value, and either loading it normally, or loading through a converter. throw new IOException("Bad magic value " + magic); } for (int z = 0; z < 32; z++) { From 7d6d34c5aaf01dc1f587ac97412412bb684d71ac Mon Sep 17 00:00:00 2001 From: Leijurv Date: Tue, 21 Aug 2018 13:17:44 -0700 Subject: [PATCH 06/10] idiocy --- src/main/java/baritone/bot/chunk/CachedRegion.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/java/baritone/bot/chunk/CachedRegion.java b/src/main/java/baritone/bot/chunk/CachedRegion.java index 6fe78009..a70cfc65 100644 --- a/src/main/java/baritone/bot/chunk/CachedRegion.java +++ b/src/main/java/baritone/bot/chunk/CachedRegion.java @@ -173,6 +173,7 @@ public final class CachedRegion implements ICachedChunkAccess { in.readFully(bytes); BitSet bits = BitSet.valueOf(bytes); updateCachedChunk(x, z, bits); + break; case CHUNK_NOT_PRESENT: this.chunks[x][z] = null; break; From 530f87ad140b5deaaf38ffecfd486d93e39efc8f Mon Sep 17 00:00:00 2001 From: Leijurv Date: Tue, 21 Aug 2018 13:18:58 -0700 Subject: [PATCH 07/10] full integrity check --- src/main/java/baritone/bot/chunk/CachedRegion.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/main/java/baritone/bot/chunk/CachedRegion.java b/src/main/java/baritone/bot/chunk/CachedRegion.java index a70cfc65..05d6ee9d 100644 --- a/src/main/java/baritone/bot/chunk/CachedRegion.java +++ b/src/main/java/baritone/bot/chunk/CachedRegion.java @@ -135,6 +135,7 @@ public final class CachedRegion implements ICachedChunkAccess { } } } + out.writeInt(~CACHED_REGION_MAGIC); } hasUnsavedChanges = false; } catch (IOException ignored) {} @@ -182,6 +183,10 @@ public final class CachedRegion implements ICachedChunkAccess { } } } + int fileEndMagic = in.readInt(); + if (fileEndMagic != ~magic) { + throw new IOException("Bad end of file magic"); + } } hasUnsavedChanges = false; } catch (IOException ignored) {} From 40dd2e33f6f1061e81193a70cf4b627f219c02dc Mon Sep 17 00:00:00 2001 From: Leijurv Date: Tue, 21 Aug 2018 13:39:28 -0700 Subject: [PATCH 08/10] fixed setting name --- src/main/java/baritone/bot/Settings.java | 2 +- src/main/java/baritone/bot/event/GameEventHandler.java | 4 ++-- src/main/java/baritone/bot/pathing/calc/AStarPathFinder.java | 2 +- src/main/java/baritone/bot/utils/BlockStateInterface.java | 2 +- src/main/java/baritone/bot/utils/ExampleBaritoneControl.java | 5 ++++- 5 files changed, 9 insertions(+), 6 deletions(-) diff --git a/src/main/java/baritone/bot/Settings.java b/src/main/java/baritone/bot/Settings.java index 13da50bb..68fcd4c2 100644 --- a/src/main/java/baritone/bot/Settings.java +++ b/src/main/java/baritone/bot/Settings.java @@ -157,7 +157,7 @@ public class Settings { /** * The big one. Download all chunks in simplified 2-bit format and save them for better very-long-distance pathing. */ - public Setting chuckCaching = new Setting<>(false); + public Setting chunkCaching = new Setting<>(true); /** * Print all the debug messages to chat diff --git a/src/main/java/baritone/bot/event/GameEventHandler.java b/src/main/java/baritone/bot/event/GameEventHandler.java index 32bcde8c..4221d3bc 100644 --- a/src/main/java/baritone/bot/event/GameEventHandler.java +++ b/src/main/java/baritone/bot/event/GameEventHandler.java @@ -108,7 +108,7 @@ public final class GameEventHandler implements IGameEventListener, Helper { && type == ChunkEvent.Type.UNLOAD && mc.world.getChunkProvider().isChunkGeneratedAt(event.getX(), event.getZ()); - if (Baritone.settings().chuckCaching.get()) { + if (Baritone.settings().chunkCaching.get()) { if (isPostPopulate || isPreUnload) { CachedWorldProvider.INSTANCE.ifWorldLoaded(world -> world.updateCachedChunk(event.getX(), event.getZ(), @@ -132,7 +132,7 @@ public final class GameEventHandler implements IGameEventListener, Helper { @Override public void onWorldEvent(WorldEvent event) { - if (Baritone.settings().chuckCaching.get()) { + if (Baritone.settings().chunkCaching.get()) { CachedWorldProvider cache = CachedWorldProvider.INSTANCE; switch (event.getState()) { diff --git a/src/main/java/baritone/bot/pathing/calc/AStarPathFinder.java b/src/main/java/baritone/bot/pathing/calc/AStarPathFinder.java index e34a7eff..9f60a80c 100644 --- a/src/main/java/baritone/bot/pathing/calc/AStarPathFinder.java +++ b/src/main/java/baritone/bot/pathing/calc/AStarPathFinder.java @@ -94,7 +94,7 @@ public class AStarPathFinder extends AbstractNodeCostSearch implements Helper { int numNodes = 0; int numEmptyChunk = 0; boolean favoring = favoredPositions.isPresent(); - boolean cache = Baritone.settings().chuckCaching.get(); // grab all settings beforehand so that changing settings during pathing doesn't cause a crash or unpredictable behavior + boolean cache = Baritone.settings().chunkCaching.get(); // grab all settings beforehand so that changing settings during pathing doesn't cause a crash or unpredictable behavior int pathingMaxChunkBorderFetch = Baritone.settings().pathingMaxChunkBorderFetch.get(); double favorCoeff = Baritone.settings().backtrackCostFavoringCoefficient.get(); boolean minimumImprovementRepropagation = Baritone.settings().minimumImprovementRepropagation.get(); diff --git a/src/main/java/baritone/bot/utils/BlockStateInterface.java b/src/main/java/baritone/bot/utils/BlockStateInterface.java index cddd7351..591f43cb 100644 --- a/src/main/java/baritone/bot/utils/BlockStateInterface.java +++ b/src/main/java/baritone/bot/utils/BlockStateInterface.java @@ -41,7 +41,7 @@ public class BlockStateInterface implements Helper { if (chunk.isLoaded()) { return chunk.getBlockState(pos); } - if (Baritone.settings().chuckCaching.get()) { + if (Baritone.settings().chunkCaching.get()) { CachedWorld world = CachedWorldProvider.INSTANCE.getCurrentWorld(); if (world != null) { PathingBlockType type = world.getBlockType(pos); diff --git a/src/main/java/baritone/bot/utils/ExampleBaritoneControl.java b/src/main/java/baritone/bot/utils/ExampleBaritoneControl.java index a200789d..0fc62b71 100644 --- a/src/main/java/baritone/bot/utils/ExampleBaritoneControl.java +++ b/src/main/java/baritone/bot/utils/ExampleBaritoneControl.java @@ -23,7 +23,10 @@ import baritone.bot.behavior.Behavior; import baritone.bot.behavior.impl.PathingBehavior; import baritone.bot.event.events.ChatEvent; import baritone.bot.pathing.calc.AStarPathFinder; -import baritone.bot.pathing.goals.*; +import baritone.bot.pathing.goals.Goal; +import baritone.bot.pathing.goals.GoalBlock; +import baritone.bot.pathing.goals.GoalXZ; +import baritone.bot.pathing.goals.GoalYLevel; import baritone.bot.pathing.movement.ActionCosts; import baritone.bot.pathing.movement.CalculationContext; import baritone.bot.pathing.movement.Movement; From 14dddfb1de8db948effa913492b0022b943d1d9f Mon Sep 17 00:00:00 2001 From: Leijurv Date: Tue, 21 Aug 2018 15:18:35 -0700 Subject: [PATCH 09/10] chunk packing linkedblockingqueue --- .../java/baritone/bot/chunk/CachedRegion.java | 20 +++++---- .../java/baritone/bot/chunk/CachedWorld.java | 42 +++++++++++++++++-- .../bot/chunk/CachedWorldProvider.java | 10 +++++ .../java/baritone/bot/chunk/ChunkPacker.java | 11 ++--- .../bot/chunk/ICachedChunkAccess.java | 31 -------------- .../baritone/bot/event/GameEventHandler.java | 12 +++--- 6 files changed, 74 insertions(+), 52 deletions(-) delete mode 100644 src/main/java/baritone/bot/chunk/ICachedChunkAccess.java diff --git a/src/main/java/baritone/bot/chunk/CachedRegion.java b/src/main/java/baritone/bot/chunk/CachedRegion.java index 05d6ee9d..8f2dfc9b 100644 --- a/src/main/java/baritone/bot/chunk/CachedRegion.java +++ b/src/main/java/baritone/bot/chunk/CachedRegion.java @@ -17,6 +17,7 @@ package baritone.bot.chunk; +import baritone.bot.utils.pathing.IBlockTypeAccess; import baritone.bot.utils.pathing.PathingBlockType; import java.io.*; @@ -32,7 +33,7 @@ import java.util.zip.GZIPOutputStream; * @author Brady * @since 8/3/2018 9:35 PM */ -public final class CachedRegion implements ICachedChunkAccess { +public final class CachedRegion implements IBlockTypeAccess { private static final byte CHUNK_NOT_PRESENT = 0; private static final byte CHUNK_PRESENT = 1; @@ -76,8 +77,7 @@ public final class CachedRegion implements ICachedChunkAccess { return null; } - @Override - public final void updateCachedChunk(int chunkX, int chunkZ, BitSet data) { + final void updateCachedChunk(int chunkX, int chunkZ, BitSet data) { CachedChunk chunk = this.getChunk(chunkX, chunkZ); if (chunk == null) { this.chunks[chunkX][chunkZ] = new CachedChunk(chunkX, chunkZ, data); @@ -111,7 +111,7 @@ public final class CachedRegion implements ICachedChunkAccess { if (!Files.exists(path)) Files.createDirectories(path); - System.out.println("Saving region " + x + "," + z + " to disk"); + System.out.println("Saving region " + x + "," + z + " to disk " + path); Path regionFile = getRegionFile(path, this.x, this.z); if (!Files.exists(regionFile)) Files.createFile(regionFile); @@ -138,7 +138,10 @@ public final class CachedRegion implements ICachedChunkAccess { out.writeInt(~CACHED_REGION_MAGIC); } hasUnsavedChanges = false; - } catch (IOException ignored) {} + System.out.println("Saved region successfully"); + } catch (IOException ex) { + ex.printStackTrace(); + } } public void load(String directory) { @@ -151,7 +154,7 @@ public final class CachedRegion implements ICachedChunkAccess { if (!Files.exists(regionFile)) return; - System.out.println("Loading region " + x + "," + z + " from disk"); + System.out.println("Loading region " + x + "," + z + " from disk " + path); try ( FileInputStream fileIn = new FileInputStream(regionFile.toFile()); @@ -189,7 +192,10 @@ public final class CachedRegion implements ICachedChunkAccess { } } hasUnsavedChanges = false; - } catch (IOException ignored) {} + System.out.println("Loaded region successfully"); + } catch (IOException ex) { + ex.printStackTrace(); + } } private static boolean isAllZeros(final byte[] array) { diff --git a/src/main/java/baritone/bot/chunk/CachedWorld.java b/src/main/java/baritone/bot/chunk/CachedWorld.java index eb7513a3..d3900f6f 100644 --- a/src/main/java/baritone/bot/chunk/CachedWorld.java +++ b/src/main/java/baritone/bot/chunk/CachedWorld.java @@ -17,18 +17,21 @@ package baritone.bot.chunk; +import baritone.bot.utils.pathing.IBlockTypeAccess; import baritone.bot.utils.pathing.PathingBlockType; import it.unimi.dsi.fastutil.longs.Long2ObjectMap; import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap; +import net.minecraft.world.chunk.Chunk; import java.util.BitSet; +import java.util.concurrent.LinkedBlockingQueue; import java.util.function.Consumer; /** * @author Brady * @since 8/4/2018 12:02 AM */ -public final class CachedWorld implements ICachedChunkAccess { +public final class CachedWorld implements IBlockTypeAccess { /** * The maximum number of regions in any direction from (0,0) @@ -45,10 +48,21 @@ public final class CachedWorld implements ICachedChunkAccess { */ private final String directory; + private final LinkedBlockingQueue toPack = new LinkedBlockingQueue<>(); + public CachedWorld(String directory) { this.directory = directory; // Insert an invalid region element cachedRegions.put(0, null); + new PackerThread().start(); + } + + public final void queueForPacking(Chunk chunk) { + try { + toPack.put(chunk); + } catch (InterruptedException e) { + e.printStackTrace(); + } } @Override @@ -57,17 +71,19 @@ public final class CachedWorld implements ICachedChunkAccess { return region.getBlockType(x & 511, y, z & 511); } - @Override - public final void updateCachedChunk(int chunkX, int chunkZ, BitSet data) { + private void updateCachedChunk(int chunkX, int chunkZ, BitSet data) { CachedRegion region = getOrCreateRegion(chunkX >> 5, chunkZ >> 5); region.updateCachedChunk(chunkX & 31, chunkZ & 31, data); } public final void save() { + long start = System.currentTimeMillis(); this.cachedRegions.values().forEach(region -> { if (region != null) region.save(this.directory); }); + long now = System.currentTimeMillis(); + System.out.println("World save took " + (now - start) + "ms"); } /** @@ -129,4 +145,24 @@ public final class CachedWorld implements ICachedChunkAccess { private boolean isRegionInWorld(int regionX, int regionZ) { return regionX <= REGION_MAX && regionX >= -REGION_MAX && regionZ <= REGION_MAX && regionZ >= -REGION_MAX; } + + private class PackerThread extends Thread { + public void run() { + while (true) { + LinkedBlockingQueue queue = toPack; + if (queue == null) { + break; + } + try { + Chunk chunk = queue.take(); + BitSet packed = ChunkPacker.createPackedChunk(chunk); + CachedWorld.this.updateCachedChunk(chunk.x, chunk.z, packed); + //System.out.println("Processed chunk at " + chunk.x + "," + chunk.z); + } catch (InterruptedException e) { + e.printStackTrace(); + break; + } + } + } + } } diff --git a/src/main/java/baritone/bot/chunk/CachedWorldProvider.java b/src/main/java/baritone/bot/chunk/CachedWorldProvider.java index e6062d6d..b59c3a52 100644 --- a/src/main/java/baritone/bot/chunk/CachedWorldProvider.java +++ b/src/main/java/baritone/bot/chunk/CachedWorldProvider.java @@ -69,7 +69,17 @@ public enum CachedWorldProvider implements Helper { } public final void closeWorld() { + CachedWorld world = this.currentWorld; this.currentWorld = null; + if (world == null) { + return; + } + new Thread() { + public void run() { + System.out.println("Started saving the world in a new thread"); + world.save(); + } + }.start(); } public final void ifWorldLoaded(Consumer currentWorldConsumer) { diff --git a/src/main/java/baritone/bot/chunk/ChunkPacker.java b/src/main/java/baritone/bot/chunk/ChunkPacker.java index 7b8fbbe4..25ef3b39 100644 --- a/src/main/java/baritone/bot/chunk/ChunkPacker.java +++ b/src/main/java/baritone/bot/chunk/ChunkPacker.java @@ -18,9 +18,9 @@ package baritone.bot.chunk; import baritone.bot.pathing.movement.MovementHelper; -import baritone.bot.utils.pathing.PathingBlockType; import baritone.bot.utils.BlockStateInterface; import baritone.bot.utils.Helper; +import baritone.bot.utils.pathing.PathingBlockType; import net.minecraft.block.Block; import net.minecraft.block.BlockAir; import net.minecraft.block.state.IBlockState; @@ -29,8 +29,6 @@ import net.minecraft.world.chunk.Chunk; import java.util.BitSet; -import static net.minecraft.block.Block.NULL_AABB; - /** * @author Brady * @since 8/3/2018 1:09 AM @@ -39,7 +37,8 @@ public final class ChunkPacker implements Helper { private ChunkPacker() {} - public static BitSet createPackedChunk(Chunk chunk) { + public static synchronized BitSet createPackedChunk(Chunk chunk) { + long start = System.currentTimeMillis(); BitSet bitSet = new BitSet(CachedChunk.SIZE); try { for (int y = 0; y < 256; y++) { @@ -55,6 +54,8 @@ public final class ChunkPacker implements Helper { } catch (Exception e) { e.printStackTrace(); } + long end = System.currentTimeMillis(); + //System.out.println("Chunk packing took " + (end - start) + "ms for " + chunk.x + "," + chunk.z); return bitSet; } @@ -69,7 +70,7 @@ public final class ChunkPacker implements Helper { return PathingBlockType.AVOID; } - if (block instanceof BlockAir || state.getCollisionBoundingBox(mc.world, pos) == NULL_AABB) { + if (block instanceof BlockAir) { return PathingBlockType.AIR; } diff --git a/src/main/java/baritone/bot/chunk/ICachedChunkAccess.java b/src/main/java/baritone/bot/chunk/ICachedChunkAccess.java deleted file mode 100644 index 9cb4e649..00000000 --- a/src/main/java/baritone/bot/chunk/ICachedChunkAccess.java +++ /dev/null @@ -1,31 +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 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Baritone. If not, see . - */ - -package baritone.bot.chunk; - -import baritone.bot.utils.pathing.IBlockTypeAccess; - -import java.util.BitSet; - -/** - * @author Brady - * @since 8/4/2018 1:10 AM - */ -public interface ICachedChunkAccess extends IBlockTypeAccess { - - void updateCachedChunk(int chunkX, int chunkZ, BitSet data); -} diff --git a/src/main/java/baritone/bot/event/GameEventHandler.java b/src/main/java/baritone/bot/event/GameEventHandler.java index 4221d3bc..c83f6815 100644 --- a/src/main/java/baritone/bot/event/GameEventHandler.java +++ b/src/main/java/baritone/bot/event/GameEventHandler.java @@ -36,9 +36,7 @@ package baritone.bot.event; import baritone.bot.Baritone; import baritone.bot.behavior.Behavior; -import baritone.bot.chunk.CachedWorld; import baritone.bot.chunk.CachedWorldProvider; -import baritone.bot.chunk.ChunkPacker; import baritone.bot.event.events.*; import baritone.bot.event.events.type.EventState; import baritone.bot.event.listener.IGameEventListener; @@ -49,6 +47,7 @@ import net.minecraft.client.renderer.GlStateManager; import net.minecraft.client.renderer.Tessellator; import net.minecraft.client.renderer.vertex.DefaultVertexFormats; import net.minecraft.client.settings.KeyBinding; +import net.minecraft.world.chunk.Chunk; import org.lwjgl.input.Keyboard; import java.util.function.Consumer; @@ -110,9 +109,10 @@ public final class GameEventHandler implements IGameEventListener, Helper { if (Baritone.settings().chunkCaching.get()) { if (isPostPopulate || isPreUnload) { - CachedWorldProvider.INSTANCE.ifWorldLoaded(world -> - world.updateCachedChunk(event.getX(), event.getZ(), - ChunkPacker.createPackedChunk(mc.world.getChunk(event.getX(), event.getZ())))); + CachedWorldProvider.INSTANCE.ifWorldLoaded(world -> { + Chunk chunk = mc.world.getChunk(event.getX(), event.getZ()); + world.queueForPacking(chunk); + }); } } @@ -137,7 +137,7 @@ public final class GameEventHandler implements IGameEventListener, Helper { switch (event.getState()) { case PRE: - cache.ifWorldLoaded(CachedWorld::save); + cache.closeWorld(); break; case POST: cache.closeWorld(); From eb34c1fc240f31788bf9575db7adb0ffdae12505 Mon Sep 17 00:00:00 2001 From: Leijurv Date: Tue, 21 Aug 2018 15:20:33 -0700 Subject: [PATCH 10/10] unneeded slowdown --- src/main/java/baritone/bot/chunk/ChunkPacker.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/baritone/bot/chunk/ChunkPacker.java b/src/main/java/baritone/bot/chunk/ChunkPacker.java index 25ef3b39..de8f3179 100644 --- a/src/main/java/baritone/bot/chunk/ChunkPacker.java +++ b/src/main/java/baritone/bot/chunk/ChunkPacker.java @@ -37,7 +37,7 @@ public final class ChunkPacker implements Helper { private ChunkPacker() {} - public static synchronized BitSet createPackedChunk(Chunk chunk) { + public static BitSet createPackedChunk(Chunk chunk) { long start = System.currentTimeMillis(); BitSet bitSet = new BitSet(CachedChunk.SIZE); try {