mirror of
				https://github.com/mcMMO-Dev/mcMMO.git
				synced 2025-11-03 18:43:43 +01:00 
			
		
		
		
	Fixed NPE on chunk unload
This commit is contained in:
		@@ -39,9 +39,7 @@ public class HashChunkManager implements ChunkManager {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    private synchronized @Nullable ChunkStore readChunkStore(@NotNull World world, int cx, int cz) throws IOException {
 | 
					    private synchronized @Nullable ChunkStore readChunkStore(@NotNull World world, int cx, int cz) throws IOException {
 | 
				
			||||||
        McMMOSimpleRegionFile rf = getReadableSimpleRegionFile(world, cx, cz);
 | 
					        final McMMOSimpleRegionFile rf = getWriteableSimpleRegionFile(world, cx, cz);
 | 
				
			||||||
        if (rf == null)
 | 
					 | 
				
			||||||
            return null; // If there is no region file, there can't be a chunk
 | 
					 | 
				
			||||||
        try (DataInputStream in = rf.getInputStream(cx, cz)) { // Get input stream for chunk
 | 
					        try (DataInputStream in = rf.getInputStream(cx, cz)) { // Get input stream for chunk
 | 
				
			||||||
            if (in == null)
 | 
					            if (in == null)
 | 
				
			||||||
                return null; // No chunk
 | 
					                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) {
 | 
					    private @NotNull File getRegionFile(@NotNull World world, @NotNull CoordinateKey regionKey) {
 | 
				
			||||||
        if (world.getUID() != regionKey.worldID)
 | 
					        if (world.getUID() != regionKey.worldID)
 | 
				
			||||||
            throw new IllegalArgumentException();
 | 
					            throw new IllegalArgumentException();
 | 
				
			||||||
@@ -112,7 +99,7 @@ public class HashChunkManager implements ChunkManager {
 | 
				
			|||||||
        CoordinateKey regionKey = toRegionKey(world.getUID(), cx, cz);
 | 
					        CoordinateKey regionKey = toRegionKey(world.getUID(), cx, cz);
 | 
				
			||||||
        HashSet<CoordinateKey> chunkKeys = chunkUsageMap.get(regionKey);
 | 
					        HashSet<CoordinateKey> chunkKeys = chunkUsageMap.get(regionKey);
 | 
				
			||||||
        chunkKeys.remove(chunkKey); // remove from region file in-use set
 | 
					        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()) {
 | 
					        if (chunkKeys.isEmpty()) {
 | 
				
			||||||
            chunkUsageMap.remove(regionKey);
 | 
					            chunkUsageMap.remove(regionKey);
 | 
				
			||||||
            regionMap.remove(regionKey).close();
 | 
					            regionMap.remove(regionKey).close();
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -170,6 +170,27 @@ class UserBlockTrackerTest {
 | 
				
			|||||||
        assertTrue(chunkManager.isIneligible(mockBlockA));
 | 
					        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
 | 
					    @NotNull
 | 
				
			||||||
    private Block initMockBlock(int x, int y, int z) {
 | 
					    private Block initMockBlock(int x, int y, int z) {
 | 
				
			||||||
        final Block mockBlock = Mockito.mock(Block.class);
 | 
					        final Block mockBlock = Mockito.mock(Block.class);
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user