mirror of
https://github.com/essentials/Essentials.git
synced 2025-09-02 19:22:37 +02:00
Better Location code for lazy loading worlds
This fixes problems with worlds that are loaded after the Location object is created and should prevent memory leaks when a world is unloaded.
This commit is contained in:
@@ -19,6 +19,7 @@ package com.earth2me.essentials;
|
|||||||
|
|
||||||
import static com.earth2me.essentials.I18n._;
|
import static com.earth2me.essentials.I18n._;
|
||||||
import com.earth2me.essentials.api.*;
|
import com.earth2me.essentials.api.*;
|
||||||
|
import com.earth2me.essentials.craftbukkit.BetterLocation;
|
||||||
import com.earth2me.essentials.craftbukkit.ItemDupeFix;
|
import com.earth2me.essentials.craftbukkit.ItemDupeFix;
|
||||||
import com.earth2me.essentials.listener.*;
|
import com.earth2me.essentials.listener.*;
|
||||||
import com.earth2me.essentials.perm.PermissionsHandler;
|
import com.earth2me.essentials.perm.PermissionsHandler;
|
||||||
@@ -230,6 +231,10 @@ public class Essentials extends JavaPlugin implements IEssentials
|
|||||||
reloadList.add(jails);
|
reloadList.add(jails);
|
||||||
|
|
||||||
pm.registerEvent(Type.ENTITY_EXPLODE, tntListener, Priority.High, this);
|
pm.registerEvent(Type.ENTITY_EXPLODE, tntListener, Priority.High, this);
|
||||||
|
|
||||||
|
pm.registerEvent(Type.WORLD_LOAD, BetterLocation.getListener(), Priority.Monitor, this);
|
||||||
|
pm.registerEvent(Type.WORLD_UNLOAD, BetterLocation.getListener(), Priority.Monitor, this);
|
||||||
|
getServer().getScheduler().scheduleAsyncRepeatingTask(this, BetterLocation.getListener(), 200, 200);
|
||||||
|
|
||||||
final EssentialsTimer timer = new EssentialsTimer(this);
|
final EssentialsTimer timer = new EssentialsTimer(this);
|
||||||
getServer().getScheduler().scheduleSyncRepeatingTask(this, timer, 1, 100);
|
getServer().getScheduler().scheduleSyncRepeatingTask(this, timer, 1, 100);
|
||||||
@@ -249,6 +254,7 @@ public class Essentials extends JavaPlugin implements IEssentials
|
|||||||
i18n.onDisable();
|
i18n.onDisable();
|
||||||
Economy.setEss(null);
|
Economy.setEss(null);
|
||||||
Trade.closeLog();
|
Trade.closeLog();
|
||||||
|
BetterLocation.cleanup();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@@ -0,0 +1,254 @@
|
|||||||
|
package com.earth2me.essentials.craftbukkit;
|
||||||
|
|
||||||
|
import java.lang.ref.WeakReference;
|
||||||
|
import java.util.*;
|
||||||
|
import org.bukkit.Bukkit;
|
||||||
|
import org.bukkit.Location;
|
||||||
|
import org.bukkit.World;
|
||||||
|
import org.bukkit.event.world.WorldLoadEvent;
|
||||||
|
import org.bukkit.event.world.WorldUnloadEvent;
|
||||||
|
|
||||||
|
|
||||||
|
public class BetterLocation extends Location
|
||||||
|
{
|
||||||
|
private transient String worldName;
|
||||||
|
private static BetterLocationListener listener = new BetterLocationListener();
|
||||||
|
|
||||||
|
public static BetterLocationListener getListener()
|
||||||
|
{
|
||||||
|
return listener;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void cleanup()
|
||||||
|
{
|
||||||
|
synchronized (listener.locationMap)
|
||||||
|
{
|
||||||
|
listener.locationMap.clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public BetterLocation(final String worldName, final double x, final double y, final double z)
|
||||||
|
{
|
||||||
|
super(Bukkit.getWorld(worldName), x, y, z);
|
||||||
|
this.worldName = worldName;
|
||||||
|
addToMap(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
public BetterLocation(final String worldName, final double x, final double y,
|
||||||
|
final double z, final float yaw, final float pitch)
|
||||||
|
{
|
||||||
|
super(Bukkit.getWorld(worldName), x, y, z, yaw, pitch);
|
||||||
|
this.worldName = worldName;
|
||||||
|
addToMap(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
public BetterLocation(final World world, final double x, final double y, final double z)
|
||||||
|
{
|
||||||
|
super(world, x, y, z);
|
||||||
|
if (world == null)
|
||||||
|
{
|
||||||
|
throw new WorldNotLoadedException();
|
||||||
|
}
|
||||||
|
this.worldName = world.getName();
|
||||||
|
addToMap(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
public BetterLocation(final World world, final double x, final double y,
|
||||||
|
final double z, final float yaw, final float pitch)
|
||||||
|
{
|
||||||
|
super(world, x, y, z, yaw, pitch);
|
||||||
|
if (world == null)
|
||||||
|
{
|
||||||
|
throw new WorldNotLoadedException();
|
||||||
|
}
|
||||||
|
this.worldName = world.getName();
|
||||||
|
addToMap(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
public BetterLocation(final Location location)
|
||||||
|
{
|
||||||
|
super(location.getWorld(), location.getX(), location.getY(), location.getZ(), location.getYaw(), location.getPitch());
|
||||||
|
if (location.getWorld() == null)
|
||||||
|
{
|
||||||
|
throw new WorldNotLoadedException();
|
||||||
|
}
|
||||||
|
this.worldName = location.getWorld().getName();
|
||||||
|
addToMap(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public World getWorld()
|
||||||
|
{
|
||||||
|
World world = super.getWorld();
|
||||||
|
if (world == null)
|
||||||
|
{
|
||||||
|
world = Bukkit.getWorld(worldName);
|
||||||
|
}
|
||||||
|
if (world == null)
|
||||||
|
{
|
||||||
|
throw new WorldNotLoadedException();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
super.setWorld(world);
|
||||||
|
}
|
||||||
|
return world;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setWorld(final World world)
|
||||||
|
{
|
||||||
|
if (world == null)
|
||||||
|
{
|
||||||
|
throw new WorldNotLoadedException();
|
||||||
|
}
|
||||||
|
if (!world.getName().equals(this.worldName))
|
||||||
|
{
|
||||||
|
getListener().removeLocation(this);
|
||||||
|
this.worldName = world.getName();
|
||||||
|
addToMap(this);
|
||||||
|
}
|
||||||
|
super.setWorld(world);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getWorldName()
|
||||||
|
{
|
||||||
|
return worldName;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void addToMap(final BetterLocation location)
|
||||||
|
{
|
||||||
|
synchronized (listener.locationMap)
|
||||||
|
{
|
||||||
|
List<WeakReference<Location>> locations = listener.locationMap.get(location.getWorldName());
|
||||||
|
if (locations == null)
|
||||||
|
{
|
||||||
|
locations = new LinkedList<WeakReference<Location>>();
|
||||||
|
listener.locationMap.put(location.getWorldName(), locations);
|
||||||
|
}
|
||||||
|
locations.add(new WeakReference<Location>(location));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static class WorldNotLoadedException extends RuntimeException
|
||||||
|
{
|
||||||
|
public WorldNotLoadedException()
|
||||||
|
{
|
||||||
|
super("World is not loaded.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static class BetterLocationListener extends org.bukkit.event.world.WorldListener implements Runnable
|
||||||
|
{
|
||||||
|
private static Random random = new Random();
|
||||||
|
private final transient Map<String, List<WeakReference<Location>>> locationMap = new HashMap<String, List<WeakReference<Location>>>();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onWorldLoad(final WorldLoadEvent event)
|
||||||
|
{
|
||||||
|
final String worldName = event.getWorld().getName();
|
||||||
|
synchronized (locationMap)
|
||||||
|
{
|
||||||
|
final List<WeakReference<Location>> locations = locationMap.get(worldName);
|
||||||
|
if (locations != null)
|
||||||
|
{
|
||||||
|
for (final Iterator<WeakReference<Location>> it = locations.iterator(); it.hasNext();)
|
||||||
|
{
|
||||||
|
final WeakReference<Location> weakReference = it.next();
|
||||||
|
final Location loc = weakReference.get();
|
||||||
|
if (loc == null)
|
||||||
|
{
|
||||||
|
it.remove();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
loc.setWorld(event.getWorld());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onWorldUnload(final WorldUnloadEvent event)
|
||||||
|
{
|
||||||
|
final String worldName = event.getWorld().getName();
|
||||||
|
synchronized (locationMap)
|
||||||
|
{
|
||||||
|
final List<WeakReference<Location>> locations = locationMap.get(worldName);
|
||||||
|
if (locations != null)
|
||||||
|
{
|
||||||
|
for (final Iterator<WeakReference<Location>> it = locations.iterator(); it.hasNext();)
|
||||||
|
{
|
||||||
|
final WeakReference<Location> weakReference = it.next();
|
||||||
|
final Location loc = weakReference.get();
|
||||||
|
if (loc == null)
|
||||||
|
{
|
||||||
|
it.remove();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
loc.setWorld(null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void run()
|
||||||
|
{
|
||||||
|
synchronized (locationMap)
|
||||||
|
{
|
||||||
|
// Pick a world by random
|
||||||
|
final Collection<List<WeakReference<Location>>> allWorlds = locationMap.values();
|
||||||
|
final int randomPick = (allWorlds.isEmpty() ? 0 : random.nextInt(allWorlds.size()));
|
||||||
|
List<WeakReference<Location>> locations = null;
|
||||||
|
final Iterator<List<WeakReference<Location>>> iterator = allWorlds.iterator();
|
||||||
|
for (int i = 0; iterator.hasNext() && i < randomPick; i++)
|
||||||
|
{
|
||||||
|
iterator.next();
|
||||||
|
}
|
||||||
|
if (iterator.hasNext())
|
||||||
|
{
|
||||||
|
locations = iterator.next();
|
||||||
|
}
|
||||||
|
if (locations != null)
|
||||||
|
{
|
||||||
|
for (final Iterator<WeakReference<Location>> it = locations.iterator(); it.hasNext();)
|
||||||
|
{
|
||||||
|
final WeakReference<Location> weakReference = it.next();
|
||||||
|
final Location loc = weakReference.get();
|
||||||
|
if (loc == null)
|
||||||
|
{
|
||||||
|
it.remove();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void removeLocation(final BetterLocation location)
|
||||||
|
{
|
||||||
|
final String worldName = location.getWorldName();
|
||||||
|
synchronized (locationMap)
|
||||||
|
{
|
||||||
|
final List<WeakReference<Location>> locations = locationMap.get(worldName);
|
||||||
|
if (locations != null)
|
||||||
|
{
|
||||||
|
for (final Iterator<WeakReference<Location>> it = locations.iterator(); it.hasNext();)
|
||||||
|
{
|
||||||
|
final WeakReference<Location> weakReference = it.next();
|
||||||
|
final Location loc = weakReference.get();
|
||||||
|
if (loc == null || loc == location)
|
||||||
|
{
|
||||||
|
it.remove();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@@ -38,7 +38,7 @@ public class OfflineBedLocation
|
|||||||
{
|
{
|
||||||
spawnWorld = cserver.getWorlds().get(0).getName();
|
spawnWorld = cserver.getWorlds().get(0).getName();
|
||||||
}
|
}
|
||||||
return new Location(cserver.getWorld(spawnWorld), playerStorage.getInt("SpawnX"), playerStorage.getInt("SpawnY"), playerStorage.getInt("SpawnZ"));
|
return new BetterLocation(spawnWorld, playerStorage.getInt("SpawnX"), playerStorage.getInt("SpawnY"), playerStorage.getInt("SpawnZ"));
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
@@ -1,15 +1,14 @@
|
|||||||
package com.earth2me.essentials.storage;
|
package com.earth2me.essentials.storage;
|
||||||
|
|
||||||
import com.earth2me.essentials.Essentials;
|
import com.earth2me.essentials.Essentials;
|
||||||
|
import com.earth2me.essentials.craftbukkit.BetterLocation;
|
||||||
import java.lang.reflect.Field;
|
import java.lang.reflect.Field;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
import org.bukkit.Bukkit;
|
|
||||||
import org.bukkit.Location;
|
import org.bukkit.Location;
|
||||||
import org.bukkit.Material;
|
import org.bukkit.Material;
|
||||||
import org.bukkit.World;
|
|
||||||
import org.bukkit.enchantments.Enchantment;
|
import org.bukkit.enchantments.Enchantment;
|
||||||
import org.bukkit.inventory.ItemStack;
|
import org.bukkit.inventory.ItemStack;
|
||||||
import org.bukkit.material.MaterialData;
|
import org.bukkit.material.MaterialData;
|
||||||
@@ -281,12 +280,7 @@ public class BukkitConstructor extends Constructor
|
|||||||
{
|
{
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
final World world = Bukkit.getWorld(worldName);
|
return new BetterLocation(worldName, x, y, z, yaw, pitch);
|
||||||
if (world == null)
|
|
||||||
{
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
return new Location(world, x, y, z, yaw, pitch);
|
|
||||||
}
|
}
|
||||||
return super.construct(node);
|
return super.construct(node);
|
||||||
}
|
}
|
||||||
|
@@ -1,5 +1,6 @@
|
|||||||
package com.earth2me.essentials.storage;
|
package com.earth2me.essentials.storage;
|
||||||
|
|
||||||
|
import com.earth2me.essentials.craftbukkit.BetterLocation;
|
||||||
import java.io.PrintWriter;
|
import java.io.PrintWriter;
|
||||||
import java.lang.reflect.Field;
|
import java.lang.reflect.Field;
|
||||||
import java.lang.reflect.Modifier;
|
import java.lang.reflect.Modifier;
|
||||||
@@ -24,12 +25,12 @@ public class YamlStorageWriter implements IStorageWriter
|
|||||||
private transient static final Pattern NON_WORD_PATTERN = Pattern.compile("\\W");
|
private transient static final Pattern NON_WORD_PATTERN = Pattern.compile("\\W");
|
||||||
private transient final PrintWriter writer;
|
private transient final PrintWriter writer;
|
||||||
private transient static final Yaml YAML = new Yaml();
|
private transient static final Yaml YAML = new Yaml();
|
||||||
|
|
||||||
public YamlStorageWriter(final PrintWriter writer)
|
public YamlStorageWriter(final PrintWriter writer)
|
||||||
{
|
{
|
||||||
this.writer = writer;
|
this.writer = writer;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void save(final StorageObject object)
|
public void save(final StorageObject object)
|
||||||
{
|
{
|
||||||
@@ -46,7 +47,7 @@ public class YamlStorageWriter implements IStorageWriter
|
|||||||
Logger.getLogger(YamlStorageWriter.class.getName()).log(Level.SEVERE, null, ex);
|
Logger.getLogger(YamlStorageWriter.class.getName()).log(Level.SEVERE, null, ex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void writeToFile(final Object object, final int depth, final Class clazz) throws IllegalAccessException
|
private void writeToFile(final Object object, final int depth, final Class clazz) throws IllegalAccessException
|
||||||
{
|
{
|
||||||
for (Field field : clazz.getDeclaredFields())
|
for (Field field : clazz.getDeclaredFields())
|
||||||
@@ -55,7 +56,7 @@ public class YamlStorageWriter implements IStorageWriter
|
|||||||
if (Modifier.isPrivate(modifier) && !Modifier.isTransient(modifier) && !Modifier.isStatic(modifier))
|
if (Modifier.isPrivate(modifier) && !Modifier.isTransient(modifier) && !Modifier.isStatic(modifier))
|
||||||
{
|
{
|
||||||
field.setAccessible(true);
|
field.setAccessible(true);
|
||||||
|
|
||||||
final Object data = field.get(object);
|
final Object data = field.get(object);
|
||||||
if (writeKey(field, depth, data))
|
if (writeKey(field, depth, data))
|
||||||
{
|
{
|
||||||
@@ -86,7 +87,7 @@ public class YamlStorageWriter implements IStorageWriter
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean writeKey(final Field field, final int depth, final Object data)
|
private boolean writeKey(final Field field, final int depth, final Object data)
|
||||||
{
|
{
|
||||||
final boolean commentPresent = writeComment(field, depth);
|
final boolean commentPresent = writeComment(field, depth);
|
||||||
@@ -110,7 +111,7 @@ public class YamlStorageWriter implements IStorageWriter
|
|||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean writeComment(final Field field, final int depth)
|
private boolean writeComment(final Field field, final int depth)
|
||||||
{
|
{
|
||||||
final boolean commentPresent = field.isAnnotationPresent(Comment.class);
|
final boolean commentPresent = field.isAnnotationPresent(Comment.class);
|
||||||
@@ -132,7 +133,7 @@ public class YamlStorageWriter implements IStorageWriter
|
|||||||
}
|
}
|
||||||
return commentPresent;
|
return commentPresent;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void writeCollection(final Collection<Object> data, final int depth) throws IllegalAccessException
|
private void writeCollection(final Collection<Object> data, final int depth) throws IllegalAccessException
|
||||||
{
|
{
|
||||||
writer.println();
|
writer.println();
|
||||||
@@ -163,7 +164,7 @@ public class YamlStorageWriter implements IStorageWriter
|
|||||||
}
|
}
|
||||||
writer.println();
|
writer.println();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void writeMap(final Map<Object, Object> data, final int depth) throws IllegalArgumentException, IllegalAccessException
|
private void writeMap(final Map<Object, Object> data, final int depth) throws IllegalArgumentException, IllegalAccessException
|
||||||
{
|
{
|
||||||
writer.println();
|
writer.println();
|
||||||
@@ -200,7 +201,7 @@ public class YamlStorageWriter implements IStorageWriter
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void writeIndention(final int depth)
|
private void writeIndention(final int depth)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < depth; i++)
|
for (int i = 0; i < depth; i++)
|
||||||
@@ -208,7 +209,7 @@ public class YamlStorageWriter implements IStorageWriter
|
|||||||
writer.print(" ");
|
writer.print(" ");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void writeScalar(final Object data)
|
private void writeScalar(final Object data)
|
||||||
{
|
{
|
||||||
if (data instanceof String || data instanceof Boolean || data instanceof Number)
|
if (data instanceof String || data instanceof Boolean || data instanceof Number)
|
||||||
@@ -248,7 +249,7 @@ public class YamlStorageWriter implements IStorageWriter
|
|||||||
throw new UnsupportedOperationException();
|
throw new UnsupportedOperationException();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void writeKey(final Object data)
|
private void writeKey(final Object data)
|
||||||
{
|
{
|
||||||
if (data instanceof String || data instanceof Boolean || data instanceof Number)
|
if (data instanceof String || data instanceof Boolean || data instanceof Number)
|
||||||
@@ -286,12 +287,12 @@ public class YamlStorageWriter implements IStorageWriter
|
|||||||
throw new UnsupportedOperationException();
|
throw new UnsupportedOperationException();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void writeMaterial(final Object data)
|
private void writeMaterial(final Object data)
|
||||||
{
|
{
|
||||||
writer.print(data.toString().toLowerCase(Locale.ENGLISH));
|
writer.print(data.toString().toLowerCase(Locale.ENGLISH));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void writeMaterialData(final Object data)
|
private void writeMaterialData(final Object data)
|
||||||
{
|
{
|
||||||
final MaterialData matData = (MaterialData)data;
|
final MaterialData matData = (MaterialData)data;
|
||||||
@@ -302,7 +303,7 @@ public class YamlStorageWriter implements IStorageWriter
|
|||||||
writer.print(matData.getData());
|
writer.print(matData.getData());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void writeItemStack(final Object data)
|
private void writeItemStack(final Object data)
|
||||||
{
|
{
|
||||||
final ItemStack itemStack = (ItemStack)data;
|
final ItemStack itemStack = (ItemStack)data;
|
||||||
@@ -315,7 +316,7 @@ public class YamlStorageWriter implements IStorageWriter
|
|||||||
writeEnchantmentLevel(entry);
|
writeEnchantmentLevel(entry);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void writeEnchantmentLevel(Object data)
|
private void writeEnchantmentLevel(Object data)
|
||||||
{
|
{
|
||||||
final Entry<Enchantment, Integer> enchLevel = (Entry<Enchantment, Integer>)data;
|
final Entry<Enchantment, Integer> enchLevel = (Entry<Enchantment, Integer>)data;
|
||||||
@@ -323,13 +324,20 @@ public class YamlStorageWriter implements IStorageWriter
|
|||||||
writer.print(':');
|
writer.print(':');
|
||||||
writer.print(enchLevel.getValue());
|
writer.print(enchLevel.getValue());
|
||||||
}
|
}
|
||||||
|
|
||||||
private void writeLocation(final Location entry, final int depth)
|
private void writeLocation(final Location entry, final int depth)
|
||||||
{
|
{
|
||||||
writer.println();
|
writer.println();
|
||||||
writeIndention(depth);
|
writeIndention(depth);
|
||||||
writer.print("world: ");
|
writer.print("world: ");
|
||||||
writeScalar(entry.getWorld().getName());
|
if (entry instanceof BetterLocation)
|
||||||
|
{
|
||||||
|
writeScalar(((BetterLocation)entry).getWorldName());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
writeScalar(entry.getWorld().getName());
|
||||||
|
}
|
||||||
writeIndention(depth);
|
writeIndention(depth);
|
||||||
writer.print("x: ");
|
writer.print("x: ");
|
||||||
writeScalar(entry.getX());
|
writeScalar(entry.getX());
|
||||||
|
@@ -4,6 +4,7 @@ import com.earth2me.essentials.Util;
|
|||||||
import com.earth2me.essentials.api.IEssentials;
|
import com.earth2me.essentials.api.IEssentials;
|
||||||
import com.earth2me.essentials.api.ISettings;
|
import com.earth2me.essentials.api.ISettings;
|
||||||
import com.earth2me.essentials.api.InvalidNameException;
|
import com.earth2me.essentials.api.InvalidNameException;
|
||||||
|
import com.earth2me.essentials.craftbukkit.BetterLocation;
|
||||||
import com.earth2me.essentials.craftbukkit.OfflineBedLocation;
|
import com.earth2me.essentials.craftbukkit.OfflineBedLocation;
|
||||||
import com.earth2me.essentials.storage.AsyncStorageObjectHolder;
|
import com.earth2me.essentials.storage.AsyncStorageObjectHolder;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
@@ -31,7 +32,7 @@ public abstract class UserBase extends AsyncStorageObjectHolder<UserData> implem
|
|||||||
Player.class, Entity.class, CommandSender.class, ServerOperator.class,
|
Player.class, Entity.class, CommandSender.class, ServerOperator.class,
|
||||||
HumanEntity.class, ConfigurationSerializable.class, LivingEntity.class,
|
HumanEntity.class, ConfigurationSerializable.class, LivingEntity.class,
|
||||||
Permissible.class
|
Permissible.class
|
||||||
}, excludes = IOfflinePlayer.class)
|
}, excludes = {IOfflinePlayer.class, OtherExcludes.class})
|
||||||
protected Player base;
|
protected Player base;
|
||||||
protected transient OfflinePlayer offlinePlayer;
|
protected transient OfflinePlayer offlinePlayer;
|
||||||
|
|
||||||
@@ -436,4 +437,14 @@ public abstract class UserBase extends AsyncStorageObjectHolder<UserData> implem
|
|||||||
unlock();
|
unlock();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Location getLocation()
|
||||||
|
{
|
||||||
|
return new BetterLocation(base.getLocation());
|
||||||
|
}
|
||||||
|
|
||||||
|
public static interface OtherExcludes {
|
||||||
|
Location getLocation();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user