remove sieges

This commit is contained in:
destro174 2022-02-19 20:07:28 +01:00
parent 998bf5201c
commit 537803028b
12 changed files with 2 additions and 853 deletions

View File

@ -299,7 +299,7 @@ public class BlockEventHandler implements Listener
playerData.lastClaim = claim; playerData.lastClaim = claim;
//warn about TNT not destroying claimed blocks //warn about TNT not destroying claimed blocks
if (block.getType() == Material.TNT && !claim.areExplosivesAllowed && playerData.siegeData == null) if (block.getType() == Material.TNT && !claim.areExplosivesAllowed)
{ {
GriefPrevention.sendMessage(player, TextMode.Warn, Messages.NoTNTDamageClaims); GriefPrevention.sendMessage(player, TextMode.Warn, Messages.NoTNTDamageClaims);
GriefPrevention.sendMessage(player, TextMode.Instr, Messages.ClaimExplosivesAdvertisement); GriefPrevention.sendMessage(player, TextMode.Instr, Messages.ClaimExplosivesAdvertisement);
@ -455,8 +455,7 @@ public class BlockEventHandler implements Listener
if (GriefPrevention.instance.config_blockSurfaceOtherExplosions && block.getType() == Material.TNT && if (GriefPrevention.instance.config_blockSurfaceOtherExplosions && block.getType() == Material.TNT &&
block.getWorld().getEnvironment() != Environment.NETHER && block.getWorld().getEnvironment() != Environment.NETHER &&
block.getY() > GriefPrevention.instance.getSeaLevel(block.getWorld()) - 5 && block.getY() > GriefPrevention.instance.getSeaLevel(block.getWorld()) - 5 &&
claim == null && claim == null)
playerData.siegeData == null)
{ {
GriefPrevention.sendMessage(player, TextMode.Warn, Messages.NoTNTDamageAboveSeaLevel); GriefPrevention.sendMessage(player, TextMode.Warn, Messages.NoTNTDamageAboveSeaLevel);
} }

View File

@ -93,9 +93,6 @@ public class Claim
//note subdivisions themselves never have children //note subdivisions themselves never have children
public ArrayList<Claim> children = new ArrayList<>(); public ArrayList<Claim> children = new ArrayList<>();
//information about a siege involving this claim. null means no siege is impacting this claim
public SiegeData siegeData = null;
//following a siege, buttons/levers are unlocked temporarily. this represents that state //following a siege, buttons/levers are unlocked temporarily. this represents that state
public boolean doorsOpen = false; public boolean doorsOpen = false;
@ -272,7 +269,6 @@ public class Claim
this.parent = claim.parent; this.parent = claim.parent;
this.inheritNothing = claim.inheritNothing; this.inheritNothing = claim.inheritNothing;
this.children = new ArrayList<>(claim.children); this.children = new ArrayList<>(claim.children);
this.siegeData = claim.siegeData;
this.doorsOpen = claim.doorsOpen; this.doorsOpen = claim.doorsOpen;
} }

View File

@ -1126,222 +1126,6 @@ public abstract class DataStore
}); });
} }
//starts a siege on a claim
//does NOT check siege cooldowns, see onCooldown() below
synchronized public void startSiege(Player attacker, Player defender, Claim defenderClaim)
{
//fill-in the necessary SiegeData instance
SiegeData siegeData = new SiegeData(attacker, defender, defenderClaim);
PlayerData attackerData = this.getPlayerData(attacker.getUniqueId());
PlayerData defenderData = this.getPlayerData(defender.getUniqueId());
attackerData.siegeData = siegeData;
defenderData.siegeData = siegeData;
defenderClaim.siegeData = siegeData;
//start a task to monitor the siege
//why isn't this a "repeating" task?
//because depending on the status of the siege at the time the task runs, there may or may not be a reason to run the task again
SiegeCheckupTask task = new SiegeCheckupTask(siegeData);
siegeData.checkupTaskID = GriefPrevention.instance.getServer().getScheduler().scheduleSyncDelayedTask(GriefPrevention.instance, task, 20L * 30);
}
//ends a siege
//either winnerName or loserName can be null, but not both
synchronized public void endSiege(SiegeData siegeData, String winnerName, String loserName, List<ItemStack> drops)
{
boolean grantAccess = false;
//determine winner and loser
if (winnerName == null && loserName != null)
{
if (siegeData.attacker.getName().equals(loserName))
{
winnerName = siegeData.defender.getName();
}
else
{
winnerName = siegeData.attacker.getName();
}
}
else if (winnerName != null && loserName == null)
{
if (siegeData.attacker.getName().equals(winnerName))
{
loserName = siegeData.defender.getName();
}
else
{
loserName = siegeData.attacker.getName();
}
}
//if the attacker won, plan to open the doors for looting
if (siegeData.attacker.getName().equals(winnerName))
{
grantAccess = true;
}
PlayerData attackerData = this.getPlayerData(siegeData.attacker.getUniqueId());
attackerData.siegeData = null;
PlayerData defenderData = this.getPlayerData(siegeData.defender.getUniqueId());
defenderData.siegeData = null;
defenderData.lastSiegeEndTimeStamp = System.currentTimeMillis();
//start a cooldown for this attacker/defender pair
Long now = Calendar.getInstance().getTimeInMillis();
Long cooldownEnd = now + 1000 * 60 * GriefPrevention.instance.config_siege_cooldownEndInMinutes; //one hour from now
this.siegeCooldownRemaining.put(siegeData.attacker.getName() + "_" + siegeData.defender.getName(), cooldownEnd);
//start cooldowns for every attacker/involved claim pair
for (int i = 0; i < siegeData.claims.size(); i++)
{
Claim claim = siegeData.claims.get(i);
claim.siegeData = null;
this.siegeCooldownRemaining.put(siegeData.attacker.getName() + "_" + claim.getOwnerName(), cooldownEnd);
//if doors should be opened for looting, do that now
if (grantAccess)
{
claim.doorsOpen = true;
}
}
//cancel the siege checkup task
GriefPrevention.instance.getServer().getScheduler().cancelTask(siegeData.checkupTaskID);
//notify everyone who won and lost
if (winnerName != null && loserName != null)
{
GriefPrevention.instance.getServer().broadcastMessage(winnerName + " defeated " + loserName + " in siege warfare!");
}
//if the claim should be opened to looting
if (grantAccess)
{
Player winner = GriefPrevention.instance.getServer().getPlayer(winnerName);
if (winner != null)
{
//notify the winner
GriefPrevention.sendMessage(winner, TextMode.Success, Messages.SiegeWinDoorsOpen);
//schedule a task to secure the claims in about 5 minutes
SecureClaimTask task = new SecureClaimTask(siegeData);
GriefPrevention.instance.getServer().getScheduler().scheduleSyncDelayedTask(
GriefPrevention.instance, task, 20L * GriefPrevention.instance.config_siege_doorsOpenSeconds
);
}
}
//if the siege ended due to death, transfer inventory to winner
if (drops != null)
{
Player winner = GriefPrevention.instance.getServer().getPlayer(winnerName);
Player loser = GriefPrevention.instance.getServer().getPlayer(loserName);
if (winner != null && loser != null)
{
//try to add any drops to the winner's inventory
for (ItemStack stack : drops)
{
if (stack == null || stack.getType() == Material.AIR || stack.getAmount() == 0) continue;
HashMap<Integer, ItemStack> wontFitItems = winner.getInventory().addItem(stack);
//drop any remainder on the ground at his feet
Object[] keys = wontFitItems.keySet().toArray();
Location winnerLocation = winner.getLocation();
for (Map.Entry<Integer, ItemStack> wontFitItem : wontFitItems.entrySet())
{
winner.getWorld().dropItemNaturally(winnerLocation, wontFitItem.getValue());
}
}
drops.clear();
}
}
}
//timestamp for each siege cooldown to end
private final HashMap<String, Long> siegeCooldownRemaining = new HashMap<>();
//whether or not a sieger can siege a particular victim or claim, considering only cooldowns
synchronized public boolean onCooldown(Player attacker, Player defender, Claim defenderClaim)
{
Long cooldownEnd = null;
//look for an attacker/defender cooldown
if (this.siegeCooldownRemaining.get(attacker.getName() + "_" + defender.getName()) != null)
{
cooldownEnd = this.siegeCooldownRemaining.get(attacker.getName() + "_" + defender.getName());
if (Calendar.getInstance().getTimeInMillis() < cooldownEnd)
{
return true;
}
//if found but expired, remove it
this.siegeCooldownRemaining.remove(attacker.getName() + "_" + defender.getName());
}
//look for genderal defender cooldown
PlayerData defenderData = this.getPlayerData(defender.getUniqueId());
if (defenderData.lastSiegeEndTimeStamp > 0)
{
long now = System.currentTimeMillis();
if (now - defenderData.lastSiegeEndTimeStamp > 1000 * 60 * 15) //15 minutes in milliseconds
{
return true;
}
}
//look for an attacker/claim cooldown
if (cooldownEnd == null && this.siegeCooldownRemaining.get(attacker.getName() + "_" + defenderClaim.getOwnerName()) != null)
{
cooldownEnd = this.siegeCooldownRemaining.get(attacker.getName() + "_" + defenderClaim.getOwnerName());
if (Calendar.getInstance().getTimeInMillis() < cooldownEnd)
{
return true;
}
//if found but expired, remove it
this.siegeCooldownRemaining.remove(attacker.getName() + "_" + defenderClaim.getOwnerName());
}
return false;
}
//extend a siege, if it's possible to do so
synchronized void tryExtendSiege(Player player, Claim claim)
{
PlayerData playerData = this.getPlayerData(player.getUniqueId());
//player must be sieged
if (playerData.siegeData == null) return;
//claim isn't already under the same siege
if (playerData.siegeData.claims.contains(claim)) return;
//admin claims can't be sieged
if (claim.isAdminClaim()) return;
//player must have some level of permission to be sieged in a claim
Claim currentClaim = claim;
while (!currentClaim.hasExplicitPermission(player, ClaimPermission.Access))
{
if (currentClaim.parent == null) return;
currentClaim = currentClaim.parent;
}
//otherwise extend the siege
playerData.siegeData.claims.add(claim);
claim.siegeData = playerData.siegeData;
}
//deletes all claims owned by a player //deletes all claims owned by a player
synchronized public void deleteClaimsForPlayer(UUID playerID, boolean releasePets) synchronized public void deleteClaimsForPlayer(UUID playerID, boolean releasePets)
{ {

View File

@ -436,15 +436,6 @@ public class EntityEventHandler implements Listener
continue; continue;
} }
//if claim is under siege, allow soft blocks to be destroyed
if (claim != null && claim.siegeData != null)
{
Material material = block.getType();
boolean breakable = GriefPrevention.instance.config_siege_blocks.contains(material);
if (breakable) continue;
}
//if no, then also consider surface rules //if no, then also consider surface rules
if (claim == null) if (claim == null)
{ {
@ -573,13 +564,6 @@ public class EntityEventHandler implements Listener
Player player = (Player) entity; Player player = (Player) entity;
PlayerData playerData = this.dataStore.getPlayerData(player.getUniqueId()); PlayerData playerData = this.dataStore.getPlayerData(player.getUniqueId());
//if involved in a siege
if (playerData.siegeData != null)
{
//end it, with the dieing player being the loser
this.dataStore.endSiege(playerData.siegeData, null, player.getName(), event.getDrops());
}
//FEATURE: lock dropped items to player who dropped them //FEATURE: lock dropped items to player who dropped them
World world = entity.getWorld(); World world = entity.getWorld();

View File

@ -156,7 +156,6 @@ public class GriefPrevention extends JavaPlugin
public boolean config_claims_lecternReadingRequiresAccessTrust; //reading lecterns requires access trust public boolean config_claims_lecternReadingRequiresAccessTrust; //reading lecterns requires access trust
public ArrayList<World> config_siege_enabledWorlds; //whether or not /siege is enabled on this server public ArrayList<World> config_siege_enabledWorlds; //whether or not /siege is enabled on this server
public Set<Material> config_siege_blocks; //which blocks will be breakable in siege mode
public int config_siege_doorsOpenSeconds; // how before claim is re-secured after siege win public int config_siege_doorsOpenSeconds; // how before claim is re-secured after siege win
public int config_siege_cooldownEndInMinutes; public int config_siege_cooldownEndInMinutes;
public boolean config_spam_enabled; //whether or not to monitor for spam public boolean config_spam_enabled; //whether or not to monitor for spam
@ -380,10 +379,6 @@ public class GriefPrevention extends JavaPlugin
entityEventHandler = new EntityEventHandler(this.dataStore, this); entityEventHandler = new EntityEventHandler(this.dataStore, this);
pluginManager.registerEvents(entityEventHandler, this); pluginManager.registerEvents(entityEventHandler, this);
//siege events
SiegeEventHandler siegeEventHandler = new SiegeEventHandler();
pluginManager.registerEvents(siegeEventHandler, this);
//vault-based economy integration //vault-based economy integration
economyHandler = new EconomyHandler(this); economyHandler = new EconomyHandler(this);
pluginManager.registerEvents(economyHandler, this); pluginManager.registerEvents(economyHandler, this);
@ -677,85 +672,6 @@ public class GriefPrevention extends JavaPlugin
this.config_claims_modificationTool = Material.GOLDEN_SHOVEL; this.config_claims_modificationTool = Material.GOLDEN_SHOVEL;
} }
//default for siege worlds list
ArrayList<String> defaultSiegeWorldNames = new ArrayList<>();
//get siege world names from the config file
List<String> siegeEnabledWorldNames = config.getStringList("GriefPrevention.Siege.Worlds");
if (siegeEnabledWorldNames == null)
{
siegeEnabledWorldNames = defaultSiegeWorldNames;
}
//validate that list
this.config_siege_enabledWorlds = new ArrayList<>();
for (String worldName : siegeEnabledWorldNames)
{
World world = this.getServer().getWorld(worldName);
if (world == null)
{
AddLogEntry("Error: Siege Configuration: There's no world named \"" + worldName + "\". Please update your config.yml.");
}
else
{
this.config_siege_enabledWorlds.add(world);
}
}
//default siege blocks
this.config_siege_blocks = EnumSet.noneOf(Material.class);
this.config_siege_blocks.add(Material.DIRT);
this.config_siege_blocks.add(Material.GRASS_BLOCK);
this.config_siege_blocks.add(Material.GRASS);
this.config_siege_blocks.add(Material.FERN);
this.config_siege_blocks.add(Material.DEAD_BUSH);
this.config_siege_blocks.add(Material.COBBLESTONE);
this.config_siege_blocks.add(Material.GRAVEL);
this.config_siege_blocks.add(Material.SAND);
this.config_siege_blocks.add(Material.GLASS);
this.config_siege_blocks.add(Material.GLASS_PANE);
this.config_siege_blocks.add(Material.OAK_PLANKS);
this.config_siege_blocks.add(Material.SPRUCE_PLANKS);
this.config_siege_blocks.add(Material.BIRCH_PLANKS);
this.config_siege_blocks.add(Material.JUNGLE_PLANKS);
this.config_siege_blocks.add(Material.ACACIA_PLANKS);
this.config_siege_blocks.add(Material.DARK_OAK_PLANKS);
this.config_siege_blocks.add(Material.WHITE_WOOL);
this.config_siege_blocks.add(Material.ORANGE_WOOL);
this.config_siege_blocks.add(Material.MAGENTA_WOOL);
this.config_siege_blocks.add(Material.LIGHT_BLUE_WOOL);
this.config_siege_blocks.add(Material.YELLOW_WOOL);
this.config_siege_blocks.add(Material.LIME_WOOL);
this.config_siege_blocks.add(Material.PINK_WOOL);
this.config_siege_blocks.add(Material.GRAY_WOOL);
this.config_siege_blocks.add(Material.LIGHT_GRAY_WOOL);
this.config_siege_blocks.add(Material.CYAN_WOOL);
this.config_siege_blocks.add(Material.PURPLE_WOOL);
this.config_siege_blocks.add(Material.BLUE_WOOL);
this.config_siege_blocks.add(Material.BROWN_WOOL);
this.config_siege_blocks.add(Material.GREEN_WOOL);
this.config_siege_blocks.add(Material.RED_WOOL);
this.config_siege_blocks.add(Material.BLACK_WOOL);
this.config_siege_blocks.add(Material.SNOW);
List<String> breakableBlocksList;
//try to load the list from the config file
if (config.isList("GriefPrevention.Siege.BreakableBlocks"))
{
breakableBlocksList = config.getStringList("GriefPrevention.Siege.BreakableBlocks");
//load materials
this.config_siege_blocks = parseMaterialListFromConfig(breakableBlocksList);
}
//if it fails, use default siege block list instead
else
{
breakableBlocksList = this.config_siege_blocks.stream().map(Material::name).collect(Collectors.toList());
}
this.config_siege_doorsOpenSeconds = config.getInt("GriefPrevention.Siege.DoorsOpenDelayInSeconds", 5 * 60);
this.config_siege_cooldownEndInMinutes = config.getInt("GriefPrevention.Siege.CooldownEndInMinutes", 60);
this.config_pvp_noCombatInPlayerLandClaims = config.getBoolean("GriefPrevention.PvP.ProtectPlayersInLandClaims.PlayerOwnedClaims", this.config_siege_enabledWorlds.size() == 0); this.config_pvp_noCombatInPlayerLandClaims = config.getBoolean("GriefPrevention.PvP.ProtectPlayersInLandClaims.PlayerOwnedClaims", this.config_siege_enabledWorlds.size() == 0);
this.config_pvp_noCombatInAdminLandClaims = config.getBoolean("GriefPrevention.PvP.ProtectPlayersInLandClaims.AdministrativeClaims", this.config_siege_enabledWorlds.size() == 0); this.config_pvp_noCombatInAdminLandClaims = config.getBoolean("GriefPrevention.PvP.ProtectPlayersInLandClaims.AdministrativeClaims", this.config_siege_enabledWorlds.size() == 0);
this.config_pvp_noCombatInAdminSubdivisions = config.getBoolean("GriefPrevention.PvP.ProtectPlayersInLandClaims.AdministrativeSubdivisions", this.config_siege_enabledWorlds.size() == 0); this.config_pvp_noCombatInAdminSubdivisions = config.getBoolean("GriefPrevention.PvP.ProtectPlayersInLandClaims.AdministrativeSubdivisions", this.config_siege_enabledWorlds.size() == 0);
@ -894,8 +810,6 @@ public class GriefPrevention extends JavaPlugin
outConfig.set("GriefPrevention.MaxPlayersPerIpAddress", this.config_ipLimit); outConfig.set("GriefPrevention.MaxPlayersPerIpAddress", this.config_ipLimit);
outConfig.set("GriefPrevention.SilenceBans", this.config_silenceBans); outConfig.set("GriefPrevention.SilenceBans", this.config_silenceBans);
outConfig.set("GriefPrevention.Siege.Worlds", siegeEnabledWorldNames);
outConfig.set("GriefPrevention.Siege.BreakableBlocks", breakableBlocksList);
outConfig.set("GriefPrevention.Siege.DoorsOpenDelayInSeconds", this.config_siege_doorsOpenSeconds); outConfig.set("GriefPrevention.Siege.DoorsOpenDelayInSeconds", this.config_siege_doorsOpenSeconds);
outConfig.set("GriefPrevention.Siege.CooldownEndInMinutes", this.config_siege_cooldownEndInMinutes); outConfig.set("GriefPrevention.Siege.CooldownEndInMinutes", this.config_siege_cooldownEndInMinutes);
outConfig.set("GriefPrevention.EndermenMoveBlocks", this.config_endermenMoveBlocks); outConfig.set("GriefPrevention.EndermenMoveBlocks", this.config_endermenMoveBlocks);
@ -2562,140 +2476,6 @@ public class GriefPrevention extends JavaPlugin
return true; return true;
} }
//siege
else if (cmd.getName().equalsIgnoreCase("siege") && player != null)
{
//error message for when siege mode is disabled
if (!this.siegeEnabledForWorld(player.getWorld()))
{
GriefPrevention.sendMessage(player, TextMode.Err, Messages.NonSiegeWorld);
return true;
}
//requires one argument
if (args.length > 1)
{
return false;
}
//can't start a siege when you're already involved in one
Player attacker = player;
PlayerData attackerData = this.dataStore.getPlayerData(attacker.getUniqueId());
if (attackerData.siegeData != null)
{
GriefPrevention.sendMessage(player, TextMode.Err, Messages.AlreadySieging);
return true;
}
//can't start a siege when you're protected from pvp combat
if (attackerData.pvpImmune)
{
GriefPrevention.sendMessage(player, TextMode.Err, Messages.CantFightWhileImmune);
return true;
}
//if a player name was specified, use that
Player defender = null;
if (args.length >= 1)
{
defender = this.getServer().getPlayer(args[0]);
if (defender == null)
{
GriefPrevention.sendMessage(player, TextMode.Err, Messages.PlayerNotFound2);
return true;
}
}
//otherwise use the last player this player was in pvp combat with
else if (attackerData.lastPvpPlayer.length() > 0)
{
defender = this.getServer().getPlayer(attackerData.lastPvpPlayer);
if (defender == null)
{
return false;
}
}
else
{
return false;
}
// First off, you cannot siege yourself, that's just
// silly:
if (attacker.getName().equals(defender.getName()))
{
GriefPrevention.sendMessage(player, TextMode.Err, Messages.NoSiegeYourself);
return true;
}
//victim must not have the permission which makes him immune to siege
if (defender.hasPermission("griefprevention.siegeimmune"))
{
GriefPrevention.sendMessage(player, TextMode.Err, Messages.SiegeImmune);
return true;
}
//victim must not be under siege already
PlayerData defenderData = this.dataStore.getPlayerData(defender.getUniqueId());
if (defenderData.siegeData != null)
{
GriefPrevention.sendMessage(player, TextMode.Err, Messages.AlreadyUnderSiegePlayer);
return true;
}
//victim must not be pvp immune
if (defenderData.pvpImmune)
{
GriefPrevention.sendMessage(player, TextMode.Err, Messages.NoSiegeDefenseless);
return true;
}
Claim defenderClaim = this.dataStore.getClaimAt(defender.getLocation(), false, null);
//defender must have some level of permission there to be protected
if (defenderClaim == null || defenderClaim.checkPermission(defender, ClaimPermission.Access, null) != null)
{
GriefPrevention.sendMessage(player, TextMode.Err, Messages.NotSiegableThere);
return true;
}
//attacker must be close to the claim he wants to siege
if (!defenderClaim.isNear(attacker.getLocation(), 25))
{
GriefPrevention.sendMessage(player, TextMode.Err, Messages.SiegeTooFarAway);
return true;
}
//claim can't be under siege already
if (defenderClaim.siegeData != null)
{
GriefPrevention.sendMessage(player, TextMode.Err, Messages.AlreadyUnderSiegeArea);
return true;
}
//can't siege admin claims
if (defenderClaim.isAdminClaim())
{
GriefPrevention.sendMessage(player, TextMode.Err, Messages.NoSiegeAdminClaim);
return true;
}
//can't be on cooldown
if (dataStore.onCooldown(attacker, defender, defenderClaim))
{
GriefPrevention.sendMessage(player, TextMode.Err, Messages.SiegeOnCooldown);
return true;
}
//start the siege
dataStore.startSiege(attacker, defender, defenderClaim);
//confirmation message for attacker, warning message for defender
GriefPrevention.sendMessage(defender, TextMode.Warn, Messages.SiegeAlert, attacker.getName());
GriefPrevention.sendMessage(player, TextMode.Success, Messages.SiegeConfirmed, defender.getName());
return true;
}
else if (cmd.getName().equalsIgnoreCase("softmute")) else if (cmd.getName().equalsIgnoreCase("softmute"))
{ {
//requires one parameter //requires one parameter
@ -3780,8 +3560,6 @@ public class GriefPrevention extends JavaPlugin
public boolean claimIsPvPSafeZone(Claim claim) public boolean claimIsPvPSafeZone(Claim claim)
{ {
if (claim.siegeData != null)
return false;
return claim.isAdminClaim() && claim.parent == null && GriefPrevention.instance.config_pvp_noCombatInAdminLandClaims || return claim.isAdminClaim() && claim.parent == null && GriefPrevention.instance.config_pvp_noCombatInAdminLandClaims ||
claim.isAdminClaim() && claim.parent != null && GriefPrevention.instance.config_pvp_noCombatInAdminSubdivisions || claim.isAdminClaim() && claim.parent != null && GriefPrevention.instance.config_pvp_noCombatInAdminSubdivisions ||
!claim.isAdminClaim() && GriefPrevention.instance.config_pvp_noCombatInPlayerLandClaims; !claim.isAdminClaim() && GriefPrevention.instance.config_pvp_noCombatInPlayerLandClaims;

View File

@ -70,9 +70,6 @@ public class PlayerData
//whether this player was recently warned about building outside land claims //whether this player was recently warned about building outside land claims
boolean warnedAboutBuildingOutsideClaims = false; boolean warnedAboutBuildingOutsideClaims = false;
//timestamp when last siege ended (where this player was the defender)
long lastSiegeEndTimeStamp = 0;
//whether the player was kicked (set and used during logout) //whether the player was kicked (set and used during logout)
boolean wasKicked = false; boolean wasKicked = false;
@ -89,9 +86,6 @@ public class PlayerData
//the last claim this player was in, that we know of //the last claim this player was in, that we know of
public Claim lastClaim = null; public Claim lastClaim = null;
//siege
public SiegeData siegeData = null;
//pvp //pvp
public long lastPvpTimestamp = 0; public long lastPvpTimestamp = 0;
public String lastPvpPlayer = ""; public String lastPvpPlayer = "";

View File

@ -518,15 +518,6 @@ class PlayerEventHandler implements Listener
player.setHealth(0); player.setHealth(0);
} }
//FEATURE: during a siege, any player who logs out dies and forfeits the siege
//if player was involved in a siege, he forfeits
if (playerData.siegeData != null)
{
if (player.getHealth() > 0)
player.setHealth(0); //might already be zero from above, this avoids a double death message
}
//drop data about this player //drop data about this player
this.dataStore.clearCachedPlayerData(playerID); this.dataStore.clearCachedPlayerData(playerID);
@ -599,13 +590,6 @@ class PlayerEventHandler implements Listener
GriefPrevention.sendMessage(player, TextMode.Err, Messages.PvPNoDrop); GriefPrevention.sendMessage(player, TextMode.Err, Messages.PvPNoDrop);
event.setCancelled(true); event.setCancelled(true);
} }
//if he's under siege, don't let him drop it
else if (playerData.siegeData != null)
{
GriefPrevention.sendMessage(player, TextMode.Err, Messages.SiegeNoDrop);
event.setCancelled(true);
}
} }
//when a player teleports via a portal //when a player teleports via a portal
@ -651,35 +635,6 @@ class PlayerEventHandler implements Listener
} }
} }
} }
//FEATURE: prevent teleport abuse to win sieges
//these rules only apply to siege worlds only
if (!instance.config_siege_enabledWorlds.contains(player.getWorld())) return;
//these rules do not apply to admins
if (player.hasPermission("griefprevention.siegeteleport")) return;
//Ignore vanilla teleports (usually corrective teleports? See issue #210)
if (event.getCause() == TeleportCause.UNKNOWN) return;
Location source = event.getFrom();
Claim sourceClaim = this.dataStore.getClaimAt(source, false, playerData.lastClaim);
if (sourceClaim != null && sourceClaim.siegeData != null)
{
GriefPrevention.sendMessage(player, TextMode.Err, Messages.SiegeNoTeleport);
event.setCancelled(true);
return;
}
Location destination = event.getTo();
Claim destinationClaim = this.dataStore.getClaimAt(destination, false, null);
if (destinationClaim != null && destinationClaim.siegeData != null)
{
GriefPrevention.sendMessage(player, TextMode.Err, Messages.BesiegedNoTeleport);
event.setCancelled(true);
return;
}
} }
//when a player triggers a raid (in a claim) //when a player triggers a raid (in a claim)
@ -817,13 +772,6 @@ class PlayerEventHandler implements Listener
//don't allow container access during pvp combat //don't allow container access during pvp combat
if ((entity instanceof StorageMinecart || entity instanceof PoweredMinecart)) if ((entity instanceof StorageMinecart || entity instanceof PoweredMinecart))
{ {
if (playerData.siegeData != null)
{
GriefPrevention.sendMessage(player, TextMode.Err, Messages.SiegeNoContainers);
event.setCancelled(true);
return;
}
if (playerData.inPvpCombat()) if (playerData.inPvpCombat())
{ {
GriefPrevention.sendMessage(player, TextMode.Err, Messages.PvPNoContainers); GriefPrevention.sendMessage(player, TextMode.Err, Messages.PvPNoContainers);
@ -1321,14 +1269,6 @@ class PlayerEventHandler implements Listener
{ {
if (playerData == null) playerData = this.dataStore.getPlayerData(player.getUniqueId()); if (playerData == null) playerData = this.dataStore.getPlayerData(player.getUniqueId());
//block container use while under siege, so players can't hide items from attackers
if (playerData.siegeData != null)
{
GriefPrevention.sendMessage(player, TextMode.Err, Messages.SiegeNoContainers);
event.setCancelled(true);
return;
}
//block container use during pvp combat, same reason //block container use during pvp combat, same reason
if (playerData.inPvpCombat()) if (playerData.inPvpCombat())
{ {
@ -1725,15 +1665,6 @@ class PlayerEventHandler implements Listener
event.setCancelled(true); //GriefPrevention exclusively reserves this tool (e.g. no grass path creation for golden shovel) event.setCancelled(true); //GriefPrevention exclusively reserves this tool (e.g. no grass path creation for golden shovel)
//disable golden shovel while under siege
if (playerData == null) playerData = this.dataStore.getPlayerData(player.getUniqueId());
if (playerData.siegeData != null)
{
GriefPrevention.sendMessage(player, TextMode.Err, Messages.SiegeNoShovel);
event.setCancelled(true);
return;
}
//FEATURE: shovel and stick can be used from a distance away //FEATURE: shovel and stick can be used from a distance away
if (action == Action.RIGHT_CLICK_AIR) if (action == Action.RIGHT_CLICK_AIR)
{ {

View File

@ -1,58 +0,0 @@
/*
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 final 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.checkPermission(player, ClaimPermission.Access, null) != null)
{
GriefPrevention.sendMessage(player, TextMode.Err, Messages.SiegeDoorsLockedEjection);
GriefPrevention.instance.ejectPlayer(player);
}
}
}
}
}

View File

@ -1,112 +0,0 @@
/*
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.function.Supplier;
//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 final 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)
{
Supplier<String> noAccessReason = defenderClaim.checkPermission(defender, ClaimPermission.Access, null);
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);
}
}

View File

@ -1,40 +0,0 @@
/*
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<>();
this.claims.add(claim);
}
}

View File

@ -1,100 +0,0 @@
package me.ryanhamshire.GriefPrevention;
import me.ryanhamshire.GriefPrevention.events.ClaimPermissionCheckEvent;
import org.bukkit.Material;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import org.bukkit.event.block.Action;
import org.bukkit.event.block.BlockBreakEvent;
import org.bukkit.event.player.PlayerInteractEvent;
public class SiegeEventHandler implements Listener
{
@EventHandler(priority = EventPriority.LOWEST)
public void onClaimPermissionCheck(ClaimPermissionCheckEvent event)
{
if (event.getRequiredPermission() == ClaimPermission.Manage) return;
Player player = event.getCheckedPlayer();
// Player must be online to use siege features.
if (player == null) return;
Claim claim = event.getClaim();
// Admin claims cannot be sieged.
if (claim.isAdminClaim()) return;
// Claim modification during siege is not allowed.
if (event.getRequiredPermission() == ClaimPermission.Edit)
{
if (claim.siegeData != null)
event.setDenialReason(() -> GriefPrevention.instance.dataStore.getMessage(Messages.NoModifyDuringSiege));
return;
}
// Following a siege where the defender lost, the claim will allow everyone access for a time.
if (event.getRequiredPermission() == ClaimPermission.Access)
{
if (claim.doorsOpen)
event.setDenialReason(null);
return;
}
// If under siege, nobody accesses containers.
if (event.getRequiredPermission() == ClaimPermission.Inventory)
{
// Trying to access inventory in a claim may extend an existing siege to include this claim.
GriefPrevention.instance.dataStore.tryExtendSiege(player, claim);
if (claim.siegeData != null)
event.setDenialReason(() -> GriefPrevention.instance.dataStore.getMessage(Messages.NoContainersSiege, claim.siegeData.attacker.getName()));
return;
}
// When a player tries to build in a claim, if he's under siege, the siege may extend to include the new claim.
GriefPrevention.instance.dataStore.tryExtendSiege(player, claim);
// If claim is not under siege and doors are not open, use default behavior.
if (claim.siegeData == null && !claim.doorsOpen)
return;
// If under siege, some blocks will be breakable.
Material broken = null;
if (event.getTriggeringEvent() instanceof BlockBreakEvent)
broken = ((BlockBreakEvent) event.getTriggeringEvent()).getBlock().getType();
else if (event.getTriggeringEvent() instanceof Claim.CompatBuildBreakEvent)
{
Claim.CompatBuildBreakEvent triggeringEvent = (Claim.CompatBuildBreakEvent) event.getTriggeringEvent();
if (triggeringEvent.isBreak())
broken = triggeringEvent.getMaterial();
}
else if (event.getTriggeringEvent() instanceof PlayerInteractEvent)
{
PlayerInteractEvent triggeringEvent = (PlayerInteractEvent) event.getTriggeringEvent();
if (triggeringEvent.getAction() == Action.PHYSICAL && triggeringEvent.getClickedBlock() != null
&& triggeringEvent.getClickedBlock().getType() == Material.TURTLE_EGG)
broken = Material.TURTLE_EGG;
}
if (broken != null)
{
// Error messages for siege mode.
if (!GriefPrevention.instance.config_siege_blocks.contains(broken))
event.setDenialReason(() -> GriefPrevention.instance.dataStore.getMessage(Messages.NonSiegeMaterial));
else if (player.getUniqueId().equals(claim.ownerID))
event.setDenialReason(() -> GriefPrevention.instance.dataStore.getMessage(Messages.NoOwnerBuildUnderSiege));
return;
}
// No building while under siege.
if (claim.siegeData != null)
event.setDenialReason(() -> GriefPrevention.instance.dataStore.getMessage(Messages.NoBuildUnderSiege, claim.siegeData.attacker.getName()));
}
}

View File

@ -144,10 +144,6 @@ commands:
description: Lists permissions for the claim you're standing in. description: Lists permissions for the claim you're standing in.
usage: /TrustList usage: /TrustList
permission: griefprevention.claims permission: griefprevention.claims
siege:
description: Initiates a siege versus another player.
usage: /Siege <playerName>
permission: griefprevention.siege
ignoreclaims: ignoreclaims:
description: Toggles ignore claims mode. description: Toggles ignore claims mode.
usage: /IgnoreClaims usage: /IgnoreClaims
@ -268,9 +264,6 @@ permissions:
griefprevention.givepet: griefprevention.givepet:
description: Grants permission to use /GivePet. description: Grants permission to use /GivePet.
default: true default: true
griefprevention.siege:
description: Grants permission to use /Siege.
default: true
griefprevention.unlockdrops: griefprevention.unlockdrops:
description: Grants permission to use /UnlockDrops. description: Grants permission to use /UnlockDrops.
default: true default: true