remove sieges
This commit is contained in:
parent
998bf5201c
commit
537803028b
|
|
@ -299,7 +299,7 @@ public class BlockEventHandler implements Listener
|
|||
playerData.lastClaim = claim;
|
||||
|
||||
//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.Instr, Messages.ClaimExplosivesAdvertisement);
|
||||
|
|
@ -455,8 +455,7 @@ public class BlockEventHandler implements Listener
|
|||
if (GriefPrevention.instance.config_blockSurfaceOtherExplosions && block.getType() == Material.TNT &&
|
||||
block.getWorld().getEnvironment() != Environment.NETHER &&
|
||||
block.getY() > GriefPrevention.instance.getSeaLevel(block.getWorld()) - 5 &&
|
||||
claim == null &&
|
||||
playerData.siegeData == null)
|
||||
claim == null)
|
||||
{
|
||||
GriefPrevention.sendMessage(player, TextMode.Warn, Messages.NoTNTDamageAboveSeaLevel);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -93,9 +93,6 @@ public class Claim
|
|||
//note subdivisions themselves never have children
|
||||
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
|
||||
public boolean doorsOpen = false;
|
||||
|
||||
|
|
@ -272,7 +269,6 @@ public class Claim
|
|||
this.parent = claim.parent;
|
||||
this.inheritNothing = claim.inheritNothing;
|
||||
this.children = new ArrayList<>(claim.children);
|
||||
this.siegeData = claim.siegeData;
|
||||
this.doorsOpen = claim.doorsOpen;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
synchronized public void deleteClaimsForPlayer(UUID playerID, boolean releasePets)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -436,15 +436,6 @@ public class EntityEventHandler implements Listener
|
|||
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 (claim == null)
|
||||
{
|
||||
|
|
@ -573,13 +564,6 @@ public class EntityEventHandler implements Listener
|
|||
Player player = (Player) entity;
|
||||
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
|
||||
|
||||
World world = entity.getWorld();
|
||||
|
|
|
|||
|
|
@ -156,7 +156,6 @@ public class GriefPrevention extends JavaPlugin
|
|||
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 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_cooldownEndInMinutes;
|
||||
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);
|
||||
pluginManager.registerEvents(entityEventHandler, this);
|
||||
|
||||
//siege events
|
||||
SiegeEventHandler siegeEventHandler = new SiegeEventHandler();
|
||||
pluginManager.registerEvents(siegeEventHandler, this);
|
||||
|
||||
//vault-based economy integration
|
||||
economyHandler = new EconomyHandler(this);
|
||||
pluginManager.registerEvents(economyHandler, this);
|
||||
|
|
@ -677,85 +672,6 @@ public class GriefPrevention extends JavaPlugin
|
|||
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_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);
|
||||
|
|
@ -894,8 +810,6 @@ public class GriefPrevention extends JavaPlugin
|
|||
outConfig.set("GriefPrevention.MaxPlayersPerIpAddress", this.config_ipLimit);
|
||||
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.CooldownEndInMinutes", this.config_siege_cooldownEndInMinutes);
|
||||
outConfig.set("GriefPrevention.EndermenMoveBlocks", this.config_endermenMoveBlocks);
|
||||
|
|
@ -2562,140 +2476,6 @@ public class GriefPrevention extends JavaPlugin
|
|||
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"))
|
||||
{
|
||||
//requires one parameter
|
||||
|
|
@ -3780,8 +3560,6 @@ public class GriefPrevention extends JavaPlugin
|
|||
|
||||
public boolean claimIsPvPSafeZone(Claim claim)
|
||||
{
|
||||
if (claim.siegeData != null)
|
||||
return false;
|
||||
return claim.isAdminClaim() && claim.parent == null && GriefPrevention.instance.config_pvp_noCombatInAdminLandClaims ||
|
||||
claim.isAdminClaim() && claim.parent != null && GriefPrevention.instance.config_pvp_noCombatInAdminSubdivisions ||
|
||||
!claim.isAdminClaim() && GriefPrevention.instance.config_pvp_noCombatInPlayerLandClaims;
|
||||
|
|
|
|||
|
|
@ -70,9 +70,6 @@ public class PlayerData
|
|||
//whether this player was recently warned about building outside land claims
|
||||
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)
|
||||
boolean wasKicked = false;
|
||||
|
||||
|
|
@ -89,9 +86,6 @@ public class PlayerData
|
|||
//the last claim this player was in, that we know of
|
||||
public Claim lastClaim = null;
|
||||
|
||||
//siege
|
||||
public SiegeData siegeData = null;
|
||||
|
||||
//pvp
|
||||
public long lastPvpTimestamp = 0;
|
||||
public String lastPvpPlayer = "";
|
||||
|
|
|
|||
|
|
@ -518,15 +518,6 @@ class PlayerEventHandler implements Listener
|
|||
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
|
||||
this.dataStore.clearCachedPlayerData(playerID);
|
||||
|
||||
|
|
@ -599,13 +590,6 @@ class PlayerEventHandler implements Listener
|
|||
GriefPrevention.sendMessage(player, TextMode.Err, Messages.PvPNoDrop);
|
||||
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
|
||||
|
|
@ -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)
|
||||
|
|
@ -817,13 +772,6 @@ class PlayerEventHandler implements Listener
|
|||
//don't allow container access during pvp combat
|
||||
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())
|
||||
{
|
||||
GriefPrevention.sendMessage(player, TextMode.Err, Messages.PvPNoContainers);
|
||||
|
|
@ -1321,14 +1269,6 @@ class PlayerEventHandler implements Listener
|
|||
{
|
||||
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
|
||||
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)
|
||||
|
||||
//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
|
||||
if (action == Action.RIGHT_CLICK_AIR)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
@ -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()));
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -144,10 +144,6 @@ commands:
|
|||
description: Lists permissions for the claim you're standing in.
|
||||
usage: /TrustList
|
||||
permission: griefprevention.claims
|
||||
siege:
|
||||
description: Initiates a siege versus another player.
|
||||
usage: /Siege <playerName>
|
||||
permission: griefprevention.siege
|
||||
ignoreclaims:
|
||||
description: Toggles ignore claims mode.
|
||||
usage: /IgnoreClaims
|
||||
|
|
@ -268,9 +264,6 @@ permissions:
|
|||
griefprevention.givepet:
|
||||
description: Grants permission to use /GivePet.
|
||||
default: true
|
||||
griefprevention.siege:
|
||||
description: Grants permission to use /Siege.
|
||||
default: true
|
||||
griefprevention.unlockdrops:
|
||||
description: Grants permission to use /UnlockDrops.
|
||||
default: true
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user