Added Protected Areas!

Switched distance -> distanceSquared to eliminate square root computation, where possible.
This commit is contained in:
Steven Lawson 2012-11-03 15:03:38 -04:00
parent b46bbd3eba
commit a1c8427850
11 changed files with 395 additions and 18 deletions

View File

@ -54,6 +54,11 @@ flatlands_generation_params: 16,stone,32,dirt,1,grass
# Admin-Only Mode
admin_only_mode: false
# Protected Areas - Protect areas so that only superadmins can directly modify blocks in those areas. WorldEdit and other such plugins might bypass this.
protected_areas_enabled: true
auto_protect_spawnpoints: true
auto_protect_radius: 25.0
# SuperAwesomeAdmins - Because normal superadmin just isn't awesome enough. These users can do even more awesomey admin shit.
super_awesome_admins:
- markbyron

View File

@ -49,16 +49,19 @@ public class Command_cartsit extends TFM_Command
Minecart nearest_cart = null;
for (Minecart cart : target_player.getWorld().getEntitiesByClass(Minecart.class))
{
if (nearest_cart == null)
if (cart.isEmpty())
{
nearest_cart = cart;
}
else
{
if (cart.getLocation().distance(target_player.getLocation()) < nearest_cart.getLocation().distance(target_player.getLocation()))
if (nearest_cart == null)
{
nearest_cart = cart;
}
else
{
if (cart.getLocation().distanceSquared(target_player.getLocation()) < nearest_cart.getLocation().distanceSquared(target_player.getLocation()))
{
nearest_cart = cart;
}
}
}
}
@ -68,7 +71,7 @@ public class Command_cartsit extends TFM_Command
}
else
{
sender.sendMessage("There are no minecarts in the target world.");
sender.sendMessage("There are no empty minecarts in the target world.");
}
}

View File

@ -54,7 +54,7 @@ public class Command_expel extends TFM_Command
boolean in_range = false;
try
{
in_range = target_pos.distance(sender_pos) < radius;
in_range = target_pos.distanceSquared(sender_pos) < (radius * radius);
}
catch (IllegalArgumentException ex)
{

View File

@ -0,0 +1,103 @@
package me.StevenLawson.TotalFreedomMod.Commands;
import me.StevenLawson.TotalFreedomMod.TFM_ProtectedArea;
import me.StevenLawson.TotalFreedomMod.TFM_Util;
import me.StevenLawson.TotalFreedomMod.TotalFreedomMod;
import org.apache.commons.lang.StringUtils;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
public class Command_protectarea extends TFM_Command
{
@Override
public boolean run(CommandSender sender, Player sender_p, Command cmd, String commandLabel, String[] args, boolean senderIsConsole)
{
if (!TFM_Util.isUserSuperadmin(sender))
{
sender.sendMessage(TotalFreedomMod.MSG_NO_PERMS);
return true;
}
if (!TotalFreedomMod.protectedAreasEnabled)
{
sender.sendMessage("Protected areas are currently disabled in the TotalFreedomMod configuration.");
return true;
}
if (args.length == 1)
{
if (args[0].equalsIgnoreCase("list"))
{
sender.sendMessage("Protected Areas: " + StringUtils.join(TFM_ProtectedArea.getProtectedAreaLabels(), ", "));
}
else if (args[0].equalsIgnoreCase("clear"))
{
TFM_ProtectedArea.clearProtectedAreas();
sender.sendMessage("Protected Areas Cleared.");
}
else
{
return false;
}
return true;
}
else if (args.length == 2)
{
if (args[0].equalsIgnoreCase("remove"))
{
TFM_ProtectedArea.removeProtectedArea(args[1]);
sender.sendMessage("Area removed. Protected Areas: " + StringUtils.join(TFM_ProtectedArea.getProtectedAreaLabels(), ", "));
}
else
{
return false;
}
return true;
}
else if (args.length == 3)
{
if (args[0].equalsIgnoreCase("add"))
{
if (senderIsConsole)
{
sender.sendMessage("You must be in-game to set a protected area.");
return true;
}
Double radius;
try
{
radius = Double.parseDouble(args[2]);
}
catch (NumberFormatException nfex)
{
sender.sendMessage("Invalid radius.");
return true;
}
if (radius > TFM_ProtectedArea.MAX_RADIUS || radius < 0.0D)
{
sender.sendMessage("Invalid radius. Radius must be a positive value less than " + TFM_ProtectedArea.MAX_RADIUS + ".");
return true;
}
TFM_ProtectedArea.addProtectedArea(args[1], sender_p.getLocation(), radius);
sender.sendMessage("Area added. Protected Areas: " + StringUtils.join(TFM_ProtectedArea.getProtectedAreaLabels(), ", "));
}
else
{
return false;
}
return true;
}
return false;
}
}

View File

@ -1,5 +1,6 @@
package me.StevenLawson.TotalFreedomMod.Commands;
import me.StevenLawson.TotalFreedomMod.TFM_ProtectedArea;
import me.StevenLawson.TotalFreedomMod.TFM_Util;
import me.StevenLawson.TotalFreedomMod.TotalFreedomMod;
import org.bukkit.ChatColor;
@ -29,6 +30,11 @@ public class Command_setspawnworld extends TFM_Command
sender_p.getWorld().setSpawnLocation(pos.getBlockX(), pos.getBlockY(), pos.getBlockZ());
sender.sendMessage(ChatColor.GRAY + "Spawn location for this world set to: " + TFM_Util.formatLocation(sender_p.getWorld().getSpawnLocation()));
if (TotalFreedomMod.protectedAreasEnabled && TotalFreedomMod.autoProtectSpawnpoints)
{
TFM_ProtectedArea.addProtectedArea("spawn_" + sender_p.getWorld().getName(), pos, TotalFreedomMod.autoProtectRadius);
}
return true;
}

View File

@ -1,6 +1,7 @@
package me.StevenLawson.TotalFreedomMod.Listener;
import me.StevenLawson.TotalFreedomMod.TFM_Log;
import me.StevenLawson.TotalFreedomMod.TFM_ProtectedArea;
import me.StevenLawson.TotalFreedomMod.TFM_UserInfo;
import me.StevenLawson.TotalFreedomMod.TFM_Util;
import me.StevenLawson.TotalFreedomMod.TotalFreedomMod;
@ -39,20 +40,21 @@ public class TFM_BlockListener implements Listener
@EventHandler(priority = EventPriority.NORMAL)
public void onBlockBreak(BlockBreakEvent event)
{
Player p = event.getPlayer();
Location block_pos = event.getBlock().getLocation();
if (TotalFreedomMod.nukeMonitor)
{
Player p = event.getPlayer();
TFM_UserInfo playerdata = TFM_UserInfo.getPlayerData(p);
Location player_pos = p.getLocation();
Location block_pos = event.getBlock().getLocation();
boolean out_of_range = false;
if (!player_pos.getWorld().equals(block_pos.getWorld()))
{
out_of_range = true;
}
else if (player_pos.distance(block_pos) > TotalFreedomMod.nukeMonitorRange)
else if (player_pos.distanceSquared(block_pos) > (TotalFreedomMod.nukeMonitorRange * TotalFreedomMod.nukeMonitorRange))
{
out_of_range = true;
}
@ -84,26 +86,38 @@ public class TFM_BlockListener implements Listener
return;
}
}
if (TotalFreedomMod.protectedAreasEnabled)
{
if (!TFM_Util.isUserSuperadmin(p))
{
if (TFM_ProtectedArea.isInProtectedArea(block_pos))
{
event.setCancelled(true);
return;
}
}
}
}
@EventHandler(priority = EventPriority.HIGH)
public void onBlockPlace(BlockPlaceEvent event)
{
Player p = event.getPlayer();
Location block_pos = event.getBlock().getLocation();
if (TotalFreedomMod.nukeMonitor)
{
TFM_UserInfo playerdata = TFM_UserInfo.getPlayerData(p);
Location player_pos = p.getLocation();
Location block_pos = event.getBlock().getLocation();
boolean out_of_range = false;
if (!player_pos.getWorld().equals(block_pos.getWorld()))
{
out_of_range = true;
}
else if (player_pos.distance(block_pos) > TotalFreedomMod.nukeMonitorRange)
else if (player_pos.distanceSquared(block_pos) > (TotalFreedomMod.nukeMonitorRange * TotalFreedomMod.nukeMonitorRange))
{
out_of_range = true;
}
@ -136,6 +150,18 @@ public class TFM_BlockListener implements Listener
}
}
if (TotalFreedomMod.protectedAreasEnabled)
{
if (!TFM_Util.isUserSuperadmin(p))
{
if (TFM_ProtectedArea.isInProtectedArea(block_pos))
{
event.setCancelled(true);
return;
}
}
}
ItemStack is = new ItemStack(event.getBlockPlaced().getType(), 1, (short) 0, event.getBlockPlaced().getData());
switch (is.getType())
{

View File

@ -154,17 +154,17 @@ public class TFM_PlayerListener implements Listener
Location mover_pos = p.getLocation();
Location fuckoff_pos = fuckoff_player.getLocation();
double distance;
double distanceSquared;
try
{
distance = mover_pos.distance(fuckoff_pos);
distanceSquared = mover_pos.distanceSquared(fuckoff_pos);
}
catch (IllegalArgumentException ex)
{
continue;
}
if (distance < fuckoff_range)
if (distanceSquared < (fuckoff_range * fuckoff_range))
{
event.setTo(fuckoff_pos.clone().add(mover_pos.subtract(fuckoff_pos).toVector().normalize().multiply(fuckoff_range * 1.1)));
break;
@ -210,7 +210,7 @@ public class TFM_PlayerListener implements Listener
}
else
{
out_of_cage = target_pos.distance(playerdata.getCagePos()) > 2.5;
out_of_cage = target_pos.distanceSquared(playerdata.getCagePos()) > (2.5 * 2.5);
}
if (out_of_cage)
@ -249,7 +249,7 @@ public class TFM_PlayerListener implements Listener
{
if (p.getWorld().equals(landmine_pos.getWorld()))
{
if (p.getLocation().distance(landmine_pos) <= landmine.radius)
if (p.getLocation().distanceSquared(landmine_pos) <= (landmine.radius * landmine.radius))
{
landmine.landmine_pos.getBlock().setType(Material.AIR);

View File

@ -0,0 +1,93 @@
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

@ -0,0 +1,125 @@
package me.StevenLawson.TotalFreedomMod;
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;
import java.util.Map;
import java.util.Set;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.World;
public class TFM_ProtectedArea implements Serializable
{
public static final double MAX_RADIUS = 50.0D;
private static Map<String, TFM_ProtectedArea> protectedAreas = new HashMap<String, TFM_ProtectedArea>();
private final SerializableLocation center_location;
private final double radius;
private TFM_ProtectedArea(Location root_location, double radius)
{
this.center_location = new SerializableLocation(root_location);
this.radius = radius;
}
public static boolean isInProtectedArea(Location check_location)
{
for (Map.Entry<String, TFM_ProtectedArea> protected_area : TFM_ProtectedArea.protectedAreas.entrySet())
{
Location protected_area_center = SerializableLocation.returnLocation(protected_area.getValue().center_location);
if (protected_area_center != null)
{
if (check_location.getWorld() == protected_area_center.getWorld())
{
double protected_area_radius = protected_area.getValue().radius;
if (check_location.distanceSquared(protected_area_center) <= (protected_area_radius * protected_area_radius))
{
return true;
}
}
}
}
return false;
}
public static void addProtectedArea(String label, Location root_location, double radius)
{
TFM_ProtectedArea.protectedAreas.put(label.toLowerCase(), new TFM_ProtectedArea(root_location, radius));
saveProtectedAreas();
}
public static void removeProtectedArea(String label)
{
TFM_ProtectedArea.protectedAreas.remove(label.toLowerCase());
saveProtectedAreas();
}
public static void clearProtectedAreas()
{
TFM_ProtectedArea.protectedAreas.clear();
autoAddSpawnpoints();
saveProtectedAreas();
}
public static Set<String> getProtectedAreaLabels()
{
return TFM_ProtectedArea.protectedAreas.keySet();
}
public static void saveProtectedAreas()
{
try
{
FileOutputStream fos = new FileOutputStream(new File(TotalFreedomMod.plugin.getDataFolder(), TotalFreedomMod.PROTECTED_AREA_FILE));
ObjectOutputStream oos = new ObjectOutputStream(fos);
oos.writeObject(TFM_ProtectedArea.protectedAreas);
oos.close();
fos.close();
}
catch (Exception ex)
{
TFM_Log.severe(ex);
}
}
@SuppressWarnings("unchecked")
public static void loadProtectedAreas()
{
try
{
File input_file = new File(TotalFreedomMod.plugin.getDataFolder(), TotalFreedomMod.PROTECTED_AREA_FILE);
if (input_file.exists())
{
FileInputStream fis = new FileInputStream(input_file);
ObjectInputStream ois = new ObjectInputStream(fis);
TFM_ProtectedArea.protectedAreas = (HashMap<String, TFM_ProtectedArea>) ois.readObject();
ois.close();
fis.close();
}
}
catch (Exception ex)
{
File input_file = new File(TotalFreedomMod.plugin.getDataFolder(), TotalFreedomMod.PROTECTED_AREA_FILE);
input_file.delete();
TFM_Log.severe(ex);
}
}
public static void autoAddSpawnpoints()
{
if (TotalFreedomMod.autoProtectSpawnpoints)
{
for (World world : Bukkit.getWorlds())
{
TFM_ProtectedArea.addProtectedArea("spawn_" + world.getName(), world.getSpawnLocation(), TotalFreedomMod.autoProtectRadius);
}
}
}
}

View File

@ -30,6 +30,7 @@ public class TotalFreedomMod extends JavaPlugin
public static final String CONFIG_FILE = "config.yml";
public static final String SUPERADMIN_FILE = "superadmin.yml";
public static final String PERMBAN_FILE = "permban.yml";
public static final String PROTECTED_AREA_FILE = "protectedareas.dat";
public static final String COMMAND_PATH = "me.StevenLawson.TotalFreedomMod.Commands";
public static final String COMMAND_PREFIX = "Command_";
@ -88,6 +89,12 @@ public class TotalFreedomMod extends JavaPlugin
world.setThunderDuration(0);
}
}
if (TotalFreedomMod.protectedAreasEnabled)
{
TFM_ProtectedArea.loadProtectedAreas();
TFM_ProtectedArea.autoAddSpawnpoints();
}
}
@Override
@ -186,6 +193,9 @@ public class TotalFreedomMod extends JavaPlugin
public static boolean allowFliudSpread = false;
public static boolean adminOnlyMode = false;
public static List<String> superAwesomeAdmins = Arrays.asList("markbyron", "mark", "madgeek1450", "madgeek", "darthsalamon", "darth");
public static boolean protectedAreasEnabled = true;
public static boolean autoProtectSpawnpoints = true;
public static double autoProtectRadius = 25.0D;
public void loadMainConfig()
{
@ -224,6 +234,9 @@ public class TotalFreedomMod extends JavaPlugin
allowFliudSpread = config.getBoolean("allow_fluid_spread", allowFliudSpread);
adminOnlyMode = config.getBoolean("admin_only_mode", adminOnlyMode);
superAwesomeAdmins = config.getStringList("super_awesome_admins");
protectedAreasEnabled = config.getBoolean("protected_areas_enabled", protectedAreasEnabled);
autoProtectSpawnpoints = config.getBoolean("auto_protect_spawnpoints", autoProtectSpawnpoints);
autoProtectRadius = config.getDouble("auto_protect_radius", autoProtectRadius);
}
catch (Exception ex)
{

View File

@ -140,6 +140,9 @@ commands:
prelog:
description: Superadmin command - Enable/disable the command prelogger. When this is on, logs will be filled with many duplicate messages.
usage: /<command> <on | off>
protectarea:
description: Superadmin command - Protect areas so that only superadmins can directly modify blocks in those areas. WorldEdit and other such plugins might bypass this.
usage: /<command> <list | clear | remove <label> | add <label> <radius>>
qdeop:
description: Quick De-Op - deop someone based on a partial name.
usage: /<command> <partialname>