Commits

Thinkofdeath authored 670d08ceb0a
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.
No tags

CraftBukkit-Patches/0121-Remove-the-lastChunkAccessed-if-it-is-unloaded.patch

Added
1 +From 2c68ddcb2ac529bdd2476720d924e5e09e588b7c Mon Sep 17 00:00:00 2001
2 +From: Thinkofdeath <thethinkofdeath@gmail.com>
3 +Date: Tue, 18 Mar 2014 09:49:30 +0000
4 +Subject: [PATCH] Remove the lastChunkAccessed if it is unloaded.
5 +
6 +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.
7 +
8 +diff --git a/src/main/java/net/minecraft/server/ChunkProviderServer.java b/src/main/java/net/minecraft/server/ChunkProviderServer.java
9 +index 9ccc057..3614cb0 100644
10 +--- a/src/main/java/net/minecraft/server/ChunkProviderServer.java
11 ++++ b/src/main/java/net/minecraft/server/ChunkProviderServer.java
12 +@@ -307,6 +307,13 @@ public class ChunkProviderServer implements IChunkProvider {
13 + long chunkcoordinates = this.unloadQueue.popFirst();
14 + Chunk chunk = this.chunks.get(chunkcoordinates);
15 + if (chunk == null) continue;
16 ++ // Spigot start - Remove the chunk from the cache if it is unloaded
17 ++ Chunk result = world.lastChunkAccessed;
18 ++ if ( result != null && result.locX == chunk.locX && result.locZ == chunk.locZ )
19 ++ {
20 ++ world.lastChunkAccessed = null;
21 ++ }
22 ++ // Spigot end
23 +
24 + ChunkUnloadEvent event = new ChunkUnloadEvent(chunk.bukkitChunk);
25 + server.getPluginManager().callEvent(event);
26 +diff --git a/src/main/java/net/minecraft/server/World.java b/src/main/java/net/minecraft/server/World.java
27 +index 97486db..02dd02e 100644
28 +--- a/src/main/java/net/minecraft/server/World.java
29 ++++ b/src/main/java/net/minecraft/server/World.java
30 +@@ -154,7 +154,7 @@ public abstract class World implements IBlockAccess {
31 + public boolean pvpMode;
32 + public boolean keepSpawnInMemory = true;
33 + public ChunkGenerator generator;
34 +- Chunk lastChunkAccessed;
35 ++ public Chunk lastChunkAccessed; // Spigot - Make public
36 + int lastXAccessed = Integer.MIN_VALUE;
37 + int lastZAccessed = Integer.MIN_VALUE;
38 + final Object chunkLock = new Object();
39 +diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
40 +index ab87519..545ae96 100644
41 +--- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
42 ++++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
43 +@@ -187,6 +187,14 @@ public class CraftWorld implements World {
44 + world.chunkProviderServer.saveChunkNOP(chunk);
45 + }
46 +
47 ++ // Spigot start - Remove the chunk from the cache if it is unloaded
48 ++ net.minecraft.server.Chunk result = world.lastChunkAccessed;
49 ++ if ( result != null && result.locX == chunk.locX && result.locZ == chunk.locZ )
50 ++ {
51 ++ world.lastChunkAccessed = null;
52 ++ }
53 ++ // Spigot end
54 ++
55 + world.chunkProviderServer.unloadQueue.remove(x, z);
56 + world.chunkProviderServer.chunks.remove(LongHash.toLong(x, z));
57 +
58 +--
59 +1.8.5.2.msysgit.0
60 +

Everything looks good. We'll let you know here if there's anything you should know about.

Add shortcut