mirror of
https://github.com/webbukkit/dynmap.git
synced 2024-12-26 18:47:40 +01:00
Combine support for pre 1.4.5 versions and new 1.4.x packaging crud
This commit is contained in:
parent
da5e2cf24a
commit
07cbd84d44
434
src/main/java/org/dynmap/bukkit/BukkitVersionHelper.java
Normal file
434
src/main/java/org/dynmap/bukkit/BukkitVersionHelper.java
Normal file
@ -0,0 +1,434 @@
|
||||
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;
|
||||
|
||||
/**
|
||||
* Helper for isolation of bukkit version specific issues
|
||||
*/
|
||||
public class BukkitVersionHelper {
|
||||
private String obc_package; // Package used for org.bukkit.craftbukkit
|
||||
private String nms_package; // Package used for net.minecraft.server
|
||||
private static BukkitVersionHelper helper;
|
||||
private boolean failed;
|
||||
private static final Object[] nullargs = new Object[0];
|
||||
private static final Map nullmap = Collections.emptyMap();
|
||||
/** BiomeBase related helpers */
|
||||
private Class<?> biomebase;
|
||||
private Class<?> biomebasearray;
|
||||
private Field biomebaselist;
|
||||
private Field biomebasetemp;
|
||||
private Field biomebasehumi;
|
||||
private Field biomebaseidstring;
|
||||
private Field biomebaseid;
|
||||
/** CraftWorld */
|
||||
private Class<?> craftworld;
|
||||
private Method cw_gethandle;
|
||||
/** n.m.s.World */
|
||||
private Class<?> nmsworld;
|
||||
private Class<?> chunkprovserver;
|
||||
private Class<?> longhashset;
|
||||
private Field nmsw_chunkproviderserver;
|
||||
private Field cps_unloadqueue;
|
||||
private Method lhs_containskey;
|
||||
/** CraftChunkSnapshot */
|
||||
private Class<?> craftchunksnapshot;
|
||||
private Field ccss_biome;
|
||||
/** CraftChunk */
|
||||
private Class<?> craftchunk;
|
||||
private Method cc_gethandle;
|
||||
/** o.m.s.Chunk */
|
||||
private Class<?> nmschunk;
|
||||
private Method nmsc_removeentities;
|
||||
private Field nmsc_tileentities;
|
||||
/** nbt classes */
|
||||
private Class<?> nbttagcompound;
|
||||
private Class<?> nbttagbyte;
|
||||
private Class<?> nbttagshort;
|
||||
private Class<?> nbttagint;
|
||||
private Class<?> nbttaglong;
|
||||
private Class<?> nbttagfloat;
|
||||
private Class<?> nbttagdouble;
|
||||
private Class<?> nbttagbytearray;
|
||||
private Class<?> nbttagstring;
|
||||
private Class<?> nbttagintarray;
|
||||
private Method compound_get;
|
||||
private Field nbttagbyte_val;
|
||||
private Field nbttagshort_val;
|
||||
private Field nbttagint_val;
|
||||
private Field nbttaglong_val;
|
||||
private Field nbttagfloat_val;
|
||||
private Field nbttagdouble_val;
|
||||
private Field nbttagbytearray_val;
|
||||
private Field nbttagstring_val;
|
||||
private Field nbttagintarray_val;
|
||||
|
||||
/** Tile entity */
|
||||
private Class<?> nms_tileentity;
|
||||
private Method nmst_readnbt;
|
||||
private Field nmst_x;
|
||||
private Field nmst_y;
|
||||
private Field nmst_z;
|
||||
|
||||
public static final BukkitVersionHelper getHelper() {
|
||||
if(helper == null) {
|
||||
helper = new BukkitVersionHelper();
|
||||
}
|
||||
return helper;
|
||||
}
|
||||
|
||||
private BukkitVersionHelper() {
|
||||
failed = false;
|
||||
Server srv = Bukkit.getServer();
|
||||
/* Look up base classname for bukkit server - tells us OBC package */
|
||||
obc_package = Bukkit.getServer().getClass().getPackage().getName();
|
||||
/* Get getHandle() method */
|
||||
try {
|
||||
Method m = srv.getClass().getMethod("getHandle");
|
||||
Object scm = m.invoke(srv); /* And use it to get SCM (nms object) */
|
||||
nms_package = scm.getClass().getPackage().getName();
|
||||
} catch (Exception x) {
|
||||
Log.severe("Error finding net.minecraft.server packages");
|
||||
nms_package = "net.minecraft.server" + obc_package.substring("org.bukkit.craftbukkit".length());
|
||||
failed = true;
|
||||
}
|
||||
|
||||
/* Set up biomebase fields */
|
||||
biomebase = getNMSClass("net.minecraft.server.BiomeBase");
|
||||
biomebasearray = getNMSClass("[Lnet.minecraft.server.BiomeBase;");
|
||||
biomebaselist = getField(biomebase, new String[] { "biomes" }, biomebasearray);
|
||||
biomebasetemp = getField(biomebase, new String[] { "temperature", "F" }, float.class);
|
||||
biomebasehumi = getField(biomebase, new String[] { "humidity", "G" }, float.class);
|
||||
biomebaseidstring = getField(biomebase, new String[] { "y" }, String.class);
|
||||
biomebaseid = getField(biomebase, new String[] { "id" }, int.class);
|
||||
/* Craftworld fields */
|
||||
craftworld = getOBCClass("org.bukkit.craftbukkit.CraftWorld");
|
||||
cw_gethandle = getMethod(craftworld, new String[] { "getHandle" }, new Class[0]);
|
||||
/* n.m.s.World */
|
||||
nmsworld = getNMSClass("net.minecraft.server.WorldServer");
|
||||
chunkprovserver = getNMSClass("net.minecraft.server.ChunkProviderServer");
|
||||
longhashset = getOBCClassNoFail("org.bukkit.craftbukkit.util.LongHashSet");
|
||||
if(longhashset != null) {
|
||||
lhs_containskey = getMethod(longhashset, new String[] { "contains" }, new Class[] { int.class, int.class });
|
||||
}
|
||||
else {
|
||||
longhashset = getOBCClass("org.bukkit.craftbukkit.util.LongHashset");
|
||||
lhs_containskey = getMethod(longhashset, new String[] { "containsKey" }, new Class[] { int.class, int.class });
|
||||
}
|
||||
nmsw_chunkproviderserver = getField(nmsworld, new String[] { "chunkProviderServer" }, chunkprovserver);
|
||||
cps_unloadqueue = getFieldNoFail(chunkprovserver, new String[] { "unloadQueue" }, longhashset);
|
||||
if(cps_unloadqueue == null) {
|
||||
Log.info("Unload queue not found - default to unload all chunks");
|
||||
}
|
||||
/* CraftChunkSnapshot */
|
||||
craftchunksnapshot = getOBCClass("org.bukkit.craftbukkit.CraftChunkSnapshot");
|
||||
ccss_biome = getPrivateField(craftchunksnapshot, new String[] { "biome" }, biomebasearray);
|
||||
/** CraftChunk */
|
||||
craftchunk = getOBCClass("org.bukkit.craftbukkit.CraftChunk");
|
||||
cc_gethandle = getMethod(craftchunk, new String[] { "getHandle" }, new Class[0]);
|
||||
/** n.m.s.Chunk */
|
||||
nmschunk = getNMSClass("net.minecraft.server.Chunk");
|
||||
nmsc_removeentities = getMethod(nmschunk, new String[] { "removeEntities" }, new Class[0]);
|
||||
nmsc_tileentities = getField(nmschunk, new String[] { "tileEntities" }, Map.class);
|
||||
/** nbt classes */
|
||||
nbttagcompound = getNMSClass("net.minecraft.server.NBTTagCompound");
|
||||
nbttagbyte = getNMSClass("net.minecraft.server.NBTTagByte");
|
||||
nbttagshort = getNMSClass("net.minecraft.server.NBTTagShort");
|
||||
nbttagint = getNMSClass("net.minecraft.server.NBTTagInt");
|
||||
nbttaglong = getNMSClass("net.minecraft.server.NBTTagLong");
|
||||
nbttagfloat = getNMSClass("net.minecraft.server.NBTTagFloat");
|
||||
nbttagdouble = getNMSClass("net.minecraft.server.NBTTagDouble");
|
||||
nbttagbytearray = getNMSClass("net.minecraft.server.NBTTagByteArray");
|
||||
nbttagstring = getNMSClass("net.minecraft.server.NBTTagString");
|
||||
nbttagintarray = getNMSClass("net.minecraft.server.NBTTagIntArray");
|
||||
compound_get = getMethod(nbttagcompound, new String[] { "get" }, new Class[] { String.class });
|
||||
nbttagbyte_val = getField(nbttagbyte, new String[] { "data" }, byte.class);
|
||||
nbttagshort_val = getField(nbttagshort, new String[] { "data" }, short.class);
|
||||
nbttagint_val = getField(nbttagint, new String[] { "data" }, int.class);
|
||||
nbttaglong_val = getField(nbttaglong, new String[] { "data" }, long.class);
|
||||
nbttagfloat_val = getField(nbttagfloat, new String[] { "data" }, float.class);
|
||||
nbttagdouble_val = getField(nbttagdouble, new String[] { "data" }, double.class);
|
||||
nbttagbytearray_val = getField(nbttagbytearray, new String[] { "data" }, byte[].class);
|
||||
nbttagstring_val = getField(nbttagstring, new String[] { "data" }, String.class);
|
||||
nbttagintarray_val = getField(nbttagintarray, new String[] { "data" }, int[].class);
|
||||
|
||||
/** Tile entity */
|
||||
nms_tileentity = getNMSClass("net.minecraft.server.TileEntity");
|
||||
nmst_readnbt = getMethod(nms_tileentity, new String[] { "b" }, new Class[] { nbttagcompound });
|
||||
nmst_x = getField(nms_tileentity, new String[] { "x" }, int.class);
|
||||
nmst_y = getField(nms_tileentity, new String[] { "y" }, int.class);
|
||||
nmst_z = getField(nms_tileentity, new String[] { "z" }, int.class);
|
||||
|
||||
if(failed)
|
||||
throw new IllegalArgumentException("Error initializing dynmap - bukkit version incompatible!");
|
||||
}
|
||||
|
||||
public Class<?> getOBCClass(String classname) {
|
||||
return getClassByName(classname, "org.bukkit.craftbukkit", obc_package, false);
|
||||
}
|
||||
|
||||
public Class<?> getOBCClassNoFail(String classname) {
|
||||
return getClassByName(classname, "org.bukkit.craftbukkit", obc_package, true);
|
||||
}
|
||||
|
||||
public Class<?> getNMSClass(String classname) {
|
||||
return getClassByName(classname, "net.minecraft.server", nms_package, false);
|
||||
}
|
||||
|
||||
public Class<?> getClassByName(String classname, String base, String mapping, boolean nofail) {
|
||||
String n = classname;
|
||||
int idx = classname.indexOf(base);
|
||||
if(idx >= 0) {
|
||||
n = classname.substring(0, idx) + mapping + classname.substring(idx + base.length());
|
||||
}
|
||||
try {
|
||||
return Class.forName(n);
|
||||
} catch (ClassNotFoundException cnfx) {
|
||||
try {
|
||||
return Class.forName(classname);
|
||||
} catch (ClassNotFoundException cnfx2) {
|
||||
if(!nofail) {
|
||||
Log.severe("Cannot find " + classname);
|
||||
failed = true;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Get field
|
||||
*/
|
||||
private Field getField(Class<?> cls, String[] ids, Class<?> type) {
|
||||
return getField(cls, ids, type, false);
|
||||
}
|
||||
private Field getFieldNoFail(Class<?> cls, String[] ids, Class<?> type) {
|
||||
return getField(cls, ids, type, true);
|
||||
}
|
||||
/**
|
||||
* Get field
|
||||
*/
|
||||
private Field getField(Class<?> cls, String[] ids, Class<?> type, boolean nofail) {
|
||||
if((cls == null) || (type == null)) return null;
|
||||
for(String id : ids) {
|
||||
try {
|
||||
Field f = cls.getField(id);
|
||||
if(f.getType().isAssignableFrom(type)) {
|
||||
return f;
|
||||
}
|
||||
} catch (NoSuchFieldException nsfx) {
|
||||
}
|
||||
}
|
||||
if(!nofail) {
|
||||
Log.severe("Unable to find field " + ids[0] + " for " + cls.getName());
|
||||
failed = true;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
/**
|
||||
* Get private field
|
||||
*/
|
||||
private Field getPrivateField(Class<?> cls, String[] ids, Class<?> type) {
|
||||
if((cls == null) || (type == null)) return null;
|
||||
for(String id : ids) {
|
||||
try {
|
||||
Field f = cls.getDeclaredField(id);
|
||||
if(f.getType().isAssignableFrom(type)) {
|
||||
f.setAccessible(true);
|
||||
return f;
|
||||
}
|
||||
} catch (NoSuchFieldException nsfx) {
|
||||
}
|
||||
}
|
||||
Log.severe("Unable to find field " + ids[0] + " for " + cls.getName());
|
||||
failed = true;
|
||||
return null;
|
||||
}
|
||||
private Object getFieldValue(Object obj, Field field, Object def) {
|
||||
if((obj != null) && (field != null)) {
|
||||
try {
|
||||
return field.get(obj);
|
||||
} catch (IllegalArgumentException e) {
|
||||
} catch (IllegalAccessException e) {
|
||||
}
|
||||
}
|
||||
return def;
|
||||
}
|
||||
/**
|
||||
* Get method
|
||||
*/
|
||||
private Method getMethod(Class<?> cls, String[] ids, Class[] args) {
|
||||
if(cls == null) return null;
|
||||
for(String id : ids) {
|
||||
try {
|
||||
return cls.getMethod(id, args);
|
||||
} catch (SecurityException e) {
|
||||
} catch (NoSuchMethodException e) {
|
||||
}
|
||||
}
|
||||
Log.severe("Unable to find method " + ids[0] + " for " + cls.getName());
|
||||
failed = true;
|
||||
return null;
|
||||
}
|
||||
private Object callMethod(Object obj, Method meth, Object[] args, Object def) {
|
||||
if((obj == null) || (meth == null)) {
|
||||
return def;
|
||||
}
|
||||
try {
|
||||
return meth.invoke(obj, args);
|
||||
} catch (IllegalArgumentException iax) {
|
||||
} catch (IllegalAccessException e) {
|
||||
} catch (InvocationTargetException e) {
|
||||
}
|
||||
return def;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get list of defined biomebase objects
|
||||
*/
|
||||
public Object[] getBiomeBaseList() {
|
||||
return (Object[]) getFieldValue(biomebase, biomebaselist, new Object[0]);
|
||||
}
|
||||
/** Get temperature from biomebase */
|
||||
public float getBiomeBaseTemperature(Object bb) {
|
||||
return (Float) getFieldValue(bb, biomebasetemp, 0.5F);
|
||||
}
|
||||
/** Get humidity from biomebase */
|
||||
public float getBiomeBaseHumidity(Object bb) {
|
||||
return (Float) getFieldValue(bb, biomebasehumi, 0.5F);
|
||||
}
|
||||
/** Get ID string from biomebase */
|
||||
public String getBiomeBaseIDString(Object bb) {
|
||||
return (String) getFieldValue(bb, biomebaseidstring, null);
|
||||
}
|
||||
/** Get ID from biomebase */
|
||||
public int getBiomeBaseID(Object bb) {
|
||||
return (Integer) getFieldValue(bb, biomebaseid, -1);
|
||||
}
|
||||
|
||||
/* Get net.minecraft.server.world for given world */
|
||||
public Object getNMSWorld(World w) {
|
||||
return callMethod(w, cw_gethandle, nullargs, null);
|
||||
}
|
||||
|
||||
/* Get unload queue for given NMS world */
|
||||
public Object getUnloadQueue(Object nmsworld) {
|
||||
Object cps = getFieldValue(nmsworld, nmsw_chunkproviderserver, null); // Get chunkproviderserver
|
||||
if(cps != null) {
|
||||
return getFieldValue(cps, cps_unloadqueue, null);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/* For testing unload queue for presence of givne chunk */
|
||||
public boolean isInUnloadQueue(Object unloadqueue, int x, int z) {
|
||||
if(unloadqueue != null) {
|
||||
return (Boolean)callMethod(unloadqueue, lhs_containskey, new Object[] { x, z }, true);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public Object[] getBiomeBaseFromSnapshot(ChunkSnapshot css) {
|
||||
return (Object[])getFieldValue(css, ccss_biome, null);
|
||||
}
|
||||
public boolean isCraftChunkSnapshot(ChunkSnapshot css) {
|
||||
if(craftchunksnapshot != null) {
|
||||
return craftchunksnapshot.isAssignableFrom(css.getClass());
|
||||
}
|
||||
return false;
|
||||
}
|
||||
/** Remove entities from given chunk */
|
||||
public void removeEntitiesFromChunk(Chunk c) {
|
||||
Object omsc = callMethod(c, cc_gethandle, nullargs, null);
|
||||
if(omsc != null) {
|
||||
callMethod(omsc, nmsc_removeentities, nullargs, null);
|
||||
}
|
||||
}
|
||||
/** Get tile entities map from chunk */
|
||||
public Map getTileEntitiesForChunk(Chunk c) {
|
||||
Object omsc = callMethod(c, cc_gethandle, nullargs, null);
|
||||
if(omsc != null) {
|
||||
return (Map)getFieldValue(omsc, nmsc_tileentities, nullmap);
|
||||
}
|
||||
return nullmap;
|
||||
}
|
||||
/**
|
||||
* Get X coordinate of tile entity
|
||||
*/
|
||||
public int getTileEntityX(Object te) {
|
||||
return (Integer)getFieldValue(te, nmst_x, 0);
|
||||
}
|
||||
/**
|
||||
* Get Y coordinate of tile entity
|
||||
*/
|
||||
public int getTileEntityY(Object te) {
|
||||
return (Integer)getFieldValue(te, nmst_y, 0);
|
||||
}
|
||||
/**
|
||||
* Get Z coordinate of tile entity
|
||||
*/
|
||||
public int getTileEntityZ(Object te) {
|
||||
return (Integer)getFieldValue(te, nmst_z, 0);
|
||||
}
|
||||
/**
|
||||
* Read tile entity NBT
|
||||
*/
|
||||
public Object readTileEntityNBT(Object te) {
|
||||
if(nbttagcompound == null) return null;
|
||||
Object nbt = null;
|
||||
try {
|
||||
nbt = nbttagcompound.newInstance();
|
||||
} catch (InstantiationException e) {
|
||||
} catch (IllegalAccessException e) {
|
||||
}
|
||||
if(nbt != null) {
|
||||
callMethod(te, nmst_readnbt, new Object[] { nbt }, null);
|
||||
}
|
||||
return nbt;
|
||||
}
|
||||
/**
|
||||
* Get field value from NBT compound
|
||||
*/
|
||||
public Object getFieldValue(Object nbt, String field) {
|
||||
Object val = callMethod(nbt, compound_get, new Object[] { field }, null);
|
||||
if(val == null) return null;
|
||||
Class<?> valcls = val.getClass();
|
||||
if(valcls.equals(nbttagbyte)) {
|
||||
return getFieldValue(val, nbttagbyte_val, null);
|
||||
}
|
||||
else if(valcls.equals(nbttagshort)) {
|
||||
return getFieldValue(val, nbttagshort_val, null);
|
||||
}
|
||||
else if(valcls.equals(nbttagint)) {
|
||||
return getFieldValue(val, nbttagint_val, null);
|
||||
}
|
||||
else if(valcls.equals(nbttaglong)) {
|
||||
return getFieldValue(val, nbttaglong_val, null);
|
||||
}
|
||||
else if(valcls.equals(nbttagfloat)) {
|
||||
return getFieldValue(val, nbttagfloat_val, null);
|
||||
}
|
||||
else if(valcls.equals(nbttagdouble)) {
|
||||
return getFieldValue(val, nbttagdouble_val, null);
|
||||
}
|
||||
else if(valcls.equals(nbttagbytearray)) {
|
||||
return getFieldValue(val, nbttagbytearray_val, null);
|
||||
}
|
||||
else if(valcls.equals(nbttagstring)) {
|
||||
return getFieldValue(val, nbttagstring_val, null);
|
||||
}
|
||||
else if(valcls.equals(nbttagintarray)) {
|
||||
return getFieldValue(val, nbttagintarray_val, null);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
@ -2,7 +2,6 @@ package org.dynmap.bukkit;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.net.InetSocketAddress;
|
||||
@ -16,8 +15,6 @@ import java.util.concurrent.Callable;
|
||||
import java.util.concurrent.CancellationException;
|
||||
import java.util.concurrent.Future;
|
||||
|
||||
import net.minecraft.server.BiomeBase;
|
||||
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.Chunk;
|
||||
import org.bukkit.Location;
|
||||
@ -60,8 +57,6 @@ import org.bukkit.event.world.SpawnChangeEvent;
|
||||
import org.bukkit.event.world.StructureGrowEvent;
|
||||
import org.bukkit.event.world.WorldLoadEvent;
|
||||
import org.bukkit.event.world.WorldUnloadEvent;
|
||||
import org.bukkit.material.MaterialData;
|
||||
import org.bukkit.material.Tree;
|
||||
import org.bukkit.permissions.Permission;
|
||||
import org.bukkit.permissions.PermissionDefault;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
@ -113,6 +108,8 @@ public class DynmapPlugin extends JavaPlugin implements DynmapAPI {
|
||||
private World last_world;
|
||||
private BukkitWorld last_bworld;
|
||||
|
||||
private BukkitVersionHelper helper = BukkitVersionHelper.getHelper();
|
||||
|
||||
private final BukkitWorld getWorldByName(String name) {
|
||||
if((last_world != null) && (last_world.getName().equals(name))) {
|
||||
return last_bworld;
|
||||
@ -636,58 +633,30 @@ public class DynmapPlugin extends JavaPlugin implements DynmapAPI {
|
||||
}
|
||||
|
||||
public void loadExtraBiomes() {
|
||||
Field tmpfld;
|
||||
Field humfld;
|
||||
int cnt = 0;
|
||||
try {
|
||||
tmpfld = BiomeBase.class.getField("temperature");
|
||||
} catch (NoSuchFieldException nsfx) {
|
||||
try {
|
||||
tmpfld = BiomeBase.class.getField("F");
|
||||
} catch (NoSuchFieldException nsfx2) {
|
||||
Log.warning("BiomeBase.temperature field not found");
|
||||
tmpfld = null;
|
||||
}
|
||||
}
|
||||
if((tmpfld != null) && (tmpfld.getType().getClass().isAssignableFrom(float.class) == false)) {
|
||||
tmpfld = null;
|
||||
}
|
||||
try {
|
||||
humfld = BiomeBase.class.getField("humidity");
|
||||
} catch (NoSuchFieldException nsfx) {
|
||||
try {
|
||||
humfld = BiomeBase.class.getField("G");
|
||||
} catch (NoSuchFieldException nsfx2) {
|
||||
Log.warning("BiomeBase.humidity field not found");
|
||||
humfld = null;
|
||||
}
|
||||
}
|
||||
if((humfld != null) && (humfld.getType().getClass().isAssignableFrom(float.class) == false)) {
|
||||
humfld = null;
|
||||
}
|
||||
|
||||
for(int i = BiomeMap.LAST_WELL_KNOWN+1; i < BiomeBase.biomes.length; i++) {
|
||||
BiomeBase bb = BiomeBase.biomes[i];
|
||||
/* Find array of biomes in biomebase */
|
||||
Object[] biomelist = helper.getBiomeBaseList();
|
||||
/* Loop through list, starting afer well known biomes */
|
||||
for(int i = BiomeMap.LAST_WELL_KNOWN+1; i < biomelist.length; i++) {
|
||||
Object bb = biomelist[i];
|
||||
if(bb != null) {
|
||||
String id = "BIOME_" + i;
|
||||
float tmp = 0.5F, hum = 0.5F;
|
||||
try {
|
||||
id = bb.y;
|
||||
} catch (Exception x) {}
|
||||
try {
|
||||
if(tmpfld != null)
|
||||
tmp = tmpfld.getFloat(bb);
|
||||
if(humfld != null)
|
||||
hum = humfld.getFloat(bb);
|
||||
} catch (Exception x) {
|
||||
String id = helper.getBiomeBaseIDString(bb);
|
||||
if(id == null) {
|
||||
id = "BIOME_" + i;
|
||||
}
|
||||
float tmp = helper.getBiomeBaseTemperature(bb);
|
||||
float hum = helper.getBiomeBaseHumidity(bb);
|
||||
|
||||
BiomeMap m = new BiomeMap(i, id, tmp, hum);
|
||||
Log.verboseinfo("Add custom biome [" + m.toString() + "] (" + i + ")");
|
||||
cnt++;
|
||||
}
|
||||
}
|
||||
if(cnt > 0) {
|
||||
Log.info("Added " + cnt + " custom biome mappings");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onEnable() {
|
||||
|
@ -1,33 +1,13 @@
|
||||
package org.dynmap.bukkit;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.ListIterator;
|
||||
|
||||
import net.minecraft.server.BiomeBase;
|
||||
import net.minecraft.server.ChunkProviderServer;
|
||||
import net.minecraft.server.NBTBase;
|
||||
import net.minecraft.server.NBTTagByte;
|
||||
import net.minecraft.server.NBTTagByteArray;
|
||||
import net.minecraft.server.NBTTagCompound;
|
||||
import net.minecraft.server.NBTTagDouble;
|
||||
import net.minecraft.server.NBTTagFloat;
|
||||
import net.minecraft.server.NBTTagInt;
|
||||
import net.minecraft.server.NBTTagIntArray;
|
||||
import net.minecraft.server.NBTTagLong;
|
||||
import net.minecraft.server.NBTTagShort;
|
||||
import net.minecraft.server.NBTTagString;
|
||||
import net.minecraft.server.TileEntity;
|
||||
import java.util.Map;
|
||||
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.Chunk;
|
||||
import org.bukkit.block.Biome;
|
||||
import org.bukkit.craftbukkit.CraftChunk;
|
||||
import org.bukkit.craftbukkit.CraftChunkSnapshot;
|
||||
import org.bukkit.craftbukkit.CraftWorld;
|
||||
import org.bukkit.ChunkSnapshot;
|
||||
import org.dynmap.DynmapChunk;
|
||||
import org.dynmap.DynmapCore;
|
||||
@ -49,10 +29,6 @@ import org.getspout.spoutapi.block.SpoutChunk;
|
||||
public class NewMapChunkCache implements MapChunkCache {
|
||||
private static boolean init = false;
|
||||
private static boolean use_spout = false;
|
||||
private static Field unloadqueue = null;
|
||||
private static Method queuecontainskey = null;
|
||||
private static Field biomesnapshot = null;
|
||||
|
||||
|
||||
private World w;
|
||||
private DynmapWorld dw;
|
||||
@ -80,6 +56,8 @@ public class NewMapChunkCache implements MapChunkCache {
|
||||
|
||||
private long exceptions;
|
||||
|
||||
private static BukkitVersionHelper helper = BukkitVersionHelper.getHelper();
|
||||
|
||||
private static final BlockStep unstep[] = { BlockStep.X_MINUS, BlockStep.Y_MINUS, BlockStep.Z_MINUS,
|
||||
BlockStep.X_PLUS, BlockStep.Y_PLUS, BlockStep.Z_PLUS };
|
||||
|
||||
@ -168,29 +146,23 @@ public class NewMapChunkCache implements MapChunkCache {
|
||||
sameneighborbiomecnt[i] = new byte[z_size];
|
||||
biomemap[i] = new BiomeMap[z_size];
|
||||
}
|
||||
BiomeBase[] biomebase = null;
|
||||
Object[] biomebase = null;
|
||||
ChunkSnapshot biome_css = null;
|
||||
for(int i = 0; i < x_size; i++) {
|
||||
initialize(i + x_base, 64, z_base);
|
||||
for(int j = 0; j < z_size; j++) {
|
||||
BiomeMap bm;
|
||||
|
||||
if((biomesnapshot != null) && (snap != biome_css)) {
|
||||
if(snap != biome_css) {
|
||||
biomebase = null;
|
||||
biome_css = snap;
|
||||
try {
|
||||
if (biome_css instanceof SpoutChunkSnapshot) {
|
||||
biome_css = ((SpoutChunkSnapshot)biome_css).chunk;
|
||||
}
|
||||
if(biome_css instanceof CraftChunkSnapshot) {
|
||||
biomebase = (BiomeBase[]) biomesnapshot.get(biome_css);
|
||||
}
|
||||
} catch (IllegalArgumentException iax) {
|
||||
} catch (IllegalAccessException e) {
|
||||
}
|
||||
biomebase = helper.getBiomeBaseFromSnapshot(biome_css);
|
||||
}
|
||||
if(biomebase != null) {
|
||||
bm = BiomeMap.byBiomeID(biomebase[bz << 4 | bx].id);
|
||||
bm = BiomeMap.byBiomeID(helper.getBiomeBaseID(biomebase[bz << 4 | bx]));
|
||||
}
|
||||
else {
|
||||
Biome bb = snap.getBiome(bx, bz);
|
||||
@ -758,28 +730,6 @@ public class NewMapChunkCache implements MapChunkCache {
|
||||
if(!init) {
|
||||
use_spout = DynmapPlugin.plugin.hasSpout();
|
||||
|
||||
try {
|
||||
unloadqueue = ChunkProviderServer.class.getField("unloadQueue");
|
||||
Class cls = unloadqueue.getType();
|
||||
String nm = cls.getName();
|
||||
if (nm.equals("org.bukkit.craftbukkit.util.LongHashset")) {
|
||||
queuecontainskey = unloadqueue.getType().getMethod("containsKey", new Class[] { int.class, int.class });
|
||||
}
|
||||
else {
|
||||
unloadqueue = null;
|
||||
}
|
||||
} catch (NoSuchFieldException nsfx) {
|
||||
unloadqueue = null;
|
||||
} catch (NoSuchMethodException nsmx) {
|
||||
unloadqueue = null;
|
||||
}
|
||||
try {
|
||||
biomesnapshot = CraftChunkSnapshot.class.getDeclaredField("biome");
|
||||
biomesnapshot.setAccessible(true);
|
||||
} catch (NoSuchFieldException nsfx) {
|
||||
biomesnapshot = null;
|
||||
Log.warning("Unable to find biome field in ChunkSnapshot");
|
||||
}
|
||||
init = true;
|
||||
}
|
||||
}
|
||||
@ -836,15 +786,8 @@ public class NewMapChunkCache implements MapChunkCache {
|
||||
if(dw.isLoaded() == false)
|
||||
return 0;
|
||||
long t0 = System.nanoTime();
|
||||
CraftWorld cw = (CraftWorld)w;
|
||||
Object queue = null;
|
||||
try {
|
||||
if (unloadqueue != null) {
|
||||
queue = unloadqueue.get(cw.getHandle().chunkProviderServer);
|
||||
}
|
||||
} catch (IllegalArgumentException iax) {
|
||||
} catch (IllegalAccessException e) {
|
||||
}
|
||||
Object queue = helper.getUnloadQueue(helper.getNMSWorld(w));
|
||||
|
||||
int cnt = 0;
|
||||
if(iterator == null)
|
||||
iterator = chunks.listIterator();
|
||||
@ -897,12 +840,7 @@ public class NewMapChunkCache implements MapChunkCache {
|
||||
boolean didload = false;
|
||||
boolean isunloadpending = false;
|
||||
if (queue != null) {
|
||||
try {
|
||||
isunloadpending = (Boolean)queuecontainskey.invoke(queue, chunk.x, chunk.z);
|
||||
} catch (IllegalAccessException iax) {
|
||||
} catch (IllegalArgumentException e) {
|
||||
} catch (InvocationTargetException e) {
|
||||
}
|
||||
isunloadpending = helper.isInUnloadQueue(queue, chunk.x, chunk.z);
|
||||
}
|
||||
if (isunloadpending) { /* Workaround: can't be pending if not loaded */
|
||||
wasLoaded = true;
|
||||
@ -958,62 +896,30 @@ public class NewMapChunkCache implements MapChunkCache {
|
||||
}
|
||||
/* Get tile entity data */
|
||||
List<Object> vals = new ArrayList<Object>();
|
||||
for(Object t : ((CraftChunk)c).getHandle().tileEntities.values()) {
|
||||
TileEntity te = (TileEntity)t;
|
||||
int cx = te.x & 0xF;
|
||||
int cz = te.z & 0xF;
|
||||
int blkid = ss.getBlockTypeId(cx, te.y, cz);
|
||||
int blkdat = ss.getBlockData(cx, te.y, cz);
|
||||
Map tileents = helper.getTileEntitiesForChunk(c);
|
||||
for(Object t : tileents.values()) {
|
||||
int te_x = helper.getTileEntityX(t);
|
||||
int te_y = helper.getTileEntityY(t);
|
||||
int te_z = helper.getTileEntityZ(t);
|
||||
int cx = te_x & 0xF;
|
||||
int cz = te_z & 0xF;
|
||||
int blkid = ss.getBlockTypeId(cx, te_y, cz);
|
||||
int blkdat = ss.getBlockData(cx, te_y, cz);
|
||||
String[] te_fields = HDBlockModels.getTileEntityFieldsNeeded(blkid, blkdat);
|
||||
if(te_fields != null) {
|
||||
NBTTagCompound tc = new NBTTagCompound();
|
||||
try {
|
||||
te.b(tc);
|
||||
} catch (Exception x) {
|
||||
}
|
||||
Object nbtcompound = helper.readTileEntityNBT(t);
|
||||
|
||||
vals.clear();
|
||||
for(String id: te_fields) {
|
||||
NBTBase v = tc.get(id); /* Get field */
|
||||
if(v != null) {
|
||||
Object val = null;
|
||||
switch(v.getTypeId()) {
|
||||
case 1: // Byte
|
||||
val = Byte.valueOf(((NBTTagByte)v).data);
|
||||
break;
|
||||
case 2: // Short
|
||||
val = Short.valueOf(((NBTTagShort)v).data);
|
||||
break;
|
||||
case 3: // Int
|
||||
val = Integer.valueOf(((NBTTagInt)v).data);
|
||||
break;
|
||||
case 4: // Long
|
||||
val = Long.valueOf(((NBTTagLong)v).data);
|
||||
break;
|
||||
case 5: // Float
|
||||
val = Float.valueOf(((NBTTagFloat)v).data);
|
||||
break;
|
||||
case 6: // Double
|
||||
val = Double.valueOf(((NBTTagDouble)v).data);
|
||||
break;
|
||||
case 7: // Byte[]
|
||||
val = ((NBTTagByteArray)v).data;
|
||||
break;
|
||||
case 8: // String
|
||||
val = ((NBTTagString)v).data;
|
||||
break;
|
||||
case 11: // Int[]
|
||||
val = ((NBTTagIntArray)v).data;
|
||||
break;
|
||||
}
|
||||
Object val = helper.getFieldValue(nbtcompound, id);
|
||||
if(val != null) {
|
||||
vals.add(id);
|
||||
vals.add(val);
|
||||
}
|
||||
}
|
||||
}
|
||||
if(vals.size() > 0) {
|
||||
Object[] vlist = vals.toArray(new Object[vals.size()]);
|
||||
tileData.put(getIndexInChunk(cx,te.y,cz), vlist);
|
||||
tileData.put(getIndexInChunk(cx,te_y,cz), vlist);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1036,8 +942,7 @@ public class NewMapChunkCache implements MapChunkCache {
|
||||
/* 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 */
|
||||
if(!(didgenerate && do_save)) {
|
||||
CraftChunk cc = (CraftChunk)c;
|
||||
cc.getHandle().removeEntities();
|
||||
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
|
||||
|
Loading…
Reference in New Issue
Block a user