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