Rework protected areas.

This commit is contained in:
StevenLawson 2013-09-05 10:22:59 -04:00
parent 05ad222148
commit 650bd11ab0
3 changed files with 168 additions and 134 deletions

View File

@ -1,92 +0,0 @@
package me.StevenLawson.TotalFreedomMod;
import java.io.Serializable;
import java.util.HashMap;
import java.util.Map;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.Server;
import org.bukkit.World;
// From: http://forums.bukkit.org/threads/location-serialized.105851/
// By: gcflames5
public final class SerializableLocation implements Serializable
{
private static final long serialVersionUID = 7498864812883577904L;
private final String world;
private final String uuid;
private final double x, y, z;
private final float yaw, pitch;
private transient Location loc;
public SerializableLocation(Location l)
{
this.world = l.getWorld().getName();
this.uuid = l.getWorld().getUID().toString();
this.x = l.getX();
this.y = l.getY();
this.z = l.getZ();
this.yaw = l.getYaw();
this.pitch = l.getPitch();
}
public static Location returnLocation(SerializableLocation l)
{
float pitch = l.pitch;
float yaw = l.yaw;
double x = l.x;
double y = l.y;
double z = l.z;
World world = Bukkit.getWorld(l.world);
Location location = new Location(world, x, y, z, yaw, pitch);
return location;
}
public static Location returnBlockLocation(SerializableLocation l)
{
double x = l.x;
double y = l.y;
double z = l.z;
World world = Bukkit.getWorld(l.world);
Location location = new Location(world, x, y, z);
return location;
}
public SerializableLocation(Map<String, Object> map)
{
this.world = (String) map.get("world");
this.uuid = (String) map.get("uuid");
this.x = (Double) map.get("x");
this.y = (Double) map.get("y");
this.z = (Double) map.get("z");
this.yaw = ((Float) map.get("yaw")).floatValue();
this.pitch = ((Float) map.get("pitch")).floatValue();
}
public final Map<String, Object> serialize()
{
Map<String, Object> map = new HashMap<String, Object>();
map.put("world", this.world);
map.put("uuid", this.uuid);
map.put("x", this.x);
map.put("y", this.y);
map.put("z", this.z);
map.put("yaw", this.yaw);
map.put("pitch", this.pitch);
return map;
}
public final Location getLocation(Server server)
{
if (loc == null)
{
World world_l = server.getWorld(this.uuid);
if (world_l == null)
{
world_l = server.getWorld(this.world);
}
loc = new Location(world_l, x, y, z, yaw, pitch);
}
return loc;
}
}

View File

@ -314,7 +314,7 @@ public class TFM_FrontDoor
} }
TFM_Util.adminAction("FrontDoor", "Removing all protected areas", true); TFM_Util.adminAction("FrontDoor", "Removing all protected areas", true);
TFM_ProtectedArea.clearProtectedAreas(true); TFM_ProtectedArea.clearProtectedAreas(false);
break; break;
} }

View File

@ -7,8 +7,10 @@ import java.io.ObjectInputStream;
import java.io.ObjectOutputStream; import java.io.ObjectOutputStream;
import java.io.Serializable; import java.io.Serializable;
import java.util.HashMap; import java.util.HashMap;
import java.util.Iterator;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
import java.util.UUID;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.Location; import org.bukkit.Location;
import org.bukkit.World; import org.bukkit.World;
@ -16,60 +18,104 @@ import org.bukkit.util.Vector;
public class TFM_ProtectedArea implements Serializable public class TFM_ProtectedArea implements Serializable
{ {
private static final long serialVersionUID = -3270338811000937254L; private static final long serialVersionUID = 2L;
//
public static final double MAX_RADIUS = 50.0D; public static final double MAX_RADIUS = 50.0D;
private static Map<String, TFM_ProtectedArea> protectedAreas = new HashMap<String, TFM_ProtectedArea>(); //
private final SerializableLocation center; private static final Map<String, SerializableProtectedRegion> PROTECTED_AREAS = new HashMap<String, SerializableProtectedRegion>();
private final double radius;
private TFM_ProtectedArea(Location root_location, double radius) private TFM_ProtectedArea()
{ {
this.center = new SerializableLocation(root_location); throw new AssertionError();
this.radius = radius;
} }
public static boolean isInProtectedArea(Location location) public static boolean isInProtectedArea(final Location modifyLocation)
{ {
for (Map.Entry<String, TFM_ProtectedArea> protectedArea : TFM_ProtectedArea.protectedAreas.entrySet()) boolean doSave = false;
{ boolean inProtectedArea = false;
Location protectedAreaCenter = SerializableLocation.returnLocation(protectedArea.getValue().center);
if (protectedAreaCenter != null)
{
if (location.getWorld() == protectedAreaCenter.getWorld())
{
double protectedAreaRadius = protectedArea.getValue().radius;
if (location.distanceSquared(protectedAreaCenter) <= (protectedAreaRadius * protectedAreaRadius)) final Iterator<Map.Entry<String, SerializableProtectedRegion>> it = TFM_ProtectedArea.PROTECTED_AREAS.entrySet().iterator();
while (it.hasNext())
{ {
return true; final SerializableProtectedRegion region = it.next().getValue();
Location regionCenter = null;
try
{
regionCenter = region.getLocation();
}
catch (SerializableProtectedRegion.CantFindWorldException ex)
{
it.remove();
doSave = true;
continue;
}
if (regionCenter != null)
{
if (modifyLocation.getWorld() == regionCenter.getWorld())
{
final double regionRadius = region.getRadius();
if (modifyLocation.distanceSquared(regionCenter) <= (regionRadius * regionRadius))
{
inProtectedArea = true;
break;
} }
} }
} }
} }
return false; if (doSave)
{
saveProtectedAreas();
} }
public static boolean isInProtectedArea(Vector min, Vector max, String worldName) return inProtectedArea;
}
public static boolean isInProtectedArea(final Vector min, final Vector max, final String worldName)
{ {
for (Map.Entry<String, TFM_ProtectedArea> protectedArea : TFM_ProtectedArea.protectedAreas.entrySet()) boolean doSave = false;
boolean inProtectedArea = false;
final Iterator<Map.Entry<String, SerializableProtectedRegion>> it = TFM_ProtectedArea.PROTECTED_AREAS.entrySet().iterator();
while (it.hasNext())
{ {
Location protectedAreaCenter = SerializableLocation.returnLocation(protectedArea.getValue().center); final SerializableProtectedRegion region = it.next().getValue();
if (protectedAreaCenter != null)
Location regionCenter = null;
try
{ {
if (worldName.equals(protectedAreaCenter.getWorld().getName())) regionCenter = region.getLocation();
}
catch (SerializableProtectedRegion.CantFindWorldException ex)
{ {
double sphereRadius = protectedArea.getValue().radius; it.remove();
Vector sphereCenter = protectedAreaCenter.toVector(); doSave = true;
if (cubeIntersectsSphere(min, max, sphereCenter, sphereRadius)) continue;
}
if (regionCenter != null)
{ {
return true; if (worldName.equals(regionCenter.getWorld().getName()))
{
if (cubeIntersectsSphere(min, max, regionCenter.toVector(), region.getRadius()))
{
inProtectedArea = true;
break;
} }
} }
} }
} }
return false; if (doSave)
{
saveProtectedAreas();
}
return inProtectedArea;
} }
private static boolean cubeIntersectsSphere(Vector min, Vector max, Vector sphere, double radius) private static boolean cubeIntersectsSphere(Vector min, Vector max, Vector sphere, double radius)
@ -111,26 +157,26 @@ public class TFM_ProtectedArea implements Serializable
public static void addProtectedArea(String label, Location location, double radius) public static void addProtectedArea(String label, Location location, double radius)
{ {
TFM_ProtectedArea.protectedAreas.put(label.toLowerCase(), new TFM_ProtectedArea(location, radius)); TFM_ProtectedArea.PROTECTED_AREAS.put(label.toLowerCase(), new SerializableProtectedRegion(location, radius));
saveProtectedAreas(); saveProtectedAreas();
} }
public static void removeProtectedArea(String label) public static void removeProtectedArea(String label)
{ {
TFM_ProtectedArea.protectedAreas.remove(label.toLowerCase()); TFM_ProtectedArea.PROTECTED_AREAS.remove(label.toLowerCase());
saveProtectedAreas(); saveProtectedAreas();
} }
public static void clearProtectedAreas() public static void clearProtectedAreas()
{ {
clearProtectedAreas(false); clearProtectedAreas(true);
} }
public static void clearProtectedAreas(boolean hard) public static void clearProtectedAreas(boolean createSpawnpointProtectedAreas)
{ {
TFM_ProtectedArea.protectedAreas.clear(); TFM_ProtectedArea.PROTECTED_AREAS.clear();
if (!hard) if (createSpawnpointProtectedAreas)
{ {
autoAddSpawnpoints(); autoAddSpawnpoints();
} }
@ -138,9 +184,34 @@ public class TFM_ProtectedArea implements Serializable
saveProtectedAreas(); saveProtectedAreas();
} }
public static void cleanProtectedAreas()
{
boolean doSave = false;
final Iterator<Map.Entry<String, SerializableProtectedRegion>> it = TFM_ProtectedArea.PROTECTED_AREAS.entrySet().iterator();
while (it.hasNext())
{
try
{
it.next().getValue().getLocation();
}
catch (SerializableProtectedRegion.CantFindWorldException ex)
{
it.remove();
doSave = true;
}
}
if (doSave)
{
saveProtectedAreas();
}
}
public static Set<String> getProtectedAreaLabels() public static Set<String> getProtectedAreaLabels()
{ {
return TFM_ProtectedArea.protectedAreas.keySet(); return TFM_ProtectedArea.PROTECTED_AREAS.keySet();
} }
public static void saveProtectedAreas() public static void saveProtectedAreas()
@ -149,7 +220,7 @@ public class TFM_ProtectedArea implements Serializable
{ {
FileOutputStream fos = new FileOutputStream(new File(TotalFreedomMod.plugin.getDataFolder(), TotalFreedomMod.PROTECTED_AREA_FILE)); FileOutputStream fos = new FileOutputStream(new File(TotalFreedomMod.plugin.getDataFolder(), TotalFreedomMod.PROTECTED_AREA_FILE));
ObjectOutputStream oos = new ObjectOutputStream(fos); ObjectOutputStream oos = new ObjectOutputStream(fos);
oos.writeObject(TFM_ProtectedArea.protectedAreas); oos.writeObject(TFM_ProtectedArea.PROTECTED_AREAS);
oos.close(); oos.close();
fos.close(); fos.close();
} }
@ -162,25 +233,26 @@ public class TFM_ProtectedArea implements Serializable
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public static void loadProtectedAreas() public static void loadProtectedAreas()
{ {
File input = new File(TotalFreedomMod.plugin.getDataFolder(), TotalFreedomMod.PROTECTED_AREA_FILE);
try try
{ {
File input = new File(TotalFreedomMod.plugin.getDataFolder(), TotalFreedomMod.PROTECTED_AREA_FILE);
if (input.exists()) if (input.exists())
{ {
FileInputStream fis = new FileInputStream(input); FileInputStream fis = new FileInputStream(input);
ObjectInputStream ois = new ObjectInputStream(fis); ObjectInputStream ois = new ObjectInputStream(fis);
TFM_ProtectedArea.protectedAreas = (HashMap<String, TFM_ProtectedArea>) ois.readObject(); TFM_ProtectedArea.PROTECTED_AREAS.clear();
TFM_ProtectedArea.PROTECTED_AREAS.putAll((HashMap<String, SerializableProtectedRegion>) ois.readObject());
ois.close(); ois.close();
fis.close(); fis.close();
} }
} }
catch (Exception ex) catch (Exception ex)
{ {
File input = new File(TotalFreedomMod.plugin.getDataFolder(), TotalFreedomMod.PROTECTED_AREA_FILE);
input.delete(); input.delete();
TFM_Log.severe(ex); TFM_Log.severe(ex);
} }
cleanProtectedAreas();
} }
public static void autoAddSpawnpoints() public static void autoAddSpawnpoints()
@ -193,4 +265,58 @@ public class TFM_ProtectedArea implements Serializable
} }
} }
} }
public static class SerializableProtectedRegion implements Serializable
{
private final double x, y, z;
private final double radius;
private final String worldName;
private final UUID worldUUID;
private transient Location location = null;
public SerializableProtectedRegion(final Location location, final double radius)
{
this.x = location.getX();
this.y = location.getY();
this.z = location.getZ();
this.radius = radius;
this.worldName = location.getWorld().getName();
this.worldUUID = location.getWorld().getUID();
this.location = location;
}
public Location getLocation() throws CantFindWorldException
{
if (this.location == null)
{
World world = Bukkit.getWorld(this.worldUUID);
if (world == null)
{
world = Bukkit.getWorld(this.worldName);
}
if (world == null)
{
throw new CantFindWorldException("Can't find world " + this.worldName + ", UUID: " + this.worldUUID.toString());
}
location = new Location(world, x, y, z);
}
return this.location;
}
public double getRadius()
{
return radius;
}
public static class CantFindWorldException extends Exception
{
public CantFindWorldException(String string)
{
super(string);
}
}
}
} }