Workaround for CB 953 furnace freakout (fixed in CB955)

This commit is contained in:
Mike Primm 2011-07-03 12:03:06 -05:00
parent e724a7bccb
commit c393eec159

View File

@ -25,6 +25,8 @@ public class NewMapChunkCache implements MapChunkCache {
private static Method poppreservedchunk = null; private static Method poppreservedchunk = null;
private static Method getsnapshot2 = null; private static Method getsnapshot2 = null;
private static Method getemptysnapshot = null; private static Method getemptysnapshot = null;
private static Method gethandle = null;
private static Method removeentities = null;
private World w; private World w;
private List<DynmapChunk> chunks; private List<DynmapChunk> chunks;
@ -230,10 +232,18 @@ public class NewMapChunkCache implements MapChunkCache {
} catch (ClassNotFoundException cnfx) { } catch (ClassNotFoundException cnfx) {
} catch (NoSuchMethodException nsmx) { } catch (NoSuchMethodException nsmx) {
} }
/* Get CraftChunk.getChunkSnapshot(boolean,boolean,boolean) */ /* Get CraftChunk.getChunkSnapshot(boolean,boolean,boolean) and CraftChunk.getHandle() */
try { try {
Class c = Class.forName("org.bukkit.craftbukkit.CraftChunk"); Class c = Class.forName("org.bukkit.craftbukkit.CraftChunk");
getsnapshot2 = c.getDeclaredMethod("getChunkSnapshot", new Class[] { boolean.class, boolean.class, boolean.class }); getsnapshot2 = c.getDeclaredMethod("getChunkSnapshot", new Class[] { boolean.class, boolean.class, boolean.class });
gethandle = c.getDeclaredMethod("getHandle", new Class[0]);
} catch (ClassNotFoundException cnfx) {
} catch (NoSuchMethodException nsmx) {
}
/* Get Chunk.removeEntities() */
try {
Class c = Class.forName("net.minecraft.server.Chunk");
removeentities = c.getDeclaredMethod("removeEntities", new Class[0]);
} catch (ClassNotFoundException cnfx) { } catch (ClassNotFoundException cnfx) {
} catch (NoSuchMethodException nsmx) { } catch (NoSuchMethodException nsmx) {
} }
@ -341,13 +351,28 @@ public class NewMapChunkCache implements MapChunkCache {
if ((!wasLoaded) && didload) { if ((!wasLoaded) && didload) {
/* It looks like bukkit "leaks" entities - they don't get removed from the world-level table /* 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 */ * when chunks are unloaded but not saved - removing them seems to do the trick */
if(!didgenerate) { if(!(didgenerate && do_save)) {
boolean did_remove = false;
Chunk cc = w.getChunkAt(chunk.x, chunk.z); Chunk cc = w.getChunkAt(chunk.x, chunk.z);
if((gethandle != null) && (removeentities != null)) {
try {
Object chk = gethandle.invoke(cc);
if(chk != null) {
removeentities.invoke(chk);
did_remove = true;
}
} catch (InvocationTargetException itx) {
} catch (IllegalArgumentException e) {
} catch (IllegalAccessException e) {
}
}
if(!did_remove) {
if(cc != null) { if(cc != null) {
for(Entity e: cc.getEntities()) for(Entity e: cc.getEntities())
e.remove(); e.remove();
} }
} }
}
/* Since we only remember ones we loaded, and we're synchronous, no player has /* 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 * 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, * because isChunkInUse defined "in use" as being within 256 blocks of a player,