diff --git a/anvil-loader/src/main/java/mc/world/anvil/Region.java b/anvil-loader/src/main/java/mc/world/anvil/Region.java index 794d27f..b171aee 100644 --- a/anvil-loader/src/main/java/mc/world/anvil/Region.java +++ b/anvil-loader/src/main/java/mc/world/anvil/Region.java @@ -51,7 +51,7 @@ class Region implements Closeable { Chunk getChunk(int x, int z) { int offset; try { - offset = getOffset(x, z); + offset = getOffset(x & 31, z & 31); } catch (Exception e) { return new EmptyChunk(x, z); } diff --git a/anvil-loader/src/test/java/mc/world/anvil/RegionTest.java b/anvil-loader/src/test/java/mc/world/anvil/RegionTest.java index d7ea2b1..88fa1b3 100644 --- a/anvil-loader/src/test/java/mc/world/anvil/RegionTest.java +++ b/anvil-loader/src/test/java/mc/world/anvil/RegionTest.java @@ -21,19 +21,30 @@ import java.util.List; import java.util.stream.Stream; import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertNotNull; class RegionTest { - private static Region region; + private static RegionManager regionManager; @BeforeAll @SneakyThrows static void before() { - region = new Region(Paths.get(RegionTest.class.getResource("/region/r.0.0.mca").toURI()).toFile()); + regionManager = new RegionManager(Paths.get(RegionTest.class.getResource("/region/").toURI())); } - private static Stream streamArguments() { - ChunkChecker chunkChecker00 = new ChunkChecker() { + private static void assertZeroPlast(int x, int z, Block block, String msg) { + // @formatter:off + if (x == 0 && z == 0) assertEquals(BlockType.STONE, block.getType(), msg); + else if (x == 15 && z == 0) assertEquals(BlockType.GRANITE, block.getType(), msg); + else if (x == 0 && z == 15) assertEquals(BlockType.POLISHED_GRANITE, block.getType(), msg); + else if (x == 15 && z == 15) assertEquals(BlockType.DIORITE, block.getType(), msg); + else assertEquals(BlockType.BEDROCK, block.getType(), msg); + // @formatter:on + } + + private static ChunkChecker chunkChecker00() { + return new ChunkChecker() { private void checkSection0(ChunkSection chunkSection) { for (int y = 0; y < 16; y++) { for (int x = 0; x < 16; x++) { @@ -42,13 +53,7 @@ class RegionTest { String msg = String.format("coords: %d %d %d", x, y, z); if (y == 0) { - // @formatter:off - if (x == 0 && z == 0) assertEquals(BlockType.STONE, block.getType(), msg); - else if (x == 15 && z == 0) assertEquals(BlockType.GRANITE, block.getType(), msg); - else if (x == 0 && z == 15) assertEquals(BlockType.POLISHED_GRANITE, block.getType(), msg); - else if (x == 15 && z == 15) assertEquals(BlockType.DIORITE, block.getType(), msg); - else assertEquals(BlockType.BEDROCK, block.getType(), msg); - // @formatter:on + assertZeroPlast(x, z, block, msg); } else { assertEquals(BlockType.STONE, block.getType(), msg); } @@ -112,8 +117,10 @@ class RegionTest { checkSection1(chunkSection); } }; + } - ChunkChecker chunkChecker01 = new ChunkChecker() { + private static ChunkChecker chunkChecker01() { + return new ChunkChecker() { @Override public void check(Chunk chunk) { ChunkSection section = chunk.getChunkSection(0); @@ -145,13 +152,7 @@ class RegionTest { String msg = String.format("coords: %d %d %d", x, y, z); if (y == 0) { - // @formatter:off - if (x == 0 && z == 0) assertEquals(BlockType.STONE, block.getType(), msg); - else if (x == 15 && z == 0) assertEquals(BlockType.GRANITE, block.getType(), msg); - else if (x == 0 && z == 15) assertEquals(BlockType.POLISHED_GRANITE, block.getType(), msg); - else if (x == 15 && z == 15) assertEquals(BlockType.DIORITE, block.getType(), msg); - else assertEquals(BlockType.BEDROCK, block.getType(), msg); - // @formatter:on + assertZeroPlast(x, z, block, msg); } else { assertEquals(exceptedTypes.get(x), block.getType(), msg); } @@ -160,10 +161,35 @@ class RegionTest { } } }; + } + + private static ChunkChecker chunkChecker0N1() { + return new ChunkChecker() { + @Override + public void check(Chunk chunk) { + ChunkSection section = chunk.getChunkSection(0); + assertNotNull(section); + + for (int y = 0; y < 1; y++) { + for (int x = 0; x < 16; x++) { + for (int z = 0; z < 16; z++) { + assertZeroPlast(x, z, + section.getBlock(x, y, z), + String.format("coords: %d %d %d", x, y, z)); + } + } + } + } + }; + } + + private static Stream streamArguments() { + return Stream.of( - Arguments.of(0, 0, chunkChecker00), - Arguments.of(0, 1, chunkChecker01) + Arguments.of(0, 0, chunkChecker00()), + Arguments.of(0, 1, chunkChecker01()), + Arguments.of(0, -1, chunkChecker0N1()) ); } @@ -171,8 +197,12 @@ class RegionTest { @ParameterizedTest(name = "[{index}] chunk {0},{1}") @MethodSource("streamArguments") void testGetChunk(int chunkX, int chunkZ, ChunkChecker chunkChecker) { + final Region region = regionManager.getRegion(chunkX >> 5, chunkZ >> 5); + assertNotNull(region); + final Chunk chunk = region.getChunk(chunkX, chunkZ); assertNotNull(chunk); + assertFalse(chunk instanceof EmptyChunk); chunkChecker.check(chunk); } diff --git a/anvil-loader/src/test/resources/region/r.0.-1.mca b/anvil-loader/src/test/resources/region/r.0.-1.mca new file mode 100644 index 0000000..25001f9 Binary files /dev/null and b/anvil-loader/src/test/resources/region/r.0.-1.mca differ