4.6
This commit is contained in:
parent
03c920f568
commit
0b27cb36d5
12
plugin.yml
12
plugin.yml
|
|
@ -1,7 +1,7 @@
|
|||
name: GriefPrevention
|
||||
main: me.ryanhamshire.GriefPrevention.GriefPrevention
|
||||
softdepend: [Vault, Multiverse-Core]
|
||||
version: 4.5
|
||||
version: 4.6
|
||||
commands:
|
||||
abandonclaim:
|
||||
description: Deletes a claim.
|
||||
|
|
@ -83,7 +83,7 @@ commands:
|
|||
usage: /SellClaimBlocks <numberOfBlocks>
|
||||
aliases: sellclaim
|
||||
trapped:
|
||||
description: Ejects you to nearby unclaimed land. Usable once per 8 hours.
|
||||
description: Ejects you to nearby unclaimed land. Has a substantial cooldown period.
|
||||
usage: /Trapped
|
||||
trustlist:
|
||||
description: Lists permissions for the claim you're standing in.
|
||||
|
|
@ -104,6 +104,10 @@ commands:
|
|||
description: Converts an administrative claim to a private claim.
|
||||
usage: /TransferClaim <player>
|
||||
permission: griefprevention.adjustclaimblocks
|
||||
deathblow:
|
||||
description: Kills a player, optionally giving his inventory to another player.
|
||||
usage: /DeathBlow <player> [recipientPlayer]
|
||||
permission: griefprevention.deathblow
|
||||
permissions:
|
||||
griefprevention.createclaims:
|
||||
description: Grants permission to create claims.
|
||||
|
|
@ -120,6 +124,7 @@ permissions:
|
|||
griefprevention.spam: true
|
||||
griefprevention.lava: true
|
||||
griefprevention.eavesdrop: true
|
||||
griefprevention.deathblow: true
|
||||
griefprevention.restorenature:
|
||||
description: Grants permission to use /RestoreNature.
|
||||
default: op
|
||||
|
|
@ -147,3 +152,6 @@ permissions:
|
|||
griefprevention.restorenatureaggressive:
|
||||
description: Grants access to /RestoreNatureAggressive and /RestoreNatureFill.
|
||||
default: op
|
||||
griefprevention.deathblow:
|
||||
description: Grants access to /DeathBlow.
|
||||
default: op
|
||||
|
|
@ -94,7 +94,7 @@ public class BlockEventHandler implements Listener
|
|||
PlayerData playerData = this.dataStore.getPlayerData(event.getPlayer().getName());
|
||||
if(playerData.siegeData != null)
|
||||
{
|
||||
GriefPrevention.sendMessage(player, TextMode.Err, "You can't give away items while involved in a siege.");
|
||||
GriefPrevention.sendMessage(player, TextMode.Err, Messages.SiegeNoDrop);
|
||||
event.setCancelled(true);
|
||||
return;
|
||||
}
|
||||
|
|
@ -109,7 +109,7 @@ public class BlockEventHandler implements Listener
|
|||
playerData.lastChestDamageLocation = block.getLocation();
|
||||
|
||||
//give the player instructions
|
||||
GriefPrevention.sendMessage(player, TextMode.Instr, "To give away the item(s) in your hand, left-click the chest again.");
|
||||
GriefPrevention.sendMessage(player, TextMode.Instr, Messages.DonateItemsInstruction);
|
||||
}
|
||||
|
||||
//otherwise, try to donate the item stack in hand
|
||||
|
|
@ -124,7 +124,7 @@ public class BlockEventHandler implements Listener
|
|||
if(availableSlot < 0)
|
||||
{
|
||||
//tell the player and stop here
|
||||
GriefPrevention.sendMessage(player, TextMode.Err, "This chest is full.");
|
||||
GriefPrevention.sendMessage(player, TextMode.Err, Messages.ChestFull);
|
||||
|
||||
return;
|
||||
}
|
||||
|
|
@ -135,7 +135,7 @@ public class BlockEventHandler implements Listener
|
|||
playerInventory.setItemInHand(new ItemStack(Material.AIR));
|
||||
|
||||
//and confirm for the player
|
||||
GriefPrevention.sendMessage(player, TextMode.Success, "Item(s) transferred to chest!");
|
||||
GriefPrevention.sendMessage(player, TextMode.Success, Messages.DonationSuccess);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -162,8 +162,8 @@ public class BlockEventHandler implements Listener
|
|||
//if there's a claim here
|
||||
if(claim != null)
|
||||
{
|
||||
//if breaking UNDER the claim
|
||||
if(block.getY() < claim.lesserBoundaryCorner.getBlockY())
|
||||
//if breaking UNDER the claim and the player has permission to build in the claim
|
||||
if(block.getY() < claim.lesserBoundaryCorner.getBlockY() && claim.allowBuild(player) == null)
|
||||
{
|
||||
//extend the claim downward beyond the breakage point
|
||||
this.dataStore.extendClaim(claim, claim.getLesserBoundaryCorner().getBlockY() - GriefPrevention.instance.config_claims_claimsExtendIntoGroundDistance);
|
||||
|
|
@ -226,27 +226,13 @@ public class BlockEventHandler implements Listener
|
|||
Location location = otherPlayer.getLocation();
|
||||
if(!otherPlayer.equals(player) && location.distanceSquared(block.getLocation()) < 9)
|
||||
{
|
||||
GriefPrevention.sendMessage(player, TextMode.Err, "You can't start a fire this close to " + otherPlayer.getName() + ".");
|
||||
GriefPrevention.sendMessage(player, TextMode.Err, Messages.PlayerTooCloseForFire, otherPlayer.getName());
|
||||
placeEvent.setCancelled(true);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//FEATURE: limit tree planting to grass, and dirt with more earth beneath it
|
||||
if(block.getType() == Material.SAPLING)
|
||||
{
|
||||
Block earthBlock = placeEvent.getBlockAgainst();
|
||||
if(earthBlock.getType() != Material.GRASS)
|
||||
{
|
||||
if(earthBlock.getRelative(BlockFace.DOWN).getType() == Material.AIR ||
|
||||
earthBlock.getRelative(BlockFace.DOWN).getRelative(BlockFace.DOWN).getType() == Material.AIR)
|
||||
{
|
||||
placeEvent.setCancelled(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//make sure the player is allowed to build at the location
|
||||
String noBuildReason = GriefPrevention.instance.allowBuild(player, block.getLocation());
|
||||
if(noBuildReason != null)
|
||||
|
|
@ -262,7 +248,7 @@ public class BlockEventHandler implements Listener
|
|||
if(claim != null)
|
||||
{
|
||||
//if the player has permission for the claim and he's placing UNDER the claim
|
||||
if(block.getY() < claim.lesserBoundaryCorner.getBlockY())
|
||||
if(block.getY() < claim.lesserBoundaryCorner.getBlockY() && claim.allowBuild(player) == null)
|
||||
{
|
||||
//extend the claim downward
|
||||
this.dataStore.extendClaim(claim, claim.getLesserBoundaryCorner().getBlockY() - GriefPrevention.instance.config_claims_claimsExtendIntoGroundDistance);
|
||||
|
|
@ -277,7 +263,7 @@ public class BlockEventHandler implements Listener
|
|||
//if the chest is too deep underground, don't create the claim and explain why
|
||||
if(GriefPrevention.instance.config_claims_preventTheft && block.getY() < GriefPrevention.instance.config_claims_maxDepth)
|
||||
{
|
||||
GriefPrevention.sendMessage(player, TextMode.Warn, "This chest can't be protected because it's too deep underground. Consider moving it.");
|
||||
GriefPrevention.sendMessage(player, TextMode.Warn, Messages.TooDeepToClaim);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -290,7 +276,7 @@ public class BlockEventHandler implements Listener
|
|||
if(GriefPrevention.instance.config_claims_automaticClaimsForNewPlayersRadius == 0)
|
||||
{
|
||||
this.dataStore.createClaim(block.getWorld(), block.getX(), block.getX(), block.getY(), block.getY(), block.getZ(), block.getZ(), player.getName(), null);
|
||||
GriefPrevention.sendMessage(player, TextMode.Success, "This chest is protected.");
|
||||
GriefPrevention.sendMessage(player, TextMode.Success, Messages.ChestClaimConfirmation);
|
||||
}
|
||||
|
||||
//otherwise, create a claim in the area around the chest
|
||||
|
|
@ -309,7 +295,7 @@ public class BlockEventHandler implements Listener
|
|||
}
|
||||
|
||||
//notify and explain to player
|
||||
GriefPrevention.sendMessage(player, TextMode.Success, "This chest and nearby blocks are protected from breakage and theft. The gold and glowstone blocks mark the protected area.");
|
||||
GriefPrevention.sendMessage(player, TextMode.Success, Messages.AutomaticClaimNotification);
|
||||
|
||||
//show the player the protected area
|
||||
Claim newClaim = this.dataStore.getClaimAt(block.getLocation(), false, null);
|
||||
|
|
@ -318,19 +304,33 @@ public class BlockEventHandler implements Listener
|
|||
}
|
||||
|
||||
//instructions for using /trust
|
||||
GriefPrevention.sendMessage(player, TextMode.Instr, "Use the /trust command to grant other players access.");
|
||||
GriefPrevention.sendMessage(player, TextMode.Instr, Messages.TrustCommandAdvertisement);
|
||||
|
||||
//unless special permission is required to create a claim with the shovel, educate the player about the shovel
|
||||
if(!GriefPrevention.instance.config_claims_creationRequiresPermission)
|
||||
{
|
||||
GriefPrevention.sendMessage(player, TextMode.Instr, "To claim more land, use a golden shovel.");
|
||||
GriefPrevention.sendMessage(player, TextMode.Instr, Messages.GoldenShovelAdvertisement);
|
||||
}
|
||||
}
|
||||
|
||||
//check to see if this chest is in a claim, and warn when it isn't
|
||||
if(GriefPrevention.instance.config_claims_preventTheft && this.dataStore.getClaimAt(block.getLocation(), false, playerData.lastClaim) == null)
|
||||
{
|
||||
GriefPrevention.sendMessage(player, TextMode.Warn, "This chest is NOT protected. Consider expanding an existing claim or creating a new one.");
|
||||
GriefPrevention.sendMessage(player, TextMode.Warn, Messages.UnprotectedChestWarning);
|
||||
}
|
||||
}
|
||||
|
||||
//FEATURE: limit wilderness tree planting to grass, or dirt with more blocks beneath it
|
||||
else if(block.getType() == Material.SAPLING && GriefPrevention.instance.config_blockSkyTrees)
|
||||
{
|
||||
Block earthBlock = placeEvent.getBlockAgainst();
|
||||
if(earthBlock.getType() != Material.GRASS)
|
||||
{
|
||||
if(earthBlock.getRelative(BlockFace.DOWN).getType() == Material.AIR ||
|
||||
earthBlock.getRelative(BlockFace.DOWN).getRelative(BlockFace.DOWN).getType() == Material.AIR)
|
||||
{
|
||||
placeEvent.setCancelled(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -416,18 +416,29 @@ public class BlockEventHandler implements Listener
|
|||
}
|
||||
|
||||
//ensures fluids don't flow out of claims, unless into another claim where the owner is trusted to build
|
||||
private Claim lastSpreadClaim = null;
|
||||
@EventHandler(ignoreCancelled = true, priority = EventPriority.LOWEST)
|
||||
public void onBlockFromTo (BlockFromToEvent spreadEvent)
|
||||
{
|
||||
//always allow fluids to flow straight down
|
||||
if(spreadEvent.getFace() == BlockFace.DOWN) return;
|
||||
|
||||
//from where?
|
||||
Block fromBlock = spreadEvent.getBlock();
|
||||
Claim fromClaim = this.dataStore.getClaimAt(fromBlock.getLocation(), false, null);
|
||||
Claim fromClaim = this.dataStore.getClaimAt(fromBlock.getLocation(), false, this.lastSpreadClaim);
|
||||
if(fromClaim != null)
|
||||
{
|
||||
this.lastSpreadClaim = fromClaim;
|
||||
}
|
||||
|
||||
//where to?
|
||||
Block toBlock = spreadEvent.getToBlock();
|
||||
Claim toClaim = this.dataStore.getClaimAt(toBlock.getLocation(), false, fromClaim);
|
||||
|
||||
//block any spread into the wilderness
|
||||
//if it's within the same claim or wilderness to wilderness, allow it
|
||||
if(fromClaim == toClaim) return;
|
||||
|
||||
//block any spread into the wilderness from a claim
|
||||
if(fromClaim != null && toClaim == null)
|
||||
{
|
||||
spreadEvent.setCancelled(true);
|
||||
|
|
@ -441,9 +452,6 @@ public class BlockEventHandler implements Listener
|
|||
OfflinePlayer fromOwner = null;
|
||||
if(fromClaim != null)
|
||||
{
|
||||
//if it's within the same claim, allow it
|
||||
if(fromClaim == toClaim) return;
|
||||
|
||||
fromOwner = GriefPrevention.instance.getServer().getOfflinePlayer(fromClaim.ownerName);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -24,6 +24,7 @@ import java.util.Date;
|
|||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import org.bukkit.*;
|
||||
import org.bukkit.World.Environment;
|
||||
|
|
@ -105,7 +106,7 @@ public class Claim
|
|||
//it may be null
|
||||
public void removeSurfaceFluids(Claim exclusionClaim)
|
||||
{
|
||||
//don't do this automatically for administrative claims
|
||||
//don't do this for administrative claims
|
||||
if(this.isAdminClaim()) return;
|
||||
|
||||
Location lesser = this.getLesserBoundaryCorner();
|
||||
|
|
@ -135,7 +136,45 @@ public class Claim
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//determines whether or not a claim has surface fluids (lots of water blocks, or any lava blocks)
|
||||
//used to warn players when they abandon their claims about automatic fluid cleanup
|
||||
boolean hasSurfaceFluids()
|
||||
{
|
||||
Location lesser = this.getLesserBoundaryCorner();
|
||||
Location greater = this.getGreaterBoundaryCorner();
|
||||
|
||||
int seaLevel = 0; //clean up all fluids in the end
|
||||
|
||||
//respect sea level in normal worlds
|
||||
if(lesser.getWorld().getEnvironment() == Environment.NORMAL) seaLevel = lesser.getWorld().getSeaLevel();
|
||||
|
||||
int waterCount = 0;
|
||||
for(int x = lesser.getBlockX(); x <= greater.getBlockX(); x++)
|
||||
{
|
||||
for(int z = lesser.getBlockZ(); z <= greater.getBlockZ(); z++)
|
||||
{
|
||||
for(int y = seaLevel - 1; y <= lesser.getWorld().getMaxHeight(); y++)
|
||||
{
|
||||
//dodge the exclusion claim
|
||||
Block block = lesser.getWorld().getBlockAt(x, y, z);
|
||||
|
||||
if(block.getType() == Material.STATIONARY_WATER || block.getType() == Material.WATER)
|
||||
{
|
||||
waterCount++;
|
||||
if(waterCount > 10) return true;
|
||||
}
|
||||
|
||||
else if(block.getType() == Material.STATIONARY_LAVA || block.getType() == Material.LAVA)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
//main constructor. note that only creating a claim instance does nothing - a claim must be added to the data store to be effective
|
||||
|
|
@ -245,7 +284,7 @@ public class Claim
|
|||
{
|
||||
if(this.siegeData != null)
|
||||
{
|
||||
return "Claims can't be modified while under siege.";
|
||||
return GriefPrevention.instance.dataStore.getMessage(Messages.NoModifyDuringSiege);
|
||||
}
|
||||
|
||||
//otherwise, owners can do whatever
|
||||
|
|
@ -257,7 +296,7 @@ public class Claim
|
|||
return this.parent.allowBuild(player);
|
||||
|
||||
//error message if all else fails
|
||||
return "Only " + this.getOwnerName() + " can modify this claim.";
|
||||
return GriefPrevention.instance.dataStore.getMessage(Messages.OnlyOwnersModifyClaims, this.getOwnerName());
|
||||
}
|
||||
|
||||
//build permission check
|
||||
|
|
@ -278,25 +317,24 @@ public class Claim
|
|||
//no building while under siege
|
||||
if(this.siegeData != null)
|
||||
{
|
||||
return "This claim is under siege by " + this.siegeData.attacker.getName() + ". No one can build here.";
|
||||
return GriefPrevention.instance.dataStore.getMessage(Messages.NoBuildUnderSiege, this.siegeData.attacker.getName());
|
||||
}
|
||||
|
||||
//no building while in pvp combat
|
||||
PlayerData playerData = GriefPrevention.instance.dataStore.getPlayerData(player.getName());
|
||||
if(playerData.inPvpCombat())
|
||||
{
|
||||
return "You can't build in claims during PvP combat.";
|
||||
return GriefPrevention.instance.dataStore.getMessage(Messages.NoBuildPvP);
|
||||
}
|
||||
|
||||
//owners can make changes, or admins with ignore claims mode enabled
|
||||
if(this.ownerName.equals(player.getName()) || GriefPrevention.instance.dataStore.getPlayerData(player.getName()).ignoreClaims) return null;
|
||||
|
||||
//anyone with explicit build permission can make changes
|
||||
ClaimPermission permissionLevel = this.playerNameToClaimPermissionMap.get(player.getName().toLowerCase());
|
||||
if(ClaimPermission.Build == permissionLevel) return null;
|
||||
if(this.hasExplicitPermission(player, ClaimPermission.Build)) return null;
|
||||
|
||||
//also everyone is a member of the "public", so check for public permission
|
||||
permissionLevel = this.playerNameToClaimPermissionMap.get("public");
|
||||
ClaimPermission permissionLevel = this.playerNameToClaimPermissionMap.get("public");
|
||||
if(ClaimPermission.Build == permissionLevel) return null;
|
||||
|
||||
//subdivision permission inheritance
|
||||
|
|
@ -304,15 +342,38 @@ public class Claim
|
|||
return this.parent.allowBuild(player);
|
||||
|
||||
//failure message for all other cases
|
||||
return "You don't have " + this.getOwnerName() + "'s permission to build here.";
|
||||
return GriefPrevention.instance.dataStore.getMessage(Messages.NoBuildPermission, this.getOwnerName());
|
||||
}
|
||||
|
||||
private boolean hasExplicitPermission(Player player, ClaimPermission level)
|
||||
{
|
||||
String playerName = player.getName();
|
||||
Set<String> keys = this.playerNameToClaimPermissionMap.keySet();
|
||||
Iterator<String> iterator = keys.iterator();
|
||||
while(iterator.hasNext())
|
||||
{
|
||||
String identifier = iterator.next();
|
||||
if(playerName.equalsIgnoreCase(identifier) && this.playerNameToClaimPermissionMap.get(identifier) == level) return true;
|
||||
|
||||
else if(identifier.startsWith("[") && identifier.endsWith("]"))
|
||||
{
|
||||
//drop the brackets
|
||||
String permissionIdentifier = identifier.substring(1, identifier.length() - 1);
|
||||
|
||||
//defensive coding
|
||||
if(permissionIdentifier == null || permissionIdentifier.isEmpty()) continue;
|
||||
|
||||
//check permission
|
||||
if(player.hasPermission(permissionIdentifier) && this.playerNameToClaimPermissionMap.get(identifier) == level) return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
//break permission check
|
||||
public String allowBreak(Player player, Material material)
|
||||
{
|
||||
//if we don't know who's asking, always say no (i've been told some mods can make this happen somehow)
|
||||
if(player == null) return "";
|
||||
|
||||
//if under siege, some blocks will be breakable
|
||||
if(this.siegeData != null)
|
||||
{
|
||||
|
|
@ -332,11 +393,11 @@ public class Claim
|
|||
//custom error messages for siege mode
|
||||
if(!breakable)
|
||||
{
|
||||
return "That material is too tough to break.";
|
||||
return GriefPrevention.instance.dataStore.getMessage(Messages.NonSiegeMaterial);
|
||||
}
|
||||
else if(this.ownerName.equals(player.getName()))
|
||||
{
|
||||
return "You can't make changes while under siege.";
|
||||
return GriefPrevention.instance.dataStore.getMessage(Messages.NoOwnerBuildUnderSiege);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -351,9 +412,6 @@ public class Claim
|
|||
//access permission check
|
||||
public String allowAccess(Player player)
|
||||
{
|
||||
//if we don't know who's asking, always say no (i've been told some mods can make this happen somehow)
|
||||
if(player == null) return "";
|
||||
|
||||
//everyone always has access to admin claims
|
||||
if(this.isAdminClaim()) return null;
|
||||
|
||||
|
|
@ -364,19 +422,20 @@ public class Claim
|
|||
if(this.ownerName.equals(player.getName()) || GriefPrevention.instance.dataStore.getPlayerData(player.getName()).ignoreClaims) return null;
|
||||
|
||||
//look for explicit individual access, inventory, or build permission
|
||||
ClaimPermission permissionLevel = this.playerNameToClaimPermissionMap.get(player.getName().toLowerCase());
|
||||
if(ClaimPermission.Build == permissionLevel || ClaimPermission.Inventory == permissionLevel || ClaimPermission.Access == permissionLevel) return null;
|
||||
if(this.hasExplicitPermission(player, ClaimPermission.Access)) return null;
|
||||
if(this.hasExplicitPermission(player, ClaimPermission.Inventory)) return null;
|
||||
if(this.hasExplicitPermission(player, ClaimPermission.Build)) return null;
|
||||
|
||||
//also check for public permission
|
||||
permissionLevel = this.playerNameToClaimPermissionMap.get("public");
|
||||
if(ClaimPermission.Build == permissionLevel || ClaimPermission.Inventory == permissionLevel || ClaimPermission.Access == permissionLevel) return null;
|
||||
ClaimPermission permissionLevel = this.playerNameToClaimPermissionMap.get("public");
|
||||
if(ClaimPermission.Build == permissionLevel || ClaimPermission.Inventory == permissionLevel || ClaimPermission.Inventory == permissionLevel) return null;
|
||||
|
||||
//permission inheritance for subdivisions
|
||||
if(this.parent != null)
|
||||
return this.parent.allowAccess(player);
|
||||
|
||||
//catch-all error message for all other cases
|
||||
return "You don't have " + this.getOwnerName() + "'s permission to use that.";
|
||||
return GriefPrevention.instance.dataStore.getMessage(Messages.NoAccessPermission, this.getOwnerName());
|
||||
}
|
||||
|
||||
//inventory permission check
|
||||
|
|
@ -391,7 +450,7 @@ public class Claim
|
|||
//if under siege, nobody accesses containers
|
||||
if(this.siegeData != null)
|
||||
{
|
||||
return "This claim is under siege by " + siegeData.attacker.getName() + ". No one can access containers here right now.";
|
||||
return GriefPrevention.instance.dataStore.getMessage(Messages.NoContainersSiege, siegeData.attacker.getName());
|
||||
}
|
||||
|
||||
//containers are always accessible in admin claims
|
||||
|
|
@ -401,11 +460,11 @@ public class Claim
|
|||
if(this.ownerName.equals(player.getName()) || GriefPrevention.instance.dataStore.getPlayerData(player.getName()).ignoreClaims) return null;
|
||||
|
||||
//check for explicit individual container or build permission
|
||||
ClaimPermission permissionLevel = this.playerNameToClaimPermissionMap.get(player.getName().toLowerCase());
|
||||
if(ClaimPermission.Build == permissionLevel || ClaimPermission.Inventory == permissionLevel) return null;
|
||||
if(this.hasExplicitPermission(player, ClaimPermission.Inventory)) return null;
|
||||
if(this.hasExplicitPermission(player, ClaimPermission.Build)) return null;
|
||||
|
||||
//check for public container or build permission
|
||||
permissionLevel = this.playerNameToClaimPermissionMap.get("public");
|
||||
ClaimPermission permissionLevel = this.playerNameToClaimPermissionMap.get("public");
|
||||
if(ClaimPermission.Build == permissionLevel || ClaimPermission.Inventory == permissionLevel) return null;
|
||||
|
||||
//permission inheritance for subdivisions
|
||||
|
|
@ -413,7 +472,7 @@ public class Claim
|
|||
return this.parent.allowContainers(player);
|
||||
|
||||
//error message for all other cases
|
||||
return "You don't have " + this.getOwnerName() + "'s permission to use that.";
|
||||
return GriefPrevention.instance.dataStore.getMessage(Messages.NoContainersPermission, this.getOwnerName());
|
||||
}
|
||||
|
||||
//grant permission check, relatively simple
|
||||
|
|
@ -422,15 +481,29 @@ public class Claim
|
|||
//if we don't know who's asking, always say no (i've been told some mods can make this happen somehow)
|
||||
if(player == null) return "";
|
||||
|
||||
//anyone who can modify the claim, or who's explicitly in the managers (/PermissionTrust) list can do this
|
||||
if(this.allowEdit(player) == null || this.managers.contains(player.getName())) return null;
|
||||
//anyone who can modify the claim can do this
|
||||
if(this.allowEdit(player) == null) return null;
|
||||
|
||||
//anyone who's in the managers (/PermissionTrust) list can do this
|
||||
for(int i = 0; i < this.managers.size(); i++)
|
||||
{
|
||||
String managerID = this.managers.get(i);
|
||||
if(player.getName().equalsIgnoreCase(managerID)) return null;
|
||||
|
||||
else if(managerID.startsWith("[") && managerID.endsWith("]"))
|
||||
{
|
||||
managerID = managerID.substring(1, managerID.length() - 1);
|
||||
if(managerID == null || managerID.isEmpty()) continue;
|
||||
if(player.hasPermission(managerID)) return null;
|
||||
}
|
||||
}
|
||||
|
||||
//permission inheritance for subdivisions
|
||||
if(this.parent != null)
|
||||
return this.parent.allowGrantPermission(player);
|
||||
|
||||
//generic error message
|
||||
return "You don't have " + this.getOwnerName() + "'s permission to grant permission here.";
|
||||
return GriefPrevention.instance.dataStore.getMessage(Messages.NoPermissionTrust, this.getOwnerName());
|
||||
}
|
||||
|
||||
//grants a permission for a player or the public
|
||||
|
|
@ -503,7 +576,7 @@ public class Claim
|
|||
return this.parent.getOwnerName();
|
||||
|
||||
if(this.ownerName.length() == 0)
|
||||
return "an administrator";
|
||||
return GriefPrevention.instance.dataStore.getMessage(Messages.OwnerNameForAdminClaims);
|
||||
|
||||
return this.ownerName;
|
||||
}
|
||||
|
|
@ -612,7 +685,7 @@ public class Claim
|
|||
|
||||
//determine maximum allowable entity count, based on claim size
|
||||
int maxEntities = this.getArea() / 50;
|
||||
if(maxEntities == 0) return "This claim isn't big enough for that. Try enlarging it.";
|
||||
if(maxEntities == 0) return GriefPrevention.instance.dataStore.getMessage(Messages.ClaimTooSmallForEntities);
|
||||
|
||||
//count current entities (ignoring players)
|
||||
Chunk lesserChunk = this.getLesserBoundaryCorner().getChunk();
|
||||
|
|
@ -627,11 +700,15 @@ public class Claim
|
|||
for(int i = 0; i < entities.length; i++)
|
||||
{
|
||||
Entity entity = entities[i];
|
||||
if(!(entity instanceof Player) && this.contains(entity.getLocation(), false, false)) totalEntities++;
|
||||
if(!(entity instanceof Player) && this.contains(entity.getLocation(), false, false))
|
||||
{
|
||||
totalEntities++;
|
||||
if(totalEntities > maxEntities) entity.remove();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(totalEntities > maxEntities) return "This claim has too many entities already. Try enlarging the claim or removing some animals, monsters, or minecarts.";
|
||||
if(totalEntities > maxEntities) return GriefPrevention.instance.dataStore.getMessage(Messages.TooManyEntitiesInClaim);
|
||||
|
||||
return null;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -25,6 +25,8 @@ import java.text.SimpleDateFormat;
|
|||
import java.util.*;
|
||||
|
||||
import org.bukkit.*;
|
||||
import org.bukkit.configuration.file.FileConfiguration;
|
||||
import org.bukkit.configuration.file.YamlConfiguration;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
|
|
@ -34,14 +36,21 @@ public class DataStore
|
|||
//in-memory cache for player data
|
||||
private HashMap<String, PlayerData> playerNameToPlayerDataMap = new HashMap<String, PlayerData>();
|
||||
|
||||
//in-memory cache for group (permission-based) data
|
||||
private HashMap<String, Integer> permissionToBonusBlocksMap = new HashMap<String, Integer>();
|
||||
|
||||
//in-memory cache for claim data
|
||||
private ArrayList<Claim> claims = new ArrayList<Claim>();
|
||||
ArrayList<Claim> claims = new ArrayList<Claim>();
|
||||
|
||||
//in-memory cache for messages
|
||||
private String [] messages;
|
||||
|
||||
//path information, for where stuff stored on disk is well... stored
|
||||
private final static String dataLayerFolderPath = "plugins" + File.separator + "GriefPreventionData";
|
||||
private final static String playerDataFolderPath = dataLayerFolderPath + File.separator + "PlayerData";
|
||||
private final static String claimDataFolderPath = dataLayerFolderPath + File.separator + "ClaimData";
|
||||
final static String configFilePath = dataLayerFolderPath + File.separator + "config.yml";
|
||||
final static String messagesFilePath = dataLayerFolderPath + File.separator + "messages.yml";
|
||||
|
||||
//initialization!
|
||||
DataStore()
|
||||
|
|
@ -50,9 +59,45 @@ public class DataStore
|
|||
new File(playerDataFolderPath).mkdirs();
|
||||
new File(claimDataFolderPath).mkdirs();
|
||||
|
||||
//load group data into memory
|
||||
File playerDataFolder = new File(playerDataFolderPath);
|
||||
File [] files = playerDataFolder.listFiles();
|
||||
for(int i = 0; i < files.length; i++)
|
||||
{
|
||||
File file = files[i];
|
||||
if(!file.isFile()) continue; //avoids folders
|
||||
|
||||
//all group data files start with an underscore. ignoring the rest, which are player data files.
|
||||
if(!file.getName().startsWith("_")) continue;
|
||||
|
||||
String groupName = file.getName().substring(1);
|
||||
if(groupName == null || groupName.isEmpty()) continue; //defensive coding, avoid unlikely cases
|
||||
|
||||
BufferedReader inStream = null;
|
||||
try
|
||||
{
|
||||
inStream = new BufferedReader(new FileReader(file.getAbsolutePath()));
|
||||
String line = inStream.readLine();
|
||||
|
||||
int groupBonusBlocks = Integer.parseInt(line);
|
||||
|
||||
this.permissionToBonusBlocksMap.put(groupName, groupBonusBlocks);
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
GriefPrevention.AddLogEntry("Unable to load group bonus block data from file \"" + file.getName() + "\": " + e.getMessage());
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
if(inStream != null) inStream.close();
|
||||
}
|
||||
catch(IOException exception) {}
|
||||
}
|
||||
|
||||
//load claims data into memory
|
||||
File claimDataFolder = new File(claimDataFolderPath);
|
||||
File [] files = claimDataFolder.listFiles();
|
||||
files = claimDataFolder.listFiles();
|
||||
|
||||
int loadedClaimCount = 0;
|
||||
|
||||
|
|
@ -239,6 +284,9 @@ public class DataStore
|
|||
this.clearCachedPlayerData(playerName);
|
||||
}
|
||||
|
||||
//load up all the messages from messages.yml
|
||||
this.loadMessages();
|
||||
|
||||
//collect garbage, since lots of stuff was loaded into memory and then tossed out
|
||||
System.gc();
|
||||
}
|
||||
|
|
@ -249,6 +297,67 @@ public class DataStore
|
|||
this.playerNameToPlayerDataMap.remove(playerName);
|
||||
}
|
||||
|
||||
//gets the number of bonus blocks a player has from his permissions
|
||||
int getGroupBonusBlocks(String playerName)
|
||||
{
|
||||
int bonusBlocks = 0;
|
||||
Set<String> keys = permissionToBonusBlocksMap.keySet();
|
||||
Iterator<String> iterator = keys.iterator();
|
||||
while(iterator.hasNext())
|
||||
{
|
||||
String groupName = iterator.next();
|
||||
Player player = GriefPrevention.instance.getServer().getPlayer(playerName);
|
||||
if(player.hasPermission(groupName))
|
||||
{
|
||||
bonusBlocks += this.permissionToBonusBlocksMap.get(groupName);
|
||||
}
|
||||
}
|
||||
|
||||
return bonusBlocks;
|
||||
}
|
||||
|
||||
//grants a group (players with a specific permission) bonus claim blocks as long as they're still members of the group
|
||||
public int adjustGroupBonusBlocks(String groupName, int amount)
|
||||
{
|
||||
Integer currentValue = this.permissionToBonusBlocksMap.get(groupName);
|
||||
if(currentValue == null) currentValue = 0;
|
||||
|
||||
currentValue += amount;
|
||||
this.permissionToBonusBlocksMap.put(groupName, currentValue);
|
||||
|
||||
//write changes to file to ensure they don't get lost
|
||||
BufferedWriter outStream = null;
|
||||
try
|
||||
{
|
||||
//open the group's file
|
||||
File groupDataFile = new File(playerDataFolderPath + File.separator + "_" + groupName);
|
||||
groupDataFile.createNewFile();
|
||||
outStream = new BufferedWriter(new FileWriter(groupDataFile));
|
||||
|
||||
//first line is number of bonus blocks
|
||||
outStream.write(currentValue.toString());
|
||||
outStream.newLine();
|
||||
}
|
||||
|
||||
//if any problem, log it
|
||||
catch(Exception e)
|
||||
{
|
||||
GriefPrevention.AddLogEntry("Unexpected exception saving data for group \"" + groupName + "\": " + e.getMessage());
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
//close the file
|
||||
if(outStream != null)
|
||||
{
|
||||
outStream.close();
|
||||
}
|
||||
}
|
||||
catch(IOException exception){}
|
||||
|
||||
return currentValue;
|
||||
}
|
||||
|
||||
public void changeClaimOwner(Claim claim, String newOwnerName) throws Exception
|
||||
{
|
||||
//if it's a subdivision, throw an exception
|
||||
|
|
@ -482,6 +591,7 @@ public class DataStore
|
|||
File playerFile = new File(playerDataFolderPath + File.separator + playerName);
|
||||
|
||||
playerData = new PlayerData();
|
||||
playerData.playerName = playerName;
|
||||
|
||||
//if it doesn't exist as a file
|
||||
if(!playerFile.exists())
|
||||
|
|
@ -741,6 +851,12 @@ public class DataStore
|
|||
bigz = z1;
|
||||
}
|
||||
|
||||
//creative mode claims always go to bedrock
|
||||
if(GriefPrevention.instance.config_claims_enabledCreativeWorlds.contains(world))
|
||||
{
|
||||
smally = 2;
|
||||
}
|
||||
|
||||
//create a new claim instance (but don't save it, yet)
|
||||
Claim newClaim = new Claim(
|
||||
new Location(world, smallx, smally, smallz),
|
||||
|
|
@ -972,7 +1088,7 @@ public class DataStore
|
|||
if(winner != null)
|
||||
{
|
||||
//notify the winner
|
||||
GriefPrevention.sendMessage(winner, TextMode.Success, "Congratulations! Buttons and levers are temporarily unlocked (five minutes).");
|
||||
GriefPrevention.sendMessage(winner, TextMode.Success, Messages.SiegeWinDoorsOpen);
|
||||
|
||||
//schedule a task to secure the claims in about 5 minutes
|
||||
SecureClaimTask task = new SecureClaimTask(siegeData);
|
||||
|
|
@ -1146,4 +1262,223 @@ public class DataStore
|
|||
|
||||
return result;
|
||||
}
|
||||
|
||||
private void loadMessages()
|
||||
{
|
||||
Messages [] messageIDs = Messages.values();
|
||||
this.messages = new String[Messages.values().length];
|
||||
|
||||
HashMap<String, CustomizableMessage> defaults = new HashMap<String, CustomizableMessage>();
|
||||
|
||||
//initialize defaults
|
||||
this.addDefault(defaults, Messages.RespectingClaims, "Now respecting claims.", null);
|
||||
this.addDefault(defaults, Messages.IgnoringClaims, "Now ignoring claims.", null);
|
||||
this.addDefault(defaults, Messages.NoCreativeUnClaim, "You can't unclaim this land. You can only make this claim larger or create additional claims.", null);
|
||||
this.addDefault(defaults, Messages.SuccessfulAbandon, "Claims abandoned. You now have {0} available claim blocks.", "0: remaining blocks");
|
||||
this.addDefault(defaults, Messages.RestoreNatureActivate, "Ready to restore some nature! Right click to restore nature, and use /BasicClaims to stop.", null);
|
||||
this.addDefault(defaults, Messages.RestoreNatureAggressiveActivate, "Aggressive mode activated. Do NOT use this underneath anything you want to keep! Right click to aggressively restore nature, and use /BasicClaims to stop.", null);
|
||||
this.addDefault(defaults, Messages.FillModeActive, "Fill mode activated with radius {0}. Right click an area to fill.", "0: fill radius");
|
||||
this.addDefault(defaults, Messages.TransferClaimPermission, "That command requires the administrative claims permission.", null);
|
||||
this.addDefault(defaults, Messages.TransferClaimMissing, "There's no claim here. Stand in the administrative claim you want to transfer.", null);
|
||||
this.addDefault(defaults, Messages.TransferClaimAdminOnly, "Only administrative claims may be transferred to a player.", null);
|
||||
this.addDefault(defaults, Messages.PlayerNotFound, "Player not found.", null);
|
||||
this.addDefault(defaults, Messages.TransferTopLevel, "Only top level claims (not subdivisions) may be transferred. Stand outside of the subdivision and try again.", null);
|
||||
this.addDefault(defaults, Messages.TransferSuccess, "Claim transferred.", null);
|
||||
this.addDefault(defaults, Messages.TrustListNoClaim, "Stand inside the claim you're curious about.", null);
|
||||
this.addDefault(defaults, Messages.ClearPermsOwnerOnly, "Only the claim owner can clear all permissions.", null);
|
||||
this.addDefault(defaults, Messages.UntrustIndividualAllClaims, "Revoked {0}'s access to ALL your claims. To set permissions for a single claim, stand inside it.", "0: untrusted player");
|
||||
this.addDefault(defaults, Messages.UntrustEveryoneAllClaims, "Cleared permissions in ALL your claims. To set permissions for a single claim, stand inside it.", null);
|
||||
this.addDefault(defaults, Messages.NoPermissionTrust, "You don't have {0}'s permission to manage permissions here.", "0: claim owner's name");
|
||||
this.addDefault(defaults, Messages.ClearPermissionsOneClaim, "Cleared permissions in this claim. To set permission for ALL your claims, stand outside them.", null);
|
||||
this.addDefault(defaults, Messages.UntrustIndividualSingleClaim, "Revoked {0}'s access to this claim. To set permissions for a ALL your claims, stand outside them.", "0: untrusted player");
|
||||
this.addDefault(defaults, Messages.OnlySellBlocks, "Claim blocks may only be sold, not purchased.", null);
|
||||
this.addDefault(defaults, Messages.BlockPurchaseCost, "Each claim block costs {0}. Your balance is {1}.", "0: cost of one block; 1: player's account balance");
|
||||
this.addDefault(defaults, Messages.ClaimBlockLimit, "You've reached your claim block limit. You can't purchase more.", null);
|
||||
this.addDefault(defaults, Messages.InsufficientFunds, "You don't have enough money. You need {0}, but you only have {1}.", "0: total cost; 1: player's account balance");
|
||||
this.addDefault(defaults, Messages.PurchaseConfirmation, "Withdrew {0} from your account. You now have {1} available claim blocks.", "0: total cost; 1: remaining blocks");
|
||||
this.addDefault(defaults, Messages.OnlyPurchaseBlocks, "Claim blocks may only be purchased, not sold.", null);
|
||||
this.addDefault(defaults, Messages.BlockSaleValue, "Each claim block is worth {0}. You have {1} available for sale.", "0: block value; 1: available blocks");
|
||||
this.addDefault(defaults, Messages.NotEnoughBlocksForSale, "You don't have that many claim blocks available for sale.", null);
|
||||
this.addDefault(defaults, Messages.BlockSaleConfirmation, "Deposited {0} in your account. You now have {1} available claim blocks.", "0: amount deposited; 1: remaining blocks");
|
||||
this.addDefault(defaults, Messages.AdminClaimsMode, "Administrative claims mode active. Any claims created will be free and editable by other administrators.", null);
|
||||
this.addDefault(defaults, Messages.BasicClaimsMode, "Returned to basic claim creation mode.", null);
|
||||
this.addDefault(defaults, Messages.SubdivisionMode, "Subdivision mode. Use your shovel to create subdivisions in your existing claims. Use /basicclaims to exit.", null);
|
||||
this.addDefault(defaults, Messages.SubdivisionDemo, "Want a demonstration? http://tinyurl.com/7urdtue", null);
|
||||
this.addDefault(defaults, Messages.DeleteClaimMissing, "There's no claim here.", null);
|
||||
this.addDefault(defaults, Messages.DeletionSubdivisionWarning, "This claim includes subdivisions. If you're sure you want to delete it, use /DeleteClaim again.", null);
|
||||
this.addDefault(defaults, Messages.DeleteSuccess, "Claim deleted.", null);
|
||||
this.addDefault(defaults, Messages.CantDeleteAdminClaim, "You don't have permission to delete administrative claims.", null);
|
||||
this.addDefault(defaults, Messages.DeleteAllSuccess, "Deleted all of {0}'s claims.", "0: owner's name");
|
||||
this.addDefault(defaults, Messages.NoDeletePermission, "You don't have permission to delete claims.", null);
|
||||
this.addDefault(defaults, Messages.AllAdminDeleted, "Deleted all administrative claims.", null);
|
||||
this.addDefault(defaults, Messages.AdjustBlocksSuccess, "Adjusted {0}'s bonus claim blocks by {1}. New total bonus blocks: {2}.", "0: player; 1: adjustment; 2: new total");
|
||||
this.addDefault(defaults, Messages.NotTrappedHere, "You can build here. Save yourself.", null);
|
||||
this.addDefault(defaults, Messages.TrappedOnCooldown, "You used /trapped within the last {0} hours. You have to wait about {1} more minutes before using it again.", "0: default cooldown hours; 1: remaining minutes");
|
||||
this.addDefault(defaults, Messages.RescuePending, "If you stay put for 10 seconds, you'll be teleported out. Please wait.", null);
|
||||
this.addDefault(defaults, Messages.NonSiegeWorld, "Siege is disabled here.", null);
|
||||
this.addDefault(defaults, Messages.AlreadySieging, "You're already involved in a siege.", null);
|
||||
this.addDefault(defaults, Messages.AlreadyUnderSiegePlayer, "{0} is already under siege. Join the party!", "0: defending player");
|
||||
this.addDefault(defaults, Messages.NotSiegableThere, "{0} isn't protected there.", "0: defending player");
|
||||
this.addDefault(defaults, Messages.SiegeTooFarAway, "You're too far away to siege.", null);
|
||||
this.addDefault(defaults, Messages.NoSiegeDefenseless, "That player is defenseless. Go pick on somebody else.", null);
|
||||
this.addDefault(defaults, Messages.AlreadyUnderSiegeArea, "That area is already under siege. Join the party!", null);
|
||||
this.addDefault(defaults, Messages.NoSiegeAdminClaim, "Siege is disabled in this area.", null);
|
||||
this.addDefault(defaults, Messages.SiegeOnCooldown, "You're still on siege cooldown for this defender or claim. Find another victim.", null);
|
||||
this.addDefault(defaults, Messages.SiegeAlert, "You're under siege! If you log out now, you will die. You must defeat {0}, wait for him to give up, or escape.", "0: attacker name");
|
||||
this.addDefault(defaults, Messages.SiegeConfirmed, "The siege has begun! If you log out now, you will die. You must defeat {0}, chase him away, or admit defeat and walk away.", "0: defender name");
|
||||
this.addDefault(defaults, Messages.AbandonClaimMissing, "Stand in the claim you want to delete, or consider /AbandonAllClaims.", null);
|
||||
this.addDefault(defaults, Messages.NotYourClaim, "This isn't your claim.", null);
|
||||
this.addDefault(defaults, Messages.DeleteTopLevelClaim, "To delete a subdivision, stand inside it. Otherwise, use /AbandonTopLevelClaim to delete this claim and all subdivisions.", null);
|
||||
this.addDefault(defaults, Messages.AbandonSuccess, "Claim abandoned. You now have {0} available claim blocks.", "0: remaining claim blocks");
|
||||
this.addDefault(defaults, Messages.CantGrantThatPermission, "You can't grant a permission you don't have yourself.", null);
|
||||
this.addDefault(defaults, Messages.GrantPermissionNoClaim, "Stand inside the claim where you want to grant permission.", null);
|
||||
this.addDefault(defaults, Messages.GrantPermissionConfirmation, "Granted {0} permission to {1} {2}.", "0: target player; 1: permission description; 2: scope (changed claims)");
|
||||
this.addDefault(defaults, Messages.ManageUniversalPermissionsInstruction, "To manage permissions for ALL your claims, stand outside them.", null);
|
||||
this.addDefault(defaults, Messages.ManageOneClaimPermissionsInstruction, "To manage permissions for a specific claim, stand inside it.", null);
|
||||
this.addDefault(defaults, Messages.CollectivePublic, "the public", "as in 'granted the public permission to...'");
|
||||
this.addDefault(defaults, Messages.BuildPermission, "build", null);
|
||||
this.addDefault(defaults, Messages.ContainersPermission, "access containers and animals", null);
|
||||
this.addDefault(defaults, Messages.AccessPermission, "use buttons and levers", null);
|
||||
this.addDefault(defaults, Messages.PermissionsPermission, "manage permissions", null);
|
||||
this.addDefault(defaults, Messages.LocationCurrentClaim, "in this claim", null);
|
||||
this.addDefault(defaults, Messages.LocationAllClaims, "in all your claims", null);
|
||||
this.addDefault(defaults, Messages.PvPImmunityStart, "You're protected from attack by other players as long as your inventory is empty.", null);
|
||||
this.addDefault(defaults, Messages.SiegeNoDrop, "You can't give away items while involved in a siege.", null);
|
||||
this.addDefault(defaults, Messages.DonateItemsInstruction, "To give away the item(s) in your hand, left-click the chest again.", null);
|
||||
this.addDefault(defaults, Messages.ChestFull, "This chest is full.", null);
|
||||
this.addDefault(defaults, Messages.DonationSuccess, "Item(s) transferred to chest!", null);
|
||||
this.addDefault(defaults, Messages.PlayerTooCloseForFire, "You can't start a fire this close to {0}.", "0: other player's name");
|
||||
this.addDefault(defaults, Messages.TooDeepToClaim, "This chest can't be protected because it's too deep underground. Consider moving it.", null);
|
||||
this.addDefault(defaults, Messages.ChestClaimConfirmation, "This chest is protected.", null);
|
||||
this.addDefault(defaults, Messages.AutomaticClaimNotification, "This chest and nearby blocks are protected from breakage and theft. The gold and glowstone blocks mark the protected area.", null);
|
||||
this.addDefault(defaults, Messages.TrustCommandAdvertisement, "Use the /trust command to grant other players access.", null);
|
||||
this.addDefault(defaults, Messages.GoldenShovelAdvertisement, "To claim more land, use a golden shovel.", null);
|
||||
this.addDefault(defaults, Messages.UnprotectedChestWarning, "This chest is NOT protected. Consider expanding an existing claim or creating a new one.", null);
|
||||
this.addDefault(defaults, Messages.ThatPlayerPvPImmune, "You can't injure defenseless players.", null);
|
||||
this.addDefault(defaults, Messages.CantFightWhileImmune, "You can't fight someone while you're protected from PvP.", null);
|
||||
this.addDefault(defaults, Messages.NoDamageClaimedEntity, "That belongs to {0}.", "0: owner name");
|
||||
this.addDefault(defaults, Messages.ShovelBasicClaimMode, "Shovel returned to basic claims mode.", null);
|
||||
this.addDefault(defaults, Messages.RemainingBlocks, "You may claim up to {0} more blocks.", "0: remaining blocks");
|
||||
this.addDefault(defaults, Messages.CreativeBasicsDemoAdvertisement, "Want a demonstration? http://tinyurl.com/c7bajb8", null);
|
||||
this.addDefault(defaults, Messages.SurvivalBasicsDemoAdvertisement, "Want a demonstration? http://tinyurl.com/6nkwegj", null);
|
||||
this.addDefault(defaults, Messages.TrappedChatKeyword, "trapped", "When mentioned in chat, players get information about the /trapped command.");
|
||||
this.addDefault(defaults, Messages.TrappedInstructions, "Are you trapped in someone's claim? Consider the /trapped command.", null);
|
||||
this.addDefault(defaults, Messages.PvPNoDrop, "You can't drop items while in PvP combat.", null);
|
||||
this.addDefault(defaults, Messages.SiegeNoTeleport, "You can't teleport out of a besieged area.", null);
|
||||
this.addDefault(defaults, Messages.BesiegedNoTeleport, "You can't teleport into a besieged area.", null);
|
||||
this.addDefault(defaults, Messages.SiegeNoContainers, "You can't access containers while involved in a siege.", null);
|
||||
this.addDefault(defaults, Messages.PvPNoContainers, "You can't access containers during PvP combat.", null);
|
||||
this.addDefault(defaults, Messages.PvPImmunityEnd, "Now you can fight with other players.", null);
|
||||
this.addDefault(defaults, Messages.NoBedPermission, "{0} hasn't given you permission to sleep here.", "0: claim owner");
|
||||
this.addDefault(defaults, Messages.NoWildernessBuckets, "You may only dump buckets inside your claim(s) or underground.", null);
|
||||
this.addDefault(defaults, Messages.NoLavaNearOtherPlayer, "You can't place lava this close to {0}.", "0: nearby player");
|
||||
this.addDefault(defaults, Messages.TooFarAway, "That's too far away.", null);
|
||||
this.addDefault(defaults, Messages.BlockNotClaimed, "No one has claimed this block.", null);
|
||||
this.addDefault(defaults, Messages.BlockClaimed, "That block has been claimed by {0}.", "0: claim owner");
|
||||
this.addDefault(defaults, Messages.SiegeNoShovel, "You can't use your shovel tool while involved in a siege.", null);
|
||||
this.addDefault(defaults, Messages.RestoreNaturePlayerInChunk, "Unable to restore. {0} is in that chunk.", "0: nearby player");
|
||||
this.addDefault(defaults, Messages.NoCreateClaimPermission, "You don't have permission to claim land.", null);
|
||||
this.addDefault(defaults, Messages.ResizeClaimTooSmall, "This new size would be too small. Claims must be at least {0} x {0}.", "0: minimum claim size");
|
||||
this.addDefault(defaults, Messages.ResizeNeedMoreBlocks, "You don't have enough blocks for this size. You need {0} more.", "0: how many needed");
|
||||
this.addDefault(defaults, Messages.ClaimResizeSuccess, "Claim resized. You now have {0} available claim blocks.", "0: remaining blocks");
|
||||
this.addDefault(defaults, Messages.ResizeFailOverlap, "Can't resize here because it would overlap another nearby claim.", null);
|
||||
this.addDefault(defaults, Messages.ResizeStart, "Resizing claim. Use your shovel again at the new location for this corner.", null);
|
||||
this.addDefault(defaults, Messages.ResizeFailOverlapSubdivision, "You can't create a subdivision here because it would overlap another subdivision. Consider /abandonclaim to delete it, or use your shovel at a corner to resize it.", null);
|
||||
this.addDefault(defaults, Messages.SubdivisionStart, "Subdivision corner set! Use your shovel at the location for the opposite corner of this new subdivision.", null);
|
||||
this.addDefault(defaults, Messages.CreateSubdivisionOverlap, "Your selected area overlaps another subdivision.", null);
|
||||
this.addDefault(defaults, Messages.SubdivisionSuccess, "Subdivision created! Use /trust to share it with friends.", null);
|
||||
this.addDefault(defaults, Messages.CreateClaimFailOverlap, "You can't create a claim here because it would overlap your other claim. Use /abandonclaim to delete it, or use your shovel at a corner to resize it.", null);
|
||||
this.addDefault(defaults, Messages.CreateClaimFailOverlapOtherPlayer, "You can't create a claim here because it would overlap {0}'s claim.", "0: other claim owner");
|
||||
this.addDefault(defaults, Messages.ClaimsDisabledWorld, "Land claims are disabled in this world.", null);
|
||||
this.addDefault(defaults, Messages.ClaimStart, "Claim corner set! Use the shovel again at the opposite corner to claim a rectangle of land. To cancel, put your shovel away.", null);
|
||||
this.addDefault(defaults, Messages.NewClaimTooSmall, "This claim would be too small. Any claim must be at least {0} x {0}.", "0: minimum claim size");
|
||||
this.addDefault(defaults, Messages.CreateClaimInsufficientBlocks, "You don't have enough blocks to claim that entire area. You need {0} more blocks.", "0: additional blocks needed");
|
||||
this.addDefault(defaults, Messages.AbandonClaimAdvertisement, "To delete another claim and free up some blocks, use /AbandonClaim.", null);
|
||||
this.addDefault(defaults, Messages.CreateClaimFailOverlapShort, "Your selected area overlaps an existing claim.", null);
|
||||
this.addDefault(defaults, Messages.CreateClaimSuccess, "Claim created! Use /trust to share it with friends.", null);
|
||||
this.addDefault(defaults, Messages.SiegeWinDoorsOpen, "Congratulations! Buttons and levers are temporarily unlocked (five minutes).", null);
|
||||
this.addDefault(defaults, Messages.RescueAbortedMoved, "You moved! Rescue cancelled.", null);
|
||||
this.addDefault(defaults, Messages.SiegeDoorsLockedEjection, "Looting time is up! Ejected from the claim.", null);
|
||||
this.addDefault(defaults, Messages.NoModifyDuringSiege, "Claims can't be modified while under siege.", null);
|
||||
this.addDefault(defaults, Messages.OnlyOwnersModifyClaims, "Only {0} can modify this claim.", "0: owner name");
|
||||
this.addDefault(defaults, Messages.NoBuildUnderSiege, "This claim is under siege by {0}. No one can build here.", "0: attacker name");
|
||||
this.addDefault(defaults, Messages.NoBuildPvP, "You can't build in claims during PvP combat.", null);
|
||||
this.addDefault(defaults, Messages.NoBuildPermission, "You don't have {0}'s permission to build here.", "0: owner name");
|
||||
this.addDefault(defaults, Messages.NonSiegeMaterial, "That material is too tough to break.", null);
|
||||
this.addDefault(defaults, Messages.NoOwnerBuildUnderSiege, "You can't make changes while under siege.", null);
|
||||
this.addDefault(defaults, Messages.NoAccessPermission, "You don't have {0}'s permission to use that.", "0: owner name. access permission controls buttons, levers, and beds");
|
||||
this.addDefault(defaults, Messages.NoContainersSiege, "This claim is under siege by {0}. No one can access containers here right now.", "0: attacker name");
|
||||
this.addDefault(defaults, Messages.NoContainersPermission, "You don't have {0}'s permission to use that.", "0: owner's name. containers also include crafting blocks");
|
||||
this.addDefault(defaults, Messages.OwnerNameForAdminClaims, "an administrator", "as in 'You don't have an administrator's permission to build here.'");
|
||||
this.addDefault(defaults, Messages.ClaimTooSmallForEntities, "This claim isn't big enough for that. Try enlarging it.", null);
|
||||
this.addDefault(defaults, Messages.TooManyEntitiesInClaim, "This claim has too many entities already. Try enlarging the claim or removing some animals, monsters, paintings, or minecarts.", null);
|
||||
this.addDefault(defaults, Messages.YouHaveNoClaims, "You don't have any land claims.", null);
|
||||
this.addDefault(defaults, Messages.ConfirmFluidRemoval, "Abandoning this claim will remove all your lava and water. If you're sure, use /AbandonClaim again.", null);
|
||||
this.addDefault(defaults, Messages.AutoBanNotify, "Auto-banned {0}({1}). See logs for details.", null);
|
||||
this.addDefault(defaults, Messages.AdjustGroupBlocksSuccess, "Adjusted bonus claim blocks for players with the {0} permission by {1}. New total: {2}.", "0: permission; 1: adjustment amount; 2: new total bonus");
|
||||
this.addDefault(defaults, Messages.InvalidPermissionID, "Please specify a player name, or a permission in [brackets].", null);
|
||||
this.addDefault(defaults, Messages.UntrustOwnerOnly, "Only {0} can revoke permissions here.", "0: claim owner's name");
|
||||
|
||||
//load the config file
|
||||
FileConfiguration config = YamlConfiguration.loadConfiguration(new File(messagesFilePath));
|
||||
|
||||
//for each message ID
|
||||
for(int i = 0; i < messageIDs.length; i++)
|
||||
{
|
||||
//get default for this message
|
||||
Messages messageID = messageIDs[i];
|
||||
CustomizableMessage messageData = defaults.get(messageID.name());
|
||||
|
||||
//if default is missing, log an error and use some fake data for now so that the plugin can run
|
||||
if(messageData == null)
|
||||
{
|
||||
GriefPrevention.AddLogEntry("Missing message for " + messageID.name() + ". Please contact the developer.");
|
||||
messageData = new CustomizableMessage(messageID, "Missing message! ID: " + messageID.name() + ". Please contact a server admin.", null);
|
||||
}
|
||||
|
||||
//read the message from the file, use default if necessary
|
||||
this.messages[messageID.ordinal()] = config.getString("Messages." + messageID.name() + ".Text", messageData.text);
|
||||
config.set("Messages." + messageID.name() + ".Text", this.messages[messageID.ordinal()]);
|
||||
|
||||
if(messageData.notes != null)
|
||||
{
|
||||
messageData.notes = config.getString("Messages." + messageID.name() + ".Notes", messageData.notes);
|
||||
config.set("Messages." + messageID.name() + ".Notes", messageData.notes);
|
||||
}
|
||||
}
|
||||
|
||||
//save any changes
|
||||
try
|
||||
{
|
||||
config.save(DataStore.messagesFilePath);
|
||||
}
|
||||
catch(IOException exception)
|
||||
{
|
||||
GriefPrevention.AddLogEntry("Unable to write to the configuration file at \"" + DataStore.messagesFilePath + "\"");
|
||||
}
|
||||
|
||||
defaults.clear();
|
||||
System.gc();
|
||||
}
|
||||
|
||||
private void addDefault(HashMap<String, CustomizableMessage> defaults,
|
||||
Messages id, String text, String notes)
|
||||
{
|
||||
CustomizableMessage message = new CustomizableMessage(id, text, notes);
|
||||
defaults.put(id.name(), message);
|
||||
}
|
||||
|
||||
public String getMessage(Messages messageID, String... args)
|
||||
{
|
||||
String message = messages[messageID.ordinal()];
|
||||
|
||||
for(int i = 0; i < args.length; i++)
|
||||
{
|
||||
String param = args[i];
|
||||
message = message.replace("{" + i + "}", param);
|
||||
}
|
||||
|
||||
return message;
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -25,11 +25,12 @@ import org.bukkit.Location;
|
|||
import org.bukkit.Material;
|
||||
import org.bukkit.World.Environment;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.entity.Animals;
|
||||
import org.bukkit.entity.Arrow;
|
||||
import org.bukkit.entity.Creature;
|
||||
import org.bukkit.entity.Enderman;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.entity.LivingEntity;
|
||||
import org.bukkit.entity.Monster;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.entity.ThrownPotion;
|
||||
import org.bukkit.entity.Vehicle;
|
||||
|
|
@ -44,6 +45,7 @@ import org.bukkit.event.entity.EntityDamageByEntityEvent;
|
|||
import org.bukkit.event.entity.EntityDamageEvent;
|
||||
import org.bukkit.event.entity.EntityDeathEvent;
|
||||
import org.bukkit.event.entity.EntityExplodeEvent;
|
||||
import org.bukkit.event.entity.ExpBottleEvent;
|
||||
import org.bukkit.event.entity.ItemSpawnEvent;
|
||||
import org.bukkit.event.painting.PaintingBreakByEntityEvent;
|
||||
import org.bukkit.event.painting.PaintingBreakEvent;
|
||||
|
|
@ -118,6 +120,17 @@ class EntityEventHandler implements Listener
|
|||
}
|
||||
}
|
||||
|
||||
//when an experience bottle explodes...
|
||||
@EventHandler(priority = EventPriority.LOWEST)
|
||||
public void onExpBottle(ExpBottleEvent event)
|
||||
{
|
||||
//if in a creative world, cancel the event (don't drop exp on the ground)
|
||||
if(GriefPrevention.instance.creativeRulesApply(event.getEntity().getLocation()))
|
||||
{
|
||||
event.setExperience(0);
|
||||
}
|
||||
}
|
||||
|
||||
//when a creature spawns...
|
||||
@EventHandler(priority = EventPriority.LOWEST)
|
||||
public void onEntitySpawn(CreatureSpawnEvent event)
|
||||
|
|
@ -129,7 +142,7 @@ class EntityEventHandler implements Listener
|
|||
|
||||
//chicken eggs and breeding could potentially make a mess in the wilderness, once griefers get involved
|
||||
SpawnReason reason = event.getSpawnReason();
|
||||
if(reason == SpawnReason.EGG || reason == SpawnReason.BREEDING)
|
||||
if(reason != SpawnReason.SPAWNER_EGG && reason != SpawnReason.BUILD_IRONGOLEM && reason != SpawnReason.BUILD_SNOWMAN)
|
||||
{
|
||||
event.setCancelled(true);
|
||||
return;
|
||||
|
|
@ -241,6 +254,23 @@ class EntityEventHandler implements Listener
|
|||
{
|
||||
event.setCancelled(true);
|
||||
GriefPrevention.sendMessage(event.getPlayer(), TextMode.Err, noBuildReason);
|
||||
return;
|
||||
}
|
||||
|
||||
//otherwise, apply entity-count limitations for creative worlds
|
||||
else if(GriefPrevention.instance.creativeRulesApply(event.getPainting().getLocation()))
|
||||
{
|
||||
PlayerData playerData = this.dataStore.getPlayerData(event.getPlayer().getName());
|
||||
Claim claim = this.dataStore.getClaimAt(event.getBlock().getLocation(), false, playerData.lastClaim);
|
||||
if(claim == null) return;
|
||||
|
||||
String noEntitiesReason = claim.allowMoreEntities();
|
||||
if(noEntitiesReason != null)
|
||||
{
|
||||
GriefPrevention.sendMessage(event.getPlayer(), TextMode.Err, noEntitiesReason);
|
||||
event.setCancelled(true);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -251,6 +281,9 @@ class EntityEventHandler implements Listener
|
|||
//only actually interested in entities damaging entities (ignoring environmental damage)
|
||||
if(!(event instanceof EntityDamageByEntityEvent)) return;
|
||||
|
||||
//monsters are never protected
|
||||
if(event.getEntity() instanceof Monster) return;
|
||||
|
||||
EntityDamageByEntityEvent subEvent = (EntityDamageByEntityEvent) event;
|
||||
|
||||
//determine which player is attacking, if any
|
||||
|
|
@ -300,14 +333,14 @@ class EntityEventHandler implements Listener
|
|||
if(defenderData.pvpImmune)
|
||||
{
|
||||
event.setCancelled(true);
|
||||
GriefPrevention.sendMessage(attacker, TextMode.Err, "You can't injure defenseless players.");
|
||||
GriefPrevention.sendMessage(attacker, TextMode.Err, Messages.ThatPlayerPvPImmune);
|
||||
return;
|
||||
}
|
||||
|
||||
if(attackerData.pvpImmune)
|
||||
{
|
||||
event.setCancelled(true);
|
||||
GriefPrevention.sendMessage(attacker, TextMode.Err, "You can't fight someone while you're protected from PvP.");
|
||||
GriefPrevention.sendMessage(attacker, TextMode.Err, Messages.CantFightWhileImmune);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
|
@ -327,12 +360,21 @@ class EntityEventHandler implements Listener
|
|||
//so unless precautions are taken by the owner, a resourceful thief might find ways to steal anyway
|
||||
|
||||
//if theft protection is enabled
|
||||
if(GriefPrevention.instance.config_claims_preventTheft && event instanceof EntityDamageByEntityEvent)
|
||||
if(event instanceof EntityDamageByEntityEvent)
|
||||
{
|
||||
//if the entity is an animal or a vehicle
|
||||
if (subEvent.getEntity() instanceof Animals || subEvent.getEntity() instanceof Vehicle)
|
||||
//if the entity is an non-monster creature (remember monsters disqualified above), or a vehicle
|
||||
if ((subEvent.getEntity() instanceof Creature && GriefPrevention.instance.config_claims_protectCreatures) ||
|
||||
(subEvent.getEntity() instanceof Vehicle && GriefPrevention.instance.config_claims_preventTheft))
|
||||
{
|
||||
Claim claim = this.dataStore.getClaimAt(event.getEntity().getLocation(), false, null);
|
||||
Claim cachedClaim = null;
|
||||
PlayerData playerData = null;
|
||||
if(attacker != null)
|
||||
{
|
||||
playerData = this.dataStore.getPlayerData(attacker.getName());
|
||||
cachedClaim = playerData.lastClaim;
|
||||
}
|
||||
|
||||
Claim claim = this.dataStore.getClaimAt(event.getEntity().getLocation(), false, cachedClaim);
|
||||
|
||||
//if it's claimed
|
||||
if(claim != null)
|
||||
|
|
@ -350,7 +392,13 @@ class EntityEventHandler implements Listener
|
|||
if(noContainersReason != null)
|
||||
{
|
||||
event.setCancelled(true);
|
||||
GriefPrevention.sendMessage(attacker, TextMode.Err, "That belongs to " + claim.getOwnerName() + ".");
|
||||
GriefPrevention.sendMessage(attacker, TextMode.Err, Messages.NoDamageClaimedEntity, claim.getOwnerName());
|
||||
}
|
||||
|
||||
//cache claim for later
|
||||
if(playerData != null)
|
||||
{
|
||||
playerData.lastClaim = claim;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -53,13 +53,22 @@ class EquipShovelProcessingTask implements Runnable
|
|||
if(playerData.shovelMode != ShovelMode.Basic)
|
||||
{
|
||||
playerData.shovelMode = ShovelMode.Basic;
|
||||
GriefPrevention.sendMessage(player, TextMode.Info, "Shovel returned to basic claims mode.");
|
||||
GriefPrevention.sendMessage(player, TextMode.Info, Messages.ShovelBasicClaimMode);
|
||||
}
|
||||
|
||||
int remainingBlocks = playerData.getRemainingClaimBlocks();
|
||||
|
||||
//instruct him in the steps to create a claim
|
||||
GriefPrevention.sendMessage(player, TextMode.Instr, "You may claim up to " + String.valueOf(remainingBlocks) + " more blocks.");
|
||||
GriefPrevention.sendMessage(player, TextMode.Instr, "Want a demonstration? http://tinyurl.com/6nkwegj");
|
||||
GriefPrevention.sendMessage(player, TextMode.Instr, Messages.RemainingBlocks, String.valueOf(remainingBlocks));
|
||||
|
||||
//demo link changes based on game mode
|
||||
if(GriefPrevention.instance.creativeRulesApply(player.getLocation()))
|
||||
{
|
||||
GriefPrevention.sendMessage(player, TextMode.Instr, Messages.CreativeBasicsDemoAdvertisement);
|
||||
}
|
||||
else
|
||||
{
|
||||
GriefPrevention.sendMessage(player, TextMode.Instr, Messages.SurvivalBasicsDemoAdvertisement);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -35,6 +35,7 @@ import org.bukkit.Location;
|
|||
import org.bukkit.Material;
|
||||
import org.bukkit.OfflinePlayer;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.World.Environment;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.block.BlockFace;
|
||||
import org.bukkit.command.*;
|
||||
|
|
@ -63,6 +64,7 @@ public class GriefPrevention extends JavaPlugin
|
|||
public ArrayList<World> config_claims_enabledCreativeWorlds; //list of worlds where additional creative mode anti-grief rules apply
|
||||
|
||||
public boolean config_claims_preventTheft; //whether containers and crafting blocks are protectable
|
||||
public boolean config_claims_protectCreatures; //whether claimed animals may be injured by players without permission
|
||||
public boolean config_claims_preventButtonsSwitches; //whether buttons and switches are protectable
|
||||
|
||||
public int config_claims_initialBlocks; //the number of claim blocks a new player starts with
|
||||
|
|
@ -101,6 +103,8 @@ public class GriefPrevention extends JavaPlugin
|
|||
public double config_economy_claimBlocksSellValue; //return on a sold claim block. set to zero to disable sale.
|
||||
|
||||
public boolean config_blockSurfaceExplosions; //whether creeper/TNT explosions near or above the surface destroy blocks
|
||||
public boolean config_blockWildernessWaterBuckets; //whether players can dump water buckets outside their claims
|
||||
public boolean config_blockSkyTrees; //whether players can build trees on platforms in the sky
|
||||
|
||||
public boolean config_fireSpreads; //whether fire spreads outside of claims
|
||||
public boolean config_fireDestroys; //whether fire destroys blocks outside of claims
|
||||
|
|
@ -204,6 +208,7 @@ public class GriefPrevention extends JavaPlugin
|
|||
}
|
||||
|
||||
this.config_claims_preventTheft = config.getBoolean("GriefPrevention.Claims.PreventTheft", true);
|
||||
this.config_claims_protectCreatures = config.getBoolean("GriefPrevention.Claims.ProtectCreatures", true);
|
||||
this.config_claims_preventButtonsSwitches = config.getBoolean("GriefPrevention.Claims.PreventButtonsSwitches", true);
|
||||
this.config_claims_initialBlocks = config.getInt("GriefPrevention.Claims.InitialBlocks", 100);
|
||||
this.config_claims_blocksAccruedPerHour = config.getInt("GriefPrevention.Claims.BlocksAccruedPerHour", 100);
|
||||
|
|
@ -236,6 +241,8 @@ public class GriefPrevention extends JavaPlugin
|
|||
this.config_economy_claimBlocksSellValue = config.getDouble("GriefPrevention.Economy.ClaimBlocksSellValue", 0);
|
||||
|
||||
this.config_blockSurfaceExplosions = config.getBoolean("GriefPrevention.BlockSurfaceExplosions", true);
|
||||
this.config_blockWildernessWaterBuckets = config.getBoolean("GriefPrevention.LimitSurfaceWaterBuckets", true);
|
||||
this.config_blockSkyTrees = config.getBoolean("GriefPrevention.LimitSkyTrees", true);
|
||||
|
||||
this.config_fireSpreads = config.getBoolean("GriefPrevention.FireSpreads", false);
|
||||
this.config_fireDestroys = config.getBoolean("GriefPrevention.FireDestroys", false);
|
||||
|
|
@ -320,6 +327,7 @@ public class GriefPrevention extends JavaPlugin
|
|||
config.set("GriefPrevention.Claims.Worlds", claimsEnabledWorldNames);
|
||||
config.set("GriefPrevention.Claims.CreativeRulesWorlds", creativeClaimsEnabledWorldNames);
|
||||
config.set("GriefPrevention.Claims.PreventTheft", this.config_claims_preventTheft);
|
||||
config.set("GriefPrevention.Claims.ProtectCreatures", this.config_claims_protectCreatures);
|
||||
config.set("GriefPrevention.Claims.PreventButtonsSwitches", this.config_claims_preventButtonsSwitches);
|
||||
config.set("GriefPrevention.Claims.InitialBlocks", this.config_claims_initialBlocks);
|
||||
config.set("GriefPrevention.Claims.BlocksAccruedPerHour", this.config_claims_blocksAccruedPerHour);
|
||||
|
|
@ -352,6 +360,8 @@ public class GriefPrevention extends JavaPlugin
|
|||
config.set("GriefPrevention.Economy.ClaimBlocksSellValue", this.config_economy_claimBlocksSellValue);
|
||||
|
||||
config.set("GriefPrevention.BlockSurfaceExplosions", this.config_blockSurfaceExplosions);
|
||||
config.set("GriefPrevention.LimitSurfaceWaterBuckets", this.config_blockWildernessWaterBuckets);
|
||||
config.set("GriefPrevention.LimitSkyTrees", this.config_blockSkyTrees);
|
||||
|
||||
config.set("GriefPrevention.FireSpreads", this.config_fireSpreads);
|
||||
config.set("GriefPrevention.FireDestroys", this.config_fireDestroys);
|
||||
|
|
@ -392,6 +402,10 @@ public class GriefPrevention extends JavaPlugin
|
|||
this.getServer().getScheduler().scheduleSyncRepeatingTask(this, task, 20L * 60 * 5, 20L * 60 * 5);
|
||||
}
|
||||
|
||||
//start the recurring cleanup event for entities in creative worlds
|
||||
EntityCleanupTask task = new EntityCleanupTask(0);
|
||||
this.getServer().getScheduler().scheduleSyncDelayedTask(GriefPrevention.instance, task, 20L);
|
||||
|
||||
//register for events
|
||||
PluginManager pluginManager = this.getServer().getPluginManager();
|
||||
|
||||
|
|
@ -475,11 +489,11 @@ public class GriefPrevention extends JavaPlugin
|
|||
//toggle ignore claims mode on or off
|
||||
if(!playerData.ignoreClaims)
|
||||
{
|
||||
GriefPrevention.sendMessage(player, TextMode.Success, "Now respecting claims.");
|
||||
GriefPrevention.sendMessage(player, TextMode.Success, Messages.RespectingClaims);
|
||||
}
|
||||
else
|
||||
{
|
||||
GriefPrevention.sendMessage(player, TextMode.Success, "Now ignoring claims.");
|
||||
GriefPrevention.sendMessage(player, TextMode.Success, Messages.IgnoringClaims);
|
||||
}
|
||||
|
||||
return true;
|
||||
|
|
@ -492,7 +506,7 @@ public class GriefPrevention extends JavaPlugin
|
|||
|
||||
if(creativeRulesApply(player.getLocation()))
|
||||
{
|
||||
GriefPrevention.sendMessage(player, TextMode.Err, "Creative mode claims can't be abandoned.");
|
||||
GriefPrevention.sendMessage(player, TextMode.Err, Messages.NoCreativeUnClaim);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -503,7 +517,7 @@ public class GriefPrevention extends JavaPlugin
|
|||
//check count
|
||||
if(originalClaimCount == 0)
|
||||
{
|
||||
GriefPrevention.sendMessage(player, TextMode.Err, "You haven't claimed any land.");
|
||||
GriefPrevention.sendMessage(player, TextMode.Err, Messages.YouHaveNoClaims);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -512,7 +526,7 @@ public class GriefPrevention extends JavaPlugin
|
|||
|
||||
//inform the player
|
||||
int remainingBlocks = playerData.getRemainingClaimBlocks();
|
||||
GriefPrevention.sendMessage(player, TextMode.Success, "Claims abandoned. You now have " + String.valueOf(remainingBlocks) + " available claim blocks.");
|
||||
GriefPrevention.sendMessage(player, TextMode.Success, Messages.SuccessfulAbandon, String.valueOf(remainingBlocks));
|
||||
|
||||
//revert any current visualization
|
||||
Visualization.Revert(player);
|
||||
|
|
@ -526,7 +540,7 @@ public class GriefPrevention extends JavaPlugin
|
|||
//change shovel mode
|
||||
PlayerData playerData = this.dataStore.getPlayerData(player.getName());
|
||||
playerData.shovelMode = ShovelMode.RestoreNature;
|
||||
GriefPrevention.sendMessage(player, TextMode.Instr, "Ready to restore some nature! Right click to restore nature, and use /BasicClaims to stop.");
|
||||
GriefPrevention.sendMessage(player, TextMode.Instr, Messages.RestoreNatureActivate);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -536,7 +550,7 @@ public class GriefPrevention extends JavaPlugin
|
|||
//change shovel mode
|
||||
PlayerData playerData = this.dataStore.getPlayerData(player.getName());
|
||||
playerData.shovelMode = ShovelMode.RestoreNatureAggressive;
|
||||
GriefPrevention.sendMessage(player, TextMode.Warn, "Aggressive mode activated. Do NOT use this underneath anything you want to keep! Right click to aggressively restore nature, and use /BasicClaims to stop.");
|
||||
GriefPrevention.sendMessage(player, TextMode.Warn, Messages.RestoreNatureAggressiveActivate);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -560,7 +574,7 @@ public class GriefPrevention extends JavaPlugin
|
|||
|
||||
if(playerData.fillRadius < 0) playerData.fillRadius = 2;
|
||||
|
||||
GriefPrevention.sendMessage(player, TextMode.Success, "Fill mode activated with radius " + playerData.fillRadius + ". Right-click an area to fill.");
|
||||
GriefPrevention.sendMessage(player, TextMode.Success, Messages.FillModeActive, String.valueOf(playerData.fillRadius));
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -585,7 +599,7 @@ public class GriefPrevention extends JavaPlugin
|
|||
//check additional permission
|
||||
if(!player.hasPermission("griefprevention.adminclaims"))
|
||||
{
|
||||
GriefPrevention.sendMessage(player, TextMode.Err, "That command requires the administrative claims permission.");
|
||||
GriefPrevention.sendMessage(player, TextMode.Err, Messages.TransferClaimPermission);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -593,19 +607,19 @@ public class GriefPrevention extends JavaPlugin
|
|||
Claim claim = this.dataStore.getClaimAt(player.getLocation(), true, null);
|
||||
if(claim == null)
|
||||
{
|
||||
GriefPrevention.sendMessage(player, TextMode.Instr, "There's no claim here. Stand in the administrative claim you want to transfer.");
|
||||
GriefPrevention.sendMessage(player, TextMode.Instr, Messages.TransferClaimMissing);
|
||||
return true;
|
||||
}
|
||||
else if(!claim.isAdminClaim())
|
||||
{
|
||||
GriefPrevention.sendMessage(player, TextMode.Err, "Only administrative claims may be transferred to a player.");
|
||||
GriefPrevention.sendMessage(player, TextMode.Err, Messages.TransferClaimAdminOnly);
|
||||
return true;
|
||||
}
|
||||
|
||||
OfflinePlayer targetPlayer = this.resolvePlayer(args[0]);
|
||||
if(targetPlayer == null)
|
||||
{
|
||||
GriefPrevention.sendMessage(player, TextMode.Err, "Player not found.");
|
||||
GriefPrevention.sendMessage(player, TextMode.Err, Messages.PlayerNotFound);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -616,12 +630,12 @@ public class GriefPrevention extends JavaPlugin
|
|||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
GriefPrevention.sendMessage(player, TextMode.Instr, "Only top level claims (not subdivisions) may be transferred. Stand outside of the subdivision and try again.");
|
||||
GriefPrevention.sendMessage(player, TextMode.Instr, Messages.TransferTopLevel);
|
||||
return true;
|
||||
}
|
||||
|
||||
//confirm
|
||||
GriefPrevention.sendMessage(player, TextMode.Success, "Claim transferred.");
|
||||
GriefPrevention.sendMessage(player, TextMode.Success, Messages.TransferSuccess);
|
||||
GriefPrevention.AddLogEntry(player.getName() + " transferred a claim at " + GriefPrevention.getfriendlyLocationString(claim.getLesserBoundaryCorner()) + " to " + targetPlayer.getName() + ".");
|
||||
|
||||
return true;
|
||||
|
|
@ -635,7 +649,7 @@ public class GriefPrevention extends JavaPlugin
|
|||
//if no claim here, error message
|
||||
if(claim == null)
|
||||
{
|
||||
GriefPrevention.sendMessage(player, TextMode.Err, "Stand inside the claim you're curious about.");
|
||||
GriefPrevention.sendMessage(player, TextMode.Err, Messages.TrustListNoClaim);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -703,7 +717,7 @@ public class GriefPrevention extends JavaPlugin
|
|||
return true;
|
||||
}
|
||||
|
||||
//untrust <player>
|
||||
//untrust <player> or untrust [<group>]
|
||||
else if(cmd.getName().equalsIgnoreCase("untrust") && player != null)
|
||||
{
|
||||
//requires exactly one parameter, the other player's name
|
||||
|
|
@ -723,18 +737,20 @@ public class GriefPrevention extends JavaPlugin
|
|||
}
|
||||
else
|
||||
{
|
||||
GriefPrevention.sendMessage(player, TextMode.Err, "Only the claim owner can clear all permissions.");
|
||||
GriefPrevention.sendMessage(player, TextMode.Err, Messages.ClearPermsOwnerOnly);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
//validate player argument
|
||||
//validate player argument or group argument
|
||||
if(!args[0].startsWith("[") || !args[0].endsWith("]"))
|
||||
{
|
||||
otherPlayer = this.resolvePlayer(args[0]);
|
||||
if(!clearPermissions && otherPlayer == null && !args[0].equals("public"))
|
||||
{
|
||||
GriefPrevention.sendMessage(player, TextMode.Err, "Player not found.");
|
||||
GriefPrevention.sendMessage(player, TextMode.Err, Messages.PlayerNotFound);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -742,6 +758,7 @@ public class GriefPrevention extends JavaPlugin
|
|||
if(otherPlayer != null)
|
||||
args[0] = otherPlayer.getName();
|
||||
}
|
||||
}
|
||||
|
||||
//if no claim here, apply changes to all his claims
|
||||
if(claim == null)
|
||||
|
|
@ -777,18 +794,18 @@ public class GriefPrevention extends JavaPlugin
|
|||
//confirmation message
|
||||
if(!clearPermissions)
|
||||
{
|
||||
GriefPrevention.sendMessage(player, TextMode.Success, "Revoked " + args[0] + "'s access to ALL your claims. To set permissions for a single claim, stand inside it.");
|
||||
GriefPrevention.sendMessage(player, TextMode.Success, Messages.UntrustIndividualAllClaims, args[0]);
|
||||
}
|
||||
else
|
||||
{
|
||||
GriefPrevention.sendMessage(player, TextMode.Success, "Cleared permissions in ALL your claims. To set permissions for a single claim, stand inside it.");
|
||||
GriefPrevention.sendMessage(player, TextMode.Success, Messages.UntrustEveryoneAllClaims);
|
||||
}
|
||||
}
|
||||
|
||||
//otherwise, apply changes to only this claim
|
||||
else if(claim.allowGrantPermission(player) != null)
|
||||
{
|
||||
GriefPrevention.sendMessage(player, TextMode.Err, "You don't have " + claim.getOwnerName() + "'s permission to manage permissions here.");
|
||||
GriefPrevention.sendMessage(player, TextMode.Err, Messages.NoPermissionTrust, claim.getOwnerName());
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -796,7 +813,7 @@ public class GriefPrevention extends JavaPlugin
|
|||
if(clearPermissions)
|
||||
{
|
||||
claim.clearPermissions();
|
||||
GriefPrevention.sendMessage(player, TextMode.Success, "Cleared permissions in this claim. To set permission for ALL your claims, stand outside them.");
|
||||
GriefPrevention.sendMessage(player, TextMode.Success, Messages.ClearPermissionsOneClaim);
|
||||
}
|
||||
|
||||
//otherwise individual permission drop
|
||||
|
|
@ -813,7 +830,11 @@ public class GriefPrevention extends JavaPlugin
|
|||
args[0] = "the public";
|
||||
}
|
||||
|
||||
GriefPrevention.sendMessage(player, TextMode.Success, "Revoked " + args[0] + "'s access to this claim. To set permissions for a ALL your claims, stand outside them.");
|
||||
GriefPrevention.sendMessage(player, TextMode.Success, Messages.UntrustIndividualSingleClaim, args[0]);
|
||||
}
|
||||
else
|
||||
{
|
||||
GriefPrevention.sendMessage(player, TextMode.Success, Messages.UntrustOwnerOnly, claim.getOwnerName());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -866,14 +887,14 @@ public class GriefPrevention extends JavaPlugin
|
|||
//if purchase disabled, send error message
|
||||
if(GriefPrevention.instance.config_economy_claimBlocksPurchaseCost == 0)
|
||||
{
|
||||
GriefPrevention.sendMessage(player, TextMode.Err, "Claim blocks may only be sold, not purchased.");
|
||||
GriefPrevention.sendMessage(player, TextMode.Err, Messages.OnlySellBlocks);
|
||||
return true;
|
||||
}
|
||||
|
||||
//if no parameter, just tell player cost per block and balance
|
||||
if(args.length != 1)
|
||||
{
|
||||
GriefPrevention.sendMessage(player, TextMode.Info, "Each claim block costs " + GriefPrevention.instance.config_economy_claimBlocksPurchaseCost + ". Your balance is " + GriefPrevention.economy.getBalance(player.getName()) + ".");
|
||||
GriefPrevention.sendMessage(player, TextMode.Info, Messages.BlockPurchaseCost, String.valueOf(GriefPrevention.instance.config_economy_claimBlocksPurchaseCost), String.valueOf(GriefPrevention.economy.getBalance(player.getName())));
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
@ -886,7 +907,7 @@ public class GriefPrevention extends JavaPlugin
|
|||
//if the player is at his max, tell him so
|
||||
if(maxPurchasable <= 0)
|
||||
{
|
||||
GriefPrevention.sendMessage(player, TextMode.Err, "You've reached your claim block limit. You can't purchase more.");
|
||||
GriefPrevention.sendMessage(player, TextMode.Err, Messages.ClaimBlockLimit);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -912,7 +933,7 @@ public class GriefPrevention extends JavaPlugin
|
|||
double totalCost = blockCount * GriefPrevention.instance.config_economy_claimBlocksPurchaseCost;
|
||||
if(totalCost > balance)
|
||||
{
|
||||
GriefPrevention.sendMessage(player, TextMode.Err, "You don't have enough money. You need " + totalCost + ", but you only have " + balance + ".");
|
||||
GriefPrevention.sendMessage(player, TextMode.Err, Messages.InsufficientFunds, String.valueOf(totalCost), String.valueOf(balance));
|
||||
}
|
||||
|
||||
//otherwise carry out transaction
|
||||
|
|
@ -926,7 +947,7 @@ public class GriefPrevention extends JavaPlugin
|
|||
this.dataStore.savePlayerData(player.getName(), playerData);
|
||||
|
||||
//inform player
|
||||
GriefPrevention.sendMessage(player, TextMode.Success, "Withdrew " + totalCost + " from your account. You now have " + playerData.getRemainingClaimBlocks() + " available claim blocks.");
|
||||
GriefPrevention.sendMessage(player, TextMode.Success, Messages.PurchaseConfirmation, String.valueOf(totalCost), String.valueOf(playerData.getRemainingClaimBlocks()));
|
||||
}
|
||||
|
||||
return true;
|
||||
|
|
@ -942,7 +963,7 @@ public class GriefPrevention extends JavaPlugin
|
|||
//if disabled, error message
|
||||
if(GriefPrevention.instance.config_economy_claimBlocksSellValue == 0)
|
||||
{
|
||||
GriefPrevention.sendMessage(player, TextMode.Err, "Claim blocks may only be purchased, not sold.");
|
||||
GriefPrevention.sendMessage(player, TextMode.Err, Messages.OnlyPurchaseBlocks);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -953,7 +974,7 @@ public class GriefPrevention extends JavaPlugin
|
|||
//if no amount provided, just tell player value per block sold, and how many he can sell
|
||||
if(args.length != 1)
|
||||
{
|
||||
GriefPrevention.sendMessage(player, TextMode.Info, "Each claim block is worth " + GriefPrevention.instance.config_economy_claimBlocksSellValue + ". You have " + availableBlocks + " available for sale.");
|
||||
GriefPrevention.sendMessage(player, TextMode.Info, Messages.BlockSaleValue, String.valueOf(GriefPrevention.instance.config_economy_claimBlocksSellValue), String.valueOf(availableBlocks));
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
@ -971,7 +992,7 @@ public class GriefPrevention extends JavaPlugin
|
|||
//if he doesn't have enough blocks, tell him so
|
||||
if(blockCount > availableBlocks)
|
||||
{
|
||||
GriefPrevention.sendMessage(player, TextMode.Err, "You don't have that many claim blocks available for sale.");
|
||||
GriefPrevention.sendMessage(player, TextMode.Err, Messages.NotEnoughBlocksForSale);
|
||||
}
|
||||
|
||||
//otherwise carry out the transaction
|
||||
|
|
@ -986,7 +1007,7 @@ public class GriefPrevention extends JavaPlugin
|
|||
this.dataStore.savePlayerData(player.getName(), playerData);
|
||||
|
||||
//inform player
|
||||
GriefPrevention.sendMessage(player, TextMode.Success, "Deposited " + totalValue + " in your account. You now have " + playerData.getRemainingClaimBlocks() + " available claim blocks.");
|
||||
GriefPrevention.sendMessage(player, TextMode.Success, Messages.BlockSaleConfirmation, String.valueOf(totalValue), String.valueOf(playerData.getRemainingClaimBlocks()));
|
||||
}
|
||||
|
||||
return true;
|
||||
|
|
@ -997,7 +1018,7 @@ public class GriefPrevention extends JavaPlugin
|
|||
{
|
||||
PlayerData playerData = this.dataStore.getPlayerData(player.getName());
|
||||
playerData.shovelMode = ShovelMode.Admin;
|
||||
GriefPrevention.sendMessage(player, TextMode.Success, "Administrative claims mode active. Any claims created will be free and editable by other administrators.");
|
||||
GriefPrevention.sendMessage(player, TextMode.Success, Messages.AdminClaimsMode);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
@ -1008,7 +1029,7 @@ public class GriefPrevention extends JavaPlugin
|
|||
PlayerData playerData = this.dataStore.getPlayerData(player.getName());
|
||||
playerData.shovelMode = ShovelMode.Basic;
|
||||
playerData.claimSubdividing = null;
|
||||
GriefPrevention.sendMessage(player, TextMode.Success, "Returned to basic claim creation mode.");
|
||||
GriefPrevention.sendMessage(player, TextMode.Success, Messages.BasicClaimsMode);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
@ -1019,7 +1040,8 @@ public class GriefPrevention extends JavaPlugin
|
|||
PlayerData playerData = this.dataStore.getPlayerData(player.getName());
|
||||
playerData.shovelMode = ShovelMode.Subdivide;
|
||||
playerData.claimSubdividing = null;
|
||||
GriefPrevention.sendMessage(player, TextMode.Instr, "Subdivision mode. Use your shovel to create subdivisions in your existing claims. Use /basicclaims to exit.");
|
||||
GriefPrevention.sendMessage(player, TextMode.Instr, Messages.SubdivisionMode);
|
||||
GriefPrevention.sendMessage(player, TextMode.Instr, Messages.SubdivisionDemo);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
@ -1032,7 +1054,7 @@ public class GriefPrevention extends JavaPlugin
|
|||
|
||||
if(claim == null)
|
||||
{
|
||||
GriefPrevention.sendMessage(player, TextMode.Err, "There's no claim here.");
|
||||
GriefPrevention.sendMessage(player, TextMode.Err, Messages.DeleteClaimMissing);
|
||||
}
|
||||
|
||||
else
|
||||
|
|
@ -1043,14 +1065,14 @@ public class GriefPrevention extends JavaPlugin
|
|||
PlayerData playerData = this.dataStore.getPlayerData(player.getName());
|
||||
if(claim.children.size() > 0 && !playerData.warnedAboutMajorDeletion)
|
||||
{
|
||||
GriefPrevention.sendMessage(player, TextMode.Warn, "This claim includes subdivisions. If you're sure you want to delete it, use /DeleteClaim again.");
|
||||
GriefPrevention.sendMessage(player, TextMode.Warn, Messages.DeletionSubdivisionWarning);
|
||||
playerData.warnedAboutMajorDeletion = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
claim.removeSurfaceFluids(null);
|
||||
this.dataStore.deleteClaim(claim);
|
||||
GriefPrevention.sendMessage(player, TextMode.Success, "Claim deleted.");
|
||||
GriefPrevention.sendMessage(player, TextMode.Success, Messages.DeleteSuccess);
|
||||
GriefPrevention.AddLogEntry(player.getName() + " deleted " + claim.getOwnerName() + "'s claim at " + GriefPrevention.getfriendlyLocationString(claim.getLesserBoundaryCorner()));
|
||||
|
||||
//revert any current visualization
|
||||
|
|
@ -1061,7 +1083,7 @@ public class GriefPrevention extends JavaPlugin
|
|||
}
|
||||
else
|
||||
{
|
||||
GriefPrevention.sendMessage(player, TextMode.Err, "You don't have permission to delete administrative claims.");
|
||||
GriefPrevention.sendMessage(player, TextMode.Err, Messages.CantDeleteAdminClaim);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1069,7 +1091,7 @@ public class GriefPrevention extends JavaPlugin
|
|||
}
|
||||
|
||||
//deleteallclaims <player>
|
||||
else if(cmd.getName().equalsIgnoreCase("deleteallclaims") && player != null)
|
||||
else if(cmd.getName().equalsIgnoreCase("deleteallclaims"))
|
||||
{
|
||||
//requires exactly one parameter, the other player's name
|
||||
if(args.length != 1) return false;
|
||||
|
|
@ -1078,55 +1100,115 @@ public class GriefPrevention extends JavaPlugin
|
|||
OfflinePlayer otherPlayer = this.resolvePlayer(args[0]);
|
||||
if(otherPlayer == null)
|
||||
{
|
||||
GriefPrevention.sendMessage(player, TextMode.Err, "Player not found.");
|
||||
GriefPrevention.sendMessage(player, TextMode.Err, Messages.PlayerNotFound);
|
||||
return true;
|
||||
}
|
||||
|
||||
//delete all that player's claims
|
||||
this.dataStore.deleteClaimsForPlayer(otherPlayer.getName(), true);
|
||||
|
||||
GriefPrevention.sendMessage(player, TextMode.Success, "Deleted all of " + otherPlayer.getName() + "'s claims.");
|
||||
GriefPrevention.sendMessage(player, TextMode.Success, Messages.DeleteAllSuccess, otherPlayer.getName());
|
||||
if(player != null)
|
||||
{
|
||||
GriefPrevention.AddLogEntry(player.getName() + " deleted all claims belonging to " + otherPlayer.getName() + ".");
|
||||
|
||||
//revert any current visualization
|
||||
Visualization.Revert(player);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//deathblow <player> [recipientPlayer]
|
||||
else if(cmd.getName().equalsIgnoreCase("deathblow"))
|
||||
{
|
||||
//requires at least one parameter, the target player's name
|
||||
if(args.length < 1) return false;
|
||||
|
||||
//try to find that player
|
||||
Player targetPlayer = this.getServer().getPlayer(args[0]);
|
||||
if(targetPlayer == null)
|
||||
{
|
||||
GriefPrevention.sendMessage(player, TextMode.Err, Messages.PlayerNotFound);
|
||||
return true;
|
||||
}
|
||||
|
||||
//try to find the recipient player, if specified
|
||||
Player recipientPlayer = null;
|
||||
if(args.length > 1)
|
||||
{
|
||||
recipientPlayer = this.getServer().getPlayer(args[1]);
|
||||
if(recipientPlayer == null)
|
||||
{
|
||||
GriefPrevention.sendMessage(player, TextMode.Err, Messages.PlayerNotFound);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
//if giving inventory to another player, teleport the target player to that receiving player
|
||||
if(recipientPlayer != null)
|
||||
{
|
||||
targetPlayer.teleport(recipientPlayer);
|
||||
}
|
||||
|
||||
//otherwise, plan to "pop" the player in place
|
||||
else
|
||||
{
|
||||
//if in a normal world, shoot him up to the sky first, so his items will fall on the surface.
|
||||
if(targetPlayer.getWorld().getEnvironment() == Environment.NORMAL)
|
||||
{
|
||||
Location location = targetPlayer.getLocation();
|
||||
location.setY(location.getWorld().getMaxHeight());
|
||||
targetPlayer.teleport(location);
|
||||
}
|
||||
}
|
||||
|
||||
//kill target player
|
||||
targetPlayer.setHealth(0);
|
||||
|
||||
//log entry
|
||||
if(player != null)
|
||||
{
|
||||
GriefPrevention.AddLogEntry(player.getName() + " used /DeathBlow to kill " + targetPlayer.getName() + ".");
|
||||
}
|
||||
else
|
||||
{
|
||||
GriefPrevention.AddLogEntry("Killed " + targetPlayer.getName() + ".");
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//deletealladminclaims
|
||||
else if(cmd.getName().equalsIgnoreCase("deletealladminclaims") && player != null)
|
||||
else if(cmd.getName().equalsIgnoreCase("deletealladminclaims"))
|
||||
{
|
||||
if(!player.hasPermission("griefprevention.deleteclaims"))
|
||||
{
|
||||
GriefPrevention.sendMessage(player, TextMode.Err, "You don't have permission to delete claims.");
|
||||
GriefPrevention.sendMessage(player, TextMode.Err, Messages.NoDeletePermission);
|
||||
return true;
|
||||
}
|
||||
|
||||
//delete all admin claims
|
||||
this.dataStore.deleteClaimsForPlayer("", true); //empty string for owner name indicates an administrative claim
|
||||
|
||||
GriefPrevention.sendMessage(player, TextMode.Success, "Deleted all administrative claims.");
|
||||
GriefPrevention.sendMessage(player, TextMode.Success, Messages.AllAdminDeleted);
|
||||
if(player != null)
|
||||
{
|
||||
GriefPrevention.AddLogEntry(player.getName() + " deleted all administrative claims.");
|
||||
|
||||
//revert any current visualization
|
||||
Visualization.Revert(player);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//adjustbonusclaimblocks <player> <amount>
|
||||
else if(cmd.getName().equalsIgnoreCase("adjustbonusclaimblocks") && player != null)
|
||||
//adjustbonusclaimblocks <player> <amount> or [<permission>] amount
|
||||
else if(cmd.getName().equalsIgnoreCase("adjustbonusclaimblocks"))
|
||||
{
|
||||
//requires exactly two parameters, the other player's name and the adjustment
|
||||
//requires exactly two parameters, the other player or group's name and the adjustment
|
||||
if(args.length != 2) return false;
|
||||
|
||||
//find the specified player
|
||||
OfflinePlayer targetPlayer = this.resolvePlayer(args[0]);
|
||||
if(targetPlayer == null)
|
||||
{
|
||||
GriefPrevention.sendMessage(player, TextMode.Err, "Player \"" + args[0] + "\" not found.");
|
||||
return true;
|
||||
}
|
||||
|
||||
//parse the adjustment amount
|
||||
int adjustment;
|
||||
try
|
||||
|
|
@ -1138,13 +1220,33 @@ public class GriefPrevention extends JavaPlugin
|
|||
return false; //causes usage to be displayed
|
||||
}
|
||||
|
||||
//if granting blocks to all players with a specific permission
|
||||
if(args[0].startsWith("[") && args[0].endsWith("]"))
|
||||
{
|
||||
String permissionIdentifier = args[0].substring(1, args[0].length() - 1);
|
||||
int newTotal = this.dataStore.adjustGroupBonusBlocks(permissionIdentifier, adjustment);
|
||||
|
||||
GriefPrevention.sendMessage(player, TextMode.Success, Messages.AdjustGroupBlocksSuccess, permissionIdentifier, String.valueOf(adjustment), String.valueOf(newTotal));
|
||||
if(player != null) GriefPrevention.AddLogEntry(player.getName() + " adjusted " + permissionIdentifier + "'s bonus claim blocks by " + adjustment + ".");
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//otherwise, find the specified player
|
||||
OfflinePlayer targetPlayer = this.resolvePlayer(args[0]);
|
||||
if(targetPlayer == null)
|
||||
{
|
||||
GriefPrevention.sendMessage(player, TextMode.Err, Messages.PlayerNotFound);
|
||||
return true;
|
||||
}
|
||||
|
||||
//give blocks to player
|
||||
PlayerData playerData = this.dataStore.getPlayerData(targetPlayer.getName());
|
||||
playerData.bonusClaimBlocks += adjustment;
|
||||
this.dataStore.savePlayerData(targetPlayer.getName(), playerData);
|
||||
|
||||
GriefPrevention.sendMessage(player, TextMode.Success, "Adjusted " + targetPlayer.getName() + "'s bonus claim blocks by " + adjustment + ". New total bonus blocks: " + playerData.bonusClaimBlocks + ".");
|
||||
GriefPrevention.AddLogEntry(player.getName() + " adjusted " + targetPlayer.getName() + "'s bonus claim blocks by " + adjustment + ".");
|
||||
GriefPrevention.sendMessage(player, TextMode.Success, Messages.AdjustBlocksSuccess, targetPlayer.getName(), String.valueOf(adjustment), String.valueOf(playerData.bonusClaimBlocks));
|
||||
if(player != null) GriefPrevention.AddLogEntry(player.getName() + " adjusted " + targetPlayer.getName() + "'s bonus claim blocks by " + adjustment + ".");
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
@ -1166,7 +1268,7 @@ public class GriefPrevention extends JavaPlugin
|
|||
//if the player isn't in a claim or has permission to build, tell him to man up
|
||||
if(claim == null || claim.allowBuild(player) == null)
|
||||
{
|
||||
GriefPrevention.sendMessage(player, TextMode.Err, "You can build here. Save yourself.");
|
||||
GriefPrevention.sendMessage(player, TextMode.Err, Messages.NotTrappedHere);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -1176,12 +1278,12 @@ public class GriefPrevention extends JavaPlugin
|
|||
long now = Calendar.getInstance().getTimeInMillis();
|
||||
if(now < nextTrappedUsage)
|
||||
{
|
||||
GriefPrevention.sendMessage(player, TextMode.Err, "You used /trapped within the last " + this.config_claims_trappedCooldownHours + " hours. You have to wait about " + ((nextTrappedUsage - now) / (1000 * 60) + 1) + " more minutes before using it again.");
|
||||
GriefPrevention.sendMessage(player, TextMode.Err, Messages.TrappedOnCooldown, String.valueOf(this.config_claims_trappedCooldownHours), String.valueOf((nextTrappedUsage - now) / (1000 * 60) + 1));
|
||||
return true;
|
||||
}
|
||||
|
||||
//send instructions
|
||||
GriefPrevention.sendMessage(player, TextMode.Instr, "If you stay put for 10 seconds, you'll be teleported out. Please wait.");
|
||||
GriefPrevention.sendMessage(player, TextMode.Instr, Messages.RescuePending);
|
||||
|
||||
//create a task to rescue this player in a little while
|
||||
PlayerRescueTask task = new PlayerRescueTask(player, player.getLocation());
|
||||
|
|
@ -1196,7 +1298,7 @@ public class GriefPrevention extends JavaPlugin
|
|||
//error message for when siege mode is disabled
|
||||
if(!this.siegeEnabledForWorld(player.getWorld()))
|
||||
{
|
||||
GriefPrevention.sendMessage(player, TextMode.Err, "Siege is disabled here.");
|
||||
GriefPrevention.sendMessage(player, TextMode.Err, Messages.NonSiegeWorld);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -1211,7 +1313,7 @@ public class GriefPrevention extends JavaPlugin
|
|||
PlayerData attackerData = this.dataStore.getPlayerData(attacker.getName());
|
||||
if(attackerData.siegeData != null)
|
||||
{
|
||||
GriefPrevention.sendMessage(player, TextMode.Err, "You're already involved in a siege.");
|
||||
GriefPrevention.sendMessage(player, TextMode.Err, Messages.AlreadySieging);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -1222,7 +1324,7 @@ public class GriefPrevention extends JavaPlugin
|
|||
defender = this.getServer().getPlayer(args[0]);
|
||||
if(defender == null)
|
||||
{
|
||||
GriefPrevention.sendMessage(player, TextMode.Err, "Player not found.");
|
||||
GriefPrevention.sendMessage(player, TextMode.Err, Messages.PlayerNotFound);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
@ -1246,14 +1348,14 @@ public class GriefPrevention extends JavaPlugin
|
|||
PlayerData defenderData = this.dataStore.getPlayerData(defender.getName());
|
||||
if(defenderData.siegeData != null)
|
||||
{
|
||||
GriefPrevention.sendMessage(player, TextMode.Err, defender.getName() + " is already under siege. Join the party!");
|
||||
GriefPrevention.sendMessage(player, TextMode.Err, Messages.AlreadyUnderSiegePlayer);
|
||||
return true;
|
||||
}
|
||||
|
||||
//victim must not be pvp immune
|
||||
if(defenderData.pvpImmune)
|
||||
{
|
||||
GriefPrevention.sendMessage(player, TextMode.Err, defender.getName() + " is defenseless. Go pick on somebody else.");
|
||||
GriefPrevention.sendMessage(player, TextMode.Err, Messages.NoSiegeDefenseless);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -1262,35 +1364,35 @@ public class GriefPrevention extends JavaPlugin
|
|||
//defender must have some level of permission there to be protected
|
||||
if(defenderClaim == null || defenderClaim.allowAccess(defender) != null)
|
||||
{
|
||||
GriefPrevention.sendMessage(player, TextMode.Err, defender.getName() + " isn't protected there.");
|
||||
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, "You're too far away from " + defender.getName() + " to siege.");
|
||||
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, "That area is already under siege. Join the party!");
|
||||
GriefPrevention.sendMessage(player, TextMode.Err, Messages.AlreadyUnderSiegeArea);
|
||||
return true;
|
||||
}
|
||||
|
||||
//can't siege admin claims
|
||||
if(defenderClaim.isAdminClaim())
|
||||
{
|
||||
GriefPrevention.sendMessage(player, TextMode.Err, "Siege is disabled in this area.");
|
||||
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, "You're still on siege cooldown for this defender or claim. Find another victim.");
|
||||
GriefPrevention.sendMessage(player, TextMode.Err, Messages.SiegeOnCooldown);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -1298,8 +1400,8 @@ public class GriefPrevention extends JavaPlugin
|
|||
dataStore.startSiege(attacker, defender, defenderClaim);
|
||||
|
||||
//confirmation message for attacker, warning message for defender
|
||||
GriefPrevention.sendMessage(defender, TextMode.Warn, "You're under siege! If you log out now, you will die. You must defeat " + attacker.getName() + ", wait for him to give up, or escape.");
|
||||
GriefPrevention.sendMessage(player, TextMode.Success, "The siege has begun! If you log out now, you will die. You must defeat " + defender.getName() + ", chase him away, or admit defeat and walk away.");
|
||||
GriefPrevention.sendMessage(defender, TextMode.Warn, Messages.SiegeAlert, attacker.getName());
|
||||
GriefPrevention.sendMessage(player, TextMode.Success, Messages.SiegeConfirmed, defender.getName());
|
||||
}
|
||||
|
||||
return false;
|
||||
|
|
@ -1312,31 +1414,41 @@ public class GriefPrevention extends JavaPlugin
|
|||
|
||||
private boolean abandonClaimHandler(Player player, boolean deleteTopLevelClaim)
|
||||
{
|
||||
PlayerData playerData = this.dataStore.getPlayerData(player.getName());
|
||||
|
||||
//which claim is being abandoned?
|
||||
Claim claim = this.dataStore.getClaimAt(player.getLocation(), true /*ignore height*/, null);
|
||||
if(claim == null)
|
||||
{
|
||||
GriefPrevention.sendMessage(player, TextMode.Instr, "Stand in the claim you want to delete, or consider /AbandonAllClaims.");
|
||||
}
|
||||
|
||||
else if(this.creativeRulesApply(player.getLocation()))
|
||||
{
|
||||
GriefPrevention.sendMessage(player, TextMode.Err, "Creative-mode claims can't be abandoned.");
|
||||
GriefPrevention.sendMessage(player, TextMode.Instr, Messages.AbandonClaimMissing);
|
||||
}
|
||||
|
||||
//verify ownership
|
||||
else if(claim.allowEdit(player) != null)
|
||||
{
|
||||
GriefPrevention.sendMessage(player, TextMode.Err, "This isn't your claim.");
|
||||
GriefPrevention.sendMessage(player, TextMode.Err, Messages.NotYourClaim);
|
||||
}
|
||||
|
||||
//don't allow abandon of creative mode claims
|
||||
else if(this.creativeRulesApply(player.getLocation()))
|
||||
{
|
||||
GriefPrevention.sendMessage(player, TextMode.Err, Messages.NoCreativeUnClaim);
|
||||
}
|
||||
|
||||
//warn if has children and we're not explicitly deleting a top level claim
|
||||
else if(claim.children.size() > 0 && !deleteTopLevelClaim)
|
||||
{
|
||||
GriefPrevention.sendMessage(player, TextMode.Instr, "To delete a subdivision, stand inside it. Otherwise, use /AbandonTopLevelClaim to delete this claim and all subdivisions.");
|
||||
GriefPrevention.sendMessage(player, TextMode.Instr, Messages.DeleteTopLevelClaim);
|
||||
return true;
|
||||
}
|
||||
|
||||
//if the claim has lots of surface water or some surface lava, warn the player it will be cleaned up
|
||||
else if(!playerData.warnedAboutMajorDeletion && claim.hasSurfaceFluids())
|
||||
{
|
||||
GriefPrevention.sendMessage(player, TextMode.Warn, Messages.ConfirmFluidRemoval);
|
||||
playerData.warnedAboutMajorDeletion = true;
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
//delete it
|
||||
|
|
@ -1344,12 +1456,13 @@ public class GriefPrevention extends JavaPlugin
|
|||
this.dataStore.deleteClaim(claim);
|
||||
|
||||
//tell the player how many claim blocks he has left
|
||||
PlayerData playerData = this.dataStore.getPlayerData(player.getName());
|
||||
int remainingBlocks = playerData.getRemainingClaimBlocks();
|
||||
GriefPrevention.sendMessage(player, TextMode.Success, "Claim abandoned. You now have " + String.valueOf(remainingBlocks) + " available claim blocks.");
|
||||
GriefPrevention.sendMessage(player, TextMode.Success, Messages.AbandonSuccess, String.valueOf(remainingBlocks));
|
||||
|
||||
//revert any current visualization
|
||||
Visualization.Revert(player);
|
||||
|
||||
playerData.warnedAboutMajorDeletion = false;
|
||||
}
|
||||
|
||||
return true;
|
||||
|
|
@ -1362,11 +1475,25 @@ public class GriefPrevention extends JavaPlugin
|
|||
//determine which claim the player is standing in
|
||||
Claim claim = this.dataStore.getClaimAt(player.getLocation(), true /*ignore height*/, null);
|
||||
|
||||
//validate player argument
|
||||
OfflinePlayer otherPlayer = this.resolvePlayer(recipientName);
|
||||
//validate player or group argument
|
||||
String permission = null;
|
||||
OfflinePlayer otherPlayer = null;
|
||||
if(recipientName.startsWith("[") && recipientName.endsWith("]"))
|
||||
{
|
||||
permission = recipientName.substring(1, recipientName.length() - 1);
|
||||
if(permission == null || permission.isEmpty())
|
||||
{
|
||||
GriefPrevention.sendMessage(player, TextMode.Err, Messages.InvalidPermissionID);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
otherPlayer = this.resolvePlayer(recipientName);
|
||||
if(otherPlayer == null && !recipientName.equals("public"))
|
||||
{
|
||||
GriefPrevention.sendMessage(player, TextMode.Err, "Player not found.");
|
||||
GriefPrevention.sendMessage(player, TextMode.Err, Messages.PlayerNotFound);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -1378,6 +1505,7 @@ public class GriefPrevention extends JavaPlugin
|
|||
{
|
||||
recipientName = "public";
|
||||
}
|
||||
}
|
||||
|
||||
//determine which claims should be modified
|
||||
ArrayList<Claim> targetClaims = new ArrayList<Claim>();
|
||||
|
|
@ -1394,7 +1522,7 @@ public class GriefPrevention extends JavaPlugin
|
|||
//check permission here
|
||||
if(claim.allowGrantPermission(player) != null)
|
||||
{
|
||||
GriefPrevention.sendMessage(player, TextMode.Err, "You don't have " + claim.getOwnerName() + "'s permission to grant permissions here.");
|
||||
GriefPrevention.sendMessage(player, TextMode.Err, Messages.NoPermissionTrust, claim.getOwnerName());
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -1430,7 +1558,7 @@ public class GriefPrevention extends JavaPlugin
|
|||
//error message for trying to grant a permission the player doesn't have
|
||||
if(errorMessage != null)
|
||||
{
|
||||
GriefPrevention.sendMessage(player, TextMode.Err, errorMessage + " You can't grant a permission you don't have yourself.");
|
||||
GriefPrevention.sendMessage(player, TextMode.Err, Messages.CantGrantThatPermission);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -1440,7 +1568,7 @@ public class GriefPrevention extends JavaPlugin
|
|||
//if we didn't determine which claims to modify, tell the player to be specific
|
||||
if(targetClaims.size() == 0)
|
||||
{
|
||||
GriefPrevention.sendMessage(player, TextMode.Err, "Stand inside the claim where you want to grant permission.");
|
||||
GriefPrevention.sendMessage(player, TextMode.Err, Messages.GrantPermissionNoClaim);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -1463,36 +1591,36 @@ public class GriefPrevention extends JavaPlugin
|
|||
}
|
||||
|
||||
//notify player
|
||||
if(recipientName.equals("public")) recipientName = "the public";
|
||||
StringBuilder resultString = new StringBuilder();
|
||||
resultString.append("Granted " + recipientName + " ");
|
||||
if(recipientName.equals("public")) recipientName = this.dataStore.getMessage(Messages.CollectivePublic);
|
||||
String permissionDescription;
|
||||
if(permissionLevel == null)
|
||||
{
|
||||
resultString.append("manager status");
|
||||
permissionDescription = this.dataStore.getMessage(Messages.PermissionsPermission);
|
||||
}
|
||||
else if(permissionLevel == ClaimPermission.Build)
|
||||
{
|
||||
resultString.append("permission to build in");
|
||||
permissionDescription = this.dataStore.getMessage(Messages.BuildPermission);
|
||||
}
|
||||
else if(permissionLevel == ClaimPermission.Access)
|
||||
{
|
||||
resultString.append("permission to use buttons and levers in");
|
||||
permissionDescription = this.dataStore.getMessage(Messages.AccessPermission);
|
||||
}
|
||||
else if(permissionLevel == ClaimPermission.Inventory)
|
||||
else //ClaimPermission.Inventory
|
||||
{
|
||||
resultString.append("permission to access containers in");
|
||||
permissionDescription = this.dataStore.getMessage(Messages.ContainersPermission);
|
||||
}
|
||||
|
||||
String location;
|
||||
if(claim == null)
|
||||
{
|
||||
resultString.append(" ALL your claims. To modify only one claim, stand inside it.");
|
||||
location = this.dataStore.getMessage(Messages.LocationAllClaims);
|
||||
}
|
||||
else
|
||||
{
|
||||
resultString.append(" this claim. To modify ALL your claims, stand outside them.");
|
||||
location = this.dataStore.getMessage(Messages.LocationCurrentClaim);
|
||||
}
|
||||
|
||||
GriefPrevention.sendMessage(player, TextMode.Success, resultString.toString());
|
||||
GriefPrevention.sendMessage(player, TextMode.Success, Messages.GrantPermissionConfirmation, recipientName, permissionDescription, location);
|
||||
}
|
||||
|
||||
//helper method to resolve a player by name
|
||||
|
|
@ -1552,7 +1680,7 @@ public class GriefPrevention extends JavaPlugin
|
|||
playerData.pvpImmune = true;
|
||||
|
||||
//inform the player
|
||||
GriefPrevention.sendMessage(player, TextMode.Success, "You're protected from attack by other players as long as your inventory is empty.");
|
||||
GriefPrevention.sendMessage(player, TextMode.Success, Messages.PvPImmunityStart);
|
||||
}
|
||||
|
||||
//checks whether players can create claims in a world
|
||||
|
|
@ -1797,11 +1925,25 @@ public class GriefPrevention extends JavaPlugin
|
|||
while(!chunk.isLoaded() || !chunk.load(true));
|
||||
}
|
||||
|
||||
//sends a color-coded message to a player
|
||||
static void sendMessage(Player player, ChatColor color, Messages messageID, String... args)
|
||||
{
|
||||
String message = GriefPrevention.instance.dataStore.getMessage(messageID, args);
|
||||
sendMessage(player, color, message);
|
||||
}
|
||||
|
||||
//sends a color-coded message to a player
|
||||
static void sendMessage(Player player, ChatColor color, String message)
|
||||
{
|
||||
if(player == null)
|
||||
{
|
||||
GriefPrevention.AddLogEntry(color + message);
|
||||
}
|
||||
else
|
||||
{
|
||||
player.sendMessage(color + message);
|
||||
}
|
||||
}
|
||||
|
||||
//determines whether creative anti-grief rules apply at a location
|
||||
boolean creativeRulesApply(Location location)
|
||||
|
|
@ -1825,20 +1967,21 @@ public class GriefPrevention extends JavaPlugin
|
|||
|
||||
return "You can't build here. Use the golden shovel to claim some land first.";
|
||||
}
|
||||
|
||||
//but it's fine in survival mode
|
||||
else
|
||||
{
|
||||
//cache the claim for later reference
|
||||
playerData.lastClaim = claim;
|
||||
|
||||
//but it's fine in survival mode
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
//if not in the wilderness, then apply claim rules (permissions, etc)
|
||||
else
|
||||
{
|
||||
//cache the claim for later reference
|
||||
playerData.lastClaim = claim;
|
||||
return claim.allowBuild(player);
|
||||
}
|
||||
}
|
||||
|
||||
public String allowBreak(Player player, Location location)
|
||||
{
|
||||
|
|
@ -1854,20 +1997,22 @@ public class GriefPrevention extends JavaPlugin
|
|||
//exception: administrators in ignore claims mode
|
||||
if(playerData.ignoreClaims) return null;
|
||||
|
||||
return "You can't build here. Use the golden shovel to claim some land first.";
|
||||
return "You can only build where you have claimed land. To claim, watch this: http://tinyurl.com/c7bajb8";
|
||||
}
|
||||
|
||||
//but it's fine in survival mode
|
||||
else
|
||||
{
|
||||
//cache the claim for later reference
|
||||
playerData.lastClaim = claim;
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
//cache the claim for later reference
|
||||
playerData.lastClaim = claim;
|
||||
|
||||
//if not in the wilderness, then apply claim rules (permissions, etc)
|
||||
return claim.allowBreak(player, location.getBlock().getType());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -2,5 +2,5 @@ package me.ryanhamshire.GriefPrevention;
|
|||
|
||||
public enum Messages
|
||||
{
|
||||
RespectingClaims, IgnoringClaims, SuccessfulAbandon, RestoreNatureActivate, RestoreNatureAggressiveActivate, FillModeActive, TransferClaimPermission, TransferClaimMissing, TransferClaimAdminOnly, PlayerNotFound, TransferTopLevel, TransferSuccess, TrustListNoClaim, ClearPermsOwnerOnly, UntrustIndividualAllClaims, UntrustEveryoneAllClaims, NoPermissionTrust, ClearPermissionsOneClaim, UntrustIndividualSingleClaim, OnlySellBlocks, BlockPurchaseCost, ClaimBlockLimit, InsufficientFunds, PurchaseConfirmation, OnlyPurchaseBlocks, BlockSaleValue, NotEnoughBlocksForSale, BlockSaleConfirmation, AdminClaimsMode, BasicClaimsMode, SubdivisionMode, SubdivisionDemo, DeleteClaimMissing, DeletionSubdivisionWarning, DeleteSuccess, CantDeleteAdminClaim, DeleteAllSuccess, NoDeletePermission, AllAdminDeleted, AdjustBlocksSuccess, NotTrappedHere, TrappedOnCooldown, RescuePending, NonSiegeWorld, AlreadySieging, NotSiegableThere, SiegeTooFarAway, NoSiegeDefenseless, AlreadyUnderSiegePlayer, AlreadyUnderSiegeArea, NoSiegeAdminClaim, SiegeOnCooldown, SiegeAlert, SiegeConfirmed, AbandonClaimMissing, NotYourClaim, DeleteTopLevelClaim, AbandonSuccess, CantGrantThatPermission, GrantPermissionNoClaim, GrantPermissionConfirmation, ManageUniversalPermissionsInstruction, ManageOneClaimPermissionsInstruction, CollectivePublic, BuildPermission, ContainersPermission, AccessPermission, PermissionsPermission, LocationCurrentClaim, LocationAllClaims, PvPImmunityStart, SiegeNoDrop, DonateItemsInstruction, ChestFull, DonationSuccess, PlayerTooCloseForFire, TooDeepToClaim, ChestClaimConfirmation, AutomaticClaimNotification, TrustCommandAdvertisement, GoldenShovelAdvertisement, UnprotectedChestWarning, ThatPlayerPvPImmune, CantFightWhileImmune, NoDamageClaimedEntity, ShovelBasicClaimMode, RemainingBlocks, CreativeBasicsDemoAdvertisement, SurvivalBasicsDemoAdvertisement, TrappedChatKeyword, TrappedInstructions, PvPNoDrop, SiegeNoTeleport, BesiegedNoTeleport, SiegeNoContainers, PvPNoContainers, PvPImmunityEnd, NoBedPermission, NoWildernessBuckets, NoLavaNearOtherPlayer, TooFarAway, BlockNotClaimed, BlockClaimed, SiegeNoShovel, RestoreNaturePlayerInChunk, NoCreateClaimPermission, ResizeClaimTooSmall, ResizeNeedMoreBlocks, NoCreativeUnClaim, ClaimResizeSuccess, ResizeFailOverlap, ResizeStart, ResizeFailOverlapSubdivision, SubdivisionStart, CreateSubdivisionOverlap, SubdivisionSuccess, CreateClaimFailOverlap, CreateClaimFailOverlapOtherPlayer, ClaimsDisabledWorld, ClaimStart, NewClaimTooSmall, CreateClaimInsufficientBlocks, AbandonClaimAdvertisement, CreateClaimFailOverlapShort, CreateClaimSuccess, SiegeWinDoorsOpen, RescueAbortedMoved, SiegeDoorsLockedEjection, NoModifyDuringSiege, OnlyOwnersModifyClaims, NoBuildUnderSiege, NoBuildPvP, NoBuildPermission, NonSiegeMaterial, NoOwnerBuildUnderSiege, NoAccessPermission, NoContainersSiege, NoContainersPermission, OwnerNameForAdminClaims, ClaimTooSmallForEntities, TooManyEntitiesInClaim, YouHaveNoClaims, ConfirmFluidRemoval, AutoBanNotify
|
||||
RespectingClaims, IgnoringClaims, SuccessfulAbandon, RestoreNatureActivate, RestoreNatureAggressiveActivate, FillModeActive, TransferClaimPermission, TransferClaimMissing, TransferClaimAdminOnly, PlayerNotFound, TransferTopLevel, TransferSuccess, TrustListNoClaim, ClearPermsOwnerOnly, UntrustIndividualAllClaims, UntrustEveryoneAllClaims, NoPermissionTrust, ClearPermissionsOneClaim, UntrustIndividualSingleClaim, OnlySellBlocks, BlockPurchaseCost, ClaimBlockLimit, InsufficientFunds, PurchaseConfirmation, OnlyPurchaseBlocks, BlockSaleValue, NotEnoughBlocksForSale, BlockSaleConfirmation, AdminClaimsMode, BasicClaimsMode, SubdivisionMode, SubdivisionDemo, DeleteClaimMissing, DeletionSubdivisionWarning, DeleteSuccess, CantDeleteAdminClaim, DeleteAllSuccess, NoDeletePermission, AllAdminDeleted, AdjustBlocksSuccess, NotTrappedHere, TrappedOnCooldown, RescuePending, NonSiegeWorld, AlreadySieging, NotSiegableThere, SiegeTooFarAway, NoSiegeDefenseless, AlreadyUnderSiegePlayer, AlreadyUnderSiegeArea, NoSiegeAdminClaim, SiegeOnCooldown, SiegeAlert, SiegeConfirmed, AbandonClaimMissing, NotYourClaim, DeleteTopLevelClaim, AbandonSuccess, CantGrantThatPermission, GrantPermissionNoClaim, GrantPermissionConfirmation, ManageUniversalPermissionsInstruction, ManageOneClaimPermissionsInstruction, CollectivePublic, BuildPermission, ContainersPermission, AccessPermission, PermissionsPermission, LocationCurrentClaim, LocationAllClaims, PvPImmunityStart, SiegeNoDrop, DonateItemsInstruction, ChestFull, DonationSuccess, PlayerTooCloseForFire, TooDeepToClaim, ChestClaimConfirmation, AutomaticClaimNotification, TrustCommandAdvertisement, GoldenShovelAdvertisement, UnprotectedChestWarning, ThatPlayerPvPImmune, CantFightWhileImmune, NoDamageClaimedEntity, ShovelBasicClaimMode, RemainingBlocks, CreativeBasicsDemoAdvertisement, SurvivalBasicsDemoAdvertisement, TrappedChatKeyword, TrappedInstructions, PvPNoDrop, SiegeNoTeleport, BesiegedNoTeleport, SiegeNoContainers, PvPNoContainers, PvPImmunityEnd, NoBedPermission, NoWildernessBuckets, NoLavaNearOtherPlayer, TooFarAway, BlockNotClaimed, BlockClaimed, SiegeNoShovel, RestoreNaturePlayerInChunk, NoCreateClaimPermission, ResizeClaimTooSmall, ResizeNeedMoreBlocks, NoCreativeUnClaim, ClaimResizeSuccess, ResizeFailOverlap, ResizeStart, ResizeFailOverlapSubdivision, SubdivisionStart, CreateSubdivisionOverlap, SubdivisionSuccess, CreateClaimFailOverlap, CreateClaimFailOverlapOtherPlayer, ClaimsDisabledWorld, ClaimStart, NewClaimTooSmall, CreateClaimInsufficientBlocks, AbandonClaimAdvertisement, CreateClaimFailOverlapShort, CreateClaimSuccess, SiegeWinDoorsOpen, RescueAbortedMoved, SiegeDoorsLockedEjection, NoModifyDuringSiege, OnlyOwnersModifyClaims, NoBuildUnderSiege, NoBuildPvP, NoBuildPermission, NonSiegeMaterial, NoOwnerBuildUnderSiege, NoAccessPermission, NoContainersSiege, NoContainersPermission, OwnerNameForAdminClaims, ClaimTooSmallForEntities, TooManyEntitiesInClaim, YouHaveNoClaims, ConfirmFluidRemoval, AutoBanNotify, AdjustGroupBlocksSuccess, InvalidPermissionID, UntrustOwnerOnly
|
||||
}
|
||||
|
|
|
|||
|
|
@ -27,6 +27,9 @@ import org.bukkit.Location;
|
|||
//holds all of GriefPrevention's player-tied data
|
||||
public class PlayerData
|
||||
{
|
||||
//the player's name
|
||||
public String playerName;
|
||||
|
||||
//the player's claims
|
||||
public Vector<Claim> claims = new Vector<Claim>();
|
||||
|
||||
|
|
@ -71,9 +74,6 @@ public class PlayerData
|
|||
public int spamCount = 0; //number of consecutive "spams"
|
||||
public boolean spamWarned = false; //whether the player recently received a warning
|
||||
|
||||
//last logout timestamp, default to long enough to trigger a join message, see player join event
|
||||
public long lastLogout = Calendar.getInstance().getTimeInMillis() - GriefPrevention.NOTIFICATION_SECONDS * 2000;
|
||||
|
||||
//visualization
|
||||
public Visualization currentVisualization = null;
|
||||
|
||||
|
|
@ -138,6 +138,9 @@ public class PlayerData
|
|||
remainingBlocks -= claim.getArea();
|
||||
}
|
||||
|
||||
//add any blocks this player might have based on group membership (permissions)
|
||||
remainingBlocks += GriefPrevention.instance.dataStore.getGroupBonusBlocks(this.playerName);
|
||||
|
||||
return remainingBlocks;
|
||||
}
|
||||
}
|
||||
|
|
@ -20,6 +20,7 @@ package me.ryanhamshire.GriefPrevention;
|
|||
import java.util.ArrayList;
|
||||
import java.util.Calendar;
|
||||
import java.util.Date;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
|
@ -59,6 +60,9 @@ class PlayerEventHandler implements Listener
|
|||
//number of milliseconds in a day
|
||||
private final long MILLISECONDS_IN_DAY = 1000 * 60 * 60 * 24;
|
||||
|
||||
//timestamps of login and logout notifications in the last minute
|
||||
private ArrayList<Long> recentLoginLogoutNotifications = new ArrayList<Long>();
|
||||
|
||||
//typical constructor, yawn
|
||||
PlayerEventHandler(DataStore dataStore, GriefPrevention plugin)
|
||||
{
|
||||
|
|
@ -75,9 +79,9 @@ class PlayerEventHandler implements Listener
|
|||
//FEATURE: automatically educate players about the /trapped command
|
||||
|
||||
//check for "trapped" or "stuck" to educate players about the /trapped command
|
||||
if(message.contains("trapped") || message.contains("stuck"))
|
||||
if(message.contains("trapped") || message.contains("stuck") || message.contains(this.dataStore.getMessage(Messages.TrappedChatKeyword)))
|
||||
{
|
||||
GriefPrevention.sendMessage(player, TextMode.Info, "Are you trapped in someone's claim? Consider the /trapped command.");
|
||||
GriefPrevention.sendMessage(player, TextMode.Info, Messages.TrappedInstructions);
|
||||
}
|
||||
|
||||
//FEATURE: monitor for chat and command spam
|
||||
|
|
@ -101,8 +105,27 @@ class PlayerEventHandler implements Listener
|
|||
boolean spam = false;
|
||||
boolean muted = false;
|
||||
|
||||
//check message content and timing
|
||||
long millisecondsSinceLastMessage = (new Date()).getTime() - playerData.lastMessageTimestamp.getTime();
|
||||
|
||||
//if the message came too close to the last one
|
||||
if(millisecondsSinceLastMessage < 3000)
|
||||
{
|
||||
//increment the spam counter
|
||||
playerData.spamCount++;
|
||||
spam = true;
|
||||
}
|
||||
|
||||
//if it's very similar to the last message
|
||||
if(!muted && this.stringsAreSimilar(message, playerData.lastMessage))
|
||||
{
|
||||
playerData.spamCount++;
|
||||
spam = true;
|
||||
muted = true;
|
||||
}
|
||||
|
||||
//filter IP addresses
|
||||
if(!(event instanceof PlayerCommandPreprocessEvent))
|
||||
if(!muted && !(event instanceof PlayerCommandPreprocessEvent))
|
||||
{
|
||||
Pattern ipAddressPattern = Pattern.compile("\\d+\\.\\d+\\.\\d+\\.\\d+");
|
||||
Matcher matcher = ipAddressPattern.matcher(event.getMessage());
|
||||
|
|
@ -126,27 +149,8 @@ class PlayerEventHandler implements Listener
|
|||
}
|
||||
}
|
||||
|
||||
//check message content and timing
|
||||
long millisecondsSinceLastMessage = (new Date()).getTime() - playerData.lastMessageTimestamp.getTime();
|
||||
|
||||
//if the message came too close to the last one
|
||||
if(millisecondsSinceLastMessage < 3000)
|
||||
{
|
||||
//increment the spam counter
|
||||
playerData.spamCount++;
|
||||
spam = true;
|
||||
}
|
||||
|
||||
//if it's very similar to the last message
|
||||
if(this.stringsAreSimilar(message, playerData.lastMessage))
|
||||
{
|
||||
playerData.spamCount++;
|
||||
spam = true;
|
||||
muted = true;
|
||||
}
|
||||
|
||||
//if the message was mostly non-alpha-numerics or doesn't include much whitespace, consider it a spam (probably ansi art or random text gibberish)
|
||||
if(message.length() > 5)
|
||||
if(!muted && message.length() > 5)
|
||||
{
|
||||
int symbolsCount = 0;
|
||||
int whitespaceCount = 0;
|
||||
|
|
@ -167,6 +171,7 @@ class PlayerEventHandler implements Listener
|
|||
if(symbolsCount > message.length() / 2 || (message.length() > 15 && whitespaceCount < message.length() / 10))
|
||||
{
|
||||
spam = true;
|
||||
if(playerData.spamCount > 0) muted = true;
|
||||
playerData.spamCount++;
|
||||
}
|
||||
}
|
||||
|
|
@ -347,7 +352,7 @@ class PlayerEventHandler implements Listener
|
|||
playerData.ipAddress = event.getAddress();
|
||||
|
||||
//FEATURE: auto-ban accounts who use an IP address which was very recently used by another banned account
|
||||
if(GriefPrevention.instance.config_smartBan)
|
||||
if(GriefPrevention.instance.config_smartBan && !player.hasPlayedBefore())
|
||||
{
|
||||
//if logging-in account is banned, remember IP address for later
|
||||
long now = Calendar.getInstance().getTimeInMillis();
|
||||
|
|
@ -399,6 +404,16 @@ class PlayerEventHandler implements Listener
|
|||
event.setResult(Result.KICK_BANNED);
|
||||
event.disallow(event.getResult(), "");
|
||||
GriefPrevention.AddLogEntry("Auto-banned " + player.getName() + " because that account is using an IP address very recently used by banned player " + info.bannedAccountName + " (" + info.address.toString() + ").");
|
||||
|
||||
//notify any online ops
|
||||
Player [] players = GriefPrevention.instance.getServer().getOnlinePlayers();
|
||||
for(int k = 0; k < players.length; k++)
|
||||
{
|
||||
if(players[k].isOp())
|
||||
{
|
||||
GriefPrevention.sendMessage(players[k], TextMode.Success, Messages.AutoBanNotify, player.getName(), info.bannedAccountName);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -430,31 +445,10 @@ class PlayerEventHandler implements Listener
|
|||
//check inventory, may need pvp protection
|
||||
GriefPrevention.instance.checkPvpProtectionNeeded(event.getPlayer());
|
||||
|
||||
//how long since the last logout?
|
||||
long elapsed = Calendar.getInstance().getTimeInMillis() - playerData.lastLogout;
|
||||
|
||||
//remember message, then silence it. may broadcast it later
|
||||
String message = event.getJoinMessage();
|
||||
//silence notifications when they're coming too fast
|
||||
if(event.getJoinMessage() != null && this.shouldSilenceNotification())
|
||||
{
|
||||
event.setJoinMessage(null);
|
||||
|
||||
if(message != null && elapsed >= GriefPrevention.NOTIFICATION_SECONDS * 1000)
|
||||
{
|
||||
//start a timer for a delayed join notification message (will only show if player is still online in 30 seconds)
|
||||
JoinLeaveAnnouncementTask task = new JoinLeaveAnnouncementTask(event.getPlayer(), message, true);
|
||||
GriefPrevention.instance.getServer().getScheduler().scheduleSyncDelayedTask(GriefPrevention.instance, task, 20L * GriefPrevention.NOTIFICATION_SECONDS);
|
||||
}
|
||||
}
|
||||
|
||||
//when a player quits...
|
||||
@EventHandler(priority = EventPriority.HIGHEST)
|
||||
void onPlayerKicked(PlayerKickEvent event)
|
||||
{
|
||||
Player player = event.getPlayer();
|
||||
PlayerData playerData = this.dataStore.getPlayerData(player.getName());
|
||||
if(player.isBanned())
|
||||
{
|
||||
long now = Calendar.getInstance().getTimeInMillis();
|
||||
this.tempBannedIps.add(new IpBanInfo(playerData.ipAddress, now + this.MILLISECONDS_IN_DAY, player.getName()));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -462,12 +456,25 @@ class PlayerEventHandler implements Listener
|
|||
@EventHandler(priority = EventPriority.HIGHEST)
|
||||
void onPlayerQuit(PlayerQuitEvent event)
|
||||
{
|
||||
this.onPlayerDisconnect(event.getPlayer(), event.getQuitMessage());
|
||||
Player player = event.getPlayer();
|
||||
PlayerData playerData = this.dataStore.getPlayerData(player.getName());
|
||||
|
||||
//silence the leave message (may be broadcast later, if the player stays offline)
|
||||
//if banned, add IP to the temporary IP ban list
|
||||
if(player.isBanned())
|
||||
{
|
||||
long now = Calendar.getInstance().getTimeInMillis();
|
||||
this.tempBannedIps.add(new IpBanInfo(playerData.ipAddress, now + this.MILLISECONDS_IN_DAY, player.getName()));
|
||||
}
|
||||
|
||||
//silence notifications when they're coming too fast
|
||||
if(event.getQuitMessage() != null && this.shouldSilenceNotification())
|
||||
{
|
||||
event.setQuitMessage(null);
|
||||
}
|
||||
|
||||
this.onPlayerDisconnect(event.getPlayer(), event.getQuitMessage());
|
||||
}
|
||||
|
||||
//helper for above
|
||||
private void onPlayerDisconnect(Player player, String notificationMessage)
|
||||
{
|
||||
|
|
@ -487,21 +494,33 @@ class PlayerEventHandler implements Listener
|
|||
{
|
||||
if(player.getHealth() > 0) player.setHealth(0); //might already be zero from above, this avoids a double death message
|
||||
}
|
||||
|
||||
//how long was the player online?
|
||||
long now = Calendar.getInstance().getTimeInMillis();
|
||||
long elapsed = now - playerData.lastLogin.getTime();
|
||||
|
||||
//remember logout time
|
||||
playerData.lastLogout = Calendar.getInstance().getTimeInMillis();
|
||||
|
||||
//if notification message isn't null and the player has been online for at least 30 seconds...
|
||||
if(notificationMessage != null && elapsed >= 1000 * GriefPrevention.NOTIFICATION_SECONDS)
|
||||
{
|
||||
//start a timer for a delayed leave notification message (will only show if player is still offline in 30 seconds)
|
||||
JoinLeaveAnnouncementTask task = new JoinLeaveAnnouncementTask(player, notificationMessage, false);
|
||||
GriefPrevention.instance.getServer().getScheduler().scheduleSyncDelayedTask(GriefPrevention.instance, task, 20L * GriefPrevention.NOTIFICATION_SECONDS);
|
||||
}
|
||||
|
||||
//determines whether or not a login or logout notification should be silenced, depending on how many there have been in the last minute
|
||||
private boolean shouldSilenceNotification()
|
||||
{
|
||||
final long ONE_MINUTE = 60000;
|
||||
final int MAX_ALLOWED = 20;
|
||||
Long now = Calendar.getInstance().getTimeInMillis();
|
||||
|
||||
//eliminate any expired entries (longer than a minute ago)
|
||||
for(int i = 0; i < this.recentLoginLogoutNotifications.size(); i++)
|
||||
{
|
||||
Long notificationTimestamp = this.recentLoginLogoutNotifications.get(i);
|
||||
if(now - notificationTimestamp > ONE_MINUTE)
|
||||
{
|
||||
this.recentLoginLogoutNotifications.remove(i--);
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//add the new entry
|
||||
this.recentLoginLogoutNotifications.add(now);
|
||||
|
||||
return this.recentLoginLogoutNotifications.size() > MAX_ALLOWED;
|
||||
}
|
||||
|
||||
//when a player drops an item
|
||||
|
|
@ -525,14 +544,14 @@ class PlayerEventHandler implements Listener
|
|||
//if in combat, don't let him drop it
|
||||
if(!GriefPrevention.instance.config_pvp_allowCombatItemDrop && playerData.inPvpCombat())
|
||||
{
|
||||
GriefPrevention.sendMessage(player, TextMode.Err, "You can't drop items while in PvP combat.");
|
||||
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, "You can't drop items while involved in a siege.");
|
||||
GriefPrevention.sendMessage(player, TextMode.Err, Messages.SiegeNoDrop);
|
||||
event.setCancelled(true);
|
||||
}
|
||||
}
|
||||
|
|
@ -552,7 +571,7 @@ class PlayerEventHandler implements Listener
|
|||
Claim sourceClaim = this.dataStore.getClaimAt(source, false, null);
|
||||
if(sourceClaim != null && sourceClaim.siegeData != null)
|
||||
{
|
||||
GriefPrevention.sendMessage(player, TextMode.Err, "You can't teleport out of a besieged area.");
|
||||
GriefPrevention.sendMessage(player, TextMode.Err, Messages.SiegeNoTeleport);
|
||||
event.setCancelled(true);
|
||||
return;
|
||||
}
|
||||
|
|
@ -561,7 +580,7 @@ class PlayerEventHandler implements Listener
|
|||
Claim destinationClaim = this.dataStore.getClaimAt(destination, false, null);
|
||||
if(destinationClaim != null && destinationClaim.siegeData != null)
|
||||
{
|
||||
GriefPrevention.sendMessage(player, TextMode.Err, "You can't teleport into a besieged area.");
|
||||
GriefPrevention.sendMessage(player, TextMode.Err, Messages.BesiegedNoTeleport);
|
||||
event.setCancelled(true);
|
||||
return;
|
||||
}
|
||||
|
|
@ -580,14 +599,14 @@ class PlayerEventHandler implements Listener
|
|||
{
|
||||
if(playerData.siegeData != null)
|
||||
{
|
||||
GriefPrevention.sendMessage(player, TextMode.Err, "You can't access containers while under siege.");
|
||||
GriefPrevention.sendMessage(player, TextMode.Err, Messages.SiegeNoContainers);
|
||||
event.setCancelled(true);
|
||||
return;
|
||||
}
|
||||
|
||||
if(playerData.inPvpCombat())
|
||||
{
|
||||
GriefPrevention.sendMessage(player, TextMode.Err, "You can't access containers during PvP combat.");
|
||||
GriefPrevention.sendMessage(player, TextMode.Err, Messages.PvPNoContainers);
|
||||
event.setCancelled(true);
|
||||
return;
|
||||
}
|
||||
|
|
@ -627,7 +646,7 @@ class PlayerEventHandler implements Listener
|
|||
{
|
||||
if(claim.allowContainers(player) != null)
|
||||
{
|
||||
GriefPrevention.sendMessage(player, TextMode.Err, "That animal belongs to " + claim.getOwnerName() + ".");
|
||||
GriefPrevention.sendMessage(player, TextMode.Err, Messages.NoDamageClaimedEntity);
|
||||
event.setCancelled(true);
|
||||
}
|
||||
}
|
||||
|
|
@ -661,7 +680,7 @@ class PlayerEventHandler implements Listener
|
|||
|
||||
//otherwise take away his immunity. he may be armed now. at least, he's worth killing for some loot
|
||||
playerData.pvpImmune = false;
|
||||
GriefPrevention.sendMessage(player, TextMode.Warn, "Now you can fight with other players.");
|
||||
GriefPrevention.sendMessage(player, TextMode.Warn, Messages.PvPImmunityEnd);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -698,7 +717,7 @@ class PlayerEventHandler implements Listener
|
|||
if(claim.allowAccess(player) != null)
|
||||
{
|
||||
bedEvent.setCancelled(true);
|
||||
GriefPrevention.sendMessage(player, TextMode.Err, claim.getOwnerName() + " hasn't given you permission to sleep here.");
|
||||
GriefPrevention.sendMessage(player, TextMode.Err, Messages.NoBedPermission, claim.getOwnerName());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -727,16 +746,19 @@ class PlayerEventHandler implements Listener
|
|||
minLavaDistance = 3;
|
||||
}
|
||||
|
||||
//otherwise no dumping anything unless underground
|
||||
else
|
||||
//otherwise no wilderness dumping (unless underground) in worlds where claims are enabled
|
||||
else if(GriefPrevention.instance.config_claims_enabledWorlds.contains(block.getWorld()))
|
||||
{
|
||||
if(block.getY() >= block.getWorld().getSeaLevel() - 5 && !player.hasPermission("griefprevention.lava"))
|
||||
{
|
||||
GriefPrevention.sendMessage(player, TextMode.Err, "You may only dump buckets inside your claim(s) or underground.");
|
||||
if(bucketEvent.getBucket() == Material.LAVA_BUCKET || GriefPrevention.instance.config_blockWildernessWaterBuckets)
|
||||
{
|
||||
GriefPrevention.sendMessage(player, TextMode.Err, Messages.NoWildernessBuckets);
|
||||
bucketEvent.setCancelled(true);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//lava buckets can't be dumped near other players unless pvp is on
|
||||
if(!block.getWorld().getPVP() && !player.hasPermission("griefprevention.lava"))
|
||||
|
|
@ -750,7 +772,7 @@ class PlayerEventHandler implements Listener
|
|||
Location location = otherPlayer.getLocation();
|
||||
if(!otherPlayer.equals(player) && block.getY() >= location.getBlockY() - 1 && location.distanceSquared(block.getLocation()) < minLavaDistance * minLavaDistance)
|
||||
{
|
||||
GriefPrevention.sendMessage(player, TextMode.Err, "You can't place lava this close to " + otherPlayer.getName() + ".");
|
||||
GriefPrevention.sendMessage(player, TextMode.Err, Messages.NoLavaNearOtherPlayer, otherPlayer.getName());
|
||||
bucketEvent.setCancelled(true);
|
||||
return;
|
||||
}
|
||||
|
|
@ -791,6 +813,9 @@ class PlayerEventHandler implements Listener
|
|||
if(clickedBlock == null)
|
||||
{
|
||||
//try to find a far away non-air block along line of sight
|
||||
HashSet<Byte> transparentMaterials = new HashSet<Byte>();
|
||||
transparentMaterials.add(Byte.valueOf((byte)Material.AIR.getId()));
|
||||
transparentMaterials.add(Byte.valueOf((byte)Material.SNOW.getId()));
|
||||
clickedBlock = player.getTargetBlock(null, 250);
|
||||
}
|
||||
}
|
||||
|
|
@ -807,23 +832,8 @@ class PlayerEventHandler implements Listener
|
|||
|
||||
Material clickedBlockType = clickedBlock.getType();
|
||||
|
||||
//apply rules for buttons and switches
|
||||
if(GriefPrevention.instance.config_claims_preventButtonsSwitches && (clickedBlockType == null || clickedBlockType == Material.STONE_BUTTON || clickedBlockType == Material.LEVER))
|
||||
{
|
||||
Claim claim = this.dataStore.getClaimAt(clickedBlock.getLocation(), false, null);
|
||||
if(claim != null)
|
||||
{
|
||||
String noAccessReason = claim.allowAccess(player);
|
||||
if(noAccessReason != null)
|
||||
{
|
||||
event.setCancelled(true);
|
||||
GriefPrevention.sendMessage(player, TextMode.Err, noAccessReason);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//otherwise apply rules for containers and crafting blocks
|
||||
else if( GriefPrevention.instance.config_claims_preventTheft && (
|
||||
//apply rules for containers and crafting blocks
|
||||
if( GriefPrevention.instance.config_claims_preventTheft && (
|
||||
event.getAction() == Action.RIGHT_CLICK_BLOCK && (
|
||||
clickedBlock.getState() instanceof InventoryHolder ||
|
||||
clickedBlockType == Material.BREWING_STAND ||
|
||||
|
|
@ -835,7 +845,7 @@ class PlayerEventHandler implements Listener
|
|||
PlayerData playerData = this.dataStore.getPlayerData(player.getName());
|
||||
if(playerData.siegeData != null)
|
||||
{
|
||||
GriefPrevention.sendMessage(player, TextMode.Err, "You can't access containers while involved in a siege.");
|
||||
GriefPrevention.sendMessage(player, TextMode.Err, Messages.SiegeNoContainers);
|
||||
event.setCancelled(true);
|
||||
return;
|
||||
}
|
||||
|
|
@ -843,7 +853,7 @@ class PlayerEventHandler implements Listener
|
|||
//block container use during pvp combat, same reason
|
||||
if(playerData.inPvpCombat())
|
||||
{
|
||||
GriefPrevention.sendMessage(player, TextMode.Err, "You can't access containers during PvP combat.");
|
||||
GriefPrevention.sendMessage(player, TextMode.Err, Messages.PvPNoContainers);
|
||||
event.setCancelled(true);
|
||||
return;
|
||||
}
|
||||
|
|
@ -857,6 +867,7 @@ class PlayerEventHandler implements Listener
|
|||
{
|
||||
event.setCancelled(true);
|
||||
GriefPrevention.sendMessage(player, TextMode.Err, noContainersReason);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -865,7 +876,23 @@ class PlayerEventHandler implements Listener
|
|||
if(playerData.pvpImmune)
|
||||
{
|
||||
playerData.pvpImmune = false;
|
||||
GriefPrevention.sendMessage(player, TextMode.Warn, "Now you can fight with other players.");
|
||||
GriefPrevention.sendMessage(player, TextMode.Warn, Messages.PvPImmunityEnd);
|
||||
}
|
||||
}
|
||||
|
||||
//otherwise apply rules for buttons and switches
|
||||
else if(GriefPrevention.instance.config_claims_preventButtonsSwitches && (clickedBlockType == null || clickedBlockType == Material.STONE_BUTTON || clickedBlockType == Material.LEVER))
|
||||
{
|
||||
Claim claim = this.dataStore.getClaimAt(clickedBlock.getLocation(), false, null);
|
||||
if(claim != null)
|
||||
{
|
||||
String noAccessReason = claim.allowAccess(player);
|
||||
if(noAccessReason != null)
|
||||
{
|
||||
event.setCancelled(true);
|
||||
GriefPrevention.sendMessage(player, TextMode.Err, noAccessReason);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -874,6 +901,23 @@ class PlayerEventHandler implements Listener
|
|||
else if(event.getAction() == Action.PHYSICAL && clickedBlockType == Material.SOIL)
|
||||
{
|
||||
event.setCancelled(true);
|
||||
return;
|
||||
}
|
||||
|
||||
//apply rule for note blocks
|
||||
else if(clickedBlockType == Material.NOTE_BLOCK)
|
||||
{
|
||||
Claim claim = this.dataStore.getClaimAt(clickedBlock.getLocation(), false, null);
|
||||
if(claim != null)
|
||||
{
|
||||
String noBuildReason = claim.allowBuild(player);
|
||||
if(noBuildReason != null)
|
||||
{
|
||||
event.setCancelled(true);
|
||||
GriefPrevention.sendMessage(player, TextMode.Err, noBuildReason);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//otherwise handle right click (shovel, string, bonemeal)
|
||||
|
|
@ -886,8 +930,8 @@ class PlayerEventHandler implements Listener
|
|||
//what's the player holding?
|
||||
Material materialInHand = player.getItemInHand().getType();
|
||||
|
||||
//if it's bonemeal, check for build permission (ink sac == bone meal, must be a Bukkit bug?)
|
||||
if(materialInHand == Material.INK_SACK)
|
||||
//if it's bonemeal or a boat, check for build permission (ink sac == bone meal, must be a Bukkit bug?)
|
||||
if(materialInHand == Material.INK_SACK || materialInHand == Material.BOAT)
|
||||
{
|
||||
String noBuildReason = GriefPrevention.instance.allowBuild(player, clickedBlock.getLocation());
|
||||
if(noBuildReason != null)
|
||||
|
|
@ -899,8 +943,8 @@ class PlayerEventHandler implements Listener
|
|||
return;
|
||||
}
|
||||
|
||||
//if it's a spawn egg or minecart and this is a creative world, apply special rules
|
||||
else if((materialInHand == Material.MONSTER_EGG || materialInHand == Material.MINECART || materialInHand == Material.POWERED_MINECART || materialInHand == Material.STORAGE_MINECART) && GriefPrevention.instance.creativeRulesApply(clickedBlock.getLocation()))
|
||||
//if it's a spawn egg, minecart, or boat, and this is a creative world, apply special rules
|
||||
else if((materialInHand == Material.MONSTER_EGG || materialInHand == Material.MINECART || materialInHand == Material.POWERED_MINECART || materialInHand == Material.STORAGE_MINECART || materialInHand == Material.BOAT) && GriefPrevention.instance.creativeRulesApply(clickedBlock.getLocation()))
|
||||
{
|
||||
//player needs build permission at this location
|
||||
String noBuildReason = GriefPrevention.instance.allowBuild(player, clickedBlock.getLocation());
|
||||
|
|
@ -933,7 +977,7 @@ class PlayerEventHandler implements Listener
|
|||
//air indicates too far away
|
||||
if(clickedBlockType == Material.AIR)
|
||||
{
|
||||
GriefPrevention.sendMessage(player, TextMode.Err, "That's too far away.");
|
||||
GriefPrevention.sendMessage(player, TextMode.Err, Messages.TooFarAway);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -942,14 +986,14 @@ class PlayerEventHandler implements Listener
|
|||
//no claim case
|
||||
if(claim == null)
|
||||
{
|
||||
GriefPrevention.sendMessage(player, TextMode.Info, "No one has claimed this block.");
|
||||
GriefPrevention.sendMessage(player, TextMode.Info, Messages.BlockNotClaimed);
|
||||
Visualization.Revert(player);
|
||||
}
|
||||
|
||||
//claim case
|
||||
else
|
||||
{
|
||||
GriefPrevention.sendMessage(player, TextMode.Info, "This block has been claimed by " + claim.getOwnerName() + ".");
|
||||
GriefPrevention.sendMessage(player, TextMode.Info, Messages.BlockClaimed, claim.getOwnerName());
|
||||
|
||||
//visualize boundary
|
||||
Visualization visualization = Visualization.FromClaim(claim, clickedBlock.getY(), VisualizationType.Claim);
|
||||
|
|
@ -967,7 +1011,7 @@ class PlayerEventHandler implements Listener
|
|||
//disable golden shovel while under siege
|
||||
if(playerData.siegeData != null)
|
||||
{
|
||||
GriefPrevention.sendMessage(player, TextMode.Err, "You can't use your shovel tool while involved in a siege.");
|
||||
GriefPrevention.sendMessage(player, TextMode.Err, Messages.SiegeNoShovel);
|
||||
event.setCancelled(true);
|
||||
return;
|
||||
}
|
||||
|
|
@ -975,7 +1019,7 @@ class PlayerEventHandler implements Listener
|
|||
//can't use the shovel from too far away
|
||||
if(clickedBlockType == Material.AIR)
|
||||
{
|
||||
GriefPrevention.sendMessage(player, TextMode.Err, "That's too far away!");
|
||||
GriefPrevention.sendMessage(player, TextMode.Err, Messages.TooFarAway);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -988,7 +1032,7 @@ class PlayerEventHandler implements Listener
|
|||
Claim claim = this.dataStore.getClaimAt(clickedBlock.getLocation(), false, playerData.lastClaim);
|
||||
if(claim != null)
|
||||
{
|
||||
GriefPrevention.sendMessage(player, TextMode.Err, claim.getOwnerName() + " claimed that block.");
|
||||
GriefPrevention.sendMessage(player, TextMode.Err, Messages.BlockClaimed, claim.getOwnerName());
|
||||
Visualization visualization = Visualization.FromClaim(claim, clickedBlock.getY(), VisualizationType.ErrorClaim);
|
||||
Visualization.Apply(player, visualization);
|
||||
|
||||
|
|
@ -1005,7 +1049,7 @@ class PlayerEventHandler implements Listener
|
|||
if(entities[i] instanceof Player)
|
||||
{
|
||||
Player otherPlayer = (Player)entities[i];
|
||||
GriefPrevention.sendMessage(player, TextMode.Err, "Unable to restore. " + otherPlayer.getName() + " is in that chunk.");
|
||||
GriefPrevention.sendMessage(player, TextMode.Err, Messages.RestoreNaturePlayerInChunk, otherPlayer.getName());
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
|
@ -1072,9 +1116,17 @@ class PlayerEventHandler implements Listener
|
|||
allowedFillBlocks.add(Material.SANDSTONE);
|
||||
allowedFillBlocks.add(Material.DIRT);
|
||||
allowedFillBlocks.add(Material.GRASS);
|
||||
allowedFillBlocks.add(Material.ICE);
|
||||
}
|
||||
|
||||
Block centerBlock = clickedBlock;
|
||||
|
||||
//sink through a snow layer
|
||||
if(centerBlock.getType() == Material.SNOW)
|
||||
{
|
||||
centerBlock = centerBlock.getRelative(BlockFace.DOWN);
|
||||
}
|
||||
|
||||
int maxHeight = centerBlock.getY();
|
||||
int minx = centerBlock.getX() - playerData.fillRadius;
|
||||
int maxx = centerBlock.getX() + playerData.fillRadius;
|
||||
|
|
@ -1105,8 +1157,8 @@ class PlayerEventHandler implements Listener
|
|||
break;
|
||||
}
|
||||
|
||||
//only replace air and spilling water
|
||||
if(block.getType() == Material.AIR || block.getType() == Material.STATIONARY_WATER && block.getData() != 0)
|
||||
//only replace air, spilling water, snow
|
||||
if(block.getType() == Material.AIR || block.getType() == Material.SNOW || (block.getType() == Material.STATIONARY_WATER && block.getData() != 0))
|
||||
{
|
||||
//look to neighbors for an appropriate fill block
|
||||
Block eastBlock = block.getRelative(BlockFace.EAST);
|
||||
|
|
@ -1155,7 +1207,7 @@ class PlayerEventHandler implements Listener
|
|||
//if the player doesn't have claims permission, don't do anything
|
||||
if(GriefPrevention.instance.config_claims_creationRequiresPermission && !player.hasPermission("griefprevention.createclaims"))
|
||||
{
|
||||
GriefPrevention.sendMessage(player, TextMode.Err, "You don't have permission to claim land.");
|
||||
GriefPrevention.sendMessage(player, TextMode.Err, Messages.NoCreateClaimPermission);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -1214,7 +1266,7 @@ class PlayerEventHandler implements Listener
|
|||
|
||||
if(!playerData.claimResizing.isAdminClaim() && (newWidth < GriefPrevention.instance.config_claims_minSize || newHeight < GriefPrevention.instance.config_claims_minSize))
|
||||
{
|
||||
GriefPrevention.sendMessage(player, TextMode.Err, "This new size would be too small. Claims must be at least " + GriefPrevention.instance.config_claims_minSize + " x " + GriefPrevention.instance.config_claims_minSize + ".");
|
||||
GriefPrevention.sendMessage(player, TextMode.Err, Messages.ResizeClaimTooSmall, String.valueOf(GriefPrevention.instance.config_claims_minSize));
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -1226,7 +1278,7 @@ class PlayerEventHandler implements Listener
|
|||
|
||||
if(blocksRemainingAfter < 0)
|
||||
{
|
||||
GriefPrevention.sendMessage(player, TextMode.Err, "You don't have enough blocks for this size. You need " + Math.abs(blocksRemainingAfter) + " more.");
|
||||
GriefPrevention.sendMessage(player, TextMode.Err, Messages.ResizeNeedMoreBlocks, String.valueOf(Math.abs(blocksRemainingAfter)));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
|
@ -1250,7 +1302,7 @@ class PlayerEventHandler implements Listener
|
|||
//enforce creative mode rule
|
||||
if(!player.hasPermission("griefprevention.deleteclaims") && GriefPrevention.instance.creativeRulesApply(player.getLocation()))
|
||||
{
|
||||
GriefPrevention.sendMessage(player, TextMode.Err, "You can't un-claim creative mode land. You can only make this claim larger or create additional claims.");
|
||||
GriefPrevention.sendMessage(player, TextMode.Err, Messages.NoCreativeUnClaim);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -1265,7 +1317,7 @@ class PlayerEventHandler implements Listener
|
|||
if(result.succeeded)
|
||||
{
|
||||
//inform and show the player
|
||||
GriefPrevention.sendMessage(player, TextMode.Success, "Claim resized. You now have " + playerData.getRemainingClaimBlocks() + " available claim blocks.");
|
||||
GriefPrevention.sendMessage(player, TextMode.Success, Messages.ClaimResizeSuccess, String.valueOf(playerData.getRemainingClaimBlocks()));
|
||||
Visualization visualization = Visualization.FromClaim(result.claim, clickedBlock.getY(), VisualizationType.Claim);
|
||||
Visualization.Apply(player, visualization);
|
||||
|
||||
|
|
@ -1282,7 +1334,7 @@ class PlayerEventHandler implements Listener
|
|||
else
|
||||
{
|
||||
//inform player
|
||||
GriefPrevention.sendMessage(player, TextMode.Err, "Can't resize here because it would overlap another nearby claim.");
|
||||
GriefPrevention.sendMessage(player, TextMode.Err, Messages.ResizeFailOverlap);
|
||||
|
||||
//show the player the conflicting claim
|
||||
Visualization visualization = Visualization.FromClaim(result.claim, clickedBlock.getY(), VisualizationType.ErrorClaim);
|
||||
|
|
@ -1307,7 +1359,7 @@ class PlayerEventHandler implements Listener
|
|||
{
|
||||
playerData.claimResizing = claim;
|
||||
playerData.lastShovelLocation = clickedBlock.getLocation();
|
||||
player.sendMessage("Resizing claim. Use your shovel again at the new location for this corner.");
|
||||
GriefPrevention.sendMessage(player, TextMode.Instr, Messages.ResizeStart);
|
||||
}
|
||||
|
||||
//if he didn't click on a corner and is in subdivision mode, he's creating a new subdivision
|
||||
|
|
@ -1319,13 +1371,13 @@ class PlayerEventHandler implements Listener
|
|||
//if the clicked claim was a subdivision, tell him he can't start a new subdivision here
|
||||
if(claim.parent != null)
|
||||
{
|
||||
GriefPrevention.sendMessage(player, TextMode.Err, "You can't create a subdivision here because it would overlap another subdivision. Consider /abandonclaim to delete it, or use your shovel at a corner to resize it.");
|
||||
GriefPrevention.sendMessage(player, TextMode.Err, Messages.ResizeFailOverlapSubdivision);
|
||||
}
|
||||
|
||||
//otherwise start a new subdivision
|
||||
else
|
||||
{
|
||||
GriefPrevention.sendMessage(player, TextMode.Instr, "Subdivision corner set! Use your shovel at the location for the opposite corner of this new subdivision.");
|
||||
GriefPrevention.sendMessage(player, TextMode.Instr, Messages.SubdivisionStart);
|
||||
playerData.lastShovelLocation = clickedBlock.getLocation();
|
||||
playerData.claimSubdividing = claim;
|
||||
}
|
||||
|
|
@ -1354,7 +1406,7 @@ class PlayerEventHandler implements Listener
|
|||
//if it didn't succeed, tell the player why
|
||||
if(!result.succeeded)
|
||||
{
|
||||
GriefPrevention.sendMessage(player, TextMode.Err, "Your selected area overlaps another subdivision.");
|
||||
GriefPrevention.sendMessage(player, TextMode.Err, Messages.CreateSubdivisionOverlap);
|
||||
|
||||
Visualization visualization = Visualization.FromClaim(result.claim, clickedBlock.getY(), VisualizationType.ErrorClaim);
|
||||
Visualization.Apply(player, visualization);
|
||||
|
|
@ -1365,7 +1417,7 @@ class PlayerEventHandler implements Listener
|
|||
//otherwise, advise him on the /trust command and show him his new subdivision
|
||||
else
|
||||
{
|
||||
GriefPrevention.sendMessage(player, TextMode.Success, "Subdivision created! Use /trust to share it with friends.");
|
||||
GriefPrevention.sendMessage(player, TextMode.Success, Messages.SubdivisionSuccess);
|
||||
Visualization visualization = Visualization.FromClaim(result.claim, clickedBlock.getY(), VisualizationType.Claim);
|
||||
Visualization.Apply(player, visualization);
|
||||
playerData.lastShovelLocation = null;
|
||||
|
|
@ -1378,7 +1430,7 @@ class PlayerEventHandler implements Listener
|
|||
//also advise him to consider /abandonclaim or resizing the existing claim
|
||||
else
|
||||
{
|
||||
GriefPrevention.sendMessage(player, TextMode.Err, "You can't create a claim here because it would overlap your other claim. Use /abandonclaim to delete it, or use your shovel at a corner to resize it.");
|
||||
GriefPrevention.sendMessage(player, TextMode.Err, Messages.CreateClaimFailOverlap);
|
||||
Visualization visualization = Visualization.FromClaim(claim, clickedBlock.getY(), VisualizationType.Claim);
|
||||
Visualization.Apply(player, visualization);
|
||||
}
|
||||
|
|
@ -1387,7 +1439,7 @@ class PlayerEventHandler implements Listener
|
|||
//otherwise tell the player he can't claim here because it's someone else's claim, and show him the claim
|
||||
else
|
||||
{
|
||||
GriefPrevention.sendMessage(player, TextMode.Err, "You can't create a claim here because it would overlap " + claim.getOwnerName() + "'s claim.");
|
||||
GriefPrevention.sendMessage(player, TextMode.Err, Messages.CreateClaimFailOverlapOtherPlayer, claim.getOwnerName());
|
||||
Visualization visualization = Visualization.FromClaim(claim, clickedBlock.getY(), VisualizationType.ErrorClaim);
|
||||
Visualization.Apply(player, visualization);
|
||||
}
|
||||
|
|
@ -1404,13 +1456,13 @@ class PlayerEventHandler implements Listener
|
|||
//if claims are not enabled in this world and it's not an administrative claim, display an error message and stop
|
||||
if(!GriefPrevention.instance.claimsEnabledForWorld(player.getWorld()) && playerData.shovelMode != ShovelMode.Admin)
|
||||
{
|
||||
GriefPrevention.sendMessage(player, TextMode.Err, "Land claims are disabled in this world.");
|
||||
GriefPrevention.sendMessage(player, TextMode.Err, Messages.ClaimsDisabledWorld);
|
||||
return;
|
||||
}
|
||||
|
||||
//remember it, and start him on the new claim
|
||||
playerData.lastShovelLocation = clickedBlock.getLocation();
|
||||
GriefPrevention.sendMessage(player, TextMode.Instr, "Claim corner set! Use the shovel again at the opposite corner to claim a rectangle of land. To cancel, put your shovel away.");
|
||||
GriefPrevention.sendMessage(player, TextMode.Instr, Messages.ClaimStart);
|
||||
}
|
||||
|
||||
//otherwise, he's trying to finish creating a claim by setting the other boundary corner
|
||||
|
|
@ -1430,7 +1482,7 @@ class PlayerEventHandler implements Listener
|
|||
|
||||
if(playerData.shovelMode != ShovelMode.Admin && (newClaimWidth < GriefPrevention.instance.config_claims_minSize || newClaimHeight < GriefPrevention.instance.config_claims_minSize))
|
||||
{
|
||||
GriefPrevention.sendMessage(player, TextMode.Err, "This claim would be too small. Any claim must be at least " + GriefPrevention.instance.config_claims_minSize + " x " + GriefPrevention.instance.config_claims_minSize + ".");
|
||||
GriefPrevention.sendMessage(player, TextMode.Err, Messages.NewClaimTooSmall, String.valueOf(GriefPrevention.instance.config_claims_minSize));
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -1441,8 +1493,8 @@ class PlayerEventHandler implements Listener
|
|||
int remainingBlocks = playerData.getRemainingClaimBlocks();
|
||||
if(newClaimArea > remainingBlocks)
|
||||
{
|
||||
GriefPrevention.sendMessage(player, TextMode.Err, "You don't have enough blocks to claim that entire area. You need " + (newClaimArea - remainingBlocks) + " more blocks.");
|
||||
GriefPrevention.sendMessage(player, TextMode.Instr, "To delete another claim and free up some blocks, use /AbandonClaim.");
|
||||
GriefPrevention.sendMessage(player, TextMode.Err, Messages.CreateClaimInsufficientBlocks, String.valueOf(newClaimArea - remainingBlocks));
|
||||
GriefPrevention.sendMessage(player, TextMode.Instr, Messages.AbandonClaimAdvertisement);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
|
@ -1463,7 +1515,7 @@ class PlayerEventHandler implements Listener
|
|||
//if it didn't succeed, tell the player why
|
||||
if(!result.succeeded)
|
||||
{
|
||||
GriefPrevention.sendMessage(player, TextMode.Err, "Your selected area overlaps an existing claim.");
|
||||
GriefPrevention.sendMessage(player, TextMode.Err, Messages.CreateClaimFailOverlapShort);
|
||||
|
||||
Visualization visualization = Visualization.FromClaim(result.claim, clickedBlock.getY(), VisualizationType.ErrorClaim);
|
||||
Visualization.Apply(player, visualization);
|
||||
|
|
@ -1474,7 +1526,7 @@ class PlayerEventHandler implements Listener
|
|||
//otherwise, advise him on the /trust command and show him his new claim
|
||||
else
|
||||
{
|
||||
GriefPrevention.sendMessage(player, TextMode.Success, "Claim created! Use /trust to share it with friends.");
|
||||
GriefPrevention.sendMessage(player, TextMode.Success, Messages.CreateClaimSuccess);
|
||||
Visualization visualization = Visualization.FromClaim(result.claim, clickedBlock.getY(), VisualizationType.Claim);
|
||||
Visualization.Apply(player, visualization);
|
||||
playerData.lastShovelLocation = null;
|
||||
|
|
|
|||
|
|
@ -53,7 +53,7 @@ class PlayerRescueTask implements Runnable
|
|||
//if the player moved three or more blocks from where he used /trapped, admonish him and don't save him
|
||||
if(player.getLocation().distance(this.location) > 3)
|
||||
{
|
||||
GriefPrevention.sendMessage(player, TextMode.Err, "You moved! Rescue cancelled.");
|
||||
GriefPrevention.sendMessage(player, TextMode.Err, Messages.RescueAbortedMoved);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -84,7 +84,6 @@ class RestoreNatureProcessingTask implements Runnable
|
|||
this.playerBlocks.add(Material.BREWING_STAND.getId());
|
||||
this.playerBlocks.add(Material.BRICK.getId());
|
||||
this.playerBlocks.add(Material.COBBLESTONE.getId());
|
||||
this.playerBlocks.add(Material.OBSIDIAN.getId());
|
||||
this.playerBlocks.add(Material.GLASS.getId());
|
||||
this.playerBlocks.add(Material.LAPIS_BLOCK.getId());
|
||||
this.playerBlocks.add(Material.DISPENSER.getId());
|
||||
|
|
@ -149,6 +148,8 @@ class RestoreNatureProcessingTask implements Runnable
|
|||
this.playerBlocks.add(Material.CAULDRON.getId());
|
||||
this.playerBlocks.add(Material.DIODE_BLOCK_ON.getId());
|
||||
this.playerBlocks.add(Material.DIODE_BLOCK_ON.getId());
|
||||
this.playerBlocks.add(Material.WEB.getId());
|
||||
this.playerBlocks.add(Material.SPONGE.getId());
|
||||
|
||||
//these are unnatural in the standard world, but not in the nether
|
||||
if(this.environment != Environment.NETHER)
|
||||
|
|
@ -161,6 +162,12 @@ class RestoreNatureProcessingTask implements Runnable
|
|||
this.playerBlocks.add(Material.NETHER_BRICK_STAIRS.getId());
|
||||
}
|
||||
|
||||
//these are unnatural in the standard and nether worlds, but not in the end
|
||||
if(this.environment != Environment.THE_END)
|
||||
{
|
||||
this.playerBlocks.add(Material.OBSIDIAN.getId());
|
||||
}
|
||||
|
||||
//these are unnatural in sandy biomes, but not elsewhere
|
||||
if(this.biome == Biome.DESERT || this.biome == Biome.DESERT_HILLS || this.biome == Biome.BEACH || this.aggressiveMode)
|
||||
{
|
||||
|
|
@ -178,6 +185,9 @@ class RestoreNatureProcessingTask implements Runnable
|
|||
this.playerBlocks.add(Material.PUMPKIN_STEM.getId());
|
||||
this.playerBlocks.add(Material.MELON_BLOCK.getId());
|
||||
this.playerBlocks.add(Material.MELON_STEM.getId());
|
||||
this.playerBlocks.add(Material.BEDROCK.getId());
|
||||
this.playerBlocks.add(Material.GRAVEL.getId());
|
||||
this.playerBlocks.add(Material.SANDSTONE.getId());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -47,7 +47,7 @@ class SecureClaimTask implements Runnable
|
|||
Player player = onlinePlayers[j];
|
||||
if(claim.contains(player.getLocation(), false, false) && claim.allowAccess(player) != null)
|
||||
{
|
||||
GriefPrevention.sendMessage(player, TextMode.Err, "Looting time is up! Ejected from the claim.");
|
||||
GriefPrevention.sendMessage(player, TextMode.Err, Messages.SiegeDoorsLockedEjection);
|
||||
GriefPrevention.instance.ejectPlayer(player);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user