6.9
This commit is contained in:
parent
6632af96df
commit
e09a6732ba
|
|
@ -2,7 +2,7 @@ name: GriefPrevention
|
||||||
main: me.ryanhamshire.GriefPrevention.GriefPrevention
|
main: me.ryanhamshire.GriefPrevention.GriefPrevention
|
||||||
softdepend: [Vault, Multiverse-Core, My Worlds, MystCraft, Transporter]
|
softdepend: [Vault, Multiverse-Core, My Worlds, MystCraft, Transporter]
|
||||||
dev-url: http://dev.bukkit.org/server-mods/grief-prevention
|
dev-url: http://dev.bukkit.org/server-mods/grief-prevention
|
||||||
version: 6.7
|
version: 6.9
|
||||||
commands:
|
commands:
|
||||||
abandonclaim:
|
abandonclaim:
|
||||||
description: Deletes a claim.
|
description: Deletes a claim.
|
||||||
|
|
|
||||||
|
|
@ -30,7 +30,10 @@ import org.bukkit.block.Block;
|
||||||
import org.bukkit.block.BlockFace;
|
import org.bukkit.block.BlockFace;
|
||||||
import org.bukkit.block.BlockState;
|
import org.bukkit.block.BlockState;
|
||||||
import org.bukkit.block.Chest;
|
import org.bukkit.block.Chest;
|
||||||
|
import org.bukkit.entity.Arrow;
|
||||||
|
import org.bukkit.entity.LivingEntity;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
|
import org.bukkit.entity.Projectile;
|
||||||
import org.bukkit.event.EventHandler;
|
import org.bukkit.event.EventHandler;
|
||||||
import org.bukkit.event.EventPriority;
|
import org.bukkit.event.EventPriority;
|
||||||
import org.bukkit.event.Listener;
|
import org.bukkit.event.Listener;
|
||||||
|
|
@ -46,6 +49,7 @@ import org.bukkit.event.block.BlockPistonRetractEvent;
|
||||||
import org.bukkit.event.block.BlockPlaceEvent;
|
import org.bukkit.event.block.BlockPlaceEvent;
|
||||||
import org.bukkit.event.block.BlockSpreadEvent;
|
import org.bukkit.event.block.BlockSpreadEvent;
|
||||||
import org.bukkit.event.block.SignChangeEvent;
|
import org.bukkit.event.block.SignChangeEvent;
|
||||||
|
import org.bukkit.event.entity.ProjectileHitEvent;
|
||||||
import org.bukkit.event.world.StructureGrowEvent;
|
import org.bukkit.event.world.StructureGrowEvent;
|
||||||
import org.bukkit.inventory.Inventory;
|
import org.bukkit.inventory.Inventory;
|
||||||
import org.bukkit.inventory.ItemStack;
|
import org.bukkit.inventory.ItemStack;
|
||||||
|
|
@ -77,6 +81,36 @@ public class BlockEventHandler implements Listener
|
||||||
this.trashBlocks.add(Material.WORKBENCH);
|
this.trashBlocks.add(Material.WORKBENCH);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//when a wooden button is triggered by an arrow...
|
||||||
|
@EventHandler(ignoreCancelled = true, priority = EventPriority.LOWEST)
|
||||||
|
public void onProjectileHit(ProjectileHitEvent event)
|
||||||
|
{
|
||||||
|
Projectile projectile = event.getEntity();
|
||||||
|
Location location = projectile.getLocation();
|
||||||
|
Block block = location.getBlock();
|
||||||
|
|
||||||
|
//only care about wooden buttons
|
||||||
|
if(block.getType() != Material.WOOD_BUTTON) return;
|
||||||
|
|
||||||
|
//only care about arrows
|
||||||
|
if(projectile instanceof Arrow)
|
||||||
|
{
|
||||||
|
Arrow arrow = (Arrow)projectile;
|
||||||
|
LivingEntity shooterEntity = arrow.getShooter();
|
||||||
|
|
||||||
|
//player arrows only trigger buttons when they have permission
|
||||||
|
if(shooterEntity instanceof Player)
|
||||||
|
{
|
||||||
|
//Player player = (Player)shooterEntity;
|
||||||
|
}
|
||||||
|
|
||||||
|
//other arrows don't trigger buttons, could be used as a workaround to get access to areas without permission
|
||||||
|
else
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//when a block is damaged...
|
//when a block is damaged...
|
||||||
@EventHandler(ignoreCancelled = true)
|
@EventHandler(ignoreCancelled = true)
|
||||||
public void onBlockDamaged(BlockDamageEvent event)
|
public void onBlockDamaged(BlockDamageEvent event)
|
||||||
|
|
@ -377,7 +411,7 @@ public class BlockEventHandler implements Listener
|
||||||
//warn players when they place TNT above sea level, since it doesn't destroy blocks there
|
//warn players when they place TNT above sea level, since it doesn't destroy blocks there
|
||||||
if( GriefPrevention.instance.config_blockSurfaceOtherExplosions && block.getType() == Material.TNT &&
|
if( GriefPrevention.instance.config_blockSurfaceOtherExplosions && block.getType() == Material.TNT &&
|
||||||
block.getWorld().getEnvironment() != Environment.NETHER &&
|
block.getWorld().getEnvironment() != Environment.NETHER &&
|
||||||
block.getY() > block.getWorld().getSeaLevel() - 5)
|
block.getY() > GriefPrevention.instance.getSeaLevel(block.getWorld()) - 5)
|
||||||
{
|
{
|
||||||
GriefPrevention.sendMessage(player, TextMode.Warn, Messages.NoTNTDamageAboveSeaLevel);
|
GriefPrevention.sendMessage(player, TextMode.Warn, Messages.NoTNTDamageAboveSeaLevel);
|
||||||
}
|
}
|
||||||
|
|
@ -514,11 +548,7 @@ public class BlockEventHandler implements Listener
|
||||||
@EventHandler(priority = EventPriority.LOWEST)
|
@EventHandler(priority = EventPriority.LOWEST)
|
||||||
public void onBlockIgnite (BlockIgniteEvent igniteEvent)
|
public void onBlockIgnite (BlockIgniteEvent igniteEvent)
|
||||||
{
|
{
|
||||||
if(!GriefPrevention.instance.config_fireSpreads &&
|
if(!GriefPrevention.instance.config_fireSpreads && igniteEvent.getCause() != IgniteCause.FLINT_AND_STEEL && igniteEvent.getCause() != IgniteCause.LIGHTNING)
|
||||||
igniteEvent.getBlock().getWorld().getEnvironment() == Environment.NORMAL &&
|
|
||||||
igniteEvent.getCause() != IgniteCause.FLINT_AND_STEEL &&
|
|
||||||
igniteEvent.getCause() != IgniteCause.LIGHTNING &&
|
|
||||||
igniteEvent.getCause() != IgniteCause.LAVA)
|
|
||||||
{
|
{
|
||||||
igniteEvent.setCancelled(true);
|
igniteEvent.setCancelled(true);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -131,7 +131,7 @@ public class Claim
|
||||||
int seaLevel = 0; //clean up all fluids in the end
|
int seaLevel = 0; //clean up all fluids in the end
|
||||||
|
|
||||||
//respect sea level in normal worlds
|
//respect sea level in normal worlds
|
||||||
if(lesser.getWorld().getEnvironment() == Environment.NORMAL) seaLevel = lesser.getWorld().getSeaLevel();
|
if(lesser.getWorld().getEnvironment() == Environment.NORMAL) seaLevel = GriefPrevention.instance.getSeaLevel(lesser.getWorld());
|
||||||
|
|
||||||
for(int x = lesser.getBlockX(); x <= greater.getBlockX(); x++)
|
for(int x = lesser.getBlockX(); x <= greater.getBlockX(); x++)
|
||||||
{
|
{
|
||||||
|
|
@ -165,7 +165,7 @@ public class Claim
|
||||||
int seaLevel = 0; //clean up all fluids in the end
|
int seaLevel = 0; //clean up all fluids in the end
|
||||||
|
|
||||||
//respect sea level in normal worlds
|
//respect sea level in normal worlds
|
||||||
if(lesser.getWorld().getEnvironment() == Environment.NORMAL) seaLevel = lesser.getWorld().getSeaLevel();
|
if(lesser.getWorld().getEnvironment() == Environment.NORMAL) seaLevel = GriefPrevention.instance.getSeaLevel(lesser.getWorld());
|
||||||
|
|
||||||
int waterCount = 0;
|
int waterCount = 0;
|
||||||
for(int x = lesser.getBlockX(); x <= greater.getBlockX(); x++)
|
for(int x = lesser.getBlockX(); x <= greater.getBlockX(); x++)
|
||||||
|
|
@ -362,7 +362,10 @@ public class Claim
|
||||||
return this.parent.allowBuild(player);
|
return this.parent.allowBuild(player);
|
||||||
|
|
||||||
//failure message for all other cases
|
//failure message for all other cases
|
||||||
return GriefPrevention.instance.dataStore.getMessage(Messages.NoBuildPermission, this.getOwnerName());
|
String reason = GriefPrevention.instance.dataStore.getMessage(Messages.NoBuildPermission, this.getOwnerName());
|
||||||
|
if(player.hasPermission("griefprevention.ignoreclaims"))
|
||||||
|
reason += " " + GriefPrevention.instance.dataStore.getMessage(Messages.IgnoreClaimsAdvertisement);
|
||||||
|
return reason;
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean hasExplicitPermission(Player player, ClaimPermission level)
|
private boolean hasExplicitPermission(Player player, ClaimPermission level)
|
||||||
|
|
@ -458,7 +461,10 @@ public class Claim
|
||||||
return this.parent.allowAccess(player);
|
return this.parent.allowAccess(player);
|
||||||
|
|
||||||
//catch-all error message for all other cases
|
//catch-all error message for all other cases
|
||||||
return GriefPrevention.instance.dataStore.getMessage(Messages.NoAccessPermission, this.getOwnerName());
|
String reason = GriefPrevention.instance.dataStore.getMessage(Messages.NoAccessPermission, this.getOwnerName());
|
||||||
|
if(player.hasPermission("griefprevention.ignoreclaims"))
|
||||||
|
reason += " " + GriefPrevention.instance.dataStore.getMessage(Messages.IgnoreClaimsAdvertisement);
|
||||||
|
return reason;
|
||||||
}
|
}
|
||||||
|
|
||||||
//inventory permission check
|
//inventory permission check
|
||||||
|
|
@ -498,7 +504,10 @@ public class Claim
|
||||||
return this.parent.allowContainers(player);
|
return this.parent.allowContainers(player);
|
||||||
|
|
||||||
//error message for all other cases
|
//error message for all other cases
|
||||||
return GriefPrevention.instance.dataStore.getMessage(Messages.NoContainersPermission, this.getOwnerName());
|
String reason = GriefPrevention.instance.dataStore.getMessage(Messages.NoContainersPermission, this.getOwnerName());
|
||||||
|
if(player.hasPermission("griefprevention.ignoreclaims"))
|
||||||
|
reason += " " + GriefPrevention.instance.dataStore.getMessage(Messages.IgnoreClaimsAdvertisement);
|
||||||
|
return reason;
|
||||||
}
|
}
|
||||||
|
|
||||||
//grant permission check, relatively simple
|
//grant permission check, relatively simple
|
||||||
|
|
@ -529,7 +538,10 @@ public class Claim
|
||||||
return this.parent.allowGrantPermission(player);
|
return this.parent.allowGrantPermission(player);
|
||||||
|
|
||||||
//generic error message
|
//generic error message
|
||||||
return GriefPrevention.instance.dataStore.getMessage(Messages.NoPermissionTrust, this.getOwnerName());
|
String reason = GriefPrevention.instance.dataStore.getMessage(Messages.NoPermissionTrust, this.getOwnerName());
|
||||||
|
if(player.hasPermission("griefprevention.ignoreclaims"))
|
||||||
|
reason += " " + GriefPrevention.instance.dataStore.getMessage(Messages.IgnoreClaimsAdvertisement);
|
||||||
|
return reason;
|
||||||
}
|
}
|
||||||
|
|
||||||
//grants a permission for a player or the public
|
//grants a permission for a player or the public
|
||||||
|
|
@ -778,7 +790,7 @@ public class Claim
|
||||||
for(int z = this.lesserBoundaryCorner.getBlockZ(); z <= this.greaterBoundaryCorner.getBlockZ(); z++)
|
for(int z = this.lesserBoundaryCorner.getBlockZ(); z <= this.greaterBoundaryCorner.getBlockZ(); z++)
|
||||||
{
|
{
|
||||||
int y = this.lesserBoundaryCorner.getBlockY();
|
int y = this.lesserBoundaryCorner.getBlockY();
|
||||||
for(; y < this.lesserBoundaryCorner.getWorld().getSeaLevel(); y++)
|
for(; y < GriefPrevention.instance.getSeaLevel(this.lesserBoundaryCorner.getWorld()) - 5; y++)
|
||||||
{
|
{
|
||||||
Block block = this.lesserBoundaryCorner.getWorld().getBlockAt(x, y, z);
|
Block block = this.lesserBoundaryCorner.getWorld().getBlockAt(x, y, z);
|
||||||
if(playerBlocks.contains(block.getTypeId()))
|
if(playerBlocks.contains(block.getTypeId()))
|
||||||
|
|
@ -789,7 +801,7 @@ public class Claim
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
score += .2;
|
score += .5;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -20,6 +20,7 @@
|
||||||
|
|
||||||
import java.util.Calendar;
|
import java.util.Calendar;
|
||||||
import java.util.Random;
|
import java.util.Random;
|
||||||
|
import java.util.Vector;
|
||||||
|
|
||||||
import org.bukkit.Chunk;
|
import org.bukkit.Chunk;
|
||||||
import org.bukkit.World;
|
import org.bukkit.World;
|
||||||
|
|
@ -63,6 +64,9 @@ class CleanupUnusedClaimsTask implements Runnable
|
||||||
//skip administrative claims
|
//skip administrative claims
|
||||||
if(claim.isAdminClaim()) return;
|
if(claim.isAdminClaim()) return;
|
||||||
|
|
||||||
|
//track whether we do any important work which would require cleanup afterward
|
||||||
|
boolean cleanupChunks = false;
|
||||||
|
|
||||||
//get data for the player, especially last login timestamp
|
//get data for the player, especially last login timestamp
|
||||||
PlayerData playerData = GriefPrevention.instance.dataStore.getPlayerData(claim.ownerName);
|
PlayerData playerData = GriefPrevention.instance.dataStore.getPlayerData(claim.ownerName);
|
||||||
|
|
||||||
|
|
@ -75,20 +79,21 @@ class CleanupUnusedClaimsTask implements Runnable
|
||||||
|
|
||||||
//if he's been gone at least a week, if he has ONLY the new player claim, it will be removed
|
//if he's been gone at least a week, if he has ONLY the new player claim, it will be removed
|
||||||
Calendar sevenDaysAgo = Calendar.getInstance();
|
Calendar sevenDaysAgo = Calendar.getInstance();
|
||||||
sevenDaysAgo.add(Calendar.DATE, -7);
|
sevenDaysAgo.add(Calendar.DATE, -GriefPrevention.instance.config_claims_chestClaimExpirationDays);
|
||||||
boolean newPlayerClaimsExpired = sevenDaysAgo.getTime().after(playerData.lastLogin);
|
boolean newPlayerClaimsExpired = sevenDaysAgo.getTime().after(playerData.lastLogin);
|
||||||
|
|
||||||
//if only one claim, and the player hasn't played in a week
|
//if only one claim, and the player hasn't played in a week
|
||||||
if(newPlayerClaimsExpired && playerData.claims.size() == 1)
|
if(newPlayerClaimsExpired && playerData.claims.size() == 1)
|
||||||
{
|
{
|
||||||
//if that's a chest claim, delete it
|
//if that's a chest claim and those are set to expire
|
||||||
if(claim.getArea() <= areaOfDefaultClaim)
|
if(claim.getArea() <= areaOfDefaultClaim && GriefPrevention.instance.config_claims_chestClaimExpirationDays > 0)
|
||||||
{
|
{
|
||||||
claim.removeSurfaceFluids(null);
|
claim.removeSurfaceFluids(null);
|
||||||
GriefPrevention.instance.dataStore.deleteClaim(claim);
|
GriefPrevention.instance.dataStore.deleteClaim(claim);
|
||||||
|
cleanupChunks = true;
|
||||||
|
|
||||||
//if in a creative mode world, delete the claim
|
//if configured to do so, restore the land to natural
|
||||||
if(GriefPrevention.instance.creativeRulesApply(claim.getLesserBoundaryCorner()))
|
if((GriefPrevention.instance.creativeRulesApply(claim.getLesserBoundaryCorner()) && GriefPrevention.instance.config_claims_creativeAutoNatureRestoration) || GriefPrevention.instance.config_claims_survivalAutoNatureRestoration)
|
||||||
{
|
{
|
||||||
GriefPrevention.instance.restoreClaim(claim, 0);
|
GriefPrevention.instance.restoreClaim(claim, 0);
|
||||||
}
|
}
|
||||||
|
|
@ -105,18 +110,35 @@ class CleanupUnusedClaimsTask implements Runnable
|
||||||
|
|
||||||
if(earliestPermissibleLastLogin.getTime().after(playerData.lastLogin))
|
if(earliestPermissibleLastLogin.getTime().after(playerData.lastLogin))
|
||||||
{
|
{
|
||||||
|
//make a copy of this player's claim list
|
||||||
|
Vector<Claim> claims = new Vector<Claim>();
|
||||||
|
for(int i = 0; i < playerData.claims.size(); i++)
|
||||||
|
{
|
||||||
|
claims.add(playerData.claims.get(i));
|
||||||
|
}
|
||||||
|
|
||||||
|
//delete them
|
||||||
GriefPrevention.instance.dataStore.deleteClaimsForPlayer(claim.getOwnerName(), true);
|
GriefPrevention.instance.dataStore.deleteClaimsForPlayer(claim.getOwnerName(), true);
|
||||||
GriefPrevention.AddLogEntry(" All of " + claim.getOwnerName() + "'s claims have expired.");
|
GriefPrevention.AddLogEntry(" All of " + claim.getOwnerName() + "'s claims have expired.");
|
||||||
|
|
||||||
|
for(int i = 0; i < claims.size(); i++)
|
||||||
|
{
|
||||||
|
//if configured to do so, restore the land to natural
|
||||||
|
if((GriefPrevention.instance.creativeRulesApply(claims.get(i).getLesserBoundaryCorner()) && GriefPrevention.instance.config_claims_creativeAutoNatureRestoration) || GriefPrevention.instance.config_claims_survivalAutoNatureRestoration)
|
||||||
|
{
|
||||||
|
GriefPrevention.instance.restoreClaim(claims.get(i), 0);
|
||||||
|
cleanupChunks = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
else
|
else if(GriefPrevention.instance.config_claims_unusedClaimExpirationDays > 0)
|
||||||
{
|
{
|
||||||
|
|
||||||
//if the player has been gone two weeks, scan claim content to assess player investment
|
//if the player has been gone two weeks, scan claim content to assess player investment
|
||||||
Calendar fourteenDaysAgo = Calendar.getInstance();
|
Calendar earliestAllowedLoginDate = Calendar.getInstance();
|
||||||
fourteenDaysAgo.add(Calendar.DATE, -14);
|
earliestAllowedLoginDate.add(Calendar.DATE, -GriefPrevention.instance.config_claims_unusedClaimExpirationDays);
|
||||||
boolean needsInvestmentScan = fourteenDaysAgo.getTime().after(playerData.lastLogin);
|
boolean needsInvestmentScan = earliestAllowedLoginDate.getTime().after(playerData.lastLogin);
|
||||||
|
|
||||||
//avoid scanning large claims and administrative claims
|
//avoid scanning large claims and administrative claims
|
||||||
if(claim.isAdminClaim() || claim.getWidth() > 25 || claim.getHeight() > 25) return;
|
if(claim.isAdminClaim() || claim.getWidth() > 25 || claim.getHeight() > 25) return;
|
||||||
|
|
@ -131,10 +153,11 @@ class CleanupUnusedClaimsTask implements Runnable
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
minInvestment = 200;
|
minInvestment = 100;
|
||||||
}
|
}
|
||||||
|
|
||||||
long investmentScore = claim.getPlayerInvestmentScore();
|
long investmentScore = claim.getPlayerInvestmentScore();
|
||||||
|
cleanupChunks = true;
|
||||||
boolean removeClaim = false;
|
boolean removeClaim = false;
|
||||||
|
|
||||||
//in creative mode, a build which is almost entirely lava above sea level will be automatically removed, even if the owner is an active player
|
//in creative mode, a build which is almost entirely lava above sea level will be automatically removed, even if the owner is an active player
|
||||||
|
|
@ -156,8 +179,8 @@ class CleanupUnusedClaimsTask implements Runnable
|
||||||
GriefPrevention.instance.dataStore.deleteClaim(claim);
|
GriefPrevention.instance.dataStore.deleteClaim(claim);
|
||||||
GriefPrevention.AddLogEntry("Removed " + claim.getOwnerName() + "'s unused claim @ " + GriefPrevention.getfriendlyLocationString(claim.getLesserBoundaryCorner()));
|
GriefPrevention.AddLogEntry("Removed " + claim.getOwnerName() + "'s unused claim @ " + GriefPrevention.getfriendlyLocationString(claim.getLesserBoundaryCorner()));
|
||||||
|
|
||||||
//if in a creative mode world, restore the claim area
|
//if configured to do so, restore the claim area to natural state
|
||||||
if(GriefPrevention.instance.creativeRulesApply(claim.getLesserBoundaryCorner()))
|
if((GriefPrevention.instance.creativeRulesApply(claim.getLesserBoundaryCorner()) && GriefPrevention.instance.config_claims_creativeAutoNatureRestoration) || GriefPrevention.instance.config_claims_survivalAutoNatureRestoration)
|
||||||
{
|
{
|
||||||
GriefPrevention.instance.restoreClaim(claim, 0);
|
GriefPrevention.instance.restoreClaim(claim, 0);
|
||||||
}
|
}
|
||||||
|
|
@ -172,8 +195,7 @@ class CleanupUnusedClaimsTask implements Runnable
|
||||||
}
|
}
|
||||||
|
|
||||||
//since we're potentially loading a lot of chunks to scan parts of the world where there are no players currently playing, be mindful of memory usage
|
//since we're potentially loading a lot of chunks to scan parts of the world where there are no players currently playing, be mindful of memory usage
|
||||||
//unfortunately, java/minecraft don't do a good job of clearing unused memory, leading to out of memory errors from this type of world scanning
|
if(cleanupChunks)
|
||||||
if(this.nextClaimIndex % 20 == 0)
|
|
||||||
{
|
{
|
||||||
World world = claim.getLesserBoundaryCorner().getWorld();
|
World world = claim.getLesserBoundaryCorner().getWorld();
|
||||||
Chunk [] chunks = world.getLoadedChunks();
|
Chunk [] chunks = world.getLoadedChunks();
|
||||||
|
|
@ -182,7 +204,11 @@ class CleanupUnusedClaimsTask implements Runnable
|
||||||
Chunk chunk = chunks[i];
|
Chunk chunk = chunks[i];
|
||||||
chunk.unload(true, true);
|
chunk.unload(true, true);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//unfortunately, java/minecraft don't do a good job of clearing unused memory, leading to out of memory errors from this type of world scanning
|
||||||
|
if(this.nextClaimIndex % 10 == 0)
|
||||||
|
{
|
||||||
System.gc();
|
System.gc();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -960,6 +960,7 @@ public abstract class DataStore
|
||||||
this.addDefault(defaults, Messages.NoTeleportPvPCombat, "You can't teleport while fighting another player.", null);
|
this.addDefault(defaults, Messages.NoTeleportPvPCombat, "You can't teleport while fighting another player.", null);
|
||||||
this.addDefault(defaults, Messages.NoTNTDamageAboveSeaLevel, "Warning: TNT will not destroy blocks above sea level.", null);
|
this.addDefault(defaults, Messages.NoTNTDamageAboveSeaLevel, "Warning: TNT will not destroy blocks above sea level.", null);
|
||||||
this.addDefault(defaults, Messages.NoTNTDamageClaims, "Warning: TNT will not destroy claimed blocks.", null);
|
this.addDefault(defaults, Messages.NoTNTDamageClaims, "Warning: TNT will not destroy claimed blocks.", null);
|
||||||
|
this.addDefault(defaults, Messages.IgnoreClaimsAdvertisement, "To override, use /IgnoreClaims.", null);
|
||||||
|
|
||||||
//load the config file
|
//load the config file
|
||||||
FileConfiguration config = YamlConfiguration.loadConfiguration(new File(messagesFilePath));
|
FileConfiguration config = YamlConfiguration.loadConfiguration(new File(messagesFilePath));
|
||||||
|
|
|
||||||
|
|
@ -50,9 +50,9 @@ import org.bukkit.event.entity.EntityExplodeEvent;
|
||||||
import org.bukkit.event.entity.EntityInteractEvent;
|
import org.bukkit.event.entity.EntityInteractEvent;
|
||||||
import org.bukkit.event.entity.ExpBottleEvent;
|
import org.bukkit.event.entity.ExpBottleEvent;
|
||||||
import org.bukkit.event.entity.ItemSpawnEvent;
|
import org.bukkit.event.entity.ItemSpawnEvent;
|
||||||
import org.bukkit.event.painting.PaintingBreakByEntityEvent;
|
import org.bukkit.event.hanging.HangingBreakByEntityEvent;
|
||||||
import org.bukkit.event.painting.PaintingBreakEvent;
|
import org.bukkit.event.hanging.HangingBreakEvent;
|
||||||
import org.bukkit.event.painting.PaintingPlaceEvent;
|
import org.bukkit.event.hanging.HangingPlaceEvent;
|
||||||
import org.bukkit.event.vehicle.VehicleDamageEvent;
|
import org.bukkit.event.vehicle.VehicleDamageEvent;
|
||||||
|
|
||||||
//handles events related to entities
|
//handles events related to entities
|
||||||
|
|
@ -74,6 +74,12 @@ class EntityEventHandler implements Listener
|
||||||
{
|
{
|
||||||
event.setCancelled(true);
|
event.setCancelled(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//don't allow the wither to break blocks, when the wither is determined, too expensive to constantly check for claimed blocks
|
||||||
|
else if(event.getEntityType() == EntityType.WITHER)
|
||||||
|
{
|
||||||
|
event.setCancelled(true);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//don't allow zombies to break down doors
|
//don't allow zombies to break down doors
|
||||||
|
|
@ -109,7 +115,7 @@ class EntityEventHandler implements Listener
|
||||||
Block block = blocks.get(i);
|
Block block = blocks.get(i);
|
||||||
if(GriefPrevention.instance.config_mods_explodableIds.Contains(new MaterialInfo(block.getTypeId(), block.getData(), null))) continue;
|
if(GriefPrevention.instance.config_mods_explodableIds.Contains(new MaterialInfo(block.getTypeId(), block.getData(), null))) continue;
|
||||||
|
|
||||||
if(block.getLocation().getBlockY() > location.getWorld().getSeaLevel() - 7)
|
if(block.getLocation().getBlockY() > GriefPrevention.instance.getSeaLevel(location.getWorld()) - 7)
|
||||||
{
|
{
|
||||||
blocks.remove(i--);
|
blocks.remove(i--);
|
||||||
}
|
}
|
||||||
|
|
@ -252,18 +258,18 @@ class EntityEventHandler implements Listener
|
||||||
|
|
||||||
//when a painting is broken
|
//when a painting is broken
|
||||||
@EventHandler(ignoreCancelled = true, priority = EventPriority.LOWEST)
|
@EventHandler(ignoreCancelled = true, priority = EventPriority.LOWEST)
|
||||||
public void onPaintingBreak(PaintingBreakEvent event)
|
public void onHangingBreak(HangingBreakEvent event)
|
||||||
{
|
{
|
||||||
//FEATURE: claimed paintings are protected from breakage
|
//FEATURE: claimed paintings are protected from breakage
|
||||||
|
|
||||||
//only allow players to break paintings, not anything else (like water and explosions)
|
//only allow players to break paintings, not anything else (like water and explosions)
|
||||||
if(!(event instanceof PaintingBreakByEntityEvent))
|
if(!(event instanceof HangingBreakByEntityEvent))
|
||||||
{
|
{
|
||||||
event.setCancelled(true);
|
event.setCancelled(true);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
PaintingBreakByEntityEvent entityEvent = (PaintingBreakByEntityEvent)event;
|
HangingBreakByEntityEvent entityEvent = (HangingBreakByEntityEvent)event;
|
||||||
|
|
||||||
//who is removing it?
|
//who is removing it?
|
||||||
Entity remover = entityEvent.getRemover();
|
Entity remover = entityEvent.getRemover();
|
||||||
|
|
@ -277,7 +283,7 @@ class EntityEventHandler implements Listener
|
||||||
|
|
||||||
//if the player doesn't have build permission, don't allow the breakage
|
//if the player doesn't have build permission, don't allow the breakage
|
||||||
Player playerRemover = (Player)entityEvent.getRemover();
|
Player playerRemover = (Player)entityEvent.getRemover();
|
||||||
String noBuildReason = GriefPrevention.instance.allowBuild(playerRemover, event.getPainting().getLocation());
|
String noBuildReason = GriefPrevention.instance.allowBuild(playerRemover, event.getEntity().getLocation());
|
||||||
if(noBuildReason != null)
|
if(noBuildReason != null)
|
||||||
{
|
{
|
||||||
event.setCancelled(true);
|
event.setCancelled(true);
|
||||||
|
|
@ -287,12 +293,12 @@ class EntityEventHandler implements Listener
|
||||||
|
|
||||||
//when a painting is placed...
|
//when a painting is placed...
|
||||||
@EventHandler(ignoreCancelled = true, priority = EventPriority.LOWEST)
|
@EventHandler(ignoreCancelled = true, priority = EventPriority.LOWEST)
|
||||||
public void onPaintingPlace(PaintingPlaceEvent event)
|
public void onPaintingPlace(HangingPlaceEvent event)
|
||||||
{
|
{
|
||||||
//FEATURE: similar to above, placing a painting requires build permission in the claim
|
//FEATURE: similar to above, placing a painting requires build permission in the claim
|
||||||
|
|
||||||
//if the player doesn't have permission, don't allow the placement
|
//if the player doesn't have permission, don't allow the placement
|
||||||
String noBuildReason = GriefPrevention.instance.allowBuild(event.getPlayer(), event.getPainting().getLocation());
|
String noBuildReason = GriefPrevention.instance.allowBuild(event.getPlayer(), event.getEntity().getLocation());
|
||||||
if(noBuildReason != null)
|
if(noBuildReason != null)
|
||||||
{
|
{
|
||||||
event.setCancelled(true);
|
event.setCancelled(true);
|
||||||
|
|
@ -301,7 +307,7 @@ class EntityEventHandler implements Listener
|
||||||
}
|
}
|
||||||
|
|
||||||
//otherwise, apply entity-count limitations for creative worlds
|
//otherwise, apply entity-count limitations for creative worlds
|
||||||
else if(GriefPrevention.instance.creativeRulesApply(event.getPainting().getLocation()))
|
else if(GriefPrevention.instance.creativeRulesApply(event.getEntity().getLocation()))
|
||||||
{
|
{
|
||||||
PlayerData playerData = this.dataStore.getPlayerData(event.getPlayer().getName());
|
PlayerData playerData = this.dataStore.getPlayerData(event.getPlayer().getName());
|
||||||
Claim claim = this.dataStore.getClaimAt(event.getBlock().getLocation(), false, playerData.lastClaim);
|
Claim claim = this.dataStore.getClaimAt(event.getBlock().getLocation(), false, playerData.lastClaim);
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
GriefPrevention Server Plugin for Minecraft
|
GriefPrevention Server Plugin for Minecraft
|
||||||
Copyright (C) 2011 Ryan Hamshire
|
Copyright (C) 2012 Ryan Hamshire
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
This program is free software: you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
|
|
@ -85,6 +85,11 @@ public class GriefPrevention extends JavaPlugin
|
||||||
|
|
||||||
public boolean config_claims_noBuildOutsideClaims; //whether players can build in survival worlds outside their claimed areas
|
public boolean config_claims_noBuildOutsideClaims; //whether players can build in survival worlds outside their claimed areas
|
||||||
|
|
||||||
|
public int config_claims_chestClaimExpirationDays; //number of days of inactivity before an automatic chest claim will be deleted
|
||||||
|
public int config_claims_unusedClaimExpirationDays; //number of days of inactivity before an unused (nothing build) claim will be deleted
|
||||||
|
public boolean config_claims_survivalAutoNatureRestoration; //whether survival claims will be automatically restored to nature when auto-deleted
|
||||||
|
public boolean config_claims_creativeAutoNatureRestoration; //whether creative claims will be automatically restored to nature when auto-deleted
|
||||||
|
|
||||||
public int config_claims_trappedCooldownHours; //number of hours between uses of the /trapped command
|
public int config_claims_trappedCooldownHours; //number of hours between uses of the /trapped command
|
||||||
|
|
||||||
public Material config_claims_investigationTool; //which material will be used to investigate claims with a right click
|
public Material config_claims_investigationTool; //which material will be used to investigate claims with a right click
|
||||||
|
|
@ -256,12 +261,26 @@ public class GriefPrevention extends JavaPlugin
|
||||||
this.config_claims_creationRequiresPermission = config.getBoolean("GriefPrevention.Claims.CreationRequiresPermission", false);
|
this.config_claims_creationRequiresPermission = config.getBoolean("GriefPrevention.Claims.CreationRequiresPermission", false);
|
||||||
this.config_claims_minSize = config.getInt("GriefPrevention.Claims.MinimumSize", 10);
|
this.config_claims_minSize = config.getInt("GriefPrevention.Claims.MinimumSize", 10);
|
||||||
this.config_claims_maxDepth = config.getInt("GriefPrevention.Claims.MaximumDepth", 0);
|
this.config_claims_maxDepth = config.getInt("GriefPrevention.Claims.MaximumDepth", 0);
|
||||||
this.config_claims_expirationDays = config.getInt("GriefPrevention.Claims.IdleLimitDays", 0);
|
|
||||||
this.config_claims_trappedCooldownHours = config.getInt("GriefPrevention.Claims.TrappedCommandCooldownHours", 8);
|
this.config_claims_trappedCooldownHours = config.getInt("GriefPrevention.Claims.TrappedCommandCooldownHours", 8);
|
||||||
this.config_claims_noBuildOutsideClaims = config.getBoolean("GriefPrevention.Claims.NoSurvivalBuildingOutsideClaims", false);
|
this.config_claims_noBuildOutsideClaims = config.getBoolean("GriefPrevention.Claims.NoSurvivalBuildingOutsideClaims", false);
|
||||||
this.config_claims_warnOnBuildOutside = config.getBoolean("GriefPrevention.Claims.WarnWhenBuildingOutsideClaims", true);
|
this.config_claims_warnOnBuildOutside = config.getBoolean("GriefPrevention.Claims.WarnWhenBuildingOutsideClaims", true);
|
||||||
this.config_claims_allowUnclaimInCreative = config.getBoolean("GriefPrevention.Claims.AllowUnclaimingCreativeModeLand", true);
|
this.config_claims_allowUnclaimInCreative = config.getBoolean("GriefPrevention.Claims.AllowUnclaimingCreativeModeLand", true);
|
||||||
|
|
||||||
|
this.config_claims_chestClaimExpirationDays = config.getInt("GriefPrevention.Claims.Expiration.ChestClaimDays", 7);
|
||||||
|
config.set("GriefPrevention.Claims.Expiration.ChestClaimDays", this.config_claims_chestClaimExpirationDays);
|
||||||
|
|
||||||
|
this.config_claims_unusedClaimExpirationDays = config.getInt("GriefPrevention.Claims.Expiration.UnusedClaimDays", 14);
|
||||||
|
config.set("GriefPrevention.Claims.Expiration.UnusedClaimDays", this.config_claims_unusedClaimExpirationDays);
|
||||||
|
|
||||||
|
this.config_claims_expirationDays = config.getInt("GriefPrevention.Claims.Expiration.AllClaimDays", 0);
|
||||||
|
config.set("GriefPrevention.Claims.Expiration.AllClaimDays", this.config_claims_expirationDays);
|
||||||
|
|
||||||
|
this.config_claims_survivalAutoNatureRestoration = config.getBoolean("GriefPrevention.Claims.Expiration.AutomaticNatureRestoration.SurvivalWorlds", false);
|
||||||
|
config.set("GriefPrevention.Claims.Expiration.AutomaticNatureRestoration.SurvivalWorlds", this.config_claims_survivalAutoNatureRestoration);
|
||||||
|
|
||||||
|
this.config_claims_creativeAutoNatureRestoration = config.getBoolean("GriefPrevention.Claims.Expiration.AutomaticNatureRestoration.CreativeWorlds", true);
|
||||||
|
config.set("GriefPrevention.Claims.Expiration.AutomaticNatureRestoration.CreativeWorlds", this.config_claims_creativeAutoNatureRestoration);
|
||||||
|
|
||||||
this.config_spam_enabled = config.getBoolean("GriefPrevention.Spam.Enabled", true);
|
this.config_spam_enabled = config.getBoolean("GriefPrevention.Spam.Enabled", true);
|
||||||
this.config_spam_loginCooldownMinutes = config.getInt("GriefPrevention.Spam.LoginCooldownMinutes", 2);
|
this.config_spam_loginCooldownMinutes = config.getInt("GriefPrevention.Spam.LoginCooldownMinutes", 2);
|
||||||
this.config_spam_warningMessage = config.getString("GriefPrevention.Spam.WarningMessage", "Please reduce your noise level. Spammers will be banned.");
|
this.config_spam_warningMessage = config.getString("GriefPrevention.Spam.WarningMessage", "Please reduce your noise level. Spammers will be banned.");
|
||||||
|
|
@ -961,6 +980,12 @@ public class GriefPrevention extends JavaPlugin
|
||||||
//determine which claim the player is standing in
|
//determine which claim the player is standing in
|
||||||
Claim claim = this.dataStore.getClaimAt(player.getLocation(), true /*ignore height*/, null);
|
Claim claim = this.dataStore.getClaimAt(player.getLocation(), true /*ignore height*/, null);
|
||||||
|
|
||||||
|
//bracket any permissions
|
||||||
|
if(args[0].contains("."))
|
||||||
|
{
|
||||||
|
args[0] = "[" + args[0] + "]";
|
||||||
|
}
|
||||||
|
|
||||||
//determine whether a single player or clearing permissions entirely
|
//determine whether a single player or clearing permissions entirely
|
||||||
boolean clearPermissions = false;
|
boolean clearPermissions = false;
|
||||||
OfflinePlayer otherPlayer = null;
|
OfflinePlayer otherPlayer = null;
|
||||||
|
|
@ -1796,6 +1821,11 @@ public class GriefPrevention extends JavaPlugin
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
else if(recipientName.contains("."))
|
||||||
|
{
|
||||||
|
permission = recipientName;
|
||||||
|
}
|
||||||
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
otherPlayer = this.resolvePlayer(recipientName);
|
otherPlayer = this.resolvePlayer(recipientName);
|
||||||
|
|
@ -2310,8 +2340,10 @@ public class GriefPrevention extends JavaPlugin
|
||||||
//no building in the wilderness in creative mode
|
//no building in the wilderness in creative mode
|
||||||
if(this.creativeRulesApply(location))
|
if(this.creativeRulesApply(location))
|
||||||
{
|
{
|
||||||
return this.dataStore.getMessage(Messages.NoBuildOutsideClaims) + " " + this.dataStore.getMessage(Messages.CreativeBasicsDemoAdvertisement);
|
String reason = this.dataStore.getMessage(Messages.NoBuildOutsideClaims) + " " + this.dataStore.getMessage(Messages.CreativeBasicsDemoAdvertisement);
|
||||||
|
if(player.hasPermission("griefprevention.ignoreclaims"))
|
||||||
|
reason += " " + this.dataStore.getMessage(Messages.IgnoreClaimsAdvertisement);
|
||||||
|
return reason;
|
||||||
}
|
}
|
||||||
|
|
||||||
//no building in survival wilderness when that is configured
|
//no building in survival wilderness when that is configured
|
||||||
|
|
@ -2350,7 +2382,10 @@ public class GriefPrevention extends JavaPlugin
|
||||||
//no building in the wilderness in creative mode
|
//no building in the wilderness in creative mode
|
||||||
if(this.creativeRulesApply(location))
|
if(this.creativeRulesApply(location))
|
||||||
{
|
{
|
||||||
return this.dataStore.getMessage(Messages.NoBuildOutsideClaims) + " " + this.dataStore.getMessage(Messages.CreativeBasicsDemoAdvertisement);
|
String reason = this.dataStore.getMessage(Messages.NoBuildOutsideClaims) + " " + this.dataStore.getMessage(Messages.CreativeBasicsDemoAdvertisement);
|
||||||
|
if(player.hasPermission("griefprevention.ignoreclaims"))
|
||||||
|
reason += " " + this.dataStore.getMessage(Messages.IgnoreClaimsAdvertisement);
|
||||||
|
return reason;
|
||||||
}
|
}
|
||||||
|
|
||||||
else if(this.config_claims_noBuildOutsideClaims && this.config_claims_enabledWorlds.contains(location.getWorld()))
|
else if(this.config_claims_noBuildOutsideClaims && this.config_claims_enabledWorlds.contains(location.getWorld()))
|
||||||
|
|
@ -2392,7 +2427,7 @@ public class GriefPrevention extends JavaPlugin
|
||||||
for(int z = lesserChunk.getZ(); z <= greaterChunk.getZ(); z++)
|
for(int z = lesserChunk.getZ(); z <= greaterChunk.getZ(); z++)
|
||||||
{
|
{
|
||||||
Chunk chunk = lesserChunk.getWorld().getChunkAt(x, z);
|
Chunk chunk = lesserChunk.getWorld().getChunkAt(x, z);
|
||||||
this.restoreChunk(chunk, chunk.getWorld().getSeaLevel() - 15, false, delayInTicks, null);
|
this.restoreChunk(chunk, this.getSeaLevel(chunk.getWorld()) - 15, false, delayInTicks, null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -2421,7 +2456,7 @@ public class GriefPrevention extends JavaPlugin
|
||||||
|
|
||||||
//create task
|
//create task
|
||||||
//when done processing, this task will create a main thread task to actually update the world with processing results
|
//when done processing, this task will create a main thread task to actually update the world with processing results
|
||||||
RestoreNatureProcessingTask task = new RestoreNatureProcessingTask(snapshots, miny, chunk.getWorld().getEnvironment(), lesserBoundaryCorner.getBlock().getBiome(), lesserBoundaryCorner, greaterBoundaryCorner, chunk.getWorld().getSeaLevel(), aggressiveMode, GriefPrevention.instance.creativeRulesApply(lesserBoundaryCorner), playerReceivingVisualization);
|
RestoreNatureProcessingTask task = new RestoreNatureProcessingTask(snapshots, miny, chunk.getWorld().getEnvironment(), lesserBoundaryCorner.getBlock().getBiome(), lesserBoundaryCorner, greaterBoundaryCorner, this.getSeaLevel(chunk.getWorld()), aggressiveMode, GriefPrevention.instance.creativeRulesApply(lesserBoundaryCorner), playerReceivingVisualization);
|
||||||
GriefPrevention.instance.getServer().getScheduler().scheduleAsyncDelayedTask(GriefPrevention.instance, task, delayInTicks);
|
GriefPrevention.instance.getServer().getScheduler().scheduleAsyncDelayedTask(GriefPrevention.instance, task, delayInTicks);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2,5 +2,5 @@ package me.ryanhamshire.GriefPrevention;
|
||||||
|
|
||||||
public enum Messages
|
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, AdjustGroupBlocksSuccess, InvalidPermissionID, UntrustOwnerOnly, HowToClaimRegex, NoBuildOutsideClaims, PlayerOfflineTime, BuildingOutsideClaims, TrappedWontWorkHere, CommandBannedInPvP, UnclaimCleanupWarning, BuySellNotConfigured, NoTeleportPvPCombat, NoTNTDamageAboveSeaLevel, NoTNTDamageClaims
|
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, HowToClaimRegex, NoBuildOutsideClaims, PlayerOfflineTime, BuildingOutsideClaims, TrappedWontWorkHere, CommandBannedInPvP, UnclaimCleanupWarning, BuySellNotConfigured, NoTeleportPvPCombat, NoTNTDamageAboveSeaLevel, NoTNTDamageClaims, IgnoreClaimsAdvertisement
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -36,6 +36,7 @@ import org.bukkit.block.BlockFace;
|
||||||
import org.bukkit.entity.Animals;
|
import org.bukkit.entity.Animals;
|
||||||
import org.bukkit.entity.Boat;
|
import org.bukkit.entity.Boat;
|
||||||
import org.bukkit.entity.Entity;
|
import org.bukkit.entity.Entity;
|
||||||
|
import org.bukkit.entity.Hanging;
|
||||||
import org.bukkit.entity.PoweredMinecart;
|
import org.bukkit.entity.PoweredMinecart;
|
||||||
import org.bukkit.entity.StorageMinecart;
|
import org.bukkit.entity.StorageMinecart;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
|
|
@ -675,9 +676,21 @@ class PlayerEventHandler implements Listener
|
||||||
{
|
{
|
||||||
Player player = event.getPlayer();
|
Player player = event.getPlayer();
|
||||||
Entity entity = event.getRightClicked();
|
Entity entity = event.getRightClicked();
|
||||||
|
PlayerData playerData = this.dataStore.getPlayerData(player.getName());
|
||||||
|
|
||||||
|
//don't allow interaction with item frames in claimed areas without build permission
|
||||||
|
if(entity instanceof Hanging)
|
||||||
|
{
|
||||||
|
String noBuildReason = GriefPrevention.instance.allowBuild(player, entity.getLocation());
|
||||||
|
if(noBuildReason != null)
|
||||||
|
{
|
||||||
|
GriefPrevention.sendMessage(player, TextMode.Err, noBuildReason);
|
||||||
|
event.setCancelled(true);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//don't allow container access during pvp combat
|
//don't allow container access during pvp combat
|
||||||
PlayerData playerData = this.dataStore.getPlayerData(player.getName());
|
|
||||||
if((entity instanceof StorageMinecart || entity instanceof PoweredMinecart))
|
if((entity instanceof StorageMinecart || entity instanceof PoweredMinecart))
|
||||||
{
|
{
|
||||||
if(playerData.siegeData != null)
|
if(playerData.siegeData != null)
|
||||||
|
|
@ -850,7 +863,7 @@ class PlayerEventHandler implements Listener
|
||||||
//otherwise no wilderness dumping (unless underground) in worlds where claims are enabled
|
//otherwise no wilderness dumping (unless underground) in worlds where claims are enabled
|
||||||
else if(GriefPrevention.instance.config_claims_enabledWorlds.contains(block.getWorld()))
|
else if(GriefPrevention.instance.config_claims_enabledWorlds.contains(block.getWorld()))
|
||||||
{
|
{
|
||||||
if(block.getY() >= block.getWorld().getSeaLevel() - 5 && !player.hasPermission("griefprevention.lava"))
|
if(block.getY() >= GriefPrevention.instance.getSeaLevel(block.getWorld()) - 5 && !player.hasPermission("griefprevention.lava"))
|
||||||
{
|
{
|
||||||
if(bucketEvent.getBucket() == Material.LAVA_BUCKET || GriefPrevention.instance.config_blockWildernessWaterBuckets)
|
if(bucketEvent.getBucket() == Material.LAVA_BUCKET || GriefPrevention.instance.config_blockWildernessWaterBuckets)
|
||||||
{
|
{
|
||||||
|
|
@ -960,6 +973,7 @@ class PlayerEventHandler implements Listener
|
||||||
clickedBlockType == Material.WORKBENCH ||
|
clickedBlockType == Material.WORKBENCH ||
|
||||||
clickedBlockType == Material.ENDER_CHEST ||
|
clickedBlockType == Material.ENDER_CHEST ||
|
||||||
clickedBlockType == Material.DISPENSER ||
|
clickedBlockType == Material.DISPENSER ||
|
||||||
|
clickedBlockType == Material.ANVIL ||
|
||||||
clickedBlockType == Material.BREWING_STAND ||
|
clickedBlockType == Material.BREWING_STAND ||
|
||||||
clickedBlockType == Material.JUKEBOX ||
|
clickedBlockType == Material.JUKEBOX ||
|
||||||
clickedBlockType == Material.ENCHANTMENT_TABLE ||
|
clickedBlockType == Material.ENCHANTMENT_TABLE ||
|
||||||
|
|
@ -1026,7 +1040,7 @@ class PlayerEventHandler implements Listener
|
||||||
}
|
}
|
||||||
|
|
||||||
//otherwise apply rules for buttons and switches
|
//otherwise apply rules for buttons and switches
|
||||||
else if(GriefPrevention.instance.config_claims_preventButtonsSwitches && (clickedBlockType == null || clickedBlockType == Material.STONE_BUTTON || clickedBlockType == Material.LEVER || GriefPrevention.instance.config_mods_accessTrustIds.Contains(new MaterialInfo(clickedBlock.getTypeId(), clickedBlock.getData(), null))))
|
else if(GriefPrevention.instance.config_claims_preventButtonsSwitches && (clickedBlockType == null || clickedBlockType == Material.STONE_BUTTON || clickedBlockType == Material.WOOD_BUTTON || clickedBlockType == Material.LEVER || GriefPrevention.instance.config_mods_accessTrustIds.Contains(new MaterialInfo(clickedBlock.getTypeId(), clickedBlock.getData(), null))))
|
||||||
{
|
{
|
||||||
Claim claim = this.dataStore.getClaimAt(clickedBlock.getLocation(), false, playerData.lastClaim);
|
Claim claim = this.dataStore.getClaimAt(clickedBlock.getLocation(), false, playerData.lastClaim);
|
||||||
if(claim != null)
|
if(claim != null)
|
||||||
|
|
@ -1216,9 +1230,9 @@ class PlayerEventHandler implements Listener
|
||||||
//if not in aggressive mode, extend the selection down to a little below sea level
|
//if not in aggressive mode, extend the selection down to a little below sea level
|
||||||
if(!(playerData.shovelMode == ShovelMode.RestoreNatureAggressive))
|
if(!(playerData.shovelMode == ShovelMode.RestoreNatureAggressive))
|
||||||
{
|
{
|
||||||
if(miny > chunk.getWorld().getSeaLevel() - 10)
|
if(miny > GriefPrevention.instance.getSeaLevel(chunk.getWorld()) - 10)
|
||||||
{
|
{
|
||||||
miny = chunk.getWorld().getSeaLevel() - 10;
|
miny = GriefPrevention.instance.getSeaLevel(chunk.getWorld()) - 10;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -25,6 +25,7 @@ import org.bukkit.block.Block;
|
||||||
import org.bukkit.block.BlockFace;
|
import org.bukkit.block.BlockFace;
|
||||||
import org.bukkit.entity.Animals;
|
import org.bukkit.entity.Animals;
|
||||||
import org.bukkit.entity.Entity;
|
import org.bukkit.entity.Entity;
|
||||||
|
import org.bukkit.entity.Hanging;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
|
|
||||||
//this main thread task takes the output from the RestoreNatureProcessingTask\
|
//this main thread task takes the output from the RestoreNatureProcessingTask\
|
||||||
|
|
@ -91,8 +92,15 @@ class RestoreNatureExecutionTask implements Runnable
|
||||||
Entity entity = entities[i];
|
Entity entity = entities[i];
|
||||||
if(!(entity instanceof Player || entity instanceof Animals))
|
if(!(entity instanceof Player || entity instanceof Animals))
|
||||||
{
|
{
|
||||||
entity.remove();
|
//hanging entities (paintings, item frames) are protected when they're in land claims
|
||||||
|
if(!(entity instanceof Hanging) || GriefPrevention.instance.dataStore.getClaimAt(entity.getLocation(), false, null) == null)
|
||||||
|
{
|
||||||
|
//everything else is removed
|
||||||
|
entity.remove();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//for players, always ensure there's air where the player is standing
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Block feetBlock = entity.getLocation().getBlock();
|
Block feetBlock = entity.getLocation().getBlock();
|
||||||
|
|
@ -101,7 +109,7 @@ class RestoreNatureExecutionTask implements Runnable
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//show visualization to player
|
//show visualization to player who started the restoration
|
||||||
if(player != null)
|
if(player != null)
|
||||||
{
|
{
|
||||||
Claim claim = new Claim(lesserCorner, greaterCorner, "", new String[] {}, new String[] {}, new String[] {}, new String[] {}, null);
|
Claim claim = new Claim(lesserCorner, greaterCorner, "", new String[] {}, new String[] {}, new String[] {}, new String[] {}, null);
|
||||||
|
|
|
||||||
|
|
@ -144,15 +144,15 @@ class RestoreNatureProcessingTask implements Runnable
|
||||||
//cover surface stone and gravel with sand or grass, as the biome requires
|
//cover surface stone and gravel with sand or grass, as the biome requires
|
||||||
this.coverSurfaceStone();
|
this.coverSurfaceStone();
|
||||||
|
|
||||||
//reset leaves to NOT player placed so that they may decay as usual
|
//remove any player-placed leaves
|
||||||
this.resetLeaves();
|
this.removePlayerLeaves();
|
||||||
|
|
||||||
//schedule main thread task to apply the result to the world
|
//schedule main thread task to apply the result to the world
|
||||||
RestoreNatureExecutionTask task = new RestoreNatureExecutionTask(this.snapshots, this.miny, this.lesserBoundaryCorner, this.greaterBoundaryCorner, this.player);
|
RestoreNatureExecutionTask task = new RestoreNatureExecutionTask(this.snapshots, this.miny, this.lesserBoundaryCorner, this.greaterBoundaryCorner, this.player);
|
||||||
GriefPrevention.instance.getServer().getScheduler().scheduleSyncDelayedTask(GriefPrevention.instance, task);
|
GriefPrevention.instance.getServer().getScheduler().scheduleSyncDelayedTask(GriefPrevention.instance, task);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void resetLeaves()
|
private void removePlayerLeaves()
|
||||||
{
|
{
|
||||||
for(int x = 1; x < snapshots.length - 1; x++)
|
for(int x = 1; x < snapshots.length - 1; x++)
|
||||||
{
|
{
|
||||||
|
|
@ -162,13 +162,9 @@ class RestoreNatureProcessingTask implements Runnable
|
||||||
{
|
{
|
||||||
//note: see minecraft wiki data values for leaves
|
//note: see minecraft wiki data values for leaves
|
||||||
BlockSnapshot block = snapshots[x][y][z];
|
BlockSnapshot block = snapshots[x][y][z];
|
||||||
if(block.typeId == Material.LEAVES.getId())
|
if(block.typeId == Material.LEAVES.getId() && (block.data & 0x4) != 0)
|
||||||
{
|
{
|
||||||
//clear "player placed" bit
|
block.typeId = Material.AIR.getId();
|
||||||
block.data = (byte)(block.data & ~(1<<2));
|
|
||||||
|
|
||||||
//set the "check for natural decay" bit
|
|
||||||
block.data = (byte)(block.data | (1<<3));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -708,6 +704,19 @@ class RestoreNatureProcessingTask implements Runnable
|
||||||
playerBlocks.add(Material.WOOD_STEP.getId());
|
playerBlocks.add(Material.WOOD_STEP.getId());
|
||||||
playerBlocks.add(Material.WOOD_DOUBLE_STEP.getId());
|
playerBlocks.add(Material.WOOD_DOUBLE_STEP.getId());
|
||||||
playerBlocks.add(Material.ENDER_CHEST.getId());
|
playerBlocks.add(Material.ENDER_CHEST.getId());
|
||||||
|
playerBlocks.add(Material.SANDSTONE_STAIRS.getId());
|
||||||
|
playerBlocks.add(Material.SPRUCE_WOOD_STAIRS.getId());
|
||||||
|
playerBlocks.add(Material.JUNGLE_WOOD_STAIRS.getId());
|
||||||
|
playerBlocks.add(Material.COMMAND.getId());
|
||||||
|
playerBlocks.add(Material.BEACON.getId());
|
||||||
|
playerBlocks.add(Material.COBBLE_WALL.getId());
|
||||||
|
playerBlocks.add(Material.FLOWER_POT.getId());
|
||||||
|
playerBlocks.add(Material.CARROT.getId());
|
||||||
|
playerBlocks.add(Material.POTATO.getId());
|
||||||
|
playerBlocks.add(Material.WOOD_BUTTON.getId());
|
||||||
|
playerBlocks.add(Material.SKULL.getId());
|
||||||
|
playerBlocks.add(Material.ANVIL.getId());
|
||||||
|
|
||||||
|
|
||||||
//these are unnatural in the standard world, but not in the nether
|
//these are unnatural in the standard world, but not in the nether
|
||||||
if(environment != Environment.NETHER)
|
if(environment != Environment.NETHER)
|
||||||
|
|
|
||||||
|
|
@ -220,6 +220,8 @@ public class Visualization
|
||||||
block.getType() == Material.LEAVES ||
|
block.getType() == Material.LEAVES ||
|
||||||
block.getType() == Material.RED_ROSE ||
|
block.getType() == Material.RED_ROSE ||
|
||||||
block.getType() == Material.CHEST ||
|
block.getType() == Material.CHEST ||
|
||||||
|
block.getType() == Material.TORCH ||
|
||||||
|
block.getType() == Material.VINE ||
|
||||||
block.getType() == Material.YELLOW_FLOWER );
|
block.getType() == Material.YELLOW_FLOWER );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user