2015-10-19 17:43:46 +00:00
|
|
|
package me.totalfreedom.totalfreedommod;
|
2012-11-03 19:03:38 +00:00
|
|
|
|
2015-10-19 17:43:46 +00:00
|
|
|
import com.google.common.collect.Maps;
|
2012-11-03 19:03:38 +00:00
|
|
|
import java.io.File;
|
|
|
|
import java.io.FileInputStream;
|
|
|
|
import java.io.FileOutputStream;
|
|
|
|
import java.io.ObjectInputStream;
|
|
|
|
import java.io.ObjectOutputStream;
|
|
|
|
import java.io.Serializable;
|
|
|
|
import java.util.HashMap;
|
2013-09-05 14:22:59 +00:00
|
|
|
import java.util.Iterator;
|
2012-11-03 19:03:38 +00:00
|
|
|
import java.util.Map;
|
|
|
|
import java.util.Set;
|
2013-09-05 14:22:59 +00:00
|
|
|
import java.util.UUID;
|
2015-10-19 17:43:46 +00:00
|
|
|
import me.totalfreedom.totalfreedommod.config.ConfigEntry;
|
2015-11-15 23:32:04 +00:00
|
|
|
import me.totalfreedom.totalfreedommod.util.FLog;
|
2015-10-19 17:43:46 +00:00
|
|
|
import net.pravian.aero.component.service.AbstractService;
|
2012-11-03 19:03:38 +00:00
|
|
|
import org.bukkit.Bukkit;
|
|
|
|
import org.bukkit.Location;
|
|
|
|
import org.bukkit.World;
|
2015-11-15 23:32:04 +00:00
|
|
|
import org.bukkit.entity.Player;
|
|
|
|
import org.bukkit.event.EventHandler;
|
|
|
|
import org.bukkit.event.EventPriority;
|
|
|
|
import org.bukkit.event.block.BlockBreakEvent;
|
|
|
|
import org.bukkit.event.block.BlockPlaceEvent;
|
2013-09-04 19:17:22 +00:00
|
|
|
import org.bukkit.util.Vector;
|
2012-11-03 19:03:38 +00:00
|
|
|
|
2015-10-19 17:43:46 +00:00
|
|
|
public class ProtectArea extends AbstractService<TotalFreedomMod>
|
2012-11-03 19:03:38 +00:00
|
|
|
{
|
2013-09-05 14:33:06 +00:00
|
|
|
public static final double MAX_RADIUS = 50.0;
|
2015-10-19 17:43:46 +00:00
|
|
|
//
|
|
|
|
private final Map<String, SerializableProtectedRegion> areas = Maps.newHashMap();
|
2012-11-03 19:03:38 +00:00
|
|
|
|
2015-10-19 17:43:46 +00:00
|
|
|
public ProtectArea(TotalFreedomMod plugin)
|
2012-11-03 19:03:38 +00:00
|
|
|
{
|
2015-10-19 17:43:46 +00:00
|
|
|
super(plugin);
|
2012-11-03 19:03:38 +00:00
|
|
|
}
|
|
|
|
|
2015-10-19 17:43:46 +00:00
|
|
|
@Override
|
|
|
|
protected void onStart()
|
|
|
|
{
|
|
|
|
if (!ConfigEntry.PROTECTAREA_ENABLED.getBoolean())
|
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
File input = new File(TotalFreedomMod.plugin.getDataFolder(), TotalFreedomMod.PROTECTED_AREA_FILENAME);
|
|
|
|
try
|
|
|
|
{
|
|
|
|
if (input.exists())
|
|
|
|
{
|
|
|
|
FileInputStream fis = new FileInputStream(input);
|
|
|
|
ObjectInputStream ois = new ObjectInputStream(fis);
|
|
|
|
areas.clear();
|
|
|
|
areas.putAll((HashMap<String, SerializableProtectedRegion>) ois.readObject());
|
|
|
|
ois.close();
|
|
|
|
fis.close();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
catch (Exception ex)
|
|
|
|
{
|
|
|
|
input.delete();
|
|
|
|
FLog.severe(ex);
|
|
|
|
}
|
|
|
|
|
|
|
|
cleanProtectedAreas();
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
protected void onStop()
|
|
|
|
{
|
|
|
|
save();
|
|
|
|
}
|
|
|
|
|
|
|
|
public void save()
|
|
|
|
{
|
|
|
|
try
|
|
|
|
{
|
|
|
|
FileOutputStream fos = new FileOutputStream(new File(TotalFreedomMod.plugin.getDataFolder(), TotalFreedomMod.PROTECTED_AREA_FILENAME));
|
|
|
|
ObjectOutputStream oos = new ObjectOutputStream(fos);
|
|
|
|
oos.writeObject(areas);
|
|
|
|
oos.close();
|
|
|
|
fos.close();
|
|
|
|
}
|
|
|
|
catch (Exception ex)
|
|
|
|
{
|
|
|
|
FLog.severe(ex);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-11-15 23:32:04 +00:00
|
|
|
@EventHandler(priority = EventPriority.NORMAL)
|
|
|
|
public void onBlockBreak(BlockBreakEvent event)
|
|
|
|
{
|
|
|
|
if (!ConfigEntry.PROTECTAREA_ENABLED.getBoolean())
|
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
final Player player = event.getPlayer();
|
|
|
|
if (plugin.al.isAdmin(player))
|
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
final Location location = event.getBlock().getLocation();
|
|
|
|
|
|
|
|
if (isInProtectedArea(location))
|
|
|
|
{
|
|
|
|
event.setCancelled(true);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
@EventHandler(priority = EventPriority.NORMAL)
|
|
|
|
public void onBlockPlace(BlockPlaceEvent event)
|
|
|
|
{
|
|
|
|
if (!ConfigEntry.PROTECTAREA_ENABLED.getBoolean())
|
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
final Player player = event.getPlayer();
|
|
|
|
if (plugin.al.isAdmin(player))
|
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
final Location location = event.getBlock().getLocation();
|
|
|
|
|
|
|
|
if (isInProtectedArea(location))
|
|
|
|
{
|
|
|
|
event.setCancelled(true);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-10-19 17:43:46 +00:00
|
|
|
public boolean isInProtectedArea(final Location modifyLocation)
|
2012-11-03 19:03:38 +00:00
|
|
|
{
|
2013-09-05 14:22:59 +00:00
|
|
|
boolean doSave = false;
|
|
|
|
boolean inProtectedArea = false;
|
|
|
|
|
2015-10-19 17:43:46 +00:00
|
|
|
final Iterator<Map.Entry<String, SerializableProtectedRegion>> it = areas.entrySet().iterator();
|
2013-09-05 14:22:59 +00:00
|
|
|
|
|
|
|
while (it.hasNext())
|
2012-11-03 19:03:38 +00:00
|
|
|
{
|
2013-09-05 14:22:59 +00:00
|
|
|
final SerializableProtectedRegion region = it.next().getValue();
|
|
|
|
|
|
|
|
Location regionCenter = null;
|
|
|
|
try
|
2012-11-03 19:03:38 +00:00
|
|
|
{
|
2013-09-05 14:22:59 +00:00
|
|
|
regionCenter = region.getLocation();
|
|
|
|
}
|
|
|
|
catch (SerializableProtectedRegion.CantFindWorldException ex)
|
|
|
|
{
|
|
|
|
it.remove();
|
|
|
|
doSave = true;
|
|
|
|
continue;
|
|
|
|
}
|
2012-11-03 19:03:38 +00:00
|
|
|
|
2013-09-05 14:22:59 +00:00
|
|
|
if (regionCenter != null)
|
|
|
|
{
|
|
|
|
if (modifyLocation.getWorld() == regionCenter.getWorld())
|
|
|
|
{
|
|
|
|
final double regionRadius = region.getRadius();
|
|
|
|
if (modifyLocation.distanceSquared(regionCenter) <= (regionRadius * regionRadius))
|
2012-11-03 19:03:38 +00:00
|
|
|
{
|
2013-09-05 14:22:59 +00:00
|
|
|
inProtectedArea = true;
|
|
|
|
break;
|
2012-11-03 19:03:38 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-09-05 14:22:59 +00:00
|
|
|
if (doSave)
|
|
|
|
{
|
2015-04-26 22:53:07 +00:00
|
|
|
save();
|
2013-09-05 14:22:59 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return inProtectedArea;
|
2012-11-03 19:03:38 +00:00
|
|
|
}
|
|
|
|
|
2015-10-19 17:43:46 +00:00
|
|
|
public boolean isInProtectedArea(final Vector min, final Vector max, final String worldName)
|
2013-09-04 19:17:22 +00:00
|
|
|
{
|
2013-09-05 14:22:59 +00:00
|
|
|
boolean doSave = false;
|
|
|
|
boolean inProtectedArea = false;
|
|
|
|
|
2015-10-19 17:43:46 +00:00
|
|
|
final Iterator<Map.Entry<String, SerializableProtectedRegion>> it = areas.entrySet().iterator();
|
2013-09-05 14:22:59 +00:00
|
|
|
|
|
|
|
while (it.hasNext())
|
2013-09-04 19:17:22 +00:00
|
|
|
{
|
2013-09-05 14:22:59 +00:00
|
|
|
final SerializableProtectedRegion region = it.next().getValue();
|
|
|
|
|
|
|
|
Location regionCenter = null;
|
|
|
|
try
|
|
|
|
{
|
|
|
|
regionCenter = region.getLocation();
|
|
|
|
}
|
|
|
|
catch (SerializableProtectedRegion.CantFindWorldException ex)
|
2013-09-04 19:17:22 +00:00
|
|
|
{
|
2013-09-05 14:22:59 +00:00
|
|
|
it.remove();
|
|
|
|
doSave = true;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (regionCenter != null)
|
|
|
|
{
|
|
|
|
if (worldName.equals(regionCenter.getWorld().getName()))
|
2013-09-04 19:17:22 +00:00
|
|
|
{
|
2013-09-05 14:22:59 +00:00
|
|
|
if (cubeIntersectsSphere(min, max, regionCenter.toVector(), region.getRadius()))
|
2013-09-04 19:17:22 +00:00
|
|
|
{
|
2013-09-05 14:22:59 +00:00
|
|
|
inProtectedArea = true;
|
|
|
|
break;
|
2013-09-04 19:17:22 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-09-05 14:22:59 +00:00
|
|
|
if (doSave)
|
|
|
|
{
|
2015-04-26 22:53:07 +00:00
|
|
|
save();
|
2013-09-05 14:22:59 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return inProtectedArea;
|
2013-09-04 19:17:22 +00:00
|
|
|
}
|
|
|
|
|
2015-10-19 17:43:46 +00:00
|
|
|
private boolean cubeIntersectsSphere(Vector min, Vector max, Vector sphere, double radius)
|
2013-09-04 19:17:22 +00:00
|
|
|
{
|
|
|
|
double d = square(radius);
|
|
|
|
|
|
|
|
if (sphere.getX() < min.getX())
|
|
|
|
{
|
|
|
|
d -= square(sphere.getX() - min.getX());
|
|
|
|
}
|
|
|
|
else if (sphere.getX() > max.getX())
|
|
|
|
{
|
|
|
|
d -= square(sphere.getX() - max.getX());
|
|
|
|
}
|
|
|
|
if (sphere.getY() < min.getY())
|
|
|
|
{
|
|
|
|
d -= square(sphere.getY() - min.getY());
|
|
|
|
}
|
|
|
|
else if (sphere.getY() > max.getY())
|
|
|
|
{
|
|
|
|
d -= square(sphere.getY() - max.getY());
|
|
|
|
}
|
|
|
|
if (sphere.getZ() < min.getZ())
|
|
|
|
{
|
|
|
|
d -= square(sphere.getZ() - min.getZ());
|
|
|
|
}
|
|
|
|
else if (sphere.getZ() > max.getZ())
|
|
|
|
{
|
|
|
|
d -= square(sphere.getZ() - max.getZ());
|
|
|
|
}
|
|
|
|
|
|
|
|
return d > 0;
|
|
|
|
}
|
|
|
|
|
2015-10-19 17:43:46 +00:00
|
|
|
private double square(double v)
|
2013-09-04 19:17:22 +00:00
|
|
|
{
|
|
|
|
return v * v;
|
|
|
|
}
|
|
|
|
|
2015-10-19 17:43:46 +00:00
|
|
|
public void addProtectedArea(String label, Location location, double radius)
|
2012-11-03 19:03:38 +00:00
|
|
|
{
|
2015-10-19 17:43:46 +00:00
|
|
|
areas.put(label.toLowerCase(), new SerializableProtectedRegion(location, radius));
|
2015-04-26 22:53:07 +00:00
|
|
|
save();
|
2012-11-03 19:03:38 +00:00
|
|
|
}
|
|
|
|
|
2015-10-19 17:43:46 +00:00
|
|
|
public void removeProtectedArea(String label)
|
2012-11-03 19:03:38 +00:00
|
|
|
{
|
2015-10-19 17:43:46 +00:00
|
|
|
areas.remove(label.toLowerCase());
|
2015-04-26 22:53:07 +00:00
|
|
|
save();
|
2012-11-03 19:03:38 +00:00
|
|
|
}
|
2013-09-03 20:49:48 +00:00
|
|
|
|
2015-10-19 17:43:46 +00:00
|
|
|
public void clearProtectedAreas()
|
2013-08-28 19:40:14 +00:00
|
|
|
{
|
2013-09-05 14:22:59 +00:00
|
|
|
clearProtectedAreas(true);
|
2013-08-28 19:40:14 +00:00
|
|
|
}
|
|
|
|
|
2015-10-19 17:43:46 +00:00
|
|
|
public void clearProtectedAreas(boolean createSpawnpointProtectedAreas)
|
2012-11-03 19:03:38 +00:00
|
|
|
{
|
2015-10-19 17:43:46 +00:00
|
|
|
areas.clear();
|
2013-09-03 20:49:48 +00:00
|
|
|
|
2013-09-05 14:22:59 +00:00
|
|
|
if (createSpawnpointProtectedAreas)
|
2013-08-28 19:40:14 +00:00
|
|
|
{
|
|
|
|
autoAddSpawnpoints();
|
|
|
|
}
|
2013-09-03 20:49:48 +00:00
|
|
|
|
2015-04-26 22:53:07 +00:00
|
|
|
save();
|
2012-11-03 19:03:38 +00:00
|
|
|
}
|
|
|
|
|
2015-10-19 17:43:46 +00:00
|
|
|
public void cleanProtectedAreas()
|
2013-09-05 14:22:59 +00:00
|
|
|
{
|
|
|
|
boolean doSave = false;
|
|
|
|
|
2015-10-19 17:43:46 +00:00
|
|
|
final Iterator<Map.Entry<String, SerializableProtectedRegion>> it = areas.entrySet().iterator();
|
2013-09-05 14:22:59 +00:00
|
|
|
|
|
|
|
while (it.hasNext())
|
|
|
|
{
|
|
|
|
try
|
|
|
|
{
|
|
|
|
it.next().getValue().getLocation();
|
|
|
|
}
|
|
|
|
catch (SerializableProtectedRegion.CantFindWorldException ex)
|
|
|
|
{
|
|
|
|
it.remove();
|
|
|
|
doSave = true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (doSave)
|
|
|
|
{
|
2015-04-26 22:53:07 +00:00
|
|
|
save();
|
2013-09-05 14:22:59 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-10-19 17:43:46 +00:00
|
|
|
public Set<String> getProtectedAreaLabels()
|
2012-11-03 19:03:38 +00:00
|
|
|
{
|
2015-10-19 17:43:46 +00:00
|
|
|
return areas.keySet();
|
2012-11-03 19:03:38 +00:00
|
|
|
}
|
|
|
|
|
2015-10-19 17:43:46 +00:00
|
|
|
public void autoAddSpawnpoints()
|
2012-11-03 19:03:38 +00:00
|
|
|
{
|
2015-10-19 17:43:46 +00:00
|
|
|
if (!ConfigEntry.PROTECTAREA_ENABLED.getBoolean())
|
2015-04-26 22:53:07 +00:00
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2015-10-19 17:43:46 +00:00
|
|
|
if (ConfigEntry.PROTECTAREA_SPAWNPOINTS.getBoolean())
|
2012-11-03 19:03:38 +00:00
|
|
|
{
|
|
|
|
for (World world : Bukkit.getWorlds())
|
|
|
|
{
|
2015-10-19 17:43:46 +00:00
|
|
|
addProtectedArea("spawn_" + world.getName(), world.getSpawnLocation(), ConfigEntry.PROTECTAREA_RADIUS.getDouble());
|
2012-11-03 19:03:38 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2013-09-05 14:22:59 +00:00
|
|
|
|
2015-11-15 23:32:04 +00:00
|
|
|
public static class SerializableProtectedRegion implements Serializable
|
2013-09-05 14:22:59 +00:00
|
|
|
{
|
2015-10-19 17:43:46 +00:00
|
|
|
private static final long serialVersionUID = 213123517828282L;
|
2013-09-05 14:22:59 +00:00
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
2015-10-19 17:43:46 +00:00
|
|
|
public class CantFindWorldException extends Exception
|
2013-09-05 14:22:59 +00:00
|
|
|
{
|
2014-05-19 17:32:25 +00:00
|
|
|
private static final long serialVersionUID = 1L;
|
|
|
|
|
2013-09-05 14:22:59 +00:00
|
|
|
public CantFindWorldException(String string)
|
|
|
|
{
|
|
|
|
super(string);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2012-11-03 19:03:38 +00:00
|
|
|
}
|