git add --renormalize .

This commit is contained in:
RoboMWM 2020-09-07 05:32:16 -07:00
parent cd5046fc71
commit e3bce9a35e
18 changed files with 1545 additions and 1545 deletions

View File

@ -1,33 +1,33 @@
/* /*
GriefPrevention Server Plugin for Minecraft GriefPrevention Server Plugin for Minecraft
Copyright (C) 2012 Ryan Hamshire Copyright (C) 2012 Ryan Hamshire
This program is free software: you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or the Free Software Foundation, either version 3 of the License, or
(at your option) any later version. (at your option) any later version.
This program is distributed in the hope that it will be useful, This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details. GNU General Public License for more details.
You should have received a copy of the GNU General Public License You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
package me.ryanhamshire.GriefPrevention; package me.ryanhamshire.GriefPrevention;
public class CustomizableMessage public class CustomizableMessage
{ {
public Messages id; public Messages id;
public String text; public String text;
public String notes; public String notes;
public CustomizableMessage(Messages id, String text, String notes) public CustomizableMessage(Messages id, String text, String notes)
{ {
this.id = id; this.id = id;
this.text = text; this.text = text;
this.notes = notes; this.notes = notes;
} }
} }

View File

@ -1,128 +1,128 @@
/* /*
GriefPrevention Server Plugin for Minecraft GriefPrevention Server Plugin for Minecraft
Copyright (C) 2012 Ryan Hamshire Copyright (C) 2012 Ryan Hamshire
This program is free software: you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or the Free Software Foundation, either version 3 of the License, or
(at your option) any later version. (at your option) any later version.
This program is distributed in the hope that it will be useful, This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details. GNU General Public License for more details.
You should have received a copy of the GNU General Public License You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
package me.ryanhamshire.GriefPrevention; package me.ryanhamshire.GriefPrevention;
import me.ryanhamshire.GriefPrevention.events.AccrueClaimBlocksEvent; import me.ryanhamshire.GriefPrevention.events.AccrueClaimBlocksEvent;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import java.util.Collection; import java.util.Collection;
//FEATURE: give players claim blocks for playing, as long as they're not away from their computer //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 //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 class DeliverClaimBlocksTask implements Runnable
{ {
private Player player; private Player player;
private GriefPrevention instance; private GriefPrevention instance;
private int idleThresholdSquared; private int idleThresholdSquared;
public DeliverClaimBlocksTask(Player player, GriefPrevention instance) public DeliverClaimBlocksTask(Player player, GriefPrevention instance)
{ {
this.player = player; this.player = player;
this.instance = instance; this.instance = instance;
this.idleThresholdSquared = instance.config_claims_accruedIdleThreshold * instance.config_claims_accruedIdleThreshold; this.idleThresholdSquared = instance.config_claims_accruedIdleThreshold * instance.config_claims_accruedIdleThreshold;
} }
@Override @Override
public void run() public void run()
{ {
//if no player specified, this task will create a player-specific task for each online player, scheduled one tick apart //if no player specified, this task will create a player-specific task for each online player, scheduled one tick apart
if (this.player == null) if (this.player == null)
{ {
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
Collection<Player> players = (Collection<Player>) GriefPrevention.instance.getServer().getOnlinePlayers(); Collection<Player> players = (Collection<Player>) GriefPrevention.instance.getServer().getOnlinePlayers();
long i = 0; long i = 0;
for (Player onlinePlayer : players) for (Player onlinePlayer : players)
{ {
DeliverClaimBlocksTask newTask = new DeliverClaimBlocksTask(onlinePlayer, instance); DeliverClaimBlocksTask newTask = new DeliverClaimBlocksTask(onlinePlayer, instance);
instance.getServer().getScheduler().scheduleSyncDelayedTask(instance, newTask, i++); instance.getServer().getScheduler().scheduleSyncDelayedTask(instance, newTask, i++);
} }
return; //tasks started for each player return; //tasks started for each player
} }
//deliver claim blocks to the specified player //deliver claim blocks to the specified player
if (!this.player.isOnline()) if (!this.player.isOnline())
{ {
return; //player is not online to receive claim blocks return; //player is not online to receive claim blocks
} }
DataStore dataStore = instance.dataStore; DataStore dataStore = instance.dataStore;
PlayerData playerData = dataStore.getPlayerData(player.getUniqueId()); PlayerData playerData = dataStore.getPlayerData(player.getUniqueId());
// check if player is idle. considered idle if // check if player is idle. considered idle if
// in vehicle or is in water (pushed by water) // in vehicle or is in water (pushed by water)
// or has not moved at least defined blocks since last check // or has not moved at least defined blocks since last check
boolean isIdle = false; boolean isIdle = false;
try try
{ {
isIdle = player.isInsideVehicle() || player.getLocation().getBlock().isLiquid() || isIdle = player.isInsideVehicle() || player.getLocation().getBlock().isLiquid() ||
!(playerData.lastAfkCheckLocation == null || playerData.lastAfkCheckLocation.distanceSquared(player.getLocation()) > idleThresholdSquared); !(playerData.lastAfkCheckLocation == null || playerData.lastAfkCheckLocation.distanceSquared(player.getLocation()) > idleThresholdSquared);
} }
catch (IllegalArgumentException ignore) //can't measure distance when to/from are different worlds catch (IllegalArgumentException ignore) //can't measure distance when to/from are different worlds
{ {
} }
//remember current location for next time //remember current location for next time
playerData.lastAfkCheckLocation = player.getLocation(); playerData.lastAfkCheckLocation = player.getLocation();
try try
{ {
//determine how fast blocks accrue for this player //RoboMWM: addons determine this instead //determine how fast blocks accrue for this player //RoboMWM: addons determine this instead
int accrualRate = instance.config_claims_blocksAccruedPerHour_default; int accrualRate = instance.config_claims_blocksAccruedPerHour_default;
//determine idle accrual rate when idle //determine idle accrual rate when idle
if (isIdle) if (isIdle)
{ {
if (instance.config_claims_accruedIdlePercent <= 0) if (instance.config_claims_accruedIdlePercent <= 0)
{ {
GriefPrevention.AddLogEntry(player.getName() + " wasn't active enough to accrue claim blocks this round.", CustomLogEntryTypes.Debug, true); GriefPrevention.AddLogEntry(player.getName() + " wasn't active enough to accrue claim blocks this round.", CustomLogEntryTypes.Debug, true);
return; //idle accrual percentage is disabled return; //idle accrual percentage is disabled
} }
accrualRate = (int) (accrualRate * (instance.config_claims_accruedIdlePercent / 100.0D)); accrualRate = (int) (accrualRate * (instance.config_claims_accruedIdlePercent / 100.0D));
} }
//fire event for addons //fire event for addons
AccrueClaimBlocksEvent event = new AccrueClaimBlocksEvent(player, accrualRate, isIdle); AccrueClaimBlocksEvent event = new AccrueClaimBlocksEvent(player, accrualRate, isIdle);
instance.getServer().getPluginManager().callEvent(event); instance.getServer().getPluginManager().callEvent(event);
if (event.isCancelled()) if (event.isCancelled())
{ {
GriefPrevention.AddLogEntry(player.getName() + " claim block delivery was canceled by another plugin.", CustomLogEntryTypes.Debug, true); GriefPrevention.AddLogEntry(player.getName() + " claim block delivery was canceled by another plugin.", CustomLogEntryTypes.Debug, true);
return; //event was cancelled return; //event was cancelled
} }
//set actual accrual //set actual accrual
accrualRate = event.getBlocksToAccrue(); accrualRate = event.getBlocksToAccrue();
if (accrualRate < 0) accrualRate = 0; if (accrualRate < 0) accrualRate = 0;
playerData.accrueBlocks(accrualRate); playerData.accrueBlocks(accrualRate);
GriefPrevention.AddLogEntry("Delivering " + event.getBlocksToAccrue() + " blocks to " + player.getName(), CustomLogEntryTypes.Debug, true); GriefPrevention.AddLogEntry("Delivering " + event.getBlocksToAccrue() + " blocks to " + player.getName(), CustomLogEntryTypes.Debug, true);
//intentionally NOT saving data here to reduce overall secondary storage access frequency //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 //many other operations will cause this player's data to save, including his eventual logout
//dataStore.savePlayerData(player.getUniqueIdentifier(), playerData); //dataStore.savePlayerData(player.getUniqueIdentifier(), playerData);
} }
catch (Exception e) catch (Exception e)
{ {
GriefPrevention.AddLogEntry("Problem delivering claim blocks to player " + player.getName() + ":"); GriefPrevention.AddLogEntry("Problem delivering claim blocks to player " + player.getName() + ":");
e.printStackTrace(); e.printStackTrace();
} }
} }
} }

View File

@ -1,149 +1,149 @@
/* /*
GriefPrevention Server Plugin for Minecraft GriefPrevention Server Plugin for Minecraft
Copyright (C) 2012 Ryan Hamshire Copyright (C) 2012 Ryan Hamshire
This program is free software: you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or the Free Software Foundation, either version 3 of the License, or
(at your option) any later version. (at your option) any later version.
This program is distributed in the hope that it will be useful, This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details. GNU General Public License for more details.
You should have received a copy of the GNU General Public License You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
package me.ryanhamshire.GriefPrevention; package me.ryanhamshire.GriefPrevention;
import org.bukkit.Material; import org.bukkit.Material;
import org.bukkit.World; import org.bukkit.World;
import org.bukkit.entity.Boat; import org.bukkit.entity.Boat;
import org.bukkit.entity.Entity; import org.bukkit.entity.Entity;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.entity.Vehicle; import org.bukkit.entity.Vehicle;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
//FEATURE: creative mode worlds get a regular entity cleanup //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 //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 //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 class EntityCleanupTask implements Runnable
{ {
//where to start cleaning in the list of entities //where to start cleaning in the list of entities
private double percentageStart; private double percentageStart;
public EntityCleanupTask(double percentageStart) public EntityCleanupTask(double percentageStart)
{ {
this.percentageStart = percentageStart; this.percentageStart = percentageStart;
} }
@Override @Override
public void run() public void run()
{ {
ArrayList<World> worlds = new ArrayList<World>(); ArrayList<World> worlds = new ArrayList<World>();
for (World world : GriefPrevention.instance.getServer().getWorlds()) for (World world : GriefPrevention.instance.getServer().getWorlds())
{ {
if (GriefPrevention.instance.config_claims_worldModes.get(world) == ClaimsMode.Creative) if (GriefPrevention.instance.config_claims_worldModes.get(world) == ClaimsMode.Creative)
{ {
worlds.add(world); worlds.add(world);
} }
} }
for (int i = 0; i < worlds.size(); i++) for (int i = 0; i < worlds.size(); i++)
{ {
World world = worlds.get(i); World world = worlds.get(i);
List<Entity> entities = world.getEntities(); List<Entity> entities = world.getEntities();
//starting and stopping point. each execution of the task scans 10% of the server's (loaded) entities //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 j = (int) (entities.size() * this.percentageStart);
int k = (int) (entities.size() * (this.percentageStart + .1)); int k = (int) (entities.size() * (this.percentageStart + .1));
Claim cachedClaim = null; Claim cachedClaim = null;
for (; j < entities.size() && j < k; j++) for (; j < entities.size() && j < k; j++)
{ {
Entity entity = entities.get(j); Entity entity = entities.get(j);
boolean remove = false; boolean remove = false;
if (entity instanceof Boat) //boats must be occupied if (entity instanceof Boat) //boats must be occupied
{ {
Boat boat = (Boat) entity; Boat boat = (Boat) entity;
if (boat.isEmpty()) remove = true; if (boat.isEmpty()) remove = true;
} }
else if (entity instanceof Vehicle) else if (entity instanceof Vehicle)
{ {
Vehicle vehicle = (Vehicle) entity; Vehicle vehicle = (Vehicle) entity;
//minecarts in motion must be occupied by a player //minecarts in motion must be occupied by a player
if (vehicle.getVelocity().lengthSquared() != 0) if (vehicle.getVelocity().lengthSquared() != 0)
{ {
if (vehicle.isEmpty() || !(vehicle.getPassenger() instanceof Player)) if (vehicle.isEmpty() || !(vehicle.getPassenger() instanceof Player))
{ {
remove = true; remove = true;
} }
} }
//stationary carts must be on rails //stationary carts must be on rails
else else
{ {
Material material = world.getBlockAt(vehicle.getLocation()).getType(); Material material = world.getBlockAt(vehicle.getLocation()).getType();
if (material != Material.RAIL && material != Material.POWERED_RAIL && material != Material.DETECTOR_RAIL) if (material != Material.RAIL && material != Material.POWERED_RAIL && material != Material.DETECTOR_RAIL)
{ {
remove = true; remove = true;
} }
} }
} }
//all non-player entities must be in claims //all non-player entities must be in claims
else if (!(entity instanceof Player)) else if (!(entity instanceof Player))
{ {
Claim claim = GriefPrevention.instance.dataStore.getClaimAt(entity.getLocation(), false, cachedClaim); Claim claim = GriefPrevention.instance.dataStore.getClaimAt(entity.getLocation(), false, cachedClaim);
if (claim != null) if (claim != null)
{ {
cachedClaim = claim; cachedClaim = claim;
} }
else else
{ {
remove = true; remove = true;
} }
} }
if (remove) if (remove)
{ {
GriefPrevention.AddLogEntry("Removing entity " + entity.getType().name() + " @ " + entity.getLocation(), CustomLogEntryTypes.Debug, true); GriefPrevention.AddLogEntry("Removing entity " + entity.getType().name() + " @ " + entity.getLocation(), CustomLogEntryTypes.Debug, true);
entity.remove(); entity.remove();
} }
} }
} }
//starting and stopping point. each execution of the task scans 5% of the server's claims //starting and stopping point. each execution of the task scans 5% of the server's claims
List<Claim> claims = GriefPrevention.instance.dataStore.claims; List<Claim> claims = GriefPrevention.instance.dataStore.claims;
int j = (int) (claims.size() * this.percentageStart); int j = (int) (claims.size() * this.percentageStart);
int k = (int) (claims.size() * (this.percentageStart + .05)); int k = (int) (claims.size() * (this.percentageStart + .05));
for (; j < claims.size() && j < k; j++) for (; j < claims.size() && j < k; j++)
{ {
Claim claim = claims.get(j); Claim claim = claims.get(j);
//if it's a creative mode claim //if it's a creative mode claim
if (GriefPrevention.instance.creativeRulesApply(claim.getLesserBoundaryCorner())) if (GriefPrevention.instance.creativeRulesApply(claim.getLesserBoundaryCorner()))
{ {
//check its entity count and remove any extras //check its entity count and remove any extras
claim.allowMoreEntities(true); claim.allowMoreEntities(true);
} }
} }
//schedule the next run of this task, in 3 minutes (20L is approximately 1 second) //schedule the next run of this task, in 3 minutes (20L is approximately 1 second)
double nextRunPercentageStart = this.percentageStart + .05; double nextRunPercentageStart = this.percentageStart + .05;
if (nextRunPercentageStart > .99) if (nextRunPercentageStart > .99)
{ {
nextRunPercentageStart = 0; nextRunPercentageStart = 0;
} }
EntityCleanupTask task = new EntityCleanupTask(nextRunPercentageStart); EntityCleanupTask task = new EntityCleanupTask(nextRunPercentageStart);
GriefPrevention.instance.getServer().getScheduler().scheduleSyncDelayedTask(GriefPrevention.instance, task, 20L * 60 * 1); GriefPrevention.instance.getServer().getScheduler().scheduleSyncDelayedTask(GriefPrevention.instance, task, 20L * 60 * 1);
} }
} }

View File

@ -1,79 +1,79 @@
/* /*
GriefPrevention Server Plugin for Minecraft GriefPrevention Server Plugin for Minecraft
Copyright (C) 2012 Ryan Hamshire Copyright (C) 2012 Ryan Hamshire
This program is free software: you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or the Free Software Foundation, either version 3 of the License, or
(at your option) any later version. (at your option) any later version.
This program is distributed in the hope that it will be useful, This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details. GNU General Public License for more details.
You should have received a copy of the GNU General Public License You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
package me.ryanhamshire.GriefPrevention; package me.ryanhamshire.GriefPrevention;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.inventory.EquipmentSlot; import org.bukkit.inventory.EquipmentSlot;
//tells a player about how many claim blocks he has, etc //tells a player about how many claim blocks he has, etc
//implemented as a task so that it can be delayed //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 //otherwise, it's spammy when players mouse-wheel past the shovel in their hot bars
class EquipShovelProcessingTask implements Runnable class EquipShovelProcessingTask implements Runnable
{ {
//player data //player data
private Player player; private Player player;
public EquipShovelProcessingTask(Player player) public EquipShovelProcessingTask(Player player)
{ {
this.player = player; this.player = player;
} }
@Override @Override
public void run() public void run()
{ {
//if he's not holding the golden shovel anymore, do nothing //if he's not holding the golden shovel anymore, do nothing
if (GriefPrevention.instance.getItemInHand(player, EquipmentSlot.HAND).getType() != GriefPrevention.instance.config_claims_modificationTool) if (GriefPrevention.instance.getItemInHand(player, EquipmentSlot.HAND).getType() != GriefPrevention.instance.config_claims_modificationTool)
return; return;
PlayerData playerData = GriefPrevention.instance.dataStore.getPlayerData(player.getUniqueId()); PlayerData playerData = GriefPrevention.instance.dataStore.getPlayerData(player.getUniqueId());
//reset any work he might have been doing //reset any work he might have been doing
playerData.lastShovelLocation = null; playerData.lastShovelLocation = null;
playerData.claimResizing = null; playerData.claimResizing = null;
//always reset to basic claims mode //always reset to basic claims mode
if (playerData.shovelMode != ShovelMode.Basic) if (playerData.shovelMode != ShovelMode.Basic)
{ {
playerData.shovelMode = ShovelMode.Basic; playerData.shovelMode = ShovelMode.Basic;
GriefPrevention.sendMessage(player, TextMode.Info, Messages.ShovelBasicClaimMode); GriefPrevention.sendMessage(player, TextMode.Info, Messages.ShovelBasicClaimMode);
} }
//tell him how many claim blocks he has available //tell him how many claim blocks he has available
int remainingBlocks = playerData.getRemainingClaimBlocks(); int remainingBlocks = playerData.getRemainingClaimBlocks();
GriefPrevention.sendMessage(player, TextMode.Instr, Messages.RemainingBlocks, String.valueOf(remainingBlocks)); GriefPrevention.sendMessage(player, TextMode.Instr, Messages.RemainingBlocks, String.valueOf(remainingBlocks));
//link to a video demo of land claiming, based on world type //link to a video demo of land claiming, based on world type
if (GriefPrevention.instance.creativeRulesApply(player.getLocation())) if (GriefPrevention.instance.creativeRulesApply(player.getLocation()))
{ {
GriefPrevention.sendMessage(player, TextMode.Instr, Messages.CreativeBasicsVideo2, DataStore.CREATIVE_VIDEO_URL); GriefPrevention.sendMessage(player, TextMode.Instr, Messages.CreativeBasicsVideo2, DataStore.CREATIVE_VIDEO_URL);
} }
else if (GriefPrevention.instance.claimsEnabledForWorld(player.getLocation().getWorld())) else if (GriefPrevention.instance.claimsEnabledForWorld(player.getLocation().getWorld()))
{ {
GriefPrevention.sendMessage(player, TextMode.Instr, Messages.SurvivalBasicsVideo2, DataStore.SURVIVAL_VIDEO_URL); GriefPrevention.sendMessage(player, TextMode.Instr, Messages.SurvivalBasicsVideo2, DataStore.SURVIVAL_VIDEO_URL);
} }
//if standing in a claim owned by the player, visualize it //if standing in a claim owned by the player, visualize it
Claim claim = GriefPrevention.instance.dataStore.getClaimAt(player.getLocation(), true, playerData.lastClaim); Claim claim = GriefPrevention.instance.dataStore.getClaimAt(player.getLocation(), true, playerData.lastClaim);
if (claim != null && claim.allowEdit(player) == null) if (claim != null && claim.allowEdit(player) == null)
{ {
playerData.lastClaim = claim; playerData.lastClaim = claim;
Visualization.Apply(player, Visualization.FromClaim(claim, player.getEyeLocation().getBlockY(), VisualizationType.Claim, player.getLocation())); Visualization.Apply(player, Visualization.FromClaim(claim, player.getEyeLocation().getBlockY(), VisualizationType.Claim, player.getLocation()));
} }
} }
} }

View File

@ -1,35 +1,35 @@
/* /*
GriefPrevention Server Plugin for Minecraft GriefPrevention Server Plugin for Minecraft
Copyright (C) 2012 Ryan Hamshire Copyright (C) 2012 Ryan Hamshire
This program is free software: you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or the Free Software Foundation, either version 3 of the License, or
(at your option) any later version. (at your option) any later version.
This program is distributed in the hope that it will be useful, This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details. GNU General Public License for more details.
You should have received a copy of the GNU General Public License You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
package me.ryanhamshire.GriefPrevention; package me.ryanhamshire.GriefPrevention;
import java.net.InetAddress; import java.net.InetAddress;
public class IpBanInfo public class IpBanInfo
{ {
InetAddress address; InetAddress address;
long expirationTimestamp; long expirationTimestamp;
String bannedAccountName; String bannedAccountName;
IpBanInfo(InetAddress address, long expirationTimestamp, String bannedAccountName) IpBanInfo(InetAddress address, long expirationTimestamp, String bannedAccountName)
{ {
this.address = address; this.address = address;
this.expirationTimestamp = expirationTimestamp; this.expirationTimestamp = expirationTimestamp;
this.bannedAccountName = bannedAccountName; this.bannedAccountName = bannedAccountName;
} }
} }

View File

@ -1,54 +1,54 @@
/* /*
GriefPrevention Server Plugin for Minecraft GriefPrevention Server Plugin for Minecraft
Copyright (C) 2012 Ryan Hamshire Copyright (C) 2012 Ryan Hamshire
This program is free software: you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or the Free Software Foundation, either version 3 of the License, or
(at your option) any later version. (at your option) any later version.
This program is distributed in the hope that it will be useful, This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details. GNU General Public License for more details.
You should have received a copy of the GNU General Public License You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
package me.ryanhamshire.GriefPrevention; package me.ryanhamshire.GriefPrevention;
import java.util.HashSet; import java.util.HashSet;
import java.util.Set; import java.util.Set;
//ordered list of material info objects, for fast searching //ordered list of material info objects, for fast searching
public class MaterialCollection public class MaterialCollection
{ {
Set<MaterialInfo> materials = new HashSet<MaterialInfo>(); Set<MaterialInfo> materials = new HashSet<MaterialInfo>();
void Add(MaterialInfo material) void Add(MaterialInfo material)
{ {
this.materials.add(material); this.materials.add(material);
} }
boolean Contains(MaterialInfo material) boolean Contains(MaterialInfo material)
{ {
return this.materials.contains(material); return this.materials.contains(material);
} }
@Override @Override
public String toString() public String toString()
{ {
return materials.toString(); return materials.toString();
} }
public int size() public int size()
{ {
return this.materials.size(); return this.materials.size();
} }
public void clear() public void clear()
{ {
this.materials.clear(); this.materials.clear();
} }
} }

View File

@ -1,96 +1,96 @@
/* /*
GriefPrevention Server Plugin for Minecraft GriefPrevention Server Plugin for Minecraft
Copyright (C) 2012 Ryan Hamshire Copyright (C) 2012 Ryan Hamshire
This program is free software: you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or the Free Software Foundation, either version 3 of the License, or
(at your option) any later version. (at your option) any later version.
This program is distributed in the hope that it will be useful, This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details. GNU General Public License for more details.
You should have received a copy of the GNU General Public License You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
package me.ryanhamshire.GriefPrevention; package me.ryanhamshire.GriefPrevention;
//represents a material or collection of materials //represents a material or collection of materials
import org.bukkit.Material; import org.bukkit.Material;
public class MaterialInfo public class MaterialInfo
{ {
Material typeID; Material typeID;
byte data; byte data;
boolean allDataValues; boolean allDataValues;
String description; String description;
public MaterialInfo(Material typeID, byte data, String description) public MaterialInfo(Material typeID, byte data, String description)
{ {
this.typeID = typeID; this.typeID = typeID;
this.data = data; this.data = data;
this.allDataValues = false; this.allDataValues = false;
this.description = description; this.description = description;
} }
public MaterialInfo(Material typeID, String description) public MaterialInfo(Material typeID, String description)
{ {
this.typeID = typeID; this.typeID = typeID;
this.data = 0; this.data = 0;
this.allDataValues = true; this.allDataValues = true;
this.description = description; this.description = description;
} }
private MaterialInfo(Material typeID, byte data, boolean allDataValues, String description) private MaterialInfo(Material typeID, byte data, boolean allDataValues, String description)
{ {
this.typeID = typeID; this.typeID = typeID;
this.data = data; this.data = data;
this.allDataValues = allDataValues; this.allDataValues = allDataValues;
this.description = description; this.description = description;
} }
@Override @Override
public String toString() public String toString()
{ {
String returnValue = String.valueOf(this.typeID) + ":" + (this.allDataValues ? "*" : String.valueOf(this.data)); String returnValue = String.valueOf(this.typeID) + ":" + (this.allDataValues ? "*" : String.valueOf(this.data));
if (this.description != null) returnValue += ":" + this.description; if (this.description != null) returnValue += ":" + this.description;
return returnValue; return returnValue;
} }
public static MaterialInfo fromString(String string) public static MaterialInfo fromString(String string)
{ {
if (string == null || string.isEmpty()) return null; if (string == null || string.isEmpty()) return null;
String[] parts = string.split(":"); String[] parts = string.split(":");
if (parts.length < 3) return null; if (parts.length < 3) return null;
try try
{ {
Material typeID = Material.matchMaterial(parts[0]); Material typeID = Material.matchMaterial(parts[0]);
byte data; byte data;
boolean allDataValues; boolean allDataValues;
if (parts[1].equals("*")) if (parts[1].equals("*"))
{ {
allDataValues = true; allDataValues = true;
data = 0; data = 0;
} }
else else
{ {
allDataValues = false; allDataValues = false;
data = Byte.parseByte(parts[1]); data = Byte.parseByte(parts[1]);
} }
return new MaterialInfo(typeID, data, allDataValues, parts[2]); return new MaterialInfo(typeID, data, allDataValues, parts[2]);
} }
catch (NumberFormatException exception) catch (NumberFormatException exception)
{ {
return null; return null;
} }
} }
} }

View File

@ -1,75 +1,75 @@
/* /*
GriefPrevention Server Plugin for Minecraft GriefPrevention Server Plugin for Minecraft
Copyright (C) 2012 Ryan Hamshire Copyright (C) 2012 Ryan Hamshire
This program is free software: you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or the Free Software Foundation, either version 3 of the License, or
(at your option) any later version. (at your option) any later version.
This program is distributed in the hope that it will be useful, This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details. GNU General Public License for more details.
You should have received a copy of the GNU General Public License You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
package me.ryanhamshire.GriefPrevention; package me.ryanhamshire.GriefPrevention;
import org.bukkit.Location; import org.bukkit.Location;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
//tries to rescue a trapped player from a claim where he doesn't have permission to save himself //tries to rescue a trapped player from a claim where he doesn't have permission to save himself
//related to the /trapped slash command //related to the /trapped slash command
//this does run in the main thread, so it's okay to make non-thread-safe calls //this does run in the main thread, so it's okay to make non-thread-safe calls
class PlayerRescueTask implements Runnable class PlayerRescueTask implements Runnable
{ {
//original location where /trapped was used //original location where /trapped was used
private Location location; private Location location;
//rescue destination, may be decided at instantiation or at execution //rescue destination, may be decided at instantiation or at execution
private Location destination; private Location destination;
//player data //player data
private Player player; private Player player;
public PlayerRescueTask(Player player, Location location, Location destination) public PlayerRescueTask(Player player, Location location, Location destination)
{ {
this.player = player; this.player = player;
this.location = location; this.location = location;
this.destination = destination; this.destination = destination;
} }
@Override @Override
public void run() public void run()
{ {
//if he logged out, don't do anything //if he logged out, don't do anything
if (!player.isOnline()) return; if (!player.isOnline()) return;
//he no longer has a pending /trapped slash command, so he can try to use it again now //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 playerData = GriefPrevention.instance.dataStore.getPlayerData(player.getUniqueId());
playerData.pendingTrapped = false; playerData.pendingTrapped = false;
//if the player moved three or more blocks from where he used /trapped, admonish him and don't save him //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) if (!player.getLocation().getWorld().equals(this.location.getWorld()) || player.getLocation().distance(this.location) > 3)
{ {
GriefPrevention.sendMessage(player, TextMode.Err, Messages.RescueAbortedMoved); GriefPrevention.sendMessage(player, TextMode.Err, Messages.RescueAbortedMoved);
return; return;
} }
//otherwise find a place to teleport him //otherwise find a place to teleport him
if (this.destination == null) if (this.destination == null)
{ {
this.destination = GriefPrevention.instance.ejectPlayer(this.player); this.destination = GriefPrevention.instance.ejectPlayer(this.player);
} }
else else
{ {
player.teleport(this.destination); player.teleport(this.destination);
} }
//log entry, in case admins want to investigate the "trap" //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.AddLogEntry("Rescued trapped player " + player.getName() + " from " + GriefPrevention.getfriendlyLocationString(this.location) + " to " + GriefPrevention.getfriendlyLocationString(this.destination) + ".");
} }
} }

View File

@ -1,130 +1,130 @@
/* /*
GriefPrevention Server Plugin for Minecraft GriefPrevention Server Plugin for Minecraft
Copyright (C) 2012 Ryan Hamshire Copyright (C) 2012 Ryan Hamshire
This program is free software: you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or the Free Software Foundation, either version 3 of the License, or
(at your option) any later version. (at your option) any later version.
This program is distributed in the hope that it will be useful, This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details. GNU General Public License for more details.
You should have received a copy of the GNU General Public License You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
package me.ryanhamshire.GriefPrevention; package me.ryanhamshire.GriefPrevention;
import org.bukkit.Chunk; import org.bukkit.Chunk;
import org.bukkit.Location; import org.bukkit.Location;
import org.bukkit.Material; import org.bukkit.Material;
import org.bukkit.block.Block; import org.bukkit.block.Block;
import org.bukkit.block.BlockFace; import org.bukkit.block.BlockFace;
import org.bukkit.entity.Animals; import org.bukkit.entity.Animals;
import org.bukkit.entity.Entity; import org.bukkit.entity.Entity;
import org.bukkit.entity.Hanging; import org.bukkit.entity.Hanging;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import java.util.ArrayList; import java.util.ArrayList;
//this main thread task takes the output from the RestoreNatureProcessingTask\ //this main thread task takes the output from the RestoreNatureProcessingTask\
//and updates the world accordingly //and updates the world accordingly
class RestoreNatureExecutionTask implements Runnable class RestoreNatureExecutionTask implements Runnable
{ {
//results from processing thread //results from processing thread
//will be applied to the world //will be applied to the world
private BlockSnapshot[][][] snapshots; private BlockSnapshot[][][] snapshots;
//boundaries for changes //boundaries for changes
private int miny; private int miny;
private Location lesserCorner; private Location lesserCorner;
private Location greaterCorner; private Location greaterCorner;
//player who should be notified about the result (will see a visualization when the restoration is complete) //player who should be notified about the result (will see a visualization when the restoration is complete)
private Player player; private Player player;
public RestoreNatureExecutionTask(BlockSnapshot[][][] snapshots, int miny, Location lesserCorner, Location greaterCorner, Player player) public RestoreNatureExecutionTask(BlockSnapshot[][][] snapshots, int miny, Location lesserCorner, Location greaterCorner, Player player)
{ {
this.snapshots = snapshots; this.snapshots = snapshots;
this.miny = miny; this.miny = miny;
this.lesserCorner = lesserCorner; this.lesserCorner = lesserCorner;
this.greaterCorner = greaterCorner; this.greaterCorner = greaterCorner;
this.player = player; this.player = player;
} }
@Override @Override
public void run() public void run()
{ {
//apply changes to the world, but ONLY to unclaimed blocks //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) //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 //those data were sent to the processing thread for referernce purposes, but aren't part of the area selected for restoration
Claim cachedClaim = null; Claim cachedClaim = null;
for (int x = 1; x < this.snapshots.length - 1; x++) for (int x = 1; x < this.snapshots.length - 1; x++)
{ {
for (int z = 1; z < this.snapshots[0][0].length - 1; z++) for (int z = 1; z < this.snapshots[0][0].length - 1; z++)
{ {
for (int y = this.miny; y < this.snapshots[0].length; y++) for (int y = this.miny; y < this.snapshots[0].length; y++)
{ {
BlockSnapshot blockUpdate = this.snapshots[x][y][z]; BlockSnapshot blockUpdate = this.snapshots[x][y][z];
Block currentBlock = blockUpdate.location.getBlock(); Block currentBlock = blockUpdate.location.getBlock();
if (blockUpdate.typeId != currentBlock.getType() || !blockUpdate.data.equals(currentBlock.getBlockData())) if (blockUpdate.typeId != currentBlock.getType() || !blockUpdate.data.equals(currentBlock.getBlockData()))
{ {
Claim claim = GriefPrevention.instance.dataStore.getClaimAt(blockUpdate.location, false, cachedClaim); Claim claim = GriefPrevention.instance.dataStore.getClaimAt(blockUpdate.location, false, cachedClaim);
if (claim != null) if (claim != null)
{ {
cachedClaim = claim; cachedClaim = claim;
break; break;
} }
try try
{ {
currentBlock.setType(blockUpdate.typeId, false); currentBlock.setType(blockUpdate.typeId, false);
// currentBlock.setBlockData(blockUpdate.data, false); // currentBlock.setBlockData(blockUpdate.data, false);
} }
catch (IllegalArgumentException e) catch (IllegalArgumentException e)
{ {
//just don't update this block and continue trying to update other blocks //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 //clean up any entities in the chunk, ensure no players are suffocated
Chunk chunk = this.lesserCorner.getChunk(); Chunk chunk = this.lesserCorner.getChunk();
Entity[] entities = chunk.getEntities(); Entity[] entities = chunk.getEntities();
for (int i = 0; i < entities.length; i++) for (int i = 0; i < entities.length; i++)
{ {
Entity entity = entities[i]; Entity entity = entities[i];
if (!(entity instanceof Player || entity instanceof Animals)) if (!(entity instanceof Player || entity instanceof Animals))
{ {
//hanging entities (paintings, item frames) are protected when they're in land claims //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) if (!(entity instanceof Hanging) || GriefPrevention.instance.dataStore.getClaimAt(entity.getLocation(), false, null) == null)
{ {
//everything else is removed //everything else is removed
entity.remove(); entity.remove();
} }
} }
//for players, always ensure there's air where the player is standing //for players, always ensure there's air where the player is standing
else else
{ {
Block feetBlock = entity.getLocation().getBlock(); Block feetBlock = entity.getLocation().getBlock();
feetBlock.setType(Material.AIR); feetBlock.setType(Material.AIR);
feetBlock.getRelative(BlockFace.UP).setType(Material.AIR); feetBlock.getRelative(BlockFace.UP).setType(Material.AIR);
} }
} }
//show visualization to player who started the restoration //show visualization to player who started the restoration
if (player != null) if (player != null)
{ {
Claim claim = new Claim(lesserCorner, greaterCorner, null, new ArrayList<String>(), new ArrayList<String>(), new ArrayList<String>(), new ArrayList<String>(), null); Claim claim = new Claim(lesserCorner, greaterCorner, null, new ArrayList<String>(), new ArrayList<String>(), new ArrayList<String>(), new ArrayList<String>(), null);
Visualization visualization = Visualization.FromClaim(claim, player.getLocation().getBlockY(), VisualizationType.RestoreNature, player.getLocation()); Visualization visualization = Visualization.FromClaim(claim, player.getLocation().getBlockY(), VisualizationType.RestoreNature, player.getLocation());
Visualization.Apply(player, visualization); Visualization.Apply(player, visualization);
} }
} }
} }

View File

@ -1,58 +1,58 @@
/* /*
GriefPrevention Server Plugin for Minecraft GriefPrevention Server Plugin for Minecraft
Copyright (C) 2012 Ryan Hamshire Copyright (C) 2012 Ryan Hamshire
This program is free software: you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or the Free Software Foundation, either version 3 of the License, or
(at your option) any later version. (at your option) any later version.
This program is distributed in the hope that it will be useful, This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details. GNU General Public License for more details.
You should have received a copy of the GNU General Public License You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
package me.ryanhamshire.GriefPrevention; package me.ryanhamshire.GriefPrevention;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import java.util.Collection; import java.util.Collection;
//secures a claim after a siege looting window has closed //secures a claim after a siege looting window has closed
class SecureClaimTask implements Runnable class SecureClaimTask implements Runnable
{ {
private SiegeData siegeData; private SiegeData siegeData;
public SecureClaimTask(SiegeData siegeData) public SecureClaimTask(SiegeData siegeData)
{ {
this.siegeData = siegeData; this.siegeData = siegeData;
} }
@Override @Override
public void run() public void run()
{ {
//for each claim involved in this siege //for each claim involved in this siege
for (int i = 0; i < this.siegeData.claims.size(); i++) for (int i = 0; i < this.siegeData.claims.size(); i++)
{ {
//lock the doors //lock the doors
Claim claim = this.siegeData.claims.get(i); Claim claim = this.siegeData.claims.get(i);
claim.doorsOpen = false; claim.doorsOpen = false;
//eject bad guys //eject bad guys
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
Collection<Player> onlinePlayers = (Collection<Player>) GriefPrevention.instance.getServer().getOnlinePlayers(); Collection<Player> onlinePlayers = (Collection<Player>) GriefPrevention.instance.getServer().getOnlinePlayers();
for (Player player : onlinePlayers) for (Player player : onlinePlayers)
{ {
if (claim.contains(player.getLocation(), false, false) && claim.allowAccess(player) != null) if (claim.contains(player.getLocation(), false, false) && claim.allowAccess(player) != null)
{ {
GriefPrevention.sendMessage(player, TextMode.Err, Messages.SiegeDoorsLockedEjection); GriefPrevention.sendMessage(player, TextMode.Err, Messages.SiegeDoorsLockedEjection);
GriefPrevention.instance.ejectPlayer(player); GriefPrevention.instance.ejectPlayer(player);
} }
} }
} }
} }
} }

View File

@ -1,61 +1,61 @@
/* /*
GriefPrevention Server Plugin for Minecraft GriefPrevention Server Plugin for Minecraft
Copyright (C) 2012 Ryan Hamshire Copyright (C) 2012 Ryan Hamshire
This program is free software: you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or the Free Software Foundation, either version 3 of the License, or
(at your option) any later version. (at your option) any later version.
This program is distributed in the hope that it will be useful, This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details. GNU General Public License for more details.
You should have received a copy of the GNU General Public License You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
package me.ryanhamshire.GriefPrevention; package me.ryanhamshire.GriefPrevention;
import org.bukkit.ChatColor; import org.bukkit.ChatColor;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
//sends a message to a player //sends a message to a player
//used to send delayed messages, for example help text triggered by a player's chat //used to send delayed messages, for example help text triggered by a player's chat
class SendPlayerMessageTask implements Runnable class SendPlayerMessageTask implements Runnable
{ {
private Player player; private Player player;
private ChatColor color; private ChatColor color;
private String message; private String message;
public SendPlayerMessageTask(Player player, ChatColor color, String message) public SendPlayerMessageTask(Player player, ChatColor color, String message)
{ {
this.player = player; this.player = player;
this.color = color; this.color = color;
this.message = message; this.message = message;
} }
@Override @Override
public void run() public void run()
{ {
if (player == null) if (player == null)
{ {
GriefPrevention.AddLogEntry(color + message); GriefPrevention.AddLogEntry(color + message);
return; return;
} }
//if the player is dead, save it for after his respawn //if the player is dead, save it for after his respawn
if (this.player.isDead()) if (this.player.isDead())
{ {
PlayerData playerData = GriefPrevention.instance.dataStore.getPlayerData(this.player.getUniqueId()); PlayerData playerData = GriefPrevention.instance.dataStore.getPlayerData(this.player.getUniqueId());
playerData.messageOnRespawn = this.color + this.message; playerData.messageOnRespawn = this.color + this.message;
} }
//otherwise send it immediately //otherwise send it immediately
else else
{ {
GriefPrevention.sendMessage(this.player, this.color, this.message); GriefPrevention.sendMessage(this.player, this.color, this.message);
} }
} }
} }

View File

@ -1,30 +1,30 @@
/* /*
GriefPrevention Server Plugin for Minecraft GriefPrevention Server Plugin for Minecraft
Copyright (C) 2012 Ryan Hamshire Copyright (C) 2012 Ryan Hamshire
This program is free software: you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or the Free Software Foundation, either version 3 of the License, or
(at your option) any later version. (at your option) any later version.
This program is distributed in the hope that it will be useful, This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details. GNU General Public License for more details.
You should have received a copy of the GNU General Public License You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
package me.ryanhamshire.GriefPrevention; package me.ryanhamshire.GriefPrevention;
//enumeration for golden shovel modes //enumeration for golden shovel modes
public enum ShovelMode public enum ShovelMode
{ {
Basic, Basic,
Admin, Admin,
Subdivide, Subdivide,
RestoreNature, RestoreNature,
RestoreNatureAggressive, RestoreNatureAggressive,
RestoreNatureFill RestoreNatureFill
} }

View File

@ -1,110 +1,110 @@
/* /*
GriefPrevention Server Plugin for Minecraft GriefPrevention Server Plugin for Minecraft
Copyright (C) 2012 Ryan Hamshire Copyright (C) 2012 Ryan Hamshire
This program is free software: you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or the Free Software Foundation, either version 3 of the License, or
(at your option) any later version. (at your option) any later version.
This program is distributed in the hope that it will be useful, This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details. GNU General Public License for more details.
You should have received a copy of the GNU General Public License You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
package me.ryanhamshire.GriefPrevention; package me.ryanhamshire.GriefPrevention;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
//checks to see whether or not a siege should end based on the locations of the players //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 //for example, defender escaped or attacker gave up and left
class SiegeCheckupTask implements Runnable class SiegeCheckupTask implements Runnable
{ {
private SiegeData siegeData; private SiegeData siegeData;
public SiegeCheckupTask(SiegeData siegeData) public SiegeCheckupTask(SiegeData siegeData)
{ {
this.siegeData = siegeData; this.siegeData = siegeData;
} }
@Override @Override
public void run() public void run()
{ {
DataStore dataStore = GriefPrevention.instance.dataStore; DataStore dataStore = GriefPrevention.instance.dataStore;
Player defender = this.siegeData.defender; Player defender = this.siegeData.defender;
Player attacker = this.siegeData.attacker; Player attacker = this.siegeData.attacker;
//where is the defender? //where is the defender?
Claim defenderClaim = dataStore.getClaimAt(defender.getLocation(), false, null); 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 this is a new claim and he has some permission there, extend the siege to include it
if (defenderClaim != null) if (defenderClaim != null)
{ {
String noAccessReason = defenderClaim.allowAccess(defender); String noAccessReason = defenderClaim.allowAccess(defender);
if (defenderClaim.canSiege(defender) && noAccessReason == null) if (defenderClaim.canSiege(defender) && noAccessReason == null)
{ {
this.siegeData.claims.add(defenderClaim); this.siegeData.claims.add(defenderClaim);
defenderClaim.siegeData = this.siegeData; defenderClaim.siegeData = this.siegeData;
} }
} }
//determine who's close enough to the siege area to be considered "still here" //determine who's close enough to the siege area to be considered "still here"
boolean attackerRemains = this.playerRemains(attacker); boolean attackerRemains = this.playerRemains(attacker);
boolean defenderRemains = this.playerRemains(defender); boolean defenderRemains = this.playerRemains(defender);
//if they're both here, just plan to come check again later //if they're both here, just plan to come check again later
if (attackerRemains && defenderRemains) if (attackerRemains && defenderRemains)
{ {
this.scheduleAnotherCheck(); this.scheduleAnotherCheck();
} }
//otherwise attacker wins if the defender runs away //otherwise attacker wins if the defender runs away
else if (attackerRemains && !defenderRemains) else if (attackerRemains && !defenderRemains)
{ {
dataStore.endSiege(this.siegeData, attacker.getName(), defender.getName(), null); dataStore.endSiege(this.siegeData, attacker.getName(), defender.getName(), null);
} }
//or defender wins if the attacker leaves //or defender wins if the attacker leaves
else if (!attackerRemains && defenderRemains) else if (!attackerRemains && defenderRemains)
{ {
dataStore.endSiege(this.siegeData, defender.getName(), attacker.getName(), null); dataStore.endSiege(this.siegeData, defender.getName(), attacker.getName(), null);
} }
//if they both left, but are still close together, the battle continues (check again later) //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 else if (attacker.getWorld().equals(defender.getWorld()) && attacker.getLocation().distanceSquared(defender.getLocation()) < 2500) //50-block radius for chasing
{ {
this.scheduleAnotherCheck(); 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) //otherwise they both left and aren't close to each other, so call the attacker the winner (defender escaped, possibly after a chase)
else else
{ {
dataStore.endSiege(this.siegeData, attacker.getName(), defender.getName(), null); 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 //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) private boolean playerRemains(Player player)
{ {
for (int i = 0; i < this.siegeData.claims.size(); i++) for (int i = 0; i < this.siegeData.claims.size(); i++)
{ {
Claim claim = this.siegeData.claims.get(i); Claim claim = this.siegeData.claims.get(i);
if (claim.isNear(player.getLocation(), 25)) if (claim.isNear(player.getLocation(), 25))
{ {
return true; return true;
} }
} }
return false; return false;
} }
//schedules another checkup later //schedules another checkup later
private void scheduleAnotherCheck() private void scheduleAnotherCheck()
{ {
this.siegeData.checkupTaskID = GriefPrevention.instance.getServer().getScheduler().scheduleSyncDelayedTask(GriefPrevention.instance, this, 20L * 30); this.siegeData.checkupTaskID = GriefPrevention.instance.getServer().getScheduler().scheduleSyncDelayedTask(GriefPrevention.instance, this, 20L * 30);
} }
} }

View File

@ -1,40 +1,40 @@
/* /*
GriefPrevention Server Plugin for Minecraft GriefPrevention Server Plugin for Minecraft
Copyright (C) 2012 Ryan Hamshire Copyright (C) 2012 Ryan Hamshire
This program is free software: you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or the Free Software Foundation, either version 3 of the License, or
(at your option) any later version. (at your option) any later version.
This program is distributed in the hope that it will be useful, This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details. GNU General Public License for more details.
You should have received a copy of the GNU General Public License You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
package me.ryanhamshire.GriefPrevention; package me.ryanhamshire.GriefPrevention;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import java.util.ArrayList; import java.util.ArrayList;
//information about an ongoing siege //information about an ongoing siege
public class SiegeData public class SiegeData
{ {
public Player defender; public Player defender;
public Player attacker; public Player attacker;
public ArrayList<Claim> claims; public ArrayList<Claim> claims;
public int checkupTaskID; public int checkupTaskID;
public SiegeData(Player attacker, Player defender, Claim claim) public SiegeData(Player attacker, Player defender, Claim claim)
{ {
this.defender = defender; this.defender = defender;
this.attacker = attacker; this.attacker = attacker;
this.claims = new ArrayList<Claim>(); this.claims = new ArrayList<Claim>();
this.claims.add(claim); this.claims.add(claim);
} }
} }

View File

@ -1,342 +1,342 @@
/* /*
GriefPrevention Server Plugin for Minecraft GriefPrevention Server Plugin for Minecraft
Copyright (C) 2012 Ryan Hamshire Copyright (C) 2012 Ryan Hamshire
This program is free software: you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or the Free Software Foundation, either version 3 of the License, or
(at your option) any later version. (at your option) any later version.
This program is distributed in the hope that it will be useful, This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details. GNU General Public License for more details.
You should have received a copy of the GNU General Public License You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
package me.ryanhamshire.GriefPrevention; package me.ryanhamshire.GriefPrevention;
import org.bukkit.Location; import org.bukkit.Location;
import org.bukkit.Material; import org.bukkit.Material;
import org.bukkit.Tag; import org.bukkit.Tag;
import org.bukkit.World; import org.bukkit.World;
import org.bukkit.block.Block; import org.bukkit.block.Block;
import org.bukkit.block.BlockFace; import org.bukkit.block.BlockFace;
import org.bukkit.block.data.BlockData; import org.bukkit.block.data.BlockData;
import org.bukkit.block.data.Lightable; import org.bukkit.block.data.Lightable;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.util.BoundingBox; import org.bukkit.util.BoundingBox;
import org.bukkit.util.Vector; import org.bukkit.util.Vector;
import java.util.ArrayList; import java.util.ArrayList;
//represents a visualization sent to a player //represents a visualization sent to a player
//FEATURE: to show players visually where claim boundaries are, we send them fake block change packets //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. //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 class Visualization
{ {
public ArrayList<VisualizationElement> elements = new ArrayList<VisualizationElement>(); public ArrayList<VisualizationElement> elements = new ArrayList<VisualizationElement>();
//sends a visualization to a player //sends a visualization to a player
public static void Apply(Player player, Visualization visualization) public static void Apply(Player player, Visualization visualization)
{ {
PlayerData playerData = GriefPrevention.instance.dataStore.getPlayerData(player.getUniqueId()); PlayerData playerData = GriefPrevention.instance.dataStore.getPlayerData(player.getUniqueId());
//if he has any current visualization, clear it first //if he has any current visualization, clear it first
if (playerData.currentVisualization != null) if (playerData.currentVisualization != null)
{ {
Visualization.Revert(player); Visualization.Revert(player);
} }
//if he's online, create a task to send him the visualization //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())) 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); 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 //reverts a visualization by sending another block change list, this time with the real world block values
public static void Revert(Player player) public static void Revert(Player player)
{ {
if (!player.isOnline()) return; if (!player.isOnline()) return;
PlayerData playerData = GriefPrevention.instance.dataStore.getPlayerData(player.getUniqueId()); PlayerData playerData = GriefPrevention.instance.dataStore.getPlayerData(player.getUniqueId());
Visualization visualization = playerData.currentVisualization; Visualization visualization = playerData.currentVisualization;
if (playerData.currentVisualization != null) if (playerData.currentVisualization != null)
{ {
//locality //locality
int minx = player.getLocation().getBlockX() - 100; int minx = player.getLocation().getBlockX() - 100;
int minz = player.getLocation().getBlockZ() - 100; int minz = player.getLocation().getBlockZ() - 100;
int maxx = player.getLocation().getBlockX() + 100; int maxx = player.getLocation().getBlockX() + 100;
int maxz = player.getLocation().getBlockZ() + 100; int maxz = player.getLocation().getBlockZ() + 100;
//remove any elements which are too far away //remove any elements which are too far away
visualization.removeElementsOutOfRange(visualization.elements, minx, minz, maxx, maxz); visualization.removeElementsOutOfRange(visualization.elements, minx, minz, maxx, maxz);
//send real block information for any remaining elements //send real block information for any remaining elements
for (int i = 0; i < visualization.elements.size(); i++) for (int i = 0; i < visualization.elements.size(); i++)
{ {
VisualizationElement element = visualization.elements.get(i); VisualizationElement element = visualization.elements.get(i);
//check player still in world where visualization exists //check player still in world where visualization exists
if (i == 0) if (i == 0)
{ {
if (!player.getWorld().equals(element.location.getWorld())) return; if (!player.getWorld().equals(element.location.getWorld())) return;
} }
player.sendBlockChange(element.location, element.realBlock); player.sendBlockChange(element.location, element.realBlock);
} }
playerData.currentVisualization = null; playerData.currentVisualization = null;
} }
} }
//convenience method to build a visualization from a claim //convenience method to build a visualization from a claim
//visualizationType determines the style (gold blocks, silver, red, diamond, etc) //visualizationType determines the style (gold blocks, silver, red, diamond, etc)
public static Visualization FromClaim(Claim claim, int height, VisualizationType visualizationType, Location locality) public static Visualization FromClaim(Claim claim, int height, VisualizationType visualizationType, Location locality)
{ {
//visualize only top level claims //visualize only top level claims
if (claim.parent != null) if (claim.parent != null)
{ {
return FromClaim(claim.parent, height, visualizationType, locality); return FromClaim(claim.parent, height, visualizationType, locality);
} }
Visualization visualization = new Visualization(); Visualization visualization = new Visualization();
//add subdivisions first //add subdivisions first
for (int i = 0; i < claim.children.size(); i++) for (int i = 0; i < claim.children.size(); i++)
{ {
Claim child = claim.children.get(i); Claim child = claim.children.get(i);
if (!child.inDataStore) continue; if (!child.inDataStore) continue;
visualization.addClaimElements(child, height, VisualizationType.Subdivision, locality); visualization.addClaimElements(child, height, VisualizationType.Subdivision, locality);
} }
//special visualization for administrative land claims //special visualization for administrative land claims
if (claim.isAdminClaim() && visualizationType == VisualizationType.Claim) if (claim.isAdminClaim() && visualizationType == VisualizationType.Claim)
{ {
visualizationType = VisualizationType.AdminClaim; 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) //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); visualization.addClaimElements(claim, height, visualizationType, locality);
return visualization; return visualization;
} }
//adds a claim's visualization to the current 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 //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 //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) public void addClaimElements(Claim claim, int height, VisualizationType visualizationType, Location locality)
{ {
BlockData cornerBlockData; BlockData cornerBlockData;
BlockData accentBlockData; BlockData accentBlockData;
if (visualizationType == VisualizationType.Claim) if (visualizationType == VisualizationType.Claim)
{ {
cornerBlockData = Material.GLOWSTONE.createBlockData(); cornerBlockData = Material.GLOWSTONE.createBlockData();
accentBlockData = Material.GOLD_BLOCK.createBlockData(); accentBlockData = Material.GOLD_BLOCK.createBlockData();
} }
else if (visualizationType == VisualizationType.AdminClaim) else if (visualizationType == VisualizationType.AdminClaim)
{ {
cornerBlockData = Material.GLOWSTONE.createBlockData(); cornerBlockData = Material.GLOWSTONE.createBlockData();
accentBlockData = Material.PUMPKIN.createBlockData(); accentBlockData = Material.PUMPKIN.createBlockData();
} }
else if (visualizationType == VisualizationType.Subdivision) else if (visualizationType == VisualizationType.Subdivision)
{ {
cornerBlockData = Material.IRON_BLOCK.createBlockData(); cornerBlockData = Material.IRON_BLOCK.createBlockData();
accentBlockData = Material.WHITE_WOOL.createBlockData(); accentBlockData = Material.WHITE_WOOL.createBlockData();
} }
else if (visualizationType == VisualizationType.RestoreNature) else if (visualizationType == VisualizationType.RestoreNature)
{ {
cornerBlockData = Material.DIAMOND_BLOCK.createBlockData(); cornerBlockData = Material.DIAMOND_BLOCK.createBlockData();
accentBlockData = Material.DIAMOND_BLOCK.createBlockData(); accentBlockData = Material.DIAMOND_BLOCK.createBlockData();
} }
else else
{ {
cornerBlockData = Material.REDSTONE_ORE.createBlockData(); cornerBlockData = Material.REDSTONE_ORE.createBlockData();
((Lightable) cornerBlockData).setLit(true); ((Lightable) cornerBlockData).setLit(true);
accentBlockData = Material.NETHERRACK.createBlockData(); accentBlockData = Material.NETHERRACK.createBlockData();
} }
addClaimElements(claim.getLesserBoundaryCorner(), claim.getGreaterBoundaryCorner(), locality, height, cornerBlockData, accentBlockData, 10); 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 //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) { public void addClaimElements(Location min, Location max, Location locality, int height, BlockData cornerBlockData, BlockData accentBlockData, int STEP) {
World world = min.getWorld(); World world = min.getWorld();
boolean waterIsTransparent = locality.getBlock().getType() == Material.WATER; boolean waterIsTransparent = locality.getBlock().getType() == Material.WATER;
int smallx = min.getBlockX(); int smallx = min.getBlockX();
int smallz = min.getBlockZ(); int smallz = min.getBlockZ();
int bigx = max.getBlockX(); int bigx = max.getBlockX();
int bigz = max.getBlockZ(); int bigz = max.getBlockZ();
ArrayList<VisualizationElement> newElements = new ArrayList<>(); ArrayList<VisualizationElement> newElements = new ArrayList<>();
//initialize visualization elements without Y values and real data //initialize visualization elements without Y values and real data
//that will be added later for only the visualization elements within visualization range //that will be added later for only the visualization elements within visualization range
//locality //locality
int minx = locality.getBlockX() - 75; int minx = locality.getBlockX() - 75;
int minz = locality.getBlockZ() - 75; int minz = locality.getBlockZ() - 75;
int maxx = locality.getBlockX() + 75; int maxx = locality.getBlockX() + 75;
int maxz = locality.getBlockZ() + 75; int maxz = locality.getBlockZ() + 75;
//top line //top line
newElements.add(new VisualizationElement(new Location(world, smallx, 0, bigz), cornerBlockData, Material.AIR.createBlockData())); 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())); 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) for (int x = smallx + STEP; x < bigx - STEP / 2; x += STEP)
{ {
if (x > minx && x < maxx) 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, x, 0, bigz), accentBlockData, Material.AIR.createBlockData()));
} }
newElements.add(new VisualizationElement(new Location(world, bigx - 1, 0, bigz), accentBlockData, Material.AIR.createBlockData())); newElements.add(new VisualizationElement(new Location(world, bigx - 1, 0, bigz), accentBlockData, Material.AIR.createBlockData()));
//bottom line //bottom line
newElements.add(new VisualizationElement(new Location(world, smallx + 1, 0, smallz), accentBlockData, Material.AIR.createBlockData())); 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) for (int x = smallx + STEP; x < bigx - STEP / 2; x += STEP)
{ {
if (x > minx && x < maxx) 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, x, 0, smallz), accentBlockData, Material.AIR.createBlockData()));
} }
newElements.add(new VisualizationElement(new Location(world, bigx - 1, 0, smallz), accentBlockData, Material.AIR.createBlockData())); newElements.add(new VisualizationElement(new Location(world, bigx - 1, 0, smallz), accentBlockData, Material.AIR.createBlockData()));
//left line //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), cornerBlockData, Material.AIR.createBlockData()));
newElements.add(new VisualizationElement(new Location(world, smallx, 0, smallz + 1), accentBlockData, 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) for (int z = smallz + STEP; z < bigz - STEP / 2; z += STEP)
{ {
if (z > minz && z < maxz) 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, z), accentBlockData, Material.AIR.createBlockData()));
} }
newElements.add(new VisualizationElement(new Location(world, smallx, 0, bigz - 1), accentBlockData, Material.AIR.createBlockData())); newElements.add(new VisualizationElement(new Location(world, smallx, 0, bigz - 1), accentBlockData, Material.AIR.createBlockData()));
//right line //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), cornerBlockData, Material.AIR.createBlockData()));
newElements.add(new VisualizationElement(new Location(world, bigx, 0, smallz + 1), accentBlockData, 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) for (int z = smallz + STEP; z < bigz - STEP / 2; z += STEP)
{ {
if (z > minz && z < maxz) 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, 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 - 1), accentBlockData, Material.AIR.createBlockData()));
newElements.add(new VisualizationElement(new Location(world, bigx, 0, bigz), cornerBlockData, Material.AIR.createBlockData())); newElements.add(new VisualizationElement(new Location(world, bigx, 0, bigz), cornerBlockData, Material.AIR.createBlockData()));
//remove any out of range elements //remove any out of range elements
this.removeElementsOutOfRange(newElements, minx, minz, maxx, maxz); this.removeElementsOutOfRange(newElements, minx, minz, maxx, maxz);
//remove any elements outside the claim //remove any elements outside the claim
BoundingBox box = BoundingBox.of(min, max); BoundingBox box = BoundingBox.of(min, max);
for (int i = 0; i < newElements.size(); i++) for (int i = 0; i < newElements.size(); i++)
{ {
VisualizationElement element = newElements.get(i); VisualizationElement element = newElements.get(i);
if (!containsIncludingIgnoringHeight(box, element.location.toVector())) if (!containsIncludingIgnoringHeight(box, element.location.toVector()))
{ {
newElements.remove(i--); newElements.remove(i--);
} }
} }
//set Y values and real block information for any remaining visualization blocks //set Y values and real block information for any remaining visualization blocks
for (VisualizationElement element : newElements) for (VisualizationElement element : newElements)
{ {
Location tempLocation = element.location; Location tempLocation = element.location;
element.location = getVisibleLocation(tempLocation.getWorld(), tempLocation.getBlockX(), height, tempLocation.getBlockZ(), waterIsTransparent); element.location = getVisibleLocation(tempLocation.getWorld(), tempLocation.getBlockX(), height, tempLocation.getBlockZ(), waterIsTransparent);
height = element.location.getBlockY(); height = element.location.getBlockY();
element.realBlock = element.location.getBlock().getBlockData(); element.realBlock = element.location.getBlock().getBlockData();
} }
this.elements.addAll(newElements); this.elements.addAll(newElements);
} }
private boolean containsIncludingIgnoringHeight(BoundingBox box, Vector vector) { private boolean containsIncludingIgnoringHeight(BoundingBox box, Vector vector) {
return vector.getBlockX() >= box.getMinX() return vector.getBlockX() >= box.getMinX()
&& vector.getBlockX() <= box.getMaxX() && vector.getBlockX() <= box.getMaxX()
&& vector.getBlockZ() >= box.getMinZ() && vector.getBlockZ() >= box.getMinZ()
&& vector.getBlockZ() <= box.getMaxZ(); && vector.getBlockZ() <= box.getMaxZ();
} }
//removes any elements which are out of visualization range //removes any elements which are out of visualization range
private void removeElementsOutOfRange(ArrayList<VisualizationElement> elements, int minx, int minz, int maxx, int maxz) private void removeElementsOutOfRange(ArrayList<VisualizationElement> elements, int minx, int minz, int maxx, int maxz)
{ {
for (int i = 0; i < elements.size(); i++) for (int i = 0; i < elements.size(); i++)
{ {
Location location = elements.get(i).location; Location location = elements.get(i).location;
if (location.getX() < minx || location.getX() > maxx || location.getZ() < minz || location.getZ() > maxz) if (location.getX() < minx || location.getX() > maxx || location.getZ() < minz || location.getZ() > maxz)
{ {
elements.remove(i--); elements.remove(i--);
} }
} }
} }
//finds a block the player can probably see. this is how visualizations "cling" to the ground or ceiling //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) private static Location getVisibleLocation(World world, int x, int y, int z, boolean waterIsTransparent)
{ {
Block block = world.getBlockAt(x, y, z); Block block = world.getBlockAt(x, y, z);
BlockFace direction = (isTransparent(block, waterIsTransparent)) ? BlockFace.DOWN : BlockFace.UP; BlockFace direction = (isTransparent(block, waterIsTransparent)) ? BlockFace.DOWN : BlockFace.UP;
while (block.getY() >= 1 && while (block.getY() >= 1 &&
block.getY() < world.getMaxHeight() - 1 && block.getY() < world.getMaxHeight() - 1 &&
(!isTransparent(block.getRelative(BlockFace.UP), waterIsTransparent) || isTransparent(block, waterIsTransparent))) (!isTransparent(block.getRelative(BlockFace.UP), waterIsTransparent) || isTransparent(block, waterIsTransparent)))
{ {
block = block.getRelative(direction); block = block.getRelative(direction);
} }
return block.getLocation(); return block.getLocation();
} }
//helper method for above. allows visualization blocks to sit underneath partly transparent blocks like grass and fence //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) private static boolean isTransparent(Block block, boolean waterIsTransparent)
{ {
Material blockMaterial = block.getType(); Material blockMaterial = block.getType();
//Blacklist //Blacklist
switch (blockMaterial) switch (blockMaterial)
{ {
case SNOW: case SNOW:
return false; return false;
} }
//Whitelist TODO: some of this might already be included in isTransparent() //Whitelist TODO: some of this might already be included in isTransparent()
switch (blockMaterial) switch (blockMaterial)
{ {
case AIR: case AIR:
case OAK_FENCE: case OAK_FENCE:
case ACACIA_FENCE: case ACACIA_FENCE:
case BIRCH_FENCE: case BIRCH_FENCE:
case DARK_OAK_FENCE: case DARK_OAK_FENCE:
case JUNGLE_FENCE: case JUNGLE_FENCE:
case NETHER_BRICK_FENCE: case NETHER_BRICK_FENCE:
case SPRUCE_FENCE: case SPRUCE_FENCE:
case OAK_FENCE_GATE: case OAK_FENCE_GATE:
case ACACIA_FENCE_GATE: case ACACIA_FENCE_GATE:
case BIRCH_FENCE_GATE: case BIRCH_FENCE_GATE:
case DARK_OAK_FENCE_GATE: case DARK_OAK_FENCE_GATE:
case SPRUCE_FENCE_GATE: case SPRUCE_FENCE_GATE:
case JUNGLE_FENCE_GATE: case JUNGLE_FENCE_GATE:
return true; return true;
} }
if (Tag.SIGNS.isTagged(blockMaterial) || Tag.WALL_SIGNS.isTagged(blockMaterial)) if (Tag.SIGNS.isTagged(blockMaterial) || Tag.WALL_SIGNS.isTagged(blockMaterial))
return true; return true;
return (waterIsTransparent && block.getType() == Material.WATER) || return (waterIsTransparent && block.getType() == Material.WATER) ||
block.getType().isTransparent(); block.getType().isTransparent();
} }
public static Visualization fromClaims(Iterable<Claim> claims, int height, VisualizationType type, Location locality) public static Visualization fromClaims(Iterable<Claim> claims, int height, VisualizationType type, Location locality)
{ {
Visualization visualization = new Visualization(); Visualization visualization = new Visualization();
for (Claim claim : claims) for (Claim claim : claims)
{ {
visualization.addClaimElements(claim, height, type, locality); visualization.addClaimElements(claim, height, type, locality);
} }
return visualization; return visualization;
} }
} }

View File

@ -1,60 +1,60 @@
/* /*
GriefPrevention Server Plugin for Minecraft GriefPrevention Server Plugin for Minecraft
Copyright (C) 2012 Ryan Hamshire Copyright (C) 2012 Ryan Hamshire
This program is free software: you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or the Free Software Foundation, either version 3 of the License, or
(at your option) any later version. (at your option) any later version.
This program is distributed in the hope that it will be useful, This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details. GNU General Public License for more details.
You should have received a copy of the GNU General Public License You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
package me.ryanhamshire.GriefPrevention; package me.ryanhamshire.GriefPrevention;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
//applies a visualization for a player by sending him block change packets //applies a visualization for a player by sending him block change packets
class VisualizationApplicationTask implements Runnable class VisualizationApplicationTask implements Runnable
{ {
private Visualization visualization; private Visualization visualization;
private Player player; private Player player;
private PlayerData playerData; private PlayerData playerData;
public VisualizationApplicationTask(Player player, PlayerData playerData, Visualization visualization) public VisualizationApplicationTask(Player player, PlayerData playerData, Visualization visualization)
{ {
this.visualization = visualization; this.visualization = visualization;
this.playerData = playerData; this.playerData = playerData;
this.player = player; this.player = player;
} }
@Override @Override
public void run() public void run()
{ {
//for each element (=block) of the visualization //for each element (=block) of the visualization
for (int i = 0; i < visualization.elements.size(); i++) for (int i = 0; i < visualization.elements.size(); i++)
{ {
VisualizationElement element = visualization.elements.get(i); VisualizationElement element = visualization.elements.get(i);
//send the player a fake block change event //send the player a fake block change event
if (!element.location.getChunk().isLoaded()) continue; //cheap distance check if (!element.location.getChunk().isLoaded()) continue; //cheap distance check
player.sendBlockChange(element.location, element.visualizedBlock); player.sendBlockChange(element.location, element.visualizedBlock);
} }
//remember the visualization applied to this player for later (so it can be inexpensively reverted) //remember the visualization applied to this player for later (so it can be inexpensively reverted)
playerData.currentVisualization = visualization; playerData.currentVisualization = visualization;
//schedule automatic visualization reversion in 60 seconds. //schedule automatic visualization reversion in 60 seconds.
GriefPrevention.instance.getServer().getScheduler().scheduleSyncDelayedTask( GriefPrevention.instance.getServer().getScheduler().scheduleSyncDelayedTask(
GriefPrevention.instance, GriefPrevention.instance,
new VisualizationReversionTask(player, playerData, visualization), new VisualizationReversionTask(player, playerData, visualization),
20L * 60); //60 seconds 20L * 60); //60 seconds
} }
} }

View File

@ -1,37 +1,37 @@
/* /*
GriefPrevention Server Plugin for Minecraft GriefPrevention Server Plugin for Minecraft
Copyright (C) 2012 Ryan Hamshire Copyright (C) 2012 Ryan Hamshire
This program is free software: you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or the Free Software Foundation, either version 3 of the License, or
(at your option) any later version. (at your option) any later version.
This program is distributed in the hope that it will be useful, This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details. GNU General Public License for more details.
You should have received a copy of the GNU General Public License You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
package me.ryanhamshire.GriefPrevention; package me.ryanhamshire.GriefPrevention;
import org.bukkit.Location; import org.bukkit.Location;
import org.bukkit.block.data.BlockData; import org.bukkit.block.data.BlockData;
//represents a "fake" block sent to a player as part of a visualization //represents a "fake" block sent to a player as part of a visualization
public class VisualizationElement public class VisualizationElement
{ {
public Location location; public Location location;
public BlockData visualizedBlock; public BlockData visualizedBlock;
public BlockData realBlock; public BlockData realBlock;
public VisualizationElement(Location location, BlockData visualizedBlock, BlockData realBlock) public VisualizationElement(Location location, BlockData visualizedBlock, BlockData realBlock)
{ {
this.location = location; this.location = location;
this.visualizedBlock = visualizedBlock; this.visualizedBlock = visualizedBlock;
this.realBlock = realBlock; this.realBlock = realBlock;
} }
} }

View File

@ -1,29 +1,29 @@
/* /*
GriefPrevention Server Plugin for Minecraft GriefPrevention Server Plugin for Minecraft
Copyright (C) 2012 Ryan Hamshire Copyright (C) 2012 Ryan Hamshire
This program is free software: you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or the Free Software Foundation, either version 3 of the License, or
(at your option) any later version. (at your option) any later version.
This program is distributed in the hope that it will be useful, This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details. GNU General Public License for more details.
You should have received a copy of the GNU General Public License You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
package me.ryanhamshire.GriefPrevention; package me.ryanhamshire.GriefPrevention;
//just an enumeration of the visualization types, which determine what materials will be for the fake blocks //just an enumeration of the visualization types, which determine what materials will be for the fake blocks
public enum VisualizationType public enum VisualizationType
{ {
Claim, Claim,
Subdivision, Subdivision,
ErrorClaim, ErrorClaim,
RestoreNature, RestoreNature,
AdminClaim AdminClaim
} }