Make sure chunk unload queue is processed quickly enough on MCPC

This commit is contained in:
Mike Primm 2013-03-18 20:30:13 -05:00
parent bee16ef331
commit 0d25fd2edc
6 changed files with 28 additions and 13 deletions

View File

@ -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);
}

View File

@ -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);
}
}

View File

@ -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);
}

View File

@ -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);

View File

@ -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) {
}
}
}
}
}
}

View File

@ -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 */