From 5254993510a208c0f3cc34b329a9ac037bde7073 Mon Sep 17 00:00:00 2001 From: Mike Primm Date: Sun, 12 Aug 2012 18:40:49 -0500 Subject: Fix issues with chunk saving. Fixes BUKKIT-2158, BUKKIT-2018 and BUKKIT-2229 --- src/main/java/net/minecraft/server/Chunk.java | 1 + .../net/minecraft/server/ChunkProviderServer.java | 22 +++++++++++++++++---- .../java/net/minecraft/server/PlayerManager.java | 9 +++++++++ .../java/org/bukkit/craftbukkit/CraftWorld.java | 23 +++++----------------- 4 files changed, 33 insertions(+), 22 deletions(-) diff --git a/src/main/java/net/minecraft/server/Chunk.java b/src/main/java/net/minecraft/server/Chunk.java index 192cd6f1..9fedd372 100644 --- a/src/main/java/net/minecraft/server/Chunk.java +++ b/src/main/java/net/minecraft/server/Chunk.java @@ -70,6 +70,7 @@ public class Chunk { } public org.bukkit.Chunk bukkitChunk; + public boolean mustSave; // CraftBukkit end public Chunk(World world, byte[] abyte, int i, int j) { diff --git a/src/main/java/net/minecraft/server/ChunkProviderServer.java b/src/main/java/net/minecraft/server/ChunkProviderServer.java index 7b76b4cd..3242f440 100644 --- a/src/main/java/net/minecraft/server/ChunkProviderServer.java +++ b/src/main/java/net/minecraft/server/ChunkProviderServer.java @@ -37,7 +37,7 @@ public class ChunkProviderServer implements IChunkProvider { } public boolean isChunkLoaded(int i, int j) { - return !this.unloadQueue.containsKey(i, j) && this.chunks.containsKey(i, j); // CraftBukkit + return this.chunks.containsKey(i, j); // CraftBukkit } public void queueUnload(int i, int j) { @@ -47,11 +47,25 @@ public class ChunkProviderServer implements IChunkProvider { int l = j * 16 + 8 - chunkcoordinates.z; short short1 = 128; - if (k < -short1 || k > short1 || l < -short1 || l > short1 || !(this.world.keepSpawnInMemory)) { // CraftBukkit - added 'this.world.keepSpawnInMemory' - this.unloadQueue.add(i, j); // CraftBukkit + // CraftBukkit start + if (k < -short1 || k > short1 || l < -short1 || l > short1 || !(this.world.keepSpawnInMemory)) { // Added 'this.world.keepSpawnInMemory' + this.unloadQueue.add(i, j); + + Chunk c = this.chunks.get(i, j); + if (c != null) { + c.mustSave = true; + } } + // CraftBukkit end } else { - this.unloadQueue.add(i, j); // CraftBukkit + // CraftBukkit start + this.unloadQueue.add(i, j); + + Chunk c = this.chunks.get(i, j); + if (c != null) { + c.mustSave = true; + } + // CraftBukkit end } } diff --git a/src/main/java/net/minecraft/server/PlayerManager.java b/src/main/java/net/minecraft/server/PlayerManager.java index 5409ba77..c824e67c 100644 --- a/src/main/java/net/minecraft/server/PlayerManager.java +++ b/src/main/java/net/minecraft/server/PlayerManager.java @@ -69,6 +69,15 @@ public class PlayerManager { return playerinstance; } + // CraftBukkit start + public final boolean isChunkInUse(int x, int z) { + PlayerInstance pi = a(x, z, false); + if (pi != null) { + return (PlayerInstance.b(pi).size() > 0); + } + return false; + } + // CraftBukkit end public void flagDirty(int i, int j, int k) { int l = i >> 4; diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java index 3208e1c4..30e80c50 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java @@ -161,9 +161,11 @@ public class CraftWorld implements World { } net.minecraft.server.Chunk chunk = world.chunkProviderServer.getOrCreateChunk(x, z); - + if (chunk.mustSave) { // If chunk had previously been queued to save, must do save to avoid loss of that data + save = true; + } + chunk.removeEntities(); // Always remove entities - even if discarding, need to get them out of world table if (save && !(chunk instanceof EmptyChunk)) { - chunk.removeEntities(); world.chunkProviderServer.saveChunk(chunk); world.chunkProviderServer.saveChunkNOP(chunk); } @@ -216,22 +218,7 @@ public class CraftWorld implements World { } public boolean isChunkInUse(int x, int z) { - Player[] players = server.getOnlinePlayers(); - - for (Player player : players) { - Location loc = player.getLocation(); - if (loc.getWorld() != world.chunkProviderServer.world.getWorld()) { - continue; - } - - // If the chunk is within 256 blocks of a player, refuse to accept the unload request - // This is larger than the distance of loaded chunks that actually surround a player - // The player is the center of a 21x21 chunk grid, so the edge is 10 chunks (160 blocks) away from the player - if (Math.abs(loc.getBlockX() - (x << 4)) <= 256 && Math.abs(loc.getBlockZ() - (z << 4)) <= 256) { - return true; - } - } - return false; + return world.getPlayerManager().isChunkInUse(x, z); } public boolean loadChunk(int x, int z, boolean generate) { -- cgit v1.2.3