Browse Source

Fixed NPE on chunk unload

nossr50 6 months ago
parent
commit
3f5f510fc5

+ 2 - 15
src/main/java/com/gmail/nossr50/util/blockmeta/HashChunkManager.java

@@ -39,9 +39,7 @@ public class HashChunkManager implements ChunkManager {
     }
 
     private synchronized @Nullable ChunkStore readChunkStore(@NotNull World world, int cx, int cz) throws IOException {
-        McMMOSimpleRegionFile rf = getReadableSimpleRegionFile(world, cx, cz);
-        if (rf == null)
-            return null; // If there is no region file, there can't be a chunk
+        final McMMOSimpleRegionFile rf = getWriteableSimpleRegionFile(world, cx, cz);
         try (DataInputStream in = rf.getInputStream(cx, cz)) { // Get input stream for chunk
             if (in == null)
                 return null; // No chunk
@@ -74,17 +72,6 @@ public class HashChunkManager implements ChunkManager {
         });
     }
 
-    private synchronized @Nullable McMMOSimpleRegionFile getReadableSimpleRegionFile(@NotNull World world, int cx, int cz) {
-        CoordinateKey regionKey = toRegionKey(world.getUID(), cx, cz);
-
-        return regionMap.computeIfAbsent(regionKey, k -> {
-            File regionFile = getRegionFile(world, regionKey);
-            if (!regionFile.exists())
-                return null; // Don't create the file on read-only operations
-            return new McMMOSimpleRegionFile(regionFile, regionKey.x, regionKey.z);
-        });
-    }
-
     private @NotNull File getRegionFile(@NotNull World world, @NotNull CoordinateKey regionKey) {
         if (world.getUID() != regionKey.worldID)
             throw new IllegalArgumentException();
@@ -112,7 +99,7 @@ public class HashChunkManager implements ChunkManager {
         CoordinateKey regionKey = toRegionKey(world.getUID(), cx, cz);
         HashSet<CoordinateKey> chunkKeys = chunkUsageMap.get(regionKey);
         chunkKeys.remove(chunkKey); // remove from region file in-use set
-        // If it was last chunk in region, close the region file and remove it from memory
+        // If it was last chunk in the region, close the region file and remove it from memory
         if (chunkKeys.isEmpty()) {
             chunkUsageMap.remove(regionKey);
             regionMap.remove(regionKey).close();

+ 21 - 0
src/test/java/com/gmail/nossr50/util/blockmeta/UserBlockTrackerTest.java

@@ -170,6 +170,27 @@ class UserBlockTrackerTest {
         assertTrue(chunkManager.isIneligible(mockBlockA));
     }
 
+    @Test
+    void testUnload() {
+        final ChunkManager chunkManager = new HashChunkManager();
+        Block mockBlockA = Mockito.mock(Block.class);
+        when(mockBlockA.getX()).thenReturn(15);
+        when(mockBlockA.getZ()).thenReturn(15);
+        when(mockBlockA.getY()).thenReturn(0);
+        when(mockBlockA.getWorld()).thenReturn(mockWorld);
+        Block mockBlockB = Mockito.mock(Block.class);
+        when(mockBlockB.getX()).thenReturn(-15);
+        when(mockBlockB.getZ()).thenReturn(-15);
+        when(mockBlockB.getY()).thenReturn(0);
+        when(mockBlockB.getWorld()).thenReturn(mockWorld);
+
+        chunkManager.setIneligible(mockBlockA);
+        chunkManager.setEligible(mockBlockB);
+        assertTrue(chunkManager.isIneligible(mockBlockA));
+
+        chunkManager.chunkUnloaded(0, 0, mockWorld);
+    }
+
     @NotNull
     private Block initMockBlock(int x, int y, int z) {
         final Block mockBlock = Mockito.mock(Block.class);