diff --git a/src/main/java/me/ryanhamshire/GriefPrevention/CustomizableMessage.java b/src/main/java/me/ryanhamshire/GriefPrevention/CustomizableMessage.java
index 8d64657..b0cb406 100644
--- a/src/main/java/me/ryanhamshire/GriefPrevention/CustomizableMessage.java
+++ b/src/main/java/me/ryanhamshire/GriefPrevention/CustomizableMessage.java
@@ -1,33 +1,33 @@
-/*
- GriefPrevention Server Plugin for Minecraft
- Copyright (C) 2012 Ryan Hamshire
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see .
- */
-
-package me.ryanhamshire.GriefPrevention;
-
-public class CustomizableMessage
-{
- public Messages id;
- public String text;
- public String notes;
-
- public CustomizableMessage(Messages id, String text, String notes)
- {
- this.id = id;
- this.text = text;
- this.notes = notes;
- }
+/*
+ GriefPrevention Server Plugin for Minecraft
+ Copyright (C) 2012 Ryan Hamshire
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see .
+ */
+
+package me.ryanhamshire.GriefPrevention;
+
+public class CustomizableMessage
+{
+ public Messages id;
+ public String text;
+ public String notes;
+
+ public CustomizableMessage(Messages id, String text, String notes)
+ {
+ this.id = id;
+ this.text = text;
+ this.notes = notes;
+ }
}
\ No newline at end of file
diff --git a/src/main/java/me/ryanhamshire/GriefPrevention/DeliverClaimBlocksTask.java b/src/main/java/me/ryanhamshire/GriefPrevention/DeliverClaimBlocksTask.java
index ddaec5c..e97bc40 100644
--- a/src/main/java/me/ryanhamshire/GriefPrevention/DeliverClaimBlocksTask.java
+++ b/src/main/java/me/ryanhamshire/GriefPrevention/DeliverClaimBlocksTask.java
@@ -1,128 +1,128 @@
-/*
- GriefPrevention Server Plugin for Minecraft
- Copyright (C) 2012 Ryan Hamshire
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see .
- */
-
-package me.ryanhamshire.GriefPrevention;
-
-import me.ryanhamshire.GriefPrevention.events.AccrueClaimBlocksEvent;
-import org.bukkit.entity.Player;
-
-import java.util.Collection;
-
-//FEATURE: give players claim blocks for playing, as long as they're not away from their computer
-
-//runs every 5 minutes in the main thread, grants blocks per hour / 12 to each online player who appears to be actively playing
-class DeliverClaimBlocksTask implements Runnable
-{
- private Player player;
- private GriefPrevention instance;
- private int idleThresholdSquared;
-
- public DeliverClaimBlocksTask(Player player, GriefPrevention instance)
- {
- this.player = player;
- this.instance = instance;
- this.idleThresholdSquared = instance.config_claims_accruedIdleThreshold * instance.config_claims_accruedIdleThreshold;
- }
-
- @Override
- public void run()
- {
- //if no player specified, this task will create a player-specific task for each online player, scheduled one tick apart
- if (this.player == null)
- {
- @SuppressWarnings("unchecked")
- Collection players = (Collection) GriefPrevention.instance.getServer().getOnlinePlayers();
-
- long i = 0;
- for (Player onlinePlayer : players)
- {
- DeliverClaimBlocksTask newTask = new DeliverClaimBlocksTask(onlinePlayer, instance);
- instance.getServer().getScheduler().scheduleSyncDelayedTask(instance, newTask, i++);
- }
-
- return; //tasks started for each player
- }
-
- //deliver claim blocks to the specified player
- if (!this.player.isOnline())
- {
- return; //player is not online to receive claim blocks
- }
-
- DataStore dataStore = instance.dataStore;
- PlayerData playerData = dataStore.getPlayerData(player.getUniqueId());
-
- // check if player is idle. considered idle if
- // in vehicle or is in water (pushed by water)
- // or has not moved at least defined blocks since last check
- boolean isIdle = false;
- try
- {
- isIdle = player.isInsideVehicle() || player.getLocation().getBlock().isLiquid() ||
- !(playerData.lastAfkCheckLocation == null || playerData.lastAfkCheckLocation.distanceSquared(player.getLocation()) > idleThresholdSquared);
- }
- catch (IllegalArgumentException ignore) //can't measure distance when to/from are different worlds
- {
- }
-
- //remember current location for next time
- playerData.lastAfkCheckLocation = player.getLocation();
-
- try
- {
- //determine how fast blocks accrue for this player //RoboMWM: addons determine this instead
- int accrualRate = instance.config_claims_blocksAccruedPerHour_default;
-
- //determine idle accrual rate when idle
- if (isIdle)
- {
- if (instance.config_claims_accruedIdlePercent <= 0)
- {
- GriefPrevention.AddLogEntry(player.getName() + " wasn't active enough to accrue claim blocks this round.", CustomLogEntryTypes.Debug, true);
- return; //idle accrual percentage is disabled
- }
-
- accrualRate = (int) (accrualRate * (instance.config_claims_accruedIdlePercent / 100.0D));
- }
-
- //fire event for addons
- AccrueClaimBlocksEvent event = new AccrueClaimBlocksEvent(player, accrualRate, isIdle);
- instance.getServer().getPluginManager().callEvent(event);
- if (event.isCancelled())
- {
- GriefPrevention.AddLogEntry(player.getName() + " claim block delivery was canceled by another plugin.", CustomLogEntryTypes.Debug, true);
- return; //event was cancelled
- }
-
- //set actual accrual
- accrualRate = event.getBlocksToAccrue();
- if (accrualRate < 0) accrualRate = 0;
- playerData.accrueBlocks(accrualRate);
- GriefPrevention.AddLogEntry("Delivering " + event.getBlocksToAccrue() + " blocks to " + player.getName(), CustomLogEntryTypes.Debug, true);
-
- //intentionally NOT saving data here to reduce overall secondary storage access frequency
- //many other operations will cause this player's data to save, including his eventual logout
- //dataStore.savePlayerData(player.getUniqueIdentifier(), playerData);
- }
- catch (Exception e)
- {
- GriefPrevention.AddLogEntry("Problem delivering claim blocks to player " + player.getName() + ":");
- e.printStackTrace();
- }
- }
-}
+/*
+ GriefPrevention Server Plugin for Minecraft
+ Copyright (C) 2012 Ryan Hamshire
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see .
+ */
+
+package me.ryanhamshire.GriefPrevention;
+
+import me.ryanhamshire.GriefPrevention.events.AccrueClaimBlocksEvent;
+import org.bukkit.entity.Player;
+
+import java.util.Collection;
+
+//FEATURE: give players claim blocks for playing, as long as they're not away from their computer
+
+//runs every 5 minutes in the main thread, grants blocks per hour / 12 to each online player who appears to be actively playing
+class DeliverClaimBlocksTask implements Runnable
+{
+ private Player player;
+ private GriefPrevention instance;
+ private int idleThresholdSquared;
+
+ public DeliverClaimBlocksTask(Player player, GriefPrevention instance)
+ {
+ this.player = player;
+ this.instance = instance;
+ this.idleThresholdSquared = instance.config_claims_accruedIdleThreshold * instance.config_claims_accruedIdleThreshold;
+ }
+
+ @Override
+ public void run()
+ {
+ //if no player specified, this task will create a player-specific task for each online player, scheduled one tick apart
+ if (this.player == null)
+ {
+ @SuppressWarnings("unchecked")
+ Collection players = (Collection) GriefPrevention.instance.getServer().getOnlinePlayers();
+
+ long i = 0;
+ for (Player onlinePlayer : players)
+ {
+ DeliverClaimBlocksTask newTask = new DeliverClaimBlocksTask(onlinePlayer, instance);
+ instance.getServer().getScheduler().scheduleSyncDelayedTask(instance, newTask, i++);
+ }
+
+ return; //tasks started for each player
+ }
+
+ //deliver claim blocks to the specified player
+ if (!this.player.isOnline())
+ {
+ return; //player is not online to receive claim blocks
+ }
+
+ DataStore dataStore = instance.dataStore;
+ PlayerData playerData = dataStore.getPlayerData(player.getUniqueId());
+
+ // check if player is idle. considered idle if
+ // in vehicle or is in water (pushed by water)
+ // or has not moved at least defined blocks since last check
+ boolean isIdle = false;
+ try
+ {
+ isIdle = player.isInsideVehicle() || player.getLocation().getBlock().isLiquid() ||
+ !(playerData.lastAfkCheckLocation == null || playerData.lastAfkCheckLocation.distanceSquared(player.getLocation()) > idleThresholdSquared);
+ }
+ catch (IllegalArgumentException ignore) //can't measure distance when to/from are different worlds
+ {
+ }
+
+ //remember current location for next time
+ playerData.lastAfkCheckLocation = player.getLocation();
+
+ try
+ {
+ //determine how fast blocks accrue for this player //RoboMWM: addons determine this instead
+ int accrualRate = instance.config_claims_blocksAccruedPerHour_default;
+
+ //determine idle accrual rate when idle
+ if (isIdle)
+ {
+ if (instance.config_claims_accruedIdlePercent <= 0)
+ {
+ GriefPrevention.AddLogEntry(player.getName() + " wasn't active enough to accrue claim blocks this round.", CustomLogEntryTypes.Debug, true);
+ return; //idle accrual percentage is disabled
+ }
+
+ accrualRate = (int) (accrualRate * (instance.config_claims_accruedIdlePercent / 100.0D));
+ }
+
+ //fire event for addons
+ AccrueClaimBlocksEvent event = new AccrueClaimBlocksEvent(player, accrualRate, isIdle);
+ instance.getServer().getPluginManager().callEvent(event);
+ if (event.isCancelled())
+ {
+ GriefPrevention.AddLogEntry(player.getName() + " claim block delivery was canceled by another plugin.", CustomLogEntryTypes.Debug, true);
+ return; //event was cancelled
+ }
+
+ //set actual accrual
+ accrualRate = event.getBlocksToAccrue();
+ if (accrualRate < 0) accrualRate = 0;
+ playerData.accrueBlocks(accrualRate);
+ GriefPrevention.AddLogEntry("Delivering " + event.getBlocksToAccrue() + " blocks to " + player.getName(), CustomLogEntryTypes.Debug, true);
+
+ //intentionally NOT saving data here to reduce overall secondary storage access frequency
+ //many other operations will cause this player's data to save, including his eventual logout
+ //dataStore.savePlayerData(player.getUniqueIdentifier(), playerData);
+ }
+ catch (Exception e)
+ {
+ GriefPrevention.AddLogEntry("Problem delivering claim blocks to player " + player.getName() + ":");
+ e.printStackTrace();
+ }
+ }
+}
diff --git a/src/main/java/me/ryanhamshire/GriefPrevention/EntityCleanupTask.java b/src/main/java/me/ryanhamshire/GriefPrevention/EntityCleanupTask.java
index 980ad24..16d03cb 100644
--- a/src/main/java/me/ryanhamshire/GriefPrevention/EntityCleanupTask.java
+++ b/src/main/java/me/ryanhamshire/GriefPrevention/EntityCleanupTask.java
@@ -1,149 +1,149 @@
-/*
- GriefPrevention Server Plugin for Minecraft
- Copyright (C) 2012 Ryan Hamshire
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see .
- */
-
-package me.ryanhamshire.GriefPrevention;
-
-import org.bukkit.Material;
-import org.bukkit.World;
-import org.bukkit.entity.Boat;
-import org.bukkit.entity.Entity;
-import org.bukkit.entity.Player;
-import org.bukkit.entity.Vehicle;
-
-import java.util.ArrayList;
-import java.util.List;
-
-//FEATURE: creative mode worlds get a regular entity cleanup
-
-//this main thread task revisits the location of a partially chopped tree from several minutes ago
-//if any part of the tree is still there and nothing else has been built in its place, remove the remaining parts
-class EntityCleanupTask implements Runnable
-{
- //where to start cleaning in the list of entities
- private double percentageStart;
-
- public EntityCleanupTask(double percentageStart)
- {
- this.percentageStart = percentageStart;
- }
-
- @Override
- public void run()
- {
- ArrayList worlds = new ArrayList();
- for (World world : GriefPrevention.instance.getServer().getWorlds())
- {
- if (GriefPrevention.instance.config_claims_worldModes.get(world) == ClaimsMode.Creative)
- {
- worlds.add(world);
- }
- }
-
- for (int i = 0; i < worlds.size(); i++)
- {
- World world = worlds.get(i);
-
- List entities = world.getEntities();
-
- //starting and stopping point. each execution of the task scans 10% of the server's (loaded) entities
- int j = (int) (entities.size() * this.percentageStart);
- int k = (int) (entities.size() * (this.percentageStart + .1));
- Claim cachedClaim = null;
- for (; j < entities.size() && j < k; j++)
- {
- Entity entity = entities.get(j);
-
- boolean remove = false;
- if (entity instanceof Boat) //boats must be occupied
- {
- Boat boat = (Boat) entity;
- if (boat.isEmpty()) remove = true;
- }
- else if (entity instanceof Vehicle)
- {
- Vehicle vehicle = (Vehicle) entity;
-
- //minecarts in motion must be occupied by a player
- if (vehicle.getVelocity().lengthSquared() != 0)
- {
- if (vehicle.isEmpty() || !(vehicle.getPassenger() instanceof Player))
- {
- remove = true;
- }
- }
-
- //stationary carts must be on rails
- else
- {
- Material material = world.getBlockAt(vehicle.getLocation()).getType();
- if (material != Material.RAIL && material != Material.POWERED_RAIL && material != Material.DETECTOR_RAIL)
- {
- remove = true;
- }
- }
- }
-
- //all non-player entities must be in claims
- else if (!(entity instanceof Player))
- {
- Claim claim = GriefPrevention.instance.dataStore.getClaimAt(entity.getLocation(), false, cachedClaim);
- if (claim != null)
- {
- cachedClaim = claim;
- }
- else
- {
- remove = true;
- }
- }
-
- if (remove)
- {
- GriefPrevention.AddLogEntry("Removing entity " + entity.getType().name() + " @ " + entity.getLocation(), CustomLogEntryTypes.Debug, true);
- entity.remove();
- }
- }
- }
-
- //starting and stopping point. each execution of the task scans 5% of the server's claims
- List claims = GriefPrevention.instance.dataStore.claims;
- int j = (int) (claims.size() * this.percentageStart);
- int k = (int) (claims.size() * (this.percentageStart + .05));
- for (; j < claims.size() && j < k; j++)
- {
- Claim claim = claims.get(j);
-
- //if it's a creative mode claim
- if (GriefPrevention.instance.creativeRulesApply(claim.getLesserBoundaryCorner()))
- {
- //check its entity count and remove any extras
- claim.allowMoreEntities(true);
- }
- }
-
- //schedule the next run of this task, in 3 minutes (20L is approximately 1 second)
- double nextRunPercentageStart = this.percentageStart + .05;
- if (nextRunPercentageStart > .99)
- {
- nextRunPercentageStart = 0;
- }
-
- EntityCleanupTask task = new EntityCleanupTask(nextRunPercentageStart);
- GriefPrevention.instance.getServer().getScheduler().scheduleSyncDelayedTask(GriefPrevention.instance, task, 20L * 60 * 1);
- }
-}
+/*
+ GriefPrevention Server Plugin for Minecraft
+ Copyright (C) 2012 Ryan Hamshire
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see .
+ */
+
+package me.ryanhamshire.GriefPrevention;
+
+import org.bukkit.Material;
+import org.bukkit.World;
+import org.bukkit.entity.Boat;
+import org.bukkit.entity.Entity;
+import org.bukkit.entity.Player;
+import org.bukkit.entity.Vehicle;
+
+import java.util.ArrayList;
+import java.util.List;
+
+//FEATURE: creative mode worlds get a regular entity cleanup
+
+//this main thread task revisits the location of a partially chopped tree from several minutes ago
+//if any part of the tree is still there and nothing else has been built in its place, remove the remaining parts
+class EntityCleanupTask implements Runnable
+{
+ //where to start cleaning in the list of entities
+ private double percentageStart;
+
+ public EntityCleanupTask(double percentageStart)
+ {
+ this.percentageStart = percentageStart;
+ }
+
+ @Override
+ public void run()
+ {
+ ArrayList worlds = new ArrayList();
+ for (World world : GriefPrevention.instance.getServer().getWorlds())
+ {
+ if (GriefPrevention.instance.config_claims_worldModes.get(world) == ClaimsMode.Creative)
+ {
+ worlds.add(world);
+ }
+ }
+
+ for (int i = 0; i < worlds.size(); i++)
+ {
+ World world = worlds.get(i);
+
+ List entities = world.getEntities();
+
+ //starting and stopping point. each execution of the task scans 10% of the server's (loaded) entities
+ int j = (int) (entities.size() * this.percentageStart);
+ int k = (int) (entities.size() * (this.percentageStart + .1));
+ Claim cachedClaim = null;
+ for (; j < entities.size() && j < k; j++)
+ {
+ Entity entity = entities.get(j);
+
+ boolean remove = false;
+ if (entity instanceof Boat) //boats must be occupied
+ {
+ Boat boat = (Boat) entity;
+ if (boat.isEmpty()) remove = true;
+ }
+ else if (entity instanceof Vehicle)
+ {
+ Vehicle vehicle = (Vehicle) entity;
+
+ //minecarts in motion must be occupied by a player
+ if (vehicle.getVelocity().lengthSquared() != 0)
+ {
+ if (vehicle.isEmpty() || !(vehicle.getPassenger() instanceof Player))
+ {
+ remove = true;
+ }
+ }
+
+ //stationary carts must be on rails
+ else
+ {
+ Material material = world.getBlockAt(vehicle.getLocation()).getType();
+ if (material != Material.RAIL && material != Material.POWERED_RAIL && material != Material.DETECTOR_RAIL)
+ {
+ remove = true;
+ }
+ }
+ }
+
+ //all non-player entities must be in claims
+ else if (!(entity instanceof Player))
+ {
+ Claim claim = GriefPrevention.instance.dataStore.getClaimAt(entity.getLocation(), false, cachedClaim);
+ if (claim != null)
+ {
+ cachedClaim = claim;
+ }
+ else
+ {
+ remove = true;
+ }
+ }
+
+ if (remove)
+ {
+ GriefPrevention.AddLogEntry("Removing entity " + entity.getType().name() + " @ " + entity.getLocation(), CustomLogEntryTypes.Debug, true);
+ entity.remove();
+ }
+ }
+ }
+
+ //starting and stopping point. each execution of the task scans 5% of the server's claims
+ List claims = GriefPrevention.instance.dataStore.claims;
+ int j = (int) (claims.size() * this.percentageStart);
+ int k = (int) (claims.size() * (this.percentageStart + .05));
+ for (; j < claims.size() && j < k; j++)
+ {
+ Claim claim = claims.get(j);
+
+ //if it's a creative mode claim
+ if (GriefPrevention.instance.creativeRulesApply(claim.getLesserBoundaryCorner()))
+ {
+ //check its entity count and remove any extras
+ claim.allowMoreEntities(true);
+ }
+ }
+
+ //schedule the next run of this task, in 3 minutes (20L is approximately 1 second)
+ double nextRunPercentageStart = this.percentageStart + .05;
+ if (nextRunPercentageStart > .99)
+ {
+ nextRunPercentageStart = 0;
+ }
+
+ EntityCleanupTask task = new EntityCleanupTask(nextRunPercentageStart);
+ GriefPrevention.instance.getServer().getScheduler().scheduleSyncDelayedTask(GriefPrevention.instance, task, 20L * 60 * 1);
+ }
+}
diff --git a/src/main/java/me/ryanhamshire/GriefPrevention/EquipShovelProcessingTask.java b/src/main/java/me/ryanhamshire/GriefPrevention/EquipShovelProcessingTask.java
index b27abef..3ead14e 100644
--- a/src/main/java/me/ryanhamshire/GriefPrevention/EquipShovelProcessingTask.java
+++ b/src/main/java/me/ryanhamshire/GriefPrevention/EquipShovelProcessingTask.java
@@ -1,79 +1,79 @@
-/*
- GriefPrevention Server Plugin for Minecraft
- Copyright (C) 2012 Ryan Hamshire
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see .
- */
-
-package me.ryanhamshire.GriefPrevention;
-
-import org.bukkit.entity.Player;
-import org.bukkit.inventory.EquipmentSlot;
-
-//tells a player about how many claim blocks he has, etc
-//implemented as a task so that it can be delayed
-//otherwise, it's spammy when players mouse-wheel past the shovel in their hot bars
-class EquipShovelProcessingTask implements Runnable
-{
- //player data
- private Player player;
-
- public EquipShovelProcessingTask(Player player)
- {
- this.player = player;
- }
-
- @Override
- public void run()
- {
- //if he's not holding the golden shovel anymore, do nothing
- if (GriefPrevention.instance.getItemInHand(player, EquipmentSlot.HAND).getType() != GriefPrevention.instance.config_claims_modificationTool)
- return;
-
- PlayerData playerData = GriefPrevention.instance.dataStore.getPlayerData(player.getUniqueId());
-
- //reset any work he might have been doing
- playerData.lastShovelLocation = null;
- playerData.claimResizing = null;
-
- //always reset to basic claims mode
- if (playerData.shovelMode != ShovelMode.Basic)
- {
- playerData.shovelMode = ShovelMode.Basic;
- GriefPrevention.sendMessage(player, TextMode.Info, Messages.ShovelBasicClaimMode);
- }
-
- //tell him how many claim blocks he has available
- int remainingBlocks = playerData.getRemainingClaimBlocks();
- GriefPrevention.sendMessage(player, TextMode.Instr, Messages.RemainingBlocks, String.valueOf(remainingBlocks));
-
- //link to a video demo of land claiming, based on world type
- if (GriefPrevention.instance.creativeRulesApply(player.getLocation()))
- {
- GriefPrevention.sendMessage(player, TextMode.Instr, Messages.CreativeBasicsVideo2, DataStore.CREATIVE_VIDEO_URL);
- }
- else if (GriefPrevention.instance.claimsEnabledForWorld(player.getLocation().getWorld()))
- {
- GriefPrevention.sendMessage(player, TextMode.Instr, Messages.SurvivalBasicsVideo2, DataStore.SURVIVAL_VIDEO_URL);
- }
-
- //if standing in a claim owned by the player, visualize it
- Claim claim = GriefPrevention.instance.dataStore.getClaimAt(player.getLocation(), true, playerData.lastClaim);
- if (claim != null && claim.allowEdit(player) == null)
- {
- playerData.lastClaim = claim;
- Visualization.Apply(player, Visualization.FromClaim(claim, player.getEyeLocation().getBlockY(), VisualizationType.Claim, player.getLocation()));
- }
- }
-}
+/*
+ GriefPrevention Server Plugin for Minecraft
+ Copyright (C) 2012 Ryan Hamshire
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see .
+ */
+
+package me.ryanhamshire.GriefPrevention;
+
+import org.bukkit.entity.Player;
+import org.bukkit.inventory.EquipmentSlot;
+
+//tells a player about how many claim blocks he has, etc
+//implemented as a task so that it can be delayed
+//otherwise, it's spammy when players mouse-wheel past the shovel in their hot bars
+class EquipShovelProcessingTask implements Runnable
+{
+ //player data
+ private Player player;
+
+ public EquipShovelProcessingTask(Player player)
+ {
+ this.player = player;
+ }
+
+ @Override
+ public void run()
+ {
+ //if he's not holding the golden shovel anymore, do nothing
+ if (GriefPrevention.instance.getItemInHand(player, EquipmentSlot.HAND).getType() != GriefPrevention.instance.config_claims_modificationTool)
+ return;
+
+ PlayerData playerData = GriefPrevention.instance.dataStore.getPlayerData(player.getUniqueId());
+
+ //reset any work he might have been doing
+ playerData.lastShovelLocation = null;
+ playerData.claimResizing = null;
+
+ //always reset to basic claims mode
+ if (playerData.shovelMode != ShovelMode.Basic)
+ {
+ playerData.shovelMode = ShovelMode.Basic;
+ GriefPrevention.sendMessage(player, TextMode.Info, Messages.ShovelBasicClaimMode);
+ }
+
+ //tell him how many claim blocks he has available
+ int remainingBlocks = playerData.getRemainingClaimBlocks();
+ GriefPrevention.sendMessage(player, TextMode.Instr, Messages.RemainingBlocks, String.valueOf(remainingBlocks));
+
+ //link to a video demo of land claiming, based on world type
+ if (GriefPrevention.instance.creativeRulesApply(player.getLocation()))
+ {
+ GriefPrevention.sendMessage(player, TextMode.Instr, Messages.CreativeBasicsVideo2, DataStore.CREATIVE_VIDEO_URL);
+ }
+ else if (GriefPrevention.instance.claimsEnabledForWorld(player.getLocation().getWorld()))
+ {
+ GriefPrevention.sendMessage(player, TextMode.Instr, Messages.SurvivalBasicsVideo2, DataStore.SURVIVAL_VIDEO_URL);
+ }
+
+ //if standing in a claim owned by the player, visualize it
+ Claim claim = GriefPrevention.instance.dataStore.getClaimAt(player.getLocation(), true, playerData.lastClaim);
+ if (claim != null && claim.allowEdit(player) == null)
+ {
+ playerData.lastClaim = claim;
+ Visualization.Apply(player, Visualization.FromClaim(claim, player.getEyeLocation().getBlockY(), VisualizationType.Claim, player.getLocation()));
+ }
+ }
+}
diff --git a/src/main/java/me/ryanhamshire/GriefPrevention/IpBanInfo.java b/src/main/java/me/ryanhamshire/GriefPrevention/IpBanInfo.java
index 2d147f1..a4e6173 100644
--- a/src/main/java/me/ryanhamshire/GriefPrevention/IpBanInfo.java
+++ b/src/main/java/me/ryanhamshire/GriefPrevention/IpBanInfo.java
@@ -1,35 +1,35 @@
-/*
- GriefPrevention Server Plugin for Minecraft
- Copyright (C) 2012 Ryan Hamshire
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see .
- */
-
-package me.ryanhamshire.GriefPrevention;
-
-import java.net.InetAddress;
-
-public class IpBanInfo
-{
- InetAddress address;
- long expirationTimestamp;
- String bannedAccountName;
-
- IpBanInfo(InetAddress address, long expirationTimestamp, String bannedAccountName)
- {
- this.address = address;
- this.expirationTimestamp = expirationTimestamp;
- this.bannedAccountName = bannedAccountName;
- }
-}
+/*
+ GriefPrevention Server Plugin for Minecraft
+ Copyright (C) 2012 Ryan Hamshire
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see .
+ */
+
+package me.ryanhamshire.GriefPrevention;
+
+import java.net.InetAddress;
+
+public class IpBanInfo
+{
+ InetAddress address;
+ long expirationTimestamp;
+ String bannedAccountName;
+
+ IpBanInfo(InetAddress address, long expirationTimestamp, String bannedAccountName)
+ {
+ this.address = address;
+ this.expirationTimestamp = expirationTimestamp;
+ this.bannedAccountName = bannedAccountName;
+ }
+}
diff --git a/src/main/java/me/ryanhamshire/GriefPrevention/MaterialCollection.java b/src/main/java/me/ryanhamshire/GriefPrevention/MaterialCollection.java
index 795c643..3ef7bd3 100644
--- a/src/main/java/me/ryanhamshire/GriefPrevention/MaterialCollection.java
+++ b/src/main/java/me/ryanhamshire/GriefPrevention/MaterialCollection.java
@@ -1,54 +1,54 @@
-/*
- GriefPrevention Server Plugin for Minecraft
- Copyright (C) 2012 Ryan Hamshire
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see .
- */
-
-package me.ryanhamshire.GriefPrevention;
-
-import java.util.HashSet;
-import java.util.Set;
-
-//ordered list of material info objects, for fast searching
-public class MaterialCollection
-{
- Set materials = new HashSet();
-
- void Add(MaterialInfo material)
- {
- this.materials.add(material);
- }
-
- boolean Contains(MaterialInfo material)
- {
- return this.materials.contains(material);
- }
-
- @Override
- public String toString()
- {
- return materials.toString();
- }
-
- public int size()
- {
- return this.materials.size();
- }
-
- public void clear()
- {
- this.materials.clear();
- }
-}
+/*
+ GriefPrevention Server Plugin for Minecraft
+ Copyright (C) 2012 Ryan Hamshire
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see .
+ */
+
+package me.ryanhamshire.GriefPrevention;
+
+import java.util.HashSet;
+import java.util.Set;
+
+//ordered list of material info objects, for fast searching
+public class MaterialCollection
+{
+ Set materials = new HashSet();
+
+ void Add(MaterialInfo material)
+ {
+ this.materials.add(material);
+ }
+
+ boolean Contains(MaterialInfo material)
+ {
+ return this.materials.contains(material);
+ }
+
+ @Override
+ public String toString()
+ {
+ return materials.toString();
+ }
+
+ public int size()
+ {
+ return this.materials.size();
+ }
+
+ public void clear()
+ {
+ this.materials.clear();
+ }
+}
diff --git a/src/main/java/me/ryanhamshire/GriefPrevention/MaterialInfo.java b/src/main/java/me/ryanhamshire/GriefPrevention/MaterialInfo.java
index 98e6451..16da4ce 100644
--- a/src/main/java/me/ryanhamshire/GriefPrevention/MaterialInfo.java
+++ b/src/main/java/me/ryanhamshire/GriefPrevention/MaterialInfo.java
@@ -1,96 +1,96 @@
-/*
- GriefPrevention Server Plugin for Minecraft
- Copyright (C) 2012 Ryan Hamshire
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see .
- */
-
-package me.ryanhamshire.GriefPrevention;
-
-//represents a material or collection of materials
-
-import org.bukkit.Material;
-
-public class MaterialInfo
-{
- Material typeID;
- byte data;
- boolean allDataValues;
- String description;
-
- public MaterialInfo(Material typeID, byte data, String description)
- {
- this.typeID = typeID;
- this.data = data;
- this.allDataValues = false;
- this.description = description;
- }
-
- public MaterialInfo(Material typeID, String description)
- {
- this.typeID = typeID;
- this.data = 0;
- this.allDataValues = true;
- this.description = description;
- }
-
- private MaterialInfo(Material typeID, byte data, boolean allDataValues, String description)
- {
- this.typeID = typeID;
- this.data = data;
- this.allDataValues = allDataValues;
- this.description = description;
- }
-
- @Override
- public String toString()
- {
- String returnValue = String.valueOf(this.typeID) + ":" + (this.allDataValues ? "*" : String.valueOf(this.data));
- if (this.description != null) returnValue += ":" + this.description;
-
- return returnValue;
- }
-
- public static MaterialInfo fromString(String string)
- {
- if (string == null || string.isEmpty()) return null;
-
- String[] parts = string.split(":");
- if (parts.length < 3) return null;
-
- try
- {
- Material typeID = Material.matchMaterial(parts[0]);
-
- byte data;
- boolean allDataValues;
- if (parts[1].equals("*"))
- {
- allDataValues = true;
- data = 0;
- }
- else
- {
- allDataValues = false;
- data = Byte.parseByte(parts[1]);
- }
-
- return new MaterialInfo(typeID, data, allDataValues, parts[2]);
- }
- catch (NumberFormatException exception)
- {
- return null;
- }
- }
-}
+/*
+ GriefPrevention Server Plugin for Minecraft
+ Copyright (C) 2012 Ryan Hamshire
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see .
+ */
+
+package me.ryanhamshire.GriefPrevention;
+
+//represents a material or collection of materials
+
+import org.bukkit.Material;
+
+public class MaterialInfo
+{
+ Material typeID;
+ byte data;
+ boolean allDataValues;
+ String description;
+
+ public MaterialInfo(Material typeID, byte data, String description)
+ {
+ this.typeID = typeID;
+ this.data = data;
+ this.allDataValues = false;
+ this.description = description;
+ }
+
+ public MaterialInfo(Material typeID, String description)
+ {
+ this.typeID = typeID;
+ this.data = 0;
+ this.allDataValues = true;
+ this.description = description;
+ }
+
+ private MaterialInfo(Material typeID, byte data, boolean allDataValues, String description)
+ {
+ this.typeID = typeID;
+ this.data = data;
+ this.allDataValues = allDataValues;
+ this.description = description;
+ }
+
+ @Override
+ public String toString()
+ {
+ String returnValue = String.valueOf(this.typeID) + ":" + (this.allDataValues ? "*" : String.valueOf(this.data));
+ if (this.description != null) returnValue += ":" + this.description;
+
+ return returnValue;
+ }
+
+ public static MaterialInfo fromString(String string)
+ {
+ if (string == null || string.isEmpty()) return null;
+
+ String[] parts = string.split(":");
+ if (parts.length < 3) return null;
+
+ try
+ {
+ Material typeID = Material.matchMaterial(parts[0]);
+
+ byte data;
+ boolean allDataValues;
+ if (parts[1].equals("*"))
+ {
+ allDataValues = true;
+ data = 0;
+ }
+ else
+ {
+ allDataValues = false;
+ data = Byte.parseByte(parts[1]);
+ }
+
+ return new MaterialInfo(typeID, data, allDataValues, parts[2]);
+ }
+ catch (NumberFormatException exception)
+ {
+ return null;
+ }
+ }
+}
diff --git a/src/main/java/me/ryanhamshire/GriefPrevention/PlayerRescueTask.java b/src/main/java/me/ryanhamshire/GriefPrevention/PlayerRescueTask.java
index d07927b..6d6ddeb 100644
--- a/src/main/java/me/ryanhamshire/GriefPrevention/PlayerRescueTask.java
+++ b/src/main/java/me/ryanhamshire/GriefPrevention/PlayerRescueTask.java
@@ -1,75 +1,75 @@
-/*
- GriefPrevention Server Plugin for Minecraft
- Copyright (C) 2012 Ryan Hamshire
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see .
- */
-
-package me.ryanhamshire.GriefPrevention;
-
-import org.bukkit.Location;
-import org.bukkit.entity.Player;
-
-//tries to rescue a trapped player from a claim where he doesn't have permission to save himself
-//related to the /trapped slash command
-//this does run in the main thread, so it's okay to make non-thread-safe calls
-class PlayerRescueTask implements Runnable
-{
- //original location where /trapped was used
- private Location location;
-
- //rescue destination, may be decided at instantiation or at execution
- private Location destination;
-
- //player data
- private Player player;
-
- public PlayerRescueTask(Player player, Location location, Location destination)
- {
- this.player = player;
- this.location = location;
- this.destination = destination;
- }
-
- @Override
- public void run()
- {
- //if he logged out, don't do anything
- if (!player.isOnline()) return;
-
- //he no longer has a pending /trapped slash command, so he can try to use it again now
- PlayerData playerData = GriefPrevention.instance.dataStore.getPlayerData(player.getUniqueId());
- playerData.pendingTrapped = false;
-
- //if the player moved three or more blocks from where he used /trapped, admonish him and don't save him
- if (!player.getLocation().getWorld().equals(this.location.getWorld()) || player.getLocation().distance(this.location) > 3)
- {
- GriefPrevention.sendMessage(player, TextMode.Err, Messages.RescueAbortedMoved);
- return;
- }
-
- //otherwise find a place to teleport him
- if (this.destination == null)
- {
- this.destination = GriefPrevention.instance.ejectPlayer(this.player);
- }
- else
- {
- player.teleport(this.destination);
- }
-
- //log entry, in case admins want to investigate the "trap"
- GriefPrevention.AddLogEntry("Rescued trapped player " + player.getName() + " from " + GriefPrevention.getfriendlyLocationString(this.location) + " to " + GriefPrevention.getfriendlyLocationString(this.destination) + ".");
- }
-}
+/*
+ GriefPrevention Server Plugin for Minecraft
+ Copyright (C) 2012 Ryan Hamshire
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see .
+ */
+
+package me.ryanhamshire.GriefPrevention;
+
+import org.bukkit.Location;
+import org.bukkit.entity.Player;
+
+//tries to rescue a trapped player from a claim where he doesn't have permission to save himself
+//related to the /trapped slash command
+//this does run in the main thread, so it's okay to make non-thread-safe calls
+class PlayerRescueTask implements Runnable
+{
+ //original location where /trapped was used
+ private Location location;
+
+ //rescue destination, may be decided at instantiation or at execution
+ private Location destination;
+
+ //player data
+ private Player player;
+
+ public PlayerRescueTask(Player player, Location location, Location destination)
+ {
+ this.player = player;
+ this.location = location;
+ this.destination = destination;
+ }
+
+ @Override
+ public void run()
+ {
+ //if he logged out, don't do anything
+ if (!player.isOnline()) return;
+
+ //he no longer has a pending /trapped slash command, so he can try to use it again now
+ PlayerData playerData = GriefPrevention.instance.dataStore.getPlayerData(player.getUniqueId());
+ playerData.pendingTrapped = false;
+
+ //if the player moved three or more blocks from where he used /trapped, admonish him and don't save him
+ if (!player.getLocation().getWorld().equals(this.location.getWorld()) || player.getLocation().distance(this.location) > 3)
+ {
+ GriefPrevention.sendMessage(player, TextMode.Err, Messages.RescueAbortedMoved);
+ return;
+ }
+
+ //otherwise find a place to teleport him
+ if (this.destination == null)
+ {
+ this.destination = GriefPrevention.instance.ejectPlayer(this.player);
+ }
+ else
+ {
+ player.teleport(this.destination);
+ }
+
+ //log entry, in case admins want to investigate the "trap"
+ GriefPrevention.AddLogEntry("Rescued trapped player " + player.getName() + " from " + GriefPrevention.getfriendlyLocationString(this.location) + " to " + GriefPrevention.getfriendlyLocationString(this.destination) + ".");
+ }
+}
diff --git a/src/main/java/me/ryanhamshire/GriefPrevention/RestoreNatureExecutionTask.java b/src/main/java/me/ryanhamshire/GriefPrevention/RestoreNatureExecutionTask.java
index 2febb0f..c58c6fe 100644
--- a/src/main/java/me/ryanhamshire/GriefPrevention/RestoreNatureExecutionTask.java
+++ b/src/main/java/me/ryanhamshire/GriefPrevention/RestoreNatureExecutionTask.java
@@ -1,130 +1,130 @@
-/*
- GriefPrevention Server Plugin for Minecraft
- Copyright (C) 2012 Ryan Hamshire
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see .
- */
-
-package me.ryanhamshire.GriefPrevention;
-
-import org.bukkit.Chunk;
-import org.bukkit.Location;
-import org.bukkit.Material;
-import org.bukkit.block.Block;
-import org.bukkit.block.BlockFace;
-import org.bukkit.entity.Animals;
-import org.bukkit.entity.Entity;
-import org.bukkit.entity.Hanging;
-import org.bukkit.entity.Player;
-
-import java.util.ArrayList;
-
-//this main thread task takes the output from the RestoreNatureProcessingTask\
-//and updates the world accordingly
-class RestoreNatureExecutionTask implements Runnable
-{
- //results from processing thread
- //will be applied to the world
- private BlockSnapshot[][][] snapshots;
-
- //boundaries for changes
- private int miny;
- private Location lesserCorner;
- private Location greaterCorner;
-
- //player who should be notified about the result (will see a visualization when the restoration is complete)
- private Player player;
-
- public RestoreNatureExecutionTask(BlockSnapshot[][][] snapshots, int miny, Location lesserCorner, Location greaterCorner, Player player)
- {
- this.snapshots = snapshots;
- this.miny = miny;
- this.lesserCorner = lesserCorner;
- this.greaterCorner = greaterCorner;
- this.player = player;
- }
-
-
- @Override
- public void run()
- {
- //apply changes to the world, but ONLY to unclaimed blocks
- //note that the edge of the results is not applied (the 1-block-wide band around the outside of the chunk)
- //those data were sent to the processing thread for referernce purposes, but aren't part of the area selected for restoration
- Claim cachedClaim = null;
- for (int x = 1; x < this.snapshots.length - 1; x++)
- {
- for (int z = 1; z < this.snapshots[0][0].length - 1; z++)
- {
- for (int y = this.miny; y < this.snapshots[0].length; y++)
- {
- BlockSnapshot blockUpdate = this.snapshots[x][y][z];
- Block currentBlock = blockUpdate.location.getBlock();
- if (blockUpdate.typeId != currentBlock.getType() || !blockUpdate.data.equals(currentBlock.getBlockData()))
- {
- Claim claim = GriefPrevention.instance.dataStore.getClaimAt(blockUpdate.location, false, cachedClaim);
- if (claim != null)
- {
- cachedClaim = claim;
- break;
- }
-
- try
- {
- currentBlock.setType(blockUpdate.typeId, false);
- // currentBlock.setBlockData(blockUpdate.data, false);
- }
- catch (IllegalArgumentException e)
- {
- //just don't update this block and continue trying to update other blocks
- }
- }
- }
- }
- }
-
- //clean up any entities in the chunk, ensure no players are suffocated
- Chunk chunk = this.lesserCorner.getChunk();
- Entity[] entities = chunk.getEntities();
- for (int i = 0; i < entities.length; i++)
- {
- Entity entity = entities[i];
- if (!(entity instanceof Player || entity instanceof Animals))
- {
- //hanging entities (paintings, item frames) are protected when they're in land claims
- if (!(entity instanceof Hanging) || GriefPrevention.instance.dataStore.getClaimAt(entity.getLocation(), false, null) == null)
- {
- //everything else is removed
- entity.remove();
- }
- }
-
- //for players, always ensure there's air where the player is standing
- else
- {
- Block feetBlock = entity.getLocation().getBlock();
- feetBlock.setType(Material.AIR);
- feetBlock.getRelative(BlockFace.UP).setType(Material.AIR);
- }
- }
-
- //show visualization to player who started the restoration
- if (player != null)
- {
- Claim claim = new Claim(lesserCorner, greaterCorner, null, new ArrayList(), new ArrayList(), new ArrayList(), new ArrayList(), null);
- Visualization visualization = Visualization.FromClaim(claim, player.getLocation().getBlockY(), VisualizationType.RestoreNature, player.getLocation());
- Visualization.Apply(player, visualization);
- }
- }
-}
+/*
+ GriefPrevention Server Plugin for Minecraft
+ Copyright (C) 2012 Ryan Hamshire
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see .
+ */
+
+package me.ryanhamshire.GriefPrevention;
+
+import org.bukkit.Chunk;
+import org.bukkit.Location;
+import org.bukkit.Material;
+import org.bukkit.block.Block;
+import org.bukkit.block.BlockFace;
+import org.bukkit.entity.Animals;
+import org.bukkit.entity.Entity;
+import org.bukkit.entity.Hanging;
+import org.bukkit.entity.Player;
+
+import java.util.ArrayList;
+
+//this main thread task takes the output from the RestoreNatureProcessingTask\
+//and updates the world accordingly
+class RestoreNatureExecutionTask implements Runnable
+{
+ //results from processing thread
+ //will be applied to the world
+ private BlockSnapshot[][][] snapshots;
+
+ //boundaries for changes
+ private int miny;
+ private Location lesserCorner;
+ private Location greaterCorner;
+
+ //player who should be notified about the result (will see a visualization when the restoration is complete)
+ private Player player;
+
+ public RestoreNatureExecutionTask(BlockSnapshot[][][] snapshots, int miny, Location lesserCorner, Location greaterCorner, Player player)
+ {
+ this.snapshots = snapshots;
+ this.miny = miny;
+ this.lesserCorner = lesserCorner;
+ this.greaterCorner = greaterCorner;
+ this.player = player;
+ }
+
+
+ @Override
+ public void run()
+ {
+ //apply changes to the world, but ONLY to unclaimed blocks
+ //note that the edge of the results is not applied (the 1-block-wide band around the outside of the chunk)
+ //those data were sent to the processing thread for referernce purposes, but aren't part of the area selected for restoration
+ Claim cachedClaim = null;
+ for (int x = 1; x < this.snapshots.length - 1; x++)
+ {
+ for (int z = 1; z < this.snapshots[0][0].length - 1; z++)
+ {
+ for (int y = this.miny; y < this.snapshots[0].length; y++)
+ {
+ BlockSnapshot blockUpdate = this.snapshots[x][y][z];
+ Block currentBlock = blockUpdate.location.getBlock();
+ if (blockUpdate.typeId != currentBlock.getType() || !blockUpdate.data.equals(currentBlock.getBlockData()))
+ {
+ Claim claim = GriefPrevention.instance.dataStore.getClaimAt(blockUpdate.location, false, cachedClaim);
+ if (claim != null)
+ {
+ cachedClaim = claim;
+ break;
+ }
+
+ try
+ {
+ currentBlock.setType(blockUpdate.typeId, false);
+ // currentBlock.setBlockData(blockUpdate.data, false);
+ }
+ catch (IllegalArgumentException e)
+ {
+ //just don't update this block and continue trying to update other blocks
+ }
+ }
+ }
+ }
+ }
+
+ //clean up any entities in the chunk, ensure no players are suffocated
+ Chunk chunk = this.lesserCorner.getChunk();
+ Entity[] entities = chunk.getEntities();
+ for (int i = 0; i < entities.length; i++)
+ {
+ Entity entity = entities[i];
+ if (!(entity instanceof Player || entity instanceof Animals))
+ {
+ //hanging entities (paintings, item frames) are protected when they're in land claims
+ if (!(entity instanceof Hanging) || GriefPrevention.instance.dataStore.getClaimAt(entity.getLocation(), false, null) == null)
+ {
+ //everything else is removed
+ entity.remove();
+ }
+ }
+
+ //for players, always ensure there's air where the player is standing
+ else
+ {
+ Block feetBlock = entity.getLocation().getBlock();
+ feetBlock.setType(Material.AIR);
+ feetBlock.getRelative(BlockFace.UP).setType(Material.AIR);
+ }
+ }
+
+ //show visualization to player who started the restoration
+ if (player != null)
+ {
+ Claim claim = new Claim(lesserCorner, greaterCorner, null, new ArrayList(), new ArrayList(), new ArrayList(), new ArrayList(), null);
+ Visualization visualization = Visualization.FromClaim(claim, player.getLocation().getBlockY(), VisualizationType.RestoreNature, player.getLocation());
+ Visualization.Apply(player, visualization);
+ }
+ }
+}
diff --git a/src/main/java/me/ryanhamshire/GriefPrevention/SecureClaimTask.java b/src/main/java/me/ryanhamshire/GriefPrevention/SecureClaimTask.java
index e63199f..6f7ed22 100644
--- a/src/main/java/me/ryanhamshire/GriefPrevention/SecureClaimTask.java
+++ b/src/main/java/me/ryanhamshire/GriefPrevention/SecureClaimTask.java
@@ -1,58 +1,58 @@
-/*
- GriefPrevention Server Plugin for Minecraft
- Copyright (C) 2012 Ryan Hamshire
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see .
- */
-
-package me.ryanhamshire.GriefPrevention;
-
-import org.bukkit.entity.Player;
-
-import java.util.Collection;
-
-//secures a claim after a siege looting window has closed
-class SecureClaimTask implements Runnable
-{
- private SiegeData siegeData;
-
- public SecureClaimTask(SiegeData siegeData)
- {
- this.siegeData = siegeData;
- }
-
- @Override
- public void run()
- {
- //for each claim involved in this siege
- for (int i = 0; i < this.siegeData.claims.size(); i++)
- {
- //lock the doors
- Claim claim = this.siegeData.claims.get(i);
- claim.doorsOpen = false;
-
- //eject bad guys
- @SuppressWarnings("unchecked")
- Collection onlinePlayers = (Collection) GriefPrevention.instance.getServer().getOnlinePlayers();
- for (Player player : onlinePlayers)
- {
- if (claim.contains(player.getLocation(), false, false) && claim.allowAccess(player) != null)
- {
- GriefPrevention.sendMessage(player, TextMode.Err, Messages.SiegeDoorsLockedEjection);
- GriefPrevention.instance.ejectPlayer(player);
- }
- }
- }
- }
-}
+/*
+ GriefPrevention Server Plugin for Minecraft
+ Copyright (C) 2012 Ryan Hamshire
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see .
+ */
+
+package me.ryanhamshire.GriefPrevention;
+
+import org.bukkit.entity.Player;
+
+import java.util.Collection;
+
+//secures a claim after a siege looting window has closed
+class SecureClaimTask implements Runnable
+{
+ private SiegeData siegeData;
+
+ public SecureClaimTask(SiegeData siegeData)
+ {
+ this.siegeData = siegeData;
+ }
+
+ @Override
+ public void run()
+ {
+ //for each claim involved in this siege
+ for (int i = 0; i < this.siegeData.claims.size(); i++)
+ {
+ //lock the doors
+ Claim claim = this.siegeData.claims.get(i);
+ claim.doorsOpen = false;
+
+ //eject bad guys
+ @SuppressWarnings("unchecked")
+ Collection onlinePlayers = (Collection) GriefPrevention.instance.getServer().getOnlinePlayers();
+ for (Player player : onlinePlayers)
+ {
+ if (claim.contains(player.getLocation(), false, false) && claim.allowAccess(player) != null)
+ {
+ GriefPrevention.sendMessage(player, TextMode.Err, Messages.SiegeDoorsLockedEjection);
+ GriefPrevention.instance.ejectPlayer(player);
+ }
+ }
+ }
+ }
+}
diff --git a/src/main/java/me/ryanhamshire/GriefPrevention/SendPlayerMessageTask.java b/src/main/java/me/ryanhamshire/GriefPrevention/SendPlayerMessageTask.java
index 9979b9a..e65652d 100644
--- a/src/main/java/me/ryanhamshire/GriefPrevention/SendPlayerMessageTask.java
+++ b/src/main/java/me/ryanhamshire/GriefPrevention/SendPlayerMessageTask.java
@@ -1,61 +1,61 @@
-/*
- GriefPrevention Server Plugin for Minecraft
- Copyright (C) 2012 Ryan Hamshire
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see .
- */
-
-package me.ryanhamshire.GriefPrevention;
-
-import org.bukkit.ChatColor;
-import org.bukkit.entity.Player;
-
-//sends a message to a player
-//used to send delayed messages, for example help text triggered by a player's chat
-class SendPlayerMessageTask implements Runnable
-{
- private Player player;
- private ChatColor color;
- private String message;
-
- public SendPlayerMessageTask(Player player, ChatColor color, String message)
- {
- this.player = player;
- this.color = color;
- this.message = message;
- }
-
- @Override
- public void run()
- {
- if (player == null)
- {
- GriefPrevention.AddLogEntry(color + message);
- return;
- }
-
- //if the player is dead, save it for after his respawn
- if (this.player.isDead())
- {
- PlayerData playerData = GriefPrevention.instance.dataStore.getPlayerData(this.player.getUniqueId());
- playerData.messageOnRespawn = this.color + this.message;
- }
-
- //otherwise send it immediately
- else
- {
- GriefPrevention.sendMessage(this.player, this.color, this.message);
- }
- }
-}
+/*
+ GriefPrevention Server Plugin for Minecraft
+ Copyright (C) 2012 Ryan Hamshire
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see .
+ */
+
+package me.ryanhamshire.GriefPrevention;
+
+import org.bukkit.ChatColor;
+import org.bukkit.entity.Player;
+
+//sends a message to a player
+//used to send delayed messages, for example help text triggered by a player's chat
+class SendPlayerMessageTask implements Runnable
+{
+ private Player player;
+ private ChatColor color;
+ private String message;
+
+ public SendPlayerMessageTask(Player player, ChatColor color, String message)
+ {
+ this.player = player;
+ this.color = color;
+ this.message = message;
+ }
+
+ @Override
+ public void run()
+ {
+ if (player == null)
+ {
+ GriefPrevention.AddLogEntry(color + message);
+ return;
+ }
+
+ //if the player is dead, save it for after his respawn
+ if (this.player.isDead())
+ {
+ PlayerData playerData = GriefPrevention.instance.dataStore.getPlayerData(this.player.getUniqueId());
+ playerData.messageOnRespawn = this.color + this.message;
+ }
+
+ //otherwise send it immediately
+ else
+ {
+ GriefPrevention.sendMessage(this.player, this.color, this.message);
+ }
+ }
+}
diff --git a/src/main/java/me/ryanhamshire/GriefPrevention/ShovelMode.java b/src/main/java/me/ryanhamshire/GriefPrevention/ShovelMode.java
index 1fbb5fe..3985be4 100644
--- a/src/main/java/me/ryanhamshire/GriefPrevention/ShovelMode.java
+++ b/src/main/java/me/ryanhamshire/GriefPrevention/ShovelMode.java
@@ -1,30 +1,30 @@
-/*
- GriefPrevention Server Plugin for Minecraft
- Copyright (C) 2012 Ryan Hamshire
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see .
- */
-
-package me.ryanhamshire.GriefPrevention;
-
-//enumeration for golden shovel modes
-public enum ShovelMode
-{
- Basic,
- Admin,
- Subdivide,
- RestoreNature,
- RestoreNatureAggressive,
- RestoreNatureFill
-}
+/*
+ GriefPrevention Server Plugin for Minecraft
+ Copyright (C) 2012 Ryan Hamshire
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see .
+ */
+
+package me.ryanhamshire.GriefPrevention;
+
+//enumeration for golden shovel modes
+public enum ShovelMode
+{
+ Basic,
+ Admin,
+ Subdivide,
+ RestoreNature,
+ RestoreNatureAggressive,
+ RestoreNatureFill
+}
diff --git a/src/main/java/me/ryanhamshire/GriefPrevention/SiegeCheckupTask.java b/src/main/java/me/ryanhamshire/GriefPrevention/SiegeCheckupTask.java
index 346e6ce..3a52cbd 100644
--- a/src/main/java/me/ryanhamshire/GriefPrevention/SiegeCheckupTask.java
+++ b/src/main/java/me/ryanhamshire/GriefPrevention/SiegeCheckupTask.java
@@ -1,110 +1,110 @@
-/*
- GriefPrevention Server Plugin for Minecraft
- Copyright (C) 2012 Ryan Hamshire
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see .
- */
-
-package me.ryanhamshire.GriefPrevention;
-
-import org.bukkit.entity.Player;
-
-//checks to see whether or not a siege should end based on the locations of the players
-//for example, defender escaped or attacker gave up and left
-class SiegeCheckupTask implements Runnable
-{
- private SiegeData siegeData;
-
- public SiegeCheckupTask(SiegeData siegeData)
- {
- this.siegeData = siegeData;
- }
-
- @Override
- public void run()
- {
- DataStore dataStore = GriefPrevention.instance.dataStore;
- Player defender = this.siegeData.defender;
- Player attacker = this.siegeData.attacker;
-
- //where is the defender?
- Claim defenderClaim = dataStore.getClaimAt(defender.getLocation(), false, null);
-
- //if this is a new claim and he has some permission there, extend the siege to include it
- if (defenderClaim != null)
- {
- String noAccessReason = defenderClaim.allowAccess(defender);
- if (defenderClaim.canSiege(defender) && noAccessReason == null)
- {
- this.siegeData.claims.add(defenderClaim);
- defenderClaim.siegeData = this.siegeData;
- }
- }
-
- //determine who's close enough to the siege area to be considered "still here"
- boolean attackerRemains = this.playerRemains(attacker);
- boolean defenderRemains = this.playerRemains(defender);
-
- //if they're both here, just plan to come check again later
- if (attackerRemains && defenderRemains)
- {
- this.scheduleAnotherCheck();
- }
-
- //otherwise attacker wins if the defender runs away
- else if (attackerRemains && !defenderRemains)
- {
- dataStore.endSiege(this.siegeData, attacker.getName(), defender.getName(), null);
- }
-
- //or defender wins if the attacker leaves
- else if (!attackerRemains && defenderRemains)
- {
- dataStore.endSiege(this.siegeData, defender.getName(), attacker.getName(), null);
- }
-
- //if they both left, but are still close together, the battle continues (check again later)
- else if (attacker.getWorld().equals(defender.getWorld()) && attacker.getLocation().distanceSquared(defender.getLocation()) < 2500) //50-block radius for chasing
- {
- this.scheduleAnotherCheck();
- }
-
- //otherwise they both left and aren't close to each other, so call the attacker the winner (defender escaped, possibly after a chase)
- else
- {
- dataStore.endSiege(this.siegeData, attacker.getName(), defender.getName(), null);
- }
- }
-
- //a player has to be within 25 blocks of the edge of a besieged claim to be considered still in the fight
- private boolean playerRemains(Player player)
- {
- for (int i = 0; i < this.siegeData.claims.size(); i++)
- {
- Claim claim = this.siegeData.claims.get(i);
- if (claim.isNear(player.getLocation(), 25))
- {
- return true;
- }
- }
-
- return false;
- }
-
- //schedules another checkup later
- private void scheduleAnotherCheck()
- {
- this.siegeData.checkupTaskID = GriefPrevention.instance.getServer().getScheduler().scheduleSyncDelayedTask(GriefPrevention.instance, this, 20L * 30);
- }
-}
+/*
+ GriefPrevention Server Plugin for Minecraft
+ Copyright (C) 2012 Ryan Hamshire
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see .
+ */
+
+package me.ryanhamshire.GriefPrevention;
+
+import org.bukkit.entity.Player;
+
+//checks to see whether or not a siege should end based on the locations of the players
+//for example, defender escaped or attacker gave up and left
+class SiegeCheckupTask implements Runnable
+{
+ private SiegeData siegeData;
+
+ public SiegeCheckupTask(SiegeData siegeData)
+ {
+ this.siegeData = siegeData;
+ }
+
+ @Override
+ public void run()
+ {
+ DataStore dataStore = GriefPrevention.instance.dataStore;
+ Player defender = this.siegeData.defender;
+ Player attacker = this.siegeData.attacker;
+
+ //where is the defender?
+ Claim defenderClaim = dataStore.getClaimAt(defender.getLocation(), false, null);
+
+ //if this is a new claim and he has some permission there, extend the siege to include it
+ if (defenderClaim != null)
+ {
+ String noAccessReason = defenderClaim.allowAccess(defender);
+ if (defenderClaim.canSiege(defender) && noAccessReason == null)
+ {
+ this.siegeData.claims.add(defenderClaim);
+ defenderClaim.siegeData = this.siegeData;
+ }
+ }
+
+ //determine who's close enough to the siege area to be considered "still here"
+ boolean attackerRemains = this.playerRemains(attacker);
+ boolean defenderRemains = this.playerRemains(defender);
+
+ //if they're both here, just plan to come check again later
+ if (attackerRemains && defenderRemains)
+ {
+ this.scheduleAnotherCheck();
+ }
+
+ //otherwise attacker wins if the defender runs away
+ else if (attackerRemains && !defenderRemains)
+ {
+ dataStore.endSiege(this.siegeData, attacker.getName(), defender.getName(), null);
+ }
+
+ //or defender wins if the attacker leaves
+ else if (!attackerRemains && defenderRemains)
+ {
+ dataStore.endSiege(this.siegeData, defender.getName(), attacker.getName(), null);
+ }
+
+ //if they both left, but are still close together, the battle continues (check again later)
+ else if (attacker.getWorld().equals(defender.getWorld()) && attacker.getLocation().distanceSquared(defender.getLocation()) < 2500) //50-block radius for chasing
+ {
+ this.scheduleAnotherCheck();
+ }
+
+ //otherwise they both left and aren't close to each other, so call the attacker the winner (defender escaped, possibly after a chase)
+ else
+ {
+ dataStore.endSiege(this.siegeData, attacker.getName(), defender.getName(), null);
+ }
+ }
+
+ //a player has to be within 25 blocks of the edge of a besieged claim to be considered still in the fight
+ private boolean playerRemains(Player player)
+ {
+ for (int i = 0; i < this.siegeData.claims.size(); i++)
+ {
+ Claim claim = this.siegeData.claims.get(i);
+ if (claim.isNear(player.getLocation(), 25))
+ {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ //schedules another checkup later
+ private void scheduleAnotherCheck()
+ {
+ this.siegeData.checkupTaskID = GriefPrevention.instance.getServer().getScheduler().scheduleSyncDelayedTask(GriefPrevention.instance, this, 20L * 30);
+ }
+}
diff --git a/src/main/java/me/ryanhamshire/GriefPrevention/SiegeData.java b/src/main/java/me/ryanhamshire/GriefPrevention/SiegeData.java
index 2fdd7c5..847e691 100644
--- a/src/main/java/me/ryanhamshire/GriefPrevention/SiegeData.java
+++ b/src/main/java/me/ryanhamshire/GriefPrevention/SiegeData.java
@@ -1,40 +1,40 @@
-/*
- GriefPrevention Server Plugin for Minecraft
- Copyright (C) 2012 Ryan Hamshire
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see .
- */
-
-package me.ryanhamshire.GriefPrevention;
-
-import org.bukkit.entity.Player;
-
-import java.util.ArrayList;
-
-//information about an ongoing siege
-public class SiegeData
-{
- public Player defender;
- public Player attacker;
- public ArrayList claims;
- public int checkupTaskID;
-
- public SiegeData(Player attacker, Player defender, Claim claim)
- {
- this.defender = defender;
- this.attacker = attacker;
- this.claims = new ArrayList();
- this.claims.add(claim);
- }
-}
+/*
+ GriefPrevention Server Plugin for Minecraft
+ Copyright (C) 2012 Ryan Hamshire
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see .
+ */
+
+package me.ryanhamshire.GriefPrevention;
+
+import org.bukkit.entity.Player;
+
+import java.util.ArrayList;
+
+//information about an ongoing siege
+public class SiegeData
+{
+ public Player defender;
+ public Player attacker;
+ public ArrayList claims;
+ public int checkupTaskID;
+
+ public SiegeData(Player attacker, Player defender, Claim claim)
+ {
+ this.defender = defender;
+ this.attacker = attacker;
+ this.claims = new ArrayList();
+ this.claims.add(claim);
+ }
+}
diff --git a/src/main/java/me/ryanhamshire/GriefPrevention/Visualization.java b/src/main/java/me/ryanhamshire/GriefPrevention/Visualization.java
index e1631f0..54e495a 100644
--- a/src/main/java/me/ryanhamshire/GriefPrevention/Visualization.java
+++ b/src/main/java/me/ryanhamshire/GriefPrevention/Visualization.java
@@ -1,342 +1,342 @@
-/*
- GriefPrevention Server Plugin for Minecraft
- Copyright (C) 2012 Ryan Hamshire
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see .
- */
-
-package me.ryanhamshire.GriefPrevention;
-
-import org.bukkit.Location;
-import org.bukkit.Material;
-import org.bukkit.Tag;
-import org.bukkit.World;
-import org.bukkit.block.Block;
-import org.bukkit.block.BlockFace;
-import org.bukkit.block.data.BlockData;
-import org.bukkit.block.data.Lightable;
-import org.bukkit.entity.Player;
-import org.bukkit.util.BoundingBox;
-import org.bukkit.util.Vector;
-
-import java.util.ArrayList;
-
-//represents a visualization sent to a player
-//FEATURE: to show players visually where claim boundaries are, we send them fake block change packets
-//the result is that those players see new blocks, but the world hasn't been changed. other players can't see the new blocks, either.
-public class Visualization
-{
- public ArrayList elements = new ArrayList();
-
- //sends a visualization to a player
- public static void Apply(Player player, Visualization visualization)
- {
- PlayerData playerData = GriefPrevention.instance.dataStore.getPlayerData(player.getUniqueId());
-
- //if he has any current visualization, clear it first
- if (playerData.currentVisualization != null)
- {
- Visualization.Revert(player);
- }
-
- //if he's online, create a task to send him the visualization
- if (player.isOnline() && visualization.elements.size() > 0 && visualization.elements.get(0).location.getWorld().equals(player.getWorld()))
- {
- GriefPrevention.instance.getServer().getScheduler().scheduleSyncDelayedTask(GriefPrevention.instance, new VisualizationApplicationTask(player, playerData, visualization), 1L);
- }
- }
-
- //reverts a visualization by sending another block change list, this time with the real world block values
-
- public static void Revert(Player player)
- {
- if (!player.isOnline()) return;
-
- PlayerData playerData = GriefPrevention.instance.dataStore.getPlayerData(player.getUniqueId());
-
- Visualization visualization = playerData.currentVisualization;
-
- if (playerData.currentVisualization != null)
- {
- //locality
- int minx = player.getLocation().getBlockX() - 100;
- int minz = player.getLocation().getBlockZ() - 100;
- int maxx = player.getLocation().getBlockX() + 100;
- int maxz = player.getLocation().getBlockZ() + 100;
-
- //remove any elements which are too far away
- visualization.removeElementsOutOfRange(visualization.elements, minx, minz, maxx, maxz);
-
- //send real block information for any remaining elements
- for (int i = 0; i < visualization.elements.size(); i++)
- {
- VisualizationElement element = visualization.elements.get(i);
-
- //check player still in world where visualization exists
- if (i == 0)
- {
- if (!player.getWorld().equals(element.location.getWorld())) return;
- }
-
- player.sendBlockChange(element.location, element.realBlock);
- }
-
- playerData.currentVisualization = null;
- }
- }
-
- //convenience method to build a visualization from a claim
- //visualizationType determines the style (gold blocks, silver, red, diamond, etc)
- public static Visualization FromClaim(Claim claim, int height, VisualizationType visualizationType, Location locality)
- {
- //visualize only top level claims
- if (claim.parent != null)
- {
- return FromClaim(claim.parent, height, visualizationType, locality);
- }
-
- Visualization visualization = new Visualization();
-
- //add subdivisions first
- for (int i = 0; i < claim.children.size(); i++)
- {
- Claim child = claim.children.get(i);
- if (!child.inDataStore) continue;
- visualization.addClaimElements(child, height, VisualizationType.Subdivision, locality);
- }
-
- //special visualization for administrative land claims
- if (claim.isAdminClaim() && visualizationType == VisualizationType.Claim)
- {
- visualizationType = VisualizationType.AdminClaim;
- }
-
- //add top level last so that it takes precedence (it shows on top when the child claim boundaries overlap with its boundaries)
- visualization.addClaimElements(claim, height, visualizationType, locality);
-
- return visualization;
- }
-
- //adds a claim's visualization to the current visualization
- //handy for combining several visualizations together, as when visualization a top level claim with several subdivisions inside
- //locality is a performance consideration. only create visualization blocks for around 100 blocks of the locality
-
- public void addClaimElements(Claim claim, int height, VisualizationType visualizationType, Location locality)
- {
- BlockData cornerBlockData;
- BlockData accentBlockData;
-
- if (visualizationType == VisualizationType.Claim)
- {
- cornerBlockData = Material.GLOWSTONE.createBlockData();
- accentBlockData = Material.GOLD_BLOCK.createBlockData();
- }
- else if (visualizationType == VisualizationType.AdminClaim)
- {
- cornerBlockData = Material.GLOWSTONE.createBlockData();
- accentBlockData = Material.PUMPKIN.createBlockData();
- }
- else if (visualizationType == VisualizationType.Subdivision)
- {
- cornerBlockData = Material.IRON_BLOCK.createBlockData();
- accentBlockData = Material.WHITE_WOOL.createBlockData();
- }
- else if (visualizationType == VisualizationType.RestoreNature)
- {
- cornerBlockData = Material.DIAMOND_BLOCK.createBlockData();
- accentBlockData = Material.DIAMOND_BLOCK.createBlockData();
- }
- else
- {
- cornerBlockData = Material.REDSTONE_ORE.createBlockData();
- ((Lightable) cornerBlockData).setLit(true);
- accentBlockData = Material.NETHERRACK.createBlockData();
- }
-
- addClaimElements(claim.getLesserBoundaryCorner(), claim.getGreaterBoundaryCorner(), locality, height, cornerBlockData, accentBlockData, 10);
- }
-
- //adds a general claim cuboid (represented by min and max) visualization to the current visualization
- public void addClaimElements(Location min, Location max, Location locality, int height, BlockData cornerBlockData, BlockData accentBlockData, int STEP) {
- World world = min.getWorld();
- boolean waterIsTransparent = locality.getBlock().getType() == Material.WATER;
-
- int smallx = min.getBlockX();
- int smallz = min.getBlockZ();
- int bigx = max.getBlockX();
- int bigz = max.getBlockZ();
-
- ArrayList newElements = new ArrayList<>();
-
- //initialize visualization elements without Y values and real data
- //that will be added later for only the visualization elements within visualization range
-
- //locality
- int minx = locality.getBlockX() - 75;
- int minz = locality.getBlockZ() - 75;
- int maxx = locality.getBlockX() + 75;
- int maxz = locality.getBlockZ() + 75;
-
- //top line
- newElements.add(new VisualizationElement(new Location(world, smallx, 0, bigz), cornerBlockData, Material.AIR.createBlockData()));
- newElements.add(new VisualizationElement(new Location(world, smallx + 1, 0, bigz), accentBlockData, Material.AIR.createBlockData()));
- for (int x = smallx + STEP; x < bigx - STEP / 2; x += STEP)
- {
- if (x > minx && x < maxx)
- newElements.add(new VisualizationElement(new Location(world, x, 0, bigz), accentBlockData, Material.AIR.createBlockData()));
- }
- newElements.add(new VisualizationElement(new Location(world, bigx - 1, 0, bigz), accentBlockData, Material.AIR.createBlockData()));
-
- //bottom line
- newElements.add(new VisualizationElement(new Location(world, smallx + 1, 0, smallz), accentBlockData, Material.AIR.createBlockData()));
- for (int x = smallx + STEP; x < bigx - STEP / 2; x += STEP)
- {
- if (x > minx && x < maxx)
- newElements.add(new VisualizationElement(new Location(world, x, 0, smallz), accentBlockData, Material.AIR.createBlockData()));
- }
- newElements.add(new VisualizationElement(new Location(world, bigx - 1, 0, smallz), accentBlockData, Material.AIR.createBlockData()));
-
- //left line
- newElements.add(new VisualizationElement(new Location(world, smallx, 0, smallz), cornerBlockData, Material.AIR.createBlockData()));
- newElements.add(new VisualizationElement(new Location(world, smallx, 0, smallz + 1), accentBlockData, Material.AIR.createBlockData()));
- for (int z = smallz + STEP; z < bigz - STEP / 2; z += STEP)
- {
- if (z > minz && z < maxz)
- newElements.add(new VisualizationElement(new Location(world, smallx, 0, z), accentBlockData, Material.AIR.createBlockData()));
- }
- newElements.add(new VisualizationElement(new Location(world, smallx, 0, bigz - 1), accentBlockData, Material.AIR.createBlockData()));
-
- //right line
- newElements.add(new VisualizationElement(new Location(world, bigx, 0, smallz), cornerBlockData, Material.AIR.createBlockData()));
- newElements.add(new VisualizationElement(new Location(world, bigx, 0, smallz + 1), accentBlockData, Material.AIR.createBlockData()));
- for (int z = smallz + STEP; z < bigz - STEP / 2; z += STEP)
- {
- if (z > minz && z < maxz)
- newElements.add(new VisualizationElement(new Location(world, bigx, 0, z), accentBlockData, Material.AIR.createBlockData()));
- }
- newElements.add(new VisualizationElement(new Location(world, bigx, 0, bigz - 1), accentBlockData, Material.AIR.createBlockData()));
- newElements.add(new VisualizationElement(new Location(world, bigx, 0, bigz), cornerBlockData, Material.AIR.createBlockData()));
-
- //remove any out of range elements
- this.removeElementsOutOfRange(newElements, minx, minz, maxx, maxz);
-
- //remove any elements outside the claim
- BoundingBox box = BoundingBox.of(min, max);
- for (int i = 0; i < newElements.size(); i++)
- {
- VisualizationElement element = newElements.get(i);
- if (!containsIncludingIgnoringHeight(box, element.location.toVector()))
- {
- newElements.remove(i--);
- }
- }
-
- //set Y values and real block information for any remaining visualization blocks
- for (VisualizationElement element : newElements)
- {
- Location tempLocation = element.location;
- element.location = getVisibleLocation(tempLocation.getWorld(), tempLocation.getBlockX(), height, tempLocation.getBlockZ(), waterIsTransparent);
- height = element.location.getBlockY();
- element.realBlock = element.location.getBlock().getBlockData();
- }
-
- this.elements.addAll(newElements);
- }
-
- private boolean containsIncludingIgnoringHeight(BoundingBox box, Vector vector) {
- return vector.getBlockX() >= box.getMinX()
- && vector.getBlockX() <= box.getMaxX()
- && vector.getBlockZ() >= box.getMinZ()
- && vector.getBlockZ() <= box.getMaxZ();
- }
-
- //removes any elements which are out of visualization range
- private void removeElementsOutOfRange(ArrayList elements, int minx, int minz, int maxx, int maxz)
- {
- for (int i = 0; i < elements.size(); i++)
- {
- Location location = elements.get(i).location;
- if (location.getX() < minx || location.getX() > maxx || location.getZ() < minz || location.getZ() > maxz)
- {
- elements.remove(i--);
- }
- }
- }
-
- //finds a block the player can probably see. this is how visualizations "cling" to the ground or ceiling
- private static Location getVisibleLocation(World world, int x, int y, int z, boolean waterIsTransparent)
- {
- Block block = world.getBlockAt(x, y, z);
- BlockFace direction = (isTransparent(block, waterIsTransparent)) ? BlockFace.DOWN : BlockFace.UP;
-
- while (block.getY() >= 1 &&
- block.getY() < world.getMaxHeight() - 1 &&
- (!isTransparent(block.getRelative(BlockFace.UP), waterIsTransparent) || isTransparent(block, waterIsTransparent)))
- {
- block = block.getRelative(direction);
- }
-
- return block.getLocation();
- }
-
- //helper method for above. allows visualization blocks to sit underneath partly transparent blocks like grass and fence
- private static boolean isTransparent(Block block, boolean waterIsTransparent)
- {
- Material blockMaterial = block.getType();
- //Blacklist
- switch (blockMaterial)
- {
- case SNOW:
- return false;
- }
-
- //Whitelist TODO: some of this might already be included in isTransparent()
- switch (blockMaterial)
- {
- case AIR:
- case OAK_FENCE:
- case ACACIA_FENCE:
- case BIRCH_FENCE:
- case DARK_OAK_FENCE:
- case JUNGLE_FENCE:
- case NETHER_BRICK_FENCE:
- case SPRUCE_FENCE:
- case OAK_FENCE_GATE:
- case ACACIA_FENCE_GATE:
- case BIRCH_FENCE_GATE:
- case DARK_OAK_FENCE_GATE:
- case SPRUCE_FENCE_GATE:
- case JUNGLE_FENCE_GATE:
- return true;
- }
-
- if (Tag.SIGNS.isTagged(blockMaterial) || Tag.WALL_SIGNS.isTagged(blockMaterial))
- return true;
-
- return (waterIsTransparent && block.getType() == Material.WATER) ||
- block.getType().isTransparent();
- }
-
- public static Visualization fromClaims(Iterable claims, int height, VisualizationType type, Location locality)
- {
- Visualization visualization = new Visualization();
-
- for (Claim claim : claims)
- {
- visualization.addClaimElements(claim, height, type, locality);
- }
-
- return visualization;
- }
-}
+/*
+ GriefPrevention Server Plugin for Minecraft
+ Copyright (C) 2012 Ryan Hamshire
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see .
+ */
+
+package me.ryanhamshire.GriefPrevention;
+
+import org.bukkit.Location;
+import org.bukkit.Material;
+import org.bukkit.Tag;
+import org.bukkit.World;
+import org.bukkit.block.Block;
+import org.bukkit.block.BlockFace;
+import org.bukkit.block.data.BlockData;
+import org.bukkit.block.data.Lightable;
+import org.bukkit.entity.Player;
+import org.bukkit.util.BoundingBox;
+import org.bukkit.util.Vector;
+
+import java.util.ArrayList;
+
+//represents a visualization sent to a player
+//FEATURE: to show players visually where claim boundaries are, we send them fake block change packets
+//the result is that those players see new blocks, but the world hasn't been changed. other players can't see the new blocks, either.
+public class Visualization
+{
+ public ArrayList elements = new ArrayList();
+
+ //sends a visualization to a player
+ public static void Apply(Player player, Visualization visualization)
+ {
+ PlayerData playerData = GriefPrevention.instance.dataStore.getPlayerData(player.getUniqueId());
+
+ //if he has any current visualization, clear it first
+ if (playerData.currentVisualization != null)
+ {
+ Visualization.Revert(player);
+ }
+
+ //if he's online, create a task to send him the visualization
+ if (player.isOnline() && visualization.elements.size() > 0 && visualization.elements.get(0).location.getWorld().equals(player.getWorld()))
+ {
+ GriefPrevention.instance.getServer().getScheduler().scheduleSyncDelayedTask(GriefPrevention.instance, new VisualizationApplicationTask(player, playerData, visualization), 1L);
+ }
+ }
+
+ //reverts a visualization by sending another block change list, this time with the real world block values
+
+ public static void Revert(Player player)
+ {
+ if (!player.isOnline()) return;
+
+ PlayerData playerData = GriefPrevention.instance.dataStore.getPlayerData(player.getUniqueId());
+
+ Visualization visualization = playerData.currentVisualization;
+
+ if (playerData.currentVisualization != null)
+ {
+ //locality
+ int minx = player.getLocation().getBlockX() - 100;
+ int minz = player.getLocation().getBlockZ() - 100;
+ int maxx = player.getLocation().getBlockX() + 100;
+ int maxz = player.getLocation().getBlockZ() + 100;
+
+ //remove any elements which are too far away
+ visualization.removeElementsOutOfRange(visualization.elements, minx, minz, maxx, maxz);
+
+ //send real block information for any remaining elements
+ for (int i = 0; i < visualization.elements.size(); i++)
+ {
+ VisualizationElement element = visualization.elements.get(i);
+
+ //check player still in world where visualization exists
+ if (i == 0)
+ {
+ if (!player.getWorld().equals(element.location.getWorld())) return;
+ }
+
+ player.sendBlockChange(element.location, element.realBlock);
+ }
+
+ playerData.currentVisualization = null;
+ }
+ }
+
+ //convenience method to build a visualization from a claim
+ //visualizationType determines the style (gold blocks, silver, red, diamond, etc)
+ public static Visualization FromClaim(Claim claim, int height, VisualizationType visualizationType, Location locality)
+ {
+ //visualize only top level claims
+ if (claim.parent != null)
+ {
+ return FromClaim(claim.parent, height, visualizationType, locality);
+ }
+
+ Visualization visualization = new Visualization();
+
+ //add subdivisions first
+ for (int i = 0; i < claim.children.size(); i++)
+ {
+ Claim child = claim.children.get(i);
+ if (!child.inDataStore) continue;
+ visualization.addClaimElements(child, height, VisualizationType.Subdivision, locality);
+ }
+
+ //special visualization for administrative land claims
+ if (claim.isAdminClaim() && visualizationType == VisualizationType.Claim)
+ {
+ visualizationType = VisualizationType.AdminClaim;
+ }
+
+ //add top level last so that it takes precedence (it shows on top when the child claim boundaries overlap with its boundaries)
+ visualization.addClaimElements(claim, height, visualizationType, locality);
+
+ return visualization;
+ }
+
+ //adds a claim's visualization to the current visualization
+ //handy for combining several visualizations together, as when visualization a top level claim with several subdivisions inside
+ //locality is a performance consideration. only create visualization blocks for around 100 blocks of the locality
+
+ public void addClaimElements(Claim claim, int height, VisualizationType visualizationType, Location locality)
+ {
+ BlockData cornerBlockData;
+ BlockData accentBlockData;
+
+ if (visualizationType == VisualizationType.Claim)
+ {
+ cornerBlockData = Material.GLOWSTONE.createBlockData();
+ accentBlockData = Material.GOLD_BLOCK.createBlockData();
+ }
+ else if (visualizationType == VisualizationType.AdminClaim)
+ {
+ cornerBlockData = Material.GLOWSTONE.createBlockData();
+ accentBlockData = Material.PUMPKIN.createBlockData();
+ }
+ else if (visualizationType == VisualizationType.Subdivision)
+ {
+ cornerBlockData = Material.IRON_BLOCK.createBlockData();
+ accentBlockData = Material.WHITE_WOOL.createBlockData();
+ }
+ else if (visualizationType == VisualizationType.RestoreNature)
+ {
+ cornerBlockData = Material.DIAMOND_BLOCK.createBlockData();
+ accentBlockData = Material.DIAMOND_BLOCK.createBlockData();
+ }
+ else
+ {
+ cornerBlockData = Material.REDSTONE_ORE.createBlockData();
+ ((Lightable) cornerBlockData).setLit(true);
+ accentBlockData = Material.NETHERRACK.createBlockData();
+ }
+
+ addClaimElements(claim.getLesserBoundaryCorner(), claim.getGreaterBoundaryCorner(), locality, height, cornerBlockData, accentBlockData, 10);
+ }
+
+ //adds a general claim cuboid (represented by min and max) visualization to the current visualization
+ public void addClaimElements(Location min, Location max, Location locality, int height, BlockData cornerBlockData, BlockData accentBlockData, int STEP) {
+ World world = min.getWorld();
+ boolean waterIsTransparent = locality.getBlock().getType() == Material.WATER;
+
+ int smallx = min.getBlockX();
+ int smallz = min.getBlockZ();
+ int bigx = max.getBlockX();
+ int bigz = max.getBlockZ();
+
+ ArrayList newElements = new ArrayList<>();
+
+ //initialize visualization elements without Y values and real data
+ //that will be added later for only the visualization elements within visualization range
+
+ //locality
+ int minx = locality.getBlockX() - 75;
+ int minz = locality.getBlockZ() - 75;
+ int maxx = locality.getBlockX() + 75;
+ int maxz = locality.getBlockZ() + 75;
+
+ //top line
+ newElements.add(new VisualizationElement(new Location(world, smallx, 0, bigz), cornerBlockData, Material.AIR.createBlockData()));
+ newElements.add(new VisualizationElement(new Location(world, smallx + 1, 0, bigz), accentBlockData, Material.AIR.createBlockData()));
+ for (int x = smallx + STEP; x < bigx - STEP / 2; x += STEP)
+ {
+ if (x > minx && x < maxx)
+ newElements.add(new VisualizationElement(new Location(world, x, 0, bigz), accentBlockData, Material.AIR.createBlockData()));
+ }
+ newElements.add(new VisualizationElement(new Location(world, bigx - 1, 0, bigz), accentBlockData, Material.AIR.createBlockData()));
+
+ //bottom line
+ newElements.add(new VisualizationElement(new Location(world, smallx + 1, 0, smallz), accentBlockData, Material.AIR.createBlockData()));
+ for (int x = smallx + STEP; x < bigx - STEP / 2; x += STEP)
+ {
+ if (x > minx && x < maxx)
+ newElements.add(new VisualizationElement(new Location(world, x, 0, smallz), accentBlockData, Material.AIR.createBlockData()));
+ }
+ newElements.add(new VisualizationElement(new Location(world, bigx - 1, 0, smallz), accentBlockData, Material.AIR.createBlockData()));
+
+ //left line
+ newElements.add(new VisualizationElement(new Location(world, smallx, 0, smallz), cornerBlockData, Material.AIR.createBlockData()));
+ newElements.add(new VisualizationElement(new Location(world, smallx, 0, smallz + 1), accentBlockData, Material.AIR.createBlockData()));
+ for (int z = smallz + STEP; z < bigz - STEP / 2; z += STEP)
+ {
+ if (z > minz && z < maxz)
+ newElements.add(new VisualizationElement(new Location(world, smallx, 0, z), accentBlockData, Material.AIR.createBlockData()));
+ }
+ newElements.add(new VisualizationElement(new Location(world, smallx, 0, bigz - 1), accentBlockData, Material.AIR.createBlockData()));
+
+ //right line
+ newElements.add(new VisualizationElement(new Location(world, bigx, 0, smallz), cornerBlockData, Material.AIR.createBlockData()));
+ newElements.add(new VisualizationElement(new Location(world, bigx, 0, smallz + 1), accentBlockData, Material.AIR.createBlockData()));
+ for (int z = smallz + STEP; z < bigz - STEP / 2; z += STEP)
+ {
+ if (z > minz && z < maxz)
+ newElements.add(new VisualizationElement(new Location(world, bigx, 0, z), accentBlockData, Material.AIR.createBlockData()));
+ }
+ newElements.add(new VisualizationElement(new Location(world, bigx, 0, bigz - 1), accentBlockData, Material.AIR.createBlockData()));
+ newElements.add(new VisualizationElement(new Location(world, bigx, 0, bigz), cornerBlockData, Material.AIR.createBlockData()));
+
+ //remove any out of range elements
+ this.removeElementsOutOfRange(newElements, minx, minz, maxx, maxz);
+
+ //remove any elements outside the claim
+ BoundingBox box = BoundingBox.of(min, max);
+ for (int i = 0; i < newElements.size(); i++)
+ {
+ VisualizationElement element = newElements.get(i);
+ if (!containsIncludingIgnoringHeight(box, element.location.toVector()))
+ {
+ newElements.remove(i--);
+ }
+ }
+
+ //set Y values and real block information for any remaining visualization blocks
+ for (VisualizationElement element : newElements)
+ {
+ Location tempLocation = element.location;
+ element.location = getVisibleLocation(tempLocation.getWorld(), tempLocation.getBlockX(), height, tempLocation.getBlockZ(), waterIsTransparent);
+ height = element.location.getBlockY();
+ element.realBlock = element.location.getBlock().getBlockData();
+ }
+
+ this.elements.addAll(newElements);
+ }
+
+ private boolean containsIncludingIgnoringHeight(BoundingBox box, Vector vector) {
+ return vector.getBlockX() >= box.getMinX()
+ && vector.getBlockX() <= box.getMaxX()
+ && vector.getBlockZ() >= box.getMinZ()
+ && vector.getBlockZ() <= box.getMaxZ();
+ }
+
+ //removes any elements which are out of visualization range
+ private void removeElementsOutOfRange(ArrayList elements, int minx, int minz, int maxx, int maxz)
+ {
+ for (int i = 0; i < elements.size(); i++)
+ {
+ Location location = elements.get(i).location;
+ if (location.getX() < minx || location.getX() > maxx || location.getZ() < minz || location.getZ() > maxz)
+ {
+ elements.remove(i--);
+ }
+ }
+ }
+
+ //finds a block the player can probably see. this is how visualizations "cling" to the ground or ceiling
+ private static Location getVisibleLocation(World world, int x, int y, int z, boolean waterIsTransparent)
+ {
+ Block block = world.getBlockAt(x, y, z);
+ BlockFace direction = (isTransparent(block, waterIsTransparent)) ? BlockFace.DOWN : BlockFace.UP;
+
+ while (block.getY() >= 1 &&
+ block.getY() < world.getMaxHeight() - 1 &&
+ (!isTransparent(block.getRelative(BlockFace.UP), waterIsTransparent) || isTransparent(block, waterIsTransparent)))
+ {
+ block = block.getRelative(direction);
+ }
+
+ return block.getLocation();
+ }
+
+ //helper method for above. allows visualization blocks to sit underneath partly transparent blocks like grass and fence
+ private static boolean isTransparent(Block block, boolean waterIsTransparent)
+ {
+ Material blockMaterial = block.getType();
+ //Blacklist
+ switch (blockMaterial)
+ {
+ case SNOW:
+ return false;
+ }
+
+ //Whitelist TODO: some of this might already be included in isTransparent()
+ switch (blockMaterial)
+ {
+ case AIR:
+ case OAK_FENCE:
+ case ACACIA_FENCE:
+ case BIRCH_FENCE:
+ case DARK_OAK_FENCE:
+ case JUNGLE_FENCE:
+ case NETHER_BRICK_FENCE:
+ case SPRUCE_FENCE:
+ case OAK_FENCE_GATE:
+ case ACACIA_FENCE_GATE:
+ case BIRCH_FENCE_GATE:
+ case DARK_OAK_FENCE_GATE:
+ case SPRUCE_FENCE_GATE:
+ case JUNGLE_FENCE_GATE:
+ return true;
+ }
+
+ if (Tag.SIGNS.isTagged(blockMaterial) || Tag.WALL_SIGNS.isTagged(blockMaterial))
+ return true;
+
+ return (waterIsTransparent && block.getType() == Material.WATER) ||
+ block.getType().isTransparent();
+ }
+
+ public static Visualization fromClaims(Iterable claims, int height, VisualizationType type, Location locality)
+ {
+ Visualization visualization = new Visualization();
+
+ for (Claim claim : claims)
+ {
+ visualization.addClaimElements(claim, height, type, locality);
+ }
+
+ return visualization;
+ }
+}
diff --git a/src/main/java/me/ryanhamshire/GriefPrevention/VisualizationApplicationTask.java b/src/main/java/me/ryanhamshire/GriefPrevention/VisualizationApplicationTask.java
index d1d9560..43c3dca 100644
--- a/src/main/java/me/ryanhamshire/GriefPrevention/VisualizationApplicationTask.java
+++ b/src/main/java/me/ryanhamshire/GriefPrevention/VisualizationApplicationTask.java
@@ -1,60 +1,60 @@
-/*
- GriefPrevention Server Plugin for Minecraft
- Copyright (C) 2012 Ryan Hamshire
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see .
- */
-
-package me.ryanhamshire.GriefPrevention;
-
-import org.bukkit.entity.Player;
-
-//applies a visualization for a player by sending him block change packets
-class VisualizationApplicationTask implements Runnable
-{
- private Visualization visualization;
- private Player player;
- private PlayerData playerData;
-
- public VisualizationApplicationTask(Player player, PlayerData playerData, Visualization visualization)
- {
- this.visualization = visualization;
- this.playerData = playerData;
- this.player = player;
- }
-
-
- @Override
- public void run()
- {
- //for each element (=block) of the visualization
- for (int i = 0; i < visualization.elements.size(); i++)
- {
- VisualizationElement element = visualization.elements.get(i);
-
- //send the player a fake block change event
- if (!element.location.getChunk().isLoaded()) continue; //cheap distance check
- player.sendBlockChange(element.location, element.visualizedBlock);
- }
-
- //remember the visualization applied to this player for later (so it can be inexpensively reverted)
- playerData.currentVisualization = visualization;
-
- //schedule automatic visualization reversion in 60 seconds.
- GriefPrevention.instance.getServer().getScheduler().scheduleSyncDelayedTask(
- GriefPrevention.instance,
- new VisualizationReversionTask(player, playerData, visualization),
- 20L * 60); //60 seconds
- }
-}
+/*
+ GriefPrevention Server Plugin for Minecraft
+ Copyright (C) 2012 Ryan Hamshire
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see .
+ */
+
+package me.ryanhamshire.GriefPrevention;
+
+import org.bukkit.entity.Player;
+
+//applies a visualization for a player by sending him block change packets
+class VisualizationApplicationTask implements Runnable
+{
+ private Visualization visualization;
+ private Player player;
+ private PlayerData playerData;
+
+ public VisualizationApplicationTask(Player player, PlayerData playerData, Visualization visualization)
+ {
+ this.visualization = visualization;
+ this.playerData = playerData;
+ this.player = player;
+ }
+
+
+ @Override
+ public void run()
+ {
+ //for each element (=block) of the visualization
+ for (int i = 0; i < visualization.elements.size(); i++)
+ {
+ VisualizationElement element = visualization.elements.get(i);
+
+ //send the player a fake block change event
+ if (!element.location.getChunk().isLoaded()) continue; //cheap distance check
+ player.sendBlockChange(element.location, element.visualizedBlock);
+ }
+
+ //remember the visualization applied to this player for later (so it can be inexpensively reverted)
+ playerData.currentVisualization = visualization;
+
+ //schedule automatic visualization reversion in 60 seconds.
+ GriefPrevention.instance.getServer().getScheduler().scheduleSyncDelayedTask(
+ GriefPrevention.instance,
+ new VisualizationReversionTask(player, playerData, visualization),
+ 20L * 60); //60 seconds
+ }
+}
diff --git a/src/main/java/me/ryanhamshire/GriefPrevention/VisualizationElement.java b/src/main/java/me/ryanhamshire/GriefPrevention/VisualizationElement.java
index 689515f..fcbfd43 100644
--- a/src/main/java/me/ryanhamshire/GriefPrevention/VisualizationElement.java
+++ b/src/main/java/me/ryanhamshire/GriefPrevention/VisualizationElement.java
@@ -1,37 +1,37 @@
-/*
- GriefPrevention Server Plugin for Minecraft
- Copyright (C) 2012 Ryan Hamshire
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see .
- */
-
-package me.ryanhamshire.GriefPrevention;
-
-import org.bukkit.Location;
-import org.bukkit.block.data.BlockData;
-
-//represents a "fake" block sent to a player as part of a visualization
-public class VisualizationElement
-{
- public Location location;
- public BlockData visualizedBlock;
- public BlockData realBlock;
-
- public VisualizationElement(Location location, BlockData visualizedBlock, BlockData realBlock)
- {
- this.location = location;
- this.visualizedBlock = visualizedBlock;
- this.realBlock = realBlock;
- }
-}
+/*
+ GriefPrevention Server Plugin for Minecraft
+ Copyright (C) 2012 Ryan Hamshire
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see .
+ */
+
+package me.ryanhamshire.GriefPrevention;
+
+import org.bukkit.Location;
+import org.bukkit.block.data.BlockData;
+
+//represents a "fake" block sent to a player as part of a visualization
+public class VisualizationElement
+{
+ public Location location;
+ public BlockData visualizedBlock;
+ public BlockData realBlock;
+
+ public VisualizationElement(Location location, BlockData visualizedBlock, BlockData realBlock)
+ {
+ this.location = location;
+ this.visualizedBlock = visualizedBlock;
+ this.realBlock = realBlock;
+ }
+}
diff --git a/src/main/java/me/ryanhamshire/GriefPrevention/VisualizationType.java b/src/main/java/me/ryanhamshire/GriefPrevention/VisualizationType.java
index f4516ef..c2a8efb 100644
--- a/src/main/java/me/ryanhamshire/GriefPrevention/VisualizationType.java
+++ b/src/main/java/me/ryanhamshire/GriefPrevention/VisualizationType.java
@@ -1,29 +1,29 @@
-/*
- GriefPrevention Server Plugin for Minecraft
- Copyright (C) 2012 Ryan Hamshire
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see .
- */
-
-package me.ryanhamshire.GriefPrevention;
-
-//just an enumeration of the visualization types, which determine what materials will be for the fake blocks
-public enum VisualizationType
-{
- Claim,
- Subdivision,
- ErrorClaim,
- RestoreNature,
- AdminClaim
-}
+/*
+ GriefPrevention Server Plugin for Minecraft
+ Copyright (C) 2012 Ryan Hamshire
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see .
+ */
+
+package me.ryanhamshire.GriefPrevention;
+
+//just an enumeration of the visualization types, which determine what materials will be for the fake blocks
+public enum VisualizationType
+{
+ Claim,
+ Subdivision,
+ ErrorClaim,
+ RestoreNature,
+ AdminClaim
+}