From 670d08ceb0a6c44d7c94b3ace975ceacbe6b0055 Mon Sep 17 00:00:00 2001 From: Thinkofdeath Date: Tue, 18 Mar 2014 09:52:01 +0000 Subject: [PATCH] Remove the lastChunkAccessed if it is unloaded. This fixes an issue where a chunk would be unloaded but remain in lastChunkAccessed meaning calls on getChunkAt could return a chunk that is no longer loaded, this caused an issue where the chunk could be reloaded whilst in use reverting any block changes. This caused findEndPortal to return null even after createEndPortal which would crash the server trying to teleport to a null location. --- ...-lastChunkAccessed-if-it-is-unloaded.patch | 60 +++++++++++++++++++ 1 file changed, 60 insertions(+) create mode 100644 CraftBukkit-Patches/0121-Remove-the-lastChunkAccessed-if-it-is-unloaded.patch diff --git a/CraftBukkit-Patches/0121-Remove-the-lastChunkAccessed-if-it-is-unloaded.patch b/CraftBukkit-Patches/0121-Remove-the-lastChunkAccessed-if-it-is-unloaded.patch new file mode 100644 index 000000000..7685e1022 --- /dev/null +++ b/CraftBukkit-Patches/0121-Remove-the-lastChunkAccessed-if-it-is-unloaded.patch @@ -0,0 +1,60 @@ +From 2c68ddcb2ac529bdd2476720d924e5e09e588b7c Mon Sep 17 00:00:00 2001 +From: Thinkofdeath +Date: Tue, 18 Mar 2014 09:49:30 +0000 +Subject: [PATCH] Remove the lastChunkAccessed if it is unloaded. + +This fixes an issue where a chunk would be unloaded but remain in lastChunkAccessed meaning calls on getChunkAt could return a chunk that is no longer loaded, this caused an issue where the chunk could be reloaded whilst in use reverting any block changes. This caused findEndPortal to return null even after createEndPortal which would crash the server trying to teleport to a null location. + +diff --git a/src/main/java/net/minecraft/server/ChunkProviderServer.java b/src/main/java/net/minecraft/server/ChunkProviderServer.java +index 9ccc057..3614cb0 100644 +--- a/src/main/java/net/minecraft/server/ChunkProviderServer.java ++++ b/src/main/java/net/minecraft/server/ChunkProviderServer.java +@@ -307,6 +307,13 @@ public class ChunkProviderServer implements IChunkProvider { + long chunkcoordinates = this.unloadQueue.popFirst(); + Chunk chunk = this.chunks.get(chunkcoordinates); + if (chunk == null) continue; ++ // Spigot start - Remove the chunk from the cache if it is unloaded ++ Chunk result = world.lastChunkAccessed; ++ if ( result != null && result.locX == chunk.locX && result.locZ == chunk.locZ ) ++ { ++ world.lastChunkAccessed = null; ++ } ++ // Spigot end + + ChunkUnloadEvent event = new ChunkUnloadEvent(chunk.bukkitChunk); + server.getPluginManager().callEvent(event); +diff --git a/src/main/java/net/minecraft/server/World.java b/src/main/java/net/minecraft/server/World.java +index 97486db..02dd02e 100644 +--- a/src/main/java/net/minecraft/server/World.java ++++ b/src/main/java/net/minecraft/server/World.java +@@ -154,7 +154,7 @@ public abstract class World implements IBlockAccess { + public boolean pvpMode; + public boolean keepSpawnInMemory = true; + public ChunkGenerator generator; +- Chunk lastChunkAccessed; ++ public Chunk lastChunkAccessed; // Spigot - Make public + int lastXAccessed = Integer.MIN_VALUE; + int lastZAccessed = Integer.MIN_VALUE; + final Object chunkLock = new Object(); +diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java +index ab87519..545ae96 100644 +--- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java ++++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java +@@ -187,6 +187,14 @@ public class CraftWorld implements World { + world.chunkProviderServer.saveChunkNOP(chunk); + } + ++ // Spigot start - Remove the chunk from the cache if it is unloaded ++ net.minecraft.server.Chunk result = world.lastChunkAccessed; ++ if ( result != null && result.locX == chunk.locX && result.locZ == chunk.locZ ) ++ { ++ world.lastChunkAccessed = null; ++ } ++ // Spigot end ++ + world.chunkProviderServer.unloadQueue.remove(x, z); + world.chunkProviderServer.chunks.remove(LongHash.toLong(x, z)); + +-- +1.8.5.2.msysgit.0 +