From 0d25fd2edcc57c189e98360e8fa348db45db67c0 Mon Sep 17 00:00:00 2001 From: Mike Primm Date: Mon, 18 Mar 2013 20:30:13 -0500 Subject: [PATCH] Make sure chunk unload queue is processed quickly enough on MCPC --- .../dynmap/bukkit/BukkitVersionHelper.java | 2 +- .../BukkitVersionHelperBukkitForge.java | 2 +- .../dynmap/bukkit/BukkitVersionHelperCB.java | 7 ++---- .../bukkit/BukkitVersionHelperGeneric.java | 2 +- .../bukkit/BukkitVersionHelperMCPC.java | 23 ++++++++++++++++++- .../org/dynmap/bukkit/NewMapChunkCache.java | 5 +--- 6 files changed, 28 insertions(+), 13 deletions(-) diff --git a/src/main/java/org/dynmap/bukkit/BukkitVersionHelper.java b/src/main/java/org/dynmap/bukkit/BukkitVersionHelper.java index 63c386e6..49311e48 100644 --- a/src/main/java/org/dynmap/bukkit/BukkitVersionHelper.java +++ b/src/main/java/org/dynmap/bukkit/BukkitVersionHelper.java @@ -109,5 +109,5 @@ public abstract class BukkitVersionHelper { /** * Unload chunk no save needed */ - public abstract void unloadChunkNoSave(World w, int cx, int cz); + public abstract void unloadChunkNoSave(World w, Chunk c, int cx, int cz); } diff --git a/src/main/java/org/dynmap/bukkit/BukkitVersionHelperBukkitForge.java b/src/main/java/org/dynmap/bukkit/BukkitVersionHelperBukkitForge.java index 4b553160..0ffb089f 100644 --- a/src/main/java/org/dynmap/bukkit/BukkitVersionHelperBukkitForge.java +++ b/src/main/java/org/dynmap/bukkit/BukkitVersionHelperBukkitForge.java @@ -96,7 +96,7 @@ public class BukkitVersionHelperBukkitForge extends BukkitVersionHelperGeneric { return true; } @Override - public void unloadChunkNoSave(World w, int cx, int cz) { + public void unloadChunkNoSave(World w, Chunk c, int cx, int cz) { w.unloadChunkRequest(cx, cz); } } diff --git a/src/main/java/org/dynmap/bukkit/BukkitVersionHelperCB.java b/src/main/java/org/dynmap/bukkit/BukkitVersionHelperCB.java index 5a5b9cae..bfc1cd10 100644 --- a/src/main/java/org/dynmap/bukkit/BukkitVersionHelperCB.java +++ b/src/main/java/org/dynmap/bukkit/BukkitVersionHelperCB.java @@ -1,13 +1,9 @@ package org.dynmap.bukkit; -import java.lang.reflect.Field; -import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; -import java.util.Collections; import java.util.Map; import org.bukkit.Bukkit; import org.bukkit.Chunk; -import org.bukkit.ChunkSnapshot; import org.bukkit.Server; import org.bukkit.World; import org.dynmap.Log; @@ -94,7 +90,8 @@ public class BukkitVersionHelperCB extends BukkitVersionHelperGeneric { nmst_z = getField(nms_tileentity, new String[] { "z" }, int.class); } @Override - public void unloadChunkNoSave(World w, int cx, int cz) { + public void unloadChunkNoSave(World w, Chunk c, int cx, int cz) { + this.removeEntitiesFromChunk(c); w.unloadChunk(cx, cz, false, false); } diff --git a/src/main/java/org/dynmap/bukkit/BukkitVersionHelperGeneric.java b/src/main/java/org/dynmap/bukkit/BukkitVersionHelperGeneric.java index a5cafb33..f413a5de 100644 --- a/src/main/java/org/dynmap/bukkit/BukkitVersionHelperGeneric.java +++ b/src/main/java/org/dynmap/bukkit/BukkitVersionHelperGeneric.java @@ -190,7 +190,7 @@ public abstract class BukkitVersionHelperGeneric extends BukkitVersionHelper { failed = true; return null; } - private Object getFieldValue(Object obj, Field field, Object def) { + protected Object getFieldValue(Object obj, Field field, Object def) { if((obj != null) && (field != null)) { try { return field.get(obj); diff --git a/src/main/java/org/dynmap/bukkit/BukkitVersionHelperMCPC.java b/src/main/java/org/dynmap/bukkit/BukkitVersionHelperMCPC.java index e41d15fe..ccc2257c 100644 --- a/src/main/java/org/dynmap/bukkit/BukkitVersionHelperMCPC.java +++ b/src/main/java/org/dynmap/bukkit/BukkitVersionHelperMCPC.java @@ -16,6 +16,9 @@ import org.dynmap.Log; * Helper for isolation of bukkit version specific issues */ public class BukkitVersionHelperMCPC extends BukkitVersionHelperGeneric { + private Method cps_unload100; + private int cnt; + BukkitVersionHelperMCPC() { } @Override @@ -69,6 +72,8 @@ public class BukkitVersionHelperMCPC extends BukkitVersionHelperGeneric { if(cps_unloadqueue == null) { Log.info("Unload queue not found - default to unload all chunks"); } + cps_unload100 = getMethod(chunkprovserver, new String[] { "b" }, new Class[0]); + nmsc_removeentities = getMethod(nmschunk, new String[] { "d" }, new Class[0]); nmsc_tileentities = getField(nmschunk, new String[] { "i" }, Map.class); /* nbt */ @@ -89,7 +94,23 @@ public class BukkitVersionHelperMCPC extends BukkitVersionHelperGeneric { nmst_z = getField(nms_tileentity, new String[] { "n" }, int.class); } @Override - public void unloadChunkNoSave(World w, int cx, int cz) { + public void unloadChunkNoSave(World w, Chunk c, int cx, int cz) { w.unloadChunkRequest(cx, cz); + cnt++; + if(cnt > 20) { + cnt = 0; + Object nmsw = this.getNMSWorld(w); + if((nmsw != null) && (cps_unload100 != null)) { + Object cps = getFieldValue(nmsw, nmsw_chunkproviderserver, null); // Get chunkproviderserver + if(cps != null) { + try { + this.cps_unload100.invoke(cps, new Object[0]); + } catch (IllegalArgumentException e) { + } catch (IllegalAccessException e) { + } catch (InvocationTargetException e) { + } + } + } + } } } diff --git a/src/main/java/org/dynmap/bukkit/NewMapChunkCache.java b/src/main/java/org/dynmap/bukkit/NewMapChunkCache.java index e00a2c64..ec5de49b 100644 --- a/src/main/java/org/dynmap/bukkit/NewMapChunkCache.java +++ b/src/main/java/org/dynmap/bukkit/NewMapChunkCache.java @@ -935,16 +935,13 @@ public class NewMapChunkCache implements MapChunkCache { /* If wasn't loaded before, we need to do unload */ if (!wasLoaded) { chunks_read++; - /* It looks like bukkit "leaks" entities - they don't get removed from the world-level table - * when chunks are unloaded but not saved - removing them seems to do the trick */ - helper.removeEntitiesFromChunk(c); /* Since we only remember ones we loaded, and we're synchronous, no player has * moved, so it must be safe (also prevent chunk leak, which appears to happen * because isChunkInUse defined "in use" as being within 256 blocks of a player, * while the actual in-use chunk area for a player where the chunks are managed * by the MC base server is 21x21 (or about a 160 block radius). * Also, if we did generate it, need to save it */ - helper.unloadChunkNoSave(w, chunk.x, chunk.z); + helper.unloadChunkNoSave(w, c, chunk.x, chunk.z); } else if (isunloadpending) { /* Else, if loaded and unload is pending */ w.unloadChunkRequest(chunk.x, chunk.z); /* Request new unload */