This commit is contained in:
ryanhamshire 2013-02-06 21:26:00 -08:00
parent 2734ba1ae9
commit 37ca831612
9 changed files with 1708 additions and 1599 deletions

View File

@ -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: 7.2.2 version: 7.6.1
commands: commands:
abandonclaim: abandonclaim:
description: Deletes a claim. description: Deletes a claim.
@ -125,6 +125,9 @@ commands:
claimslist: claimslist:
description: Lists information about a player's claim blocks and claims. description: Lists information about a player's claim blocks and claims.
usage: /ClaimsList or /ClaimsList <player> usage: /ClaimsList or /ClaimsList <player>
claimexplosions:
description: Toggles whether explosives may be used in a specific land claim.
usage: /ClaimExplosions
permissions: permissions:
griefprevention.createclaims: griefprevention.createclaims:
description: Grants permission to create claims. description: Grants permission to create claims.

View File

@ -21,6 +21,7 @@ package me.ryanhamshire.GriefPrevention;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import org.bukkit.ChatColor;
import org.bukkit.GameMode; import org.bukkit.GameMode;
import org.bukkit.Location; import org.bukkit.Location;
import org.bukkit.Material; import org.bukkit.Material;
@ -30,10 +31,7 @@ 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;
@ -49,7 +47,6 @@ 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;
@ -81,36 +78,6 @@ 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)
@ -256,6 +223,19 @@ public class BlockEventHandler implements Listener
{ {
GriefPrevention.AddLogEntry("[Sign Placement] <" + player.getName() + "> " + lines.toString() + " @ " + GriefPrevention.getfriendlyLocationString(event.getBlock().getLocation())); GriefPrevention.AddLogEntry("[Sign Placement] <" + player.getName() + "> " + lines.toString() + " @ " + GriefPrevention.getfriendlyLocationString(event.getBlock().getLocation()));
playerData.lastMessage = signMessage; playerData.lastMessage = signMessage;
if(!player.hasPermission("griefprevention.eavesdrop"))
{
Player [] players = GriefPrevention.instance.getServer().getOnlinePlayers();
for(int i = 0; i < players.length; i++)
{
Player otherPlayer = players[i];
if(otherPlayer.hasPermission("griefprevention.eavesdrop"))
{
otherPlayer.sendMessage(ChatColor.GRAY + player.getName() + "(sign): " + signMessage);
}
}
}
} }
} }
@ -300,9 +280,10 @@ public class BlockEventHandler implements Listener
if(claim != null) if(claim != null)
{ {
//warn about TNT not destroying claimed blocks //warn about TNT not destroying claimed blocks
if(block.getType() == Material.TNT) if(block.getType() == Material.TNT && !claim.areExplosivesAllowed)
{ {
GriefPrevention.sendMessage(player, TextMode.Warn, Messages.NoTNTDamageClaims); GriefPrevention.sendMessage(player, TextMode.Warn, Messages.NoTNTDamageClaims);
GriefPrevention.sendMessage(player, TextMode.Instr, Messages.ClaimExplosivesAdvertisement);
} }
//if the player has permission for the claim and he's placing UNDER the claim //if the player has permission for the claim and he's placing UNDER the claim

File diff suppressed because it is too large Load Diff

View File

@ -963,7 +963,11 @@ public abstract class DataStore
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); this.addDefault(defaults, Messages.IgnoreClaimsAdvertisement, "To override, use /IgnoreClaims.", null);
this.addDefault(defaults, Messages.NoPermissionForCommand, "You don't have permission to do that.", null); this.addDefault(defaults, Messages.NoPermissionForCommand, "You don't have permission to do that.", null);
this.addDefault(defaults, Messages.ClaimsListNoPermission, "You don't have permission to get information about another player's land claims.", null); this.addDefault(defaults, Messages.ClaimsListNoPermission, "You don't have permission to get information about another player's land claims.", null);
this.addDefault(defaults, Messages.ExplosivesDisabled, "This claim is now protected from explosions. Use /ClaimExplosions again to disable.", null);
this.addDefault(defaults, Messages.ExplosivesEnabled, "This claim is now vulnerable to explosions. Use /ClaimExplosions again to re-enable protections.", null);
this.addDefault(defaults, Messages.ClaimExplosivesAdvertisement, "To allow explosives to destroy blocks in this land claim, use /ClaimExplosions.", null);
this.addDefault(defaults, Messages.PlayerInPvPSafeZone, "That player is in a PvP safe zone.", null);
//load the config file //load the config file
FileConfiguration config = YamlConfiguration.loadConfiguration(new File(messagesFilePath)); FileConfiguration config = YamlConfiguration.loadConfiguration(new File(messagesFilePath));

File diff suppressed because it is too large Load Diff

View File

@ -70,6 +70,7 @@ public class GriefPrevention extends JavaPlugin
public boolean config_claims_lockWoodenDoors; //whether wooden doors should be locked by default (require /accesstrust) public boolean config_claims_lockWoodenDoors; //whether wooden doors should be locked by default (require /accesstrust)
public boolean config_claims_lockTrapDoors; //whether trap doors should be locked by default (require /accesstrust) public boolean config_claims_lockTrapDoors; //whether trap doors should be locked by default (require /accesstrust)
public boolean config_claims_lockFenceGates; //whether fence gates should be locked by default (require /accesstrust) public boolean config_claims_lockFenceGates; //whether fence gates should be locked by default (require /accesstrust)
public boolean config_claims_enderPearlsRequireAccessTrust; //whether teleporting into a claim with a pearl requires access trust
public int config_claims_initialBlocks; //the number of claim blocks a new player starts with public int config_claims_initialBlocks; //the number of claim blocks a new player starts with
public int config_claims_blocksAccruedPerHour; //how many additional blocks players get each hour of play (can be zero) public int config_claims_blocksAccruedPerHour; //how many additional blocks players get each hour of play (can be zero)
@ -82,6 +83,7 @@ public class GriefPrevention extends JavaPlugin
public int config_claims_claimsExtendIntoGroundDistance; //how far below the shoveled block a new claim will reach public int config_claims_claimsExtendIntoGroundDistance; //how far below the shoveled block a new claim will reach
public int config_claims_minSize; //minimum width and height for non-admin claims public int config_claims_minSize; //minimum width and height for non-admin claims
public boolean config_claims_allowUnclaimInCreative; //whether players may unclaim land (resize or abandon) in creative mode public boolean config_claims_allowUnclaimInCreative; //whether players may unclaim land (resize or abandon) in creative mode
public boolean config_claims_autoRestoreUnclaimedCreativeLand; //whether unclaimed land in creative worlds is automatically /restorenature-d
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
@ -113,6 +115,8 @@ public class GriefPrevention extends JavaPlugin
public int config_pvp_combatTimeoutSeconds; //how long combat is considered to continue after the most recent damage public int config_pvp_combatTimeoutSeconds; //how long combat is considered to continue after the most recent damage
public boolean config_pvp_allowCombatItemDrop; //whether a player can drop items during combat to hide them public boolean config_pvp_allowCombatItemDrop; //whether a player can drop items during combat to hide them
public ArrayList<String> config_pvp_blockedCommands; //list of commands which may not be used during pvp combat public ArrayList<String> config_pvp_blockedCommands; //list of commands which may not be used during pvp combat
public boolean config_pvp_noCombatInPlayerLandClaims; //whether players may fight in player-owned land claims
public boolean config_pvp_noCombatInAdminLandClaims; //whether players may fight in admin-owned land claims
public boolean config_trees_removeFloatingTreetops; //whether to automatically remove partially cut trees public boolean config_trees_removeFloatingTreetops; //whether to automatically remove partially cut trees
public boolean config_trees_regrowGriefedTrees; //whether to automatically replant partially cut trees public boolean config_trees_regrowGriefedTrees; //whether to automatically replant partially cut trees
@ -172,6 +176,7 @@ public class GriefPrevention extends JavaPlugin
//load the config if it exists //load the config if it exists
FileConfiguration config = YamlConfiguration.loadConfiguration(new File(DataStore.configFilePath)); FileConfiguration config = YamlConfiguration.loadConfiguration(new File(DataStore.configFilePath));
FileConfiguration outConfig = new YamlConfiguration();
//read configuration settings (note defaults) //read configuration settings (note defaults)
@ -280,7 +285,7 @@ public class GriefPrevention extends JavaPlugin
for(int i = 0; i < worlds.size(); i++) for(int i = 0; i < worlds.size(); i++)
{ {
int seaLevelOverride = config.getInt("GriefPrevention.SeaLevelOverrides." + worlds.get(i).getName(), -1); int seaLevelOverride = config.getInt("GriefPrevention.SeaLevelOverrides." + worlds.get(i).getName(), -1);
config.set("GriefPrevention.SeaLevelOverrides." + worlds.get(i).getName(), seaLevelOverride); outConfig.set("GriefPrevention.SeaLevelOverrides." + worlds.get(i).getName(), seaLevelOverride);
this.config_seaLevelOverride.put(worlds.get(i).getName(), seaLevelOverride); this.config_seaLevelOverride.put(worlds.get(i).getName(), seaLevelOverride);
} }
@ -290,6 +295,7 @@ public class GriefPrevention extends JavaPlugin
this.config_claims_lockWoodenDoors = config.getBoolean("GriefPrevention.Claims.LockWoodenDoors", false); this.config_claims_lockWoodenDoors = config.getBoolean("GriefPrevention.Claims.LockWoodenDoors", false);
this.config_claims_lockTrapDoors = config.getBoolean("GriefPrevention.Claims.LockTrapDoors", false); this.config_claims_lockTrapDoors = config.getBoolean("GriefPrevention.Claims.LockTrapDoors", false);
this.config_claims_lockFenceGates = config.getBoolean("GriefPrevention.Claims.LockFenceGates", true); this.config_claims_lockFenceGates = config.getBoolean("GriefPrevention.Claims.LockFenceGates", true);
this.config_claims_enderPearlsRequireAccessTrust = config.getBoolean("GriefPrevention.Claims.EnderPearlsRequireAccessTrust", true);
this.config_claims_initialBlocks = config.getInt("GriefPrevention.Claims.InitialBlocks", 100); this.config_claims_initialBlocks = config.getInt("GriefPrevention.Claims.InitialBlocks", 100);
this.config_claims_blocksAccruedPerHour = config.getInt("GriefPrevention.Claims.BlocksAccruedPerHour", 100); this.config_claims_blocksAccruedPerHour = config.getInt("GriefPrevention.Claims.BlocksAccruedPerHour", 100);
this.config_claims_maxAccruedBlocks = config.getInt("GriefPrevention.Claims.MaxAccruedBlocks", 80000); this.config_claims_maxAccruedBlocks = config.getInt("GriefPrevention.Claims.MaxAccruedBlocks", 80000);
@ -302,21 +308,22 @@ public class GriefPrevention extends JavaPlugin
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_autoRestoreUnclaimedCreativeLand = config.getBoolean("GriefPrevention.Claims.AutoRestoreUnclaimedCreativeLand", true);
this.config_claims_chestClaimExpirationDays = config.getInt("GriefPrevention.Claims.Expiration.ChestClaimDays", 7); this.config_claims_chestClaimExpirationDays = config.getInt("GriefPrevention.Claims.Expiration.ChestClaimDays", 7);
config.set("GriefPrevention.Claims.Expiration.ChestClaimDays", this.config_claims_chestClaimExpirationDays); outConfig.set("GriefPrevention.Claims.Expiration.ChestClaimDays", this.config_claims_chestClaimExpirationDays);
this.config_claims_unusedClaimExpirationDays = config.getInt("GriefPrevention.Claims.Expiration.UnusedClaimDays", 14); this.config_claims_unusedClaimExpirationDays = config.getInt("GriefPrevention.Claims.Expiration.UnusedClaimDays", 14);
config.set("GriefPrevention.Claims.Expiration.UnusedClaimDays", this.config_claims_unusedClaimExpirationDays); outConfig.set("GriefPrevention.Claims.Expiration.UnusedClaimDays", this.config_claims_unusedClaimExpirationDays);
this.config_claims_expirationDays = config.getInt("GriefPrevention.Claims.Expiration.AllClaimDays", 0); this.config_claims_expirationDays = config.getInt("GriefPrevention.Claims.Expiration.AllClaimDays", 0);
config.set("GriefPrevention.Claims.Expiration.AllClaimDays", this.config_claims_expirationDays); outConfig.set("GriefPrevention.Claims.Expiration.AllClaimDays", this.config_claims_expirationDays);
this.config_claims_survivalAutoNatureRestoration = config.getBoolean("GriefPrevention.Claims.Expiration.AutomaticNatureRestoration.SurvivalWorlds", false); this.config_claims_survivalAutoNatureRestoration = config.getBoolean("GriefPrevention.Claims.Expiration.AutomaticNatureRestoration.SurvivalWorlds", false);
config.set("GriefPrevention.Claims.Expiration.AutomaticNatureRestoration.SurvivalWorlds", this.config_claims_survivalAutoNatureRestoration); outConfig.set("GriefPrevention.Claims.Expiration.AutomaticNatureRestoration.SurvivalWorlds", this.config_claims_survivalAutoNatureRestoration);
this.config_claims_creativeAutoNatureRestoration = config.getBoolean("GriefPrevention.Claims.Expiration.AutomaticNatureRestoration.CreativeWorlds", true); this.config_claims_creativeAutoNatureRestoration = config.getBoolean("GriefPrevention.Claims.Expiration.AutomaticNatureRestoration.CreativeWorlds", true);
config.set("GriefPrevention.Claims.Expiration.AutomaticNatureRestoration.CreativeWorlds", this.config_claims_creativeAutoNatureRestoration); outConfig.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);
@ -527,94 +534,101 @@ public class GriefPrevention extends JavaPlugin
} }
} }
this.config_pvp_noCombatInPlayerLandClaims = config.getBoolean("GriefPrevention.PvP.ProtectPlayersInLandClaims.PlayerOwnedClaims", this.config_siege_enabledWorlds.size() == 0);
this.config_pvp_noCombatInAdminLandClaims = config.getBoolean("GriefPrevention.PvP.ProtectPlayersInLandClaims.AdministrativeClaims", this.config_siege_enabledWorlds.size() == 0);
//optional database settings //optional database settings
String databaseUrl = config.getString("GriefPrevention.Database.URL", ""); String databaseUrl = config.getString("GriefPrevention.Database.URL", "");
String databaseUserName = config.getString("GriefPrevention.Database.UserName", ""); String databaseUserName = config.getString("GriefPrevention.Database.UserName", "");
String databasePassword = config.getString("GriefPrevention.Database.Password", ""); String databasePassword = config.getString("GriefPrevention.Database.Password", "");
config.set("GriefPrevention.Claims.Worlds", claimsEnabledWorldNames); outConfig.set("GriefPrevention.Claims.Worlds", claimsEnabledWorldNames);
config.set("GriefPrevention.Claims.CreativeRulesWorlds", creativeClaimsEnabledWorldNames); outConfig.set("GriefPrevention.Claims.CreativeRulesWorlds", creativeClaimsEnabledWorldNames);
config.set("GriefPrevention.Claims.PreventTheft", this.config_claims_preventTheft); outConfig.set("GriefPrevention.Claims.PreventTheft", this.config_claims_preventTheft);
config.set("GriefPrevention.Claims.ProtectCreatures", this.config_claims_protectCreatures); outConfig.set("GriefPrevention.Claims.ProtectCreatures", this.config_claims_protectCreatures);
config.set("GriefPrevention.Claims.PreventButtonsSwitches", this.config_claims_preventButtonsSwitches); outConfig.set("GriefPrevention.Claims.PreventButtonsSwitches", this.config_claims_preventButtonsSwitches);
config.set("GriefPrevention.Claims.LockWoodenDoors", this.config_claims_lockWoodenDoors); outConfig.set("GriefPrevention.Claims.LockWoodenDoors", this.config_claims_lockWoodenDoors);
config.set("GriefPrevention.Claims.LockTrapDoors", this.config_claims_lockTrapDoors); outConfig.set("GriefPrevention.Claims.LockTrapDoors", this.config_claims_lockTrapDoors);
config.set("GriefPrevention.Claims.LockFenceGates", this.config_claims_lockFenceGates); outConfig.set("GriefPrevention.Claims.LockFenceGates", this.config_claims_lockFenceGates);
config.set("GriefPrevention.Claims.InitialBlocks", this.config_claims_initialBlocks); outConfig.set("GriefPrevention.Claims.EnderPearlsRequireAccessTrust", this.config_claims_enderPearlsRequireAccessTrust);
config.set("GriefPrevention.Claims.BlocksAccruedPerHour", this.config_claims_blocksAccruedPerHour); outConfig.set("GriefPrevention.Claims.InitialBlocks", this.config_claims_initialBlocks);
config.set("GriefPrevention.Claims.MaxAccruedBlocks", this.config_claims_maxAccruedBlocks); outConfig.set("GriefPrevention.Claims.BlocksAccruedPerHour", this.config_claims_blocksAccruedPerHour);
config.set("GriefPrevention.Claims.AutomaticNewPlayerClaimsRadius", this.config_claims_automaticClaimsForNewPlayersRadius); outConfig.set("GriefPrevention.Claims.MaxAccruedBlocks", this.config_claims_maxAccruedBlocks);
config.set("GriefPrevention.Claims.ExtendIntoGroundDistance", this.config_claims_claimsExtendIntoGroundDistance); outConfig.set("GriefPrevention.Claims.AutomaticNewPlayerClaimsRadius", this.config_claims_automaticClaimsForNewPlayersRadius);
config.set("GriefPrevention.Claims.CreationRequiresPermission", this.config_claims_creationRequiresPermission); outConfig.set("GriefPrevention.Claims.ExtendIntoGroundDistance", this.config_claims_claimsExtendIntoGroundDistance);
config.set("GriefPrevention.Claims.MinimumSize", this.config_claims_minSize); outConfig.set("GriefPrevention.Claims.CreationRequiresPermission", this.config_claims_creationRequiresPermission);
config.set("GriefPrevention.Claims.MaximumDepth", this.config_claims_maxDepth); outConfig.set("GriefPrevention.Claims.MinimumSize", this.config_claims_minSize);
config.set("GriefPrevention.Claims.IdleLimitDays", this.config_claims_expirationDays); outConfig.set("GriefPrevention.Claims.MaximumDepth", this.config_claims_maxDepth);
config.set("GriefPrevention.Claims.TrappedCommandCooldownHours", this.config_claims_trappedCooldownHours); outConfig.set("GriefPrevention.Claims.IdleLimitDays", this.config_claims_expirationDays);
config.set("GriefPrevention.Claims.InvestigationTool", this.config_claims_investigationTool.name()); outConfig.set("GriefPrevention.Claims.TrappedCommandCooldownHours", this.config_claims_trappedCooldownHours);
config.set("GriefPrevention.Claims.ModificationTool", this.config_claims_modificationTool.name()); outConfig.set("GriefPrevention.Claims.InvestigationTool", this.config_claims_investigationTool.name());
config.set("GriefPrevention.Claims.NoSurvivalBuildingOutsideClaims", this.config_claims_noBuildOutsideClaims); outConfig.set("GriefPrevention.Claims.ModificationTool", this.config_claims_modificationTool.name());
config.set("GriefPrevention.Claims.WarnWhenBuildingOutsideClaims", this.config_claims_warnOnBuildOutside); outConfig.set("GriefPrevention.Claims.NoSurvivalBuildingOutsideClaims", this.config_claims_noBuildOutsideClaims);
config.set("GriefPrevention.Claims.AllowUnclaimingCreativeModeLand", this.config_claims_allowUnclaimInCreative); outConfig.set("GriefPrevention.Claims.WarnWhenBuildingOutsideClaims", this.config_claims_warnOnBuildOutside);
outConfig.set("GriefPrevention.Claims.AllowUnclaimingCreativeModeLand", this.config_claims_allowUnclaimInCreative);
outConfig.set("GriefPrevention.Claims.AutoRestoreUnclaimedCreativeLand", this.config_claims_autoRestoreUnclaimedCreativeLand);
config.set("GriefPrevention.Spam.Enabled", this.config_spam_enabled); outConfig.set("GriefPrevention.Spam.Enabled", this.config_spam_enabled);
config.set("GriefPrevention.Spam.LoginCooldownMinutes", this.config_spam_loginCooldownMinutes); outConfig.set("GriefPrevention.Spam.LoginCooldownMinutes", this.config_spam_loginCooldownMinutes);
config.set("GriefPrevention.Spam.MonitorSlashCommands", slashCommandsToMonitor); outConfig.set("GriefPrevention.Spam.MonitorSlashCommands", slashCommandsToMonitor);
config.set("GriefPrevention.Spam.WarningMessage", this.config_spam_warningMessage); outConfig.set("GriefPrevention.Spam.WarningMessage", this.config_spam_warningMessage);
config.set("GriefPrevention.Spam.BanOffenders", this.config_spam_banOffenders); outConfig.set("GriefPrevention.Spam.BanOffenders", this.config_spam_banOffenders);
config.set("GriefPrevention.Spam.BanMessage", this.config_spam_banMessage); outConfig.set("GriefPrevention.Spam.BanMessage", this.config_spam_banMessage);
config.set("GriefPrevention.Spam.AllowedIpAddresses", this.config_spam_allowedIpAddresses); outConfig.set("GriefPrevention.Spam.AllowedIpAddresses", this.config_spam_allowedIpAddresses);
config.set("GriefPrevention.Spam.DeathMessageCooldownSeconds", this.config_spam_deathMessageCooldownSeconds); outConfig.set("GriefPrevention.Spam.DeathMessageCooldownSeconds", this.config_spam_deathMessageCooldownSeconds);
config.set("GriefPrevention.PvP.Worlds", pvpEnabledWorldNames); outConfig.set("GriefPrevention.PvP.Worlds", pvpEnabledWorldNames);
config.set("GriefPrevention.PvP.ProtectFreshSpawns", this.config_pvp_protectFreshSpawns); outConfig.set("GriefPrevention.PvP.ProtectFreshSpawns", this.config_pvp_protectFreshSpawns);
config.set("GriefPrevention.PvP.PunishLogout", this.config_pvp_punishLogout); outConfig.set("GriefPrevention.PvP.PunishLogout", this.config_pvp_punishLogout);
config.set("GriefPrevention.PvP.CombatTimeoutSeconds", this.config_pvp_combatTimeoutSeconds); outConfig.set("GriefPrevention.PvP.CombatTimeoutSeconds", this.config_pvp_combatTimeoutSeconds);
config.set("GriefPrevention.PvP.AllowCombatItemDrop", this.config_pvp_allowCombatItemDrop); outConfig.set("GriefPrevention.PvP.AllowCombatItemDrop", this.config_pvp_allowCombatItemDrop);
config.set("GriefPrevention.PvP.BlockedSlashCommands", bannedPvPCommandsList); outConfig.set("GriefPrevention.PvP.BlockedSlashCommands", bannedPvPCommandsList);
outConfig.set("GriefPrevention.PvP.ProtectPlayersInLandClaims.PlayerOwnedClaims", this.config_pvp_noCombatInPlayerLandClaims);
outConfig.set("GriefPrevention.PvP.ProtectPlayersInLandClaims.AdministrativeClaims", this.config_pvp_noCombatInAdminLandClaims);
config.set("GriefPrevention.Trees.RemoveFloatingTreetops", this.config_trees_removeFloatingTreetops); outConfig.set("GriefPrevention.Trees.RemoveFloatingTreetops", this.config_trees_removeFloatingTreetops);
config.set("GriefPrevention.Trees.RegrowGriefedTrees", this.config_trees_regrowGriefedTrees); outConfig.set("GriefPrevention.Trees.RegrowGriefedTrees", this.config_trees_regrowGriefedTrees);
config.set("GriefPrevention.Economy.ClaimBlocksPurchaseCost", this.config_economy_claimBlocksPurchaseCost); outConfig.set("GriefPrevention.Economy.ClaimBlocksPurchaseCost", this.config_economy_claimBlocksPurchaseCost);
config.set("GriefPrevention.Economy.ClaimBlocksSellValue", this.config_economy_claimBlocksSellValue); outConfig.set("GriefPrevention.Economy.ClaimBlocksSellValue", this.config_economy_claimBlocksSellValue);
config.set("GriefPrevention.BlockSurfaceCreeperExplosions", this.config_blockSurfaceCreeperExplosions); outConfig.set("GriefPrevention.BlockSurfaceCreeperExplosions", this.config_blockSurfaceCreeperExplosions);
config.set("GriefPrevention.BlockSurfaceOtherExplosions", this.config_blockSurfaceOtherExplosions); outConfig.set("GriefPrevention.BlockSurfaceOtherExplosions", this.config_blockSurfaceOtherExplosions);
config.set("GriefPrevention.LimitSurfaceWaterBuckets", this.config_blockWildernessWaterBuckets); outConfig.set("GriefPrevention.LimitSurfaceWaterBuckets", this.config_blockWildernessWaterBuckets);
config.set("GriefPrevention.LimitSkyTrees", this.config_blockSkyTrees); outConfig.set("GriefPrevention.LimitSkyTrees", this.config_blockSkyTrees);
config.set("GriefPrevention.FireSpreads", this.config_fireSpreads); outConfig.set("GriefPrevention.FireSpreads", this.config_fireSpreads);
config.set("GriefPrevention.FireDestroys", this.config_fireDestroys); outConfig.set("GriefPrevention.FireDestroys", this.config_fireDestroys);
config.set("GriefPrevention.AddItemsToClaimedChests", this.config_addItemsToClaimedChests); outConfig.set("GriefPrevention.AddItemsToClaimedChests", this.config_addItemsToClaimedChests);
config.set("GriefPrevention.EavesdropEnabled", this.config_eavesdrop); outConfig.set("GriefPrevention.EavesdropEnabled", this.config_eavesdrop);
config.set("GriefPrevention.WhisperCommands", whisperCommandsToMonitor); outConfig.set("GriefPrevention.WhisperCommands", whisperCommandsToMonitor);
config.set("GriefPrevention.SmartBan", this.config_smartBan); outConfig.set("GriefPrevention.SmartBan", this.config_smartBan);
config.set("GriefPrevention.Siege.Worlds", siegeEnabledWorldNames); outConfig.set("GriefPrevention.Siege.Worlds", siegeEnabledWorldNames);
config.set("GriefPrevention.Siege.BreakableBlocks", breakableBlocksList); outConfig.set("GriefPrevention.Siege.BreakableBlocks", breakableBlocksList);
config.set("GriefPrevention.EndermenMoveBlocks", this.config_endermenMoveBlocks); outConfig.set("GriefPrevention.EndermenMoveBlocks", this.config_endermenMoveBlocks);
config.set("GriefPrevention.SilverfishBreakBlocks", this.config_silverfishBreakBlocks); outConfig.set("GriefPrevention.SilverfishBreakBlocks", this.config_silverfishBreakBlocks);
config.set("GriefPrevention.CreaturesTrampleCrops", this.config_creaturesTrampleCrops); outConfig.set("GriefPrevention.CreaturesTrampleCrops", this.config_creaturesTrampleCrops);
config.set("GriefPrevention.HardModeZombiesBreakDoors", this.config_zombiesBreakDoors); outConfig.set("GriefPrevention.HardModeZombiesBreakDoors", this.config_zombiesBreakDoors);
config.set("GriefPrevention.Database.URL", databaseUrl); outConfig.set("GriefPrevention.Database.URL", databaseUrl);
config.set("GriefPrevention.Database.UserName", databaseUserName); outConfig.set("GriefPrevention.Database.UserName", databaseUserName);
config.set("GriefPrevention.Database.Password", databasePassword); outConfig.set("GriefPrevention.Database.Password", databasePassword);
config.set("GriefPrevention.Mods.BlockIdsRequiringAccessTrust", this.config_mods_accessTrustIds); outConfig.set("GriefPrevention.Mods.BlockIdsRequiringAccessTrust", this.config_mods_accessTrustIds);
config.set("GriefPrevention.Mods.BlockIdsRequiringContainerTrust", this.config_mods_containerTrustIds); outConfig.set("GriefPrevention.Mods.BlockIdsRequiringContainerTrust", this.config_mods_containerTrustIds);
config.set("GriefPrevention.Mods.BlockIdsExplodable", this.config_mods_explodableIds); outConfig.set("GriefPrevention.Mods.BlockIdsExplodable", this.config_mods_explodableIds);
config.set("GriefPrevention.Mods.PlayersIgnoringAllClaims", this.config_mods_ignoreClaimsAccounts); outConfig.set("GriefPrevention.Mods.PlayersIgnoringAllClaims", this.config_mods_ignoreClaimsAccounts);
config.set("GriefPrevention.Mods.BlockIdsRequiringAccessTrust", accessTrustStrings); outConfig.set("GriefPrevention.Mods.BlockIdsRequiringAccessTrust", accessTrustStrings);
config.set("GriefPrevention.Mods.BlockIdsRequiringContainerTrust", containerTrustStrings); outConfig.set("GriefPrevention.Mods.BlockIdsRequiringContainerTrust", containerTrustStrings);
config.set("GriefPrevention.Mods.BlockIdsExplodable", explodableStrings); outConfig.set("GriefPrevention.Mods.BlockIdsExplodable", explodableStrings);
try try
{ {
config.save(DataStore.configFilePath); outConfig.save(DataStore.configFilePath);
} }
catch(IOException exception) catch(IOException exception)
{ {
@ -1400,8 +1414,8 @@ public class GriefPrevention extends JavaPlugin
claim.removeSurfaceFluids(null); claim.removeSurfaceFluids(null);
this.dataStore.deleteClaim(claim); this.dataStore.deleteClaim(claim);
//if in a creative mode world, delete the claim //if in a creative mode world, /restorenature the claim
if(GriefPrevention.instance.creativeRulesApply(claim.getLesserBoundaryCorner())) if(GriefPrevention.instance.config_claims_autoRestoreUnclaimedCreativeLand && GriefPrevention.instance.creativeRulesApply(claim.getLesserBoundaryCorner()))
{ {
GriefPrevention.instance.restoreClaim(claim, 0); GriefPrevention.instance.restoreClaim(claim, 0);
} }
@ -1424,6 +1438,40 @@ public class GriefPrevention extends JavaPlugin
return true; return true;
} }
else if(cmd.getName().equalsIgnoreCase("claimexplosions") && player != null)
{
//determine which claim the player is standing in
Claim claim = this.dataStore.getClaimAt(player.getLocation(), true /*ignore height*/, null);
if(claim == null)
{
GriefPrevention.sendMessage(player, TextMode.Err, Messages.DeleteClaimMissing);
}
else
{
String noBuildReason = claim.allowBuild(player);
if(noBuildReason != null)
{
GriefPrevention.sendMessage(player, TextMode.Err, noBuildReason);
return true;
}
if(claim.areExplosivesAllowed)
{
claim.areExplosivesAllowed = false;
GriefPrevention.sendMessage(player, TextMode.Success, Messages.ExplosivesDisabled);
}
else
{
claim.areExplosivesAllowed = true;
GriefPrevention.sendMessage(player, TextMode.Success, Messages.ExplosivesEnabled);
}
}
return true;
}
//deleteallclaims <player> //deleteallclaims <player>
else if(cmd.getName().equalsIgnoreCase("deleteallclaims")) else if(cmd.getName().equalsIgnoreCase("deleteallclaims"))
{ {
@ -1720,6 +1768,13 @@ public class GriefPrevention extends JavaPlugin
return true; return true;
} }
//can't start a siege when you're protected from pvp combat
if(attackerData.pvpImmune)
{
GriefPrevention.sendMessage(player, TextMode.Err, Messages.CantFightWhileImmune);
return true;
}
//if a player name was specified, use that //if a player name was specified, use that
Player defender = null; Player defender = null;
if(args.length >= 1) if(args.length >= 1)

View File

@ -1,24 +1,24 @@
/* /*
GriefPrevention Server Plugin for Minecraft GriefPrevention Server Plugin for Minecraft
Copyright (C) 2012 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
the Free Software Foundation, either version 3 of the License, or the Free Software Foundation, either version 3 of the License, or
(at your option) any later version. (at your option) any later version.
This program is distributed in the hope that it will be useful, This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details. GNU General Public License for more details.
You should have received a copy of the GNU General Public License You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
package me.ryanhamshire.GriefPrevention; 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, IgnoreClaimsAdvertisement, NoPermissionForCommand, ClaimsListNoPermission 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, NoPermissionForCommand, ClaimsListNoPermission, ExplosivesDisabled, ExplosivesEnabled, ClaimExplosivesAdvertisement, PlayerInPvPSafeZone
} }

View File

@ -22,6 +22,12 @@ import java.util.Calendar;
import java.util.Date; import java.util.Date;
import java.util.Vector; import java.util.Vector;
import me.ryanhamshire.GriefPrevention.Claim;
import me.ryanhamshire.GriefPrevention.GriefPrevention;
import me.ryanhamshire.GriefPrevention.ShovelMode;
import me.ryanhamshire.GriefPrevention.SiegeData;
import me.ryanhamshire.GriefPrevention.Visualization;
import org.bukkit.Location; import org.bukkit.Location;
//holds all of GriefPrevention's player-tied data //holds all of GriefPrevention's player-tied data

View File

@ -150,7 +150,7 @@ class PlayerEventHandler implements Listener
long millisecondsSinceLastMessage = (new Date()).getTime() - playerData.lastMessageTimestamp.getTime(); long millisecondsSinceLastMessage = (new Date()).getTime() - playerData.lastMessageTimestamp.getTime();
//if the message came too close to the last one //if the message came too close to the last one
if(millisecondsSinceLastMessage < 2000) if(millisecondsSinceLastMessage < 1500)
{ {
//increment the spam counter //increment the spam counter
playerData.spamCount++; playerData.spamCount++;
@ -355,8 +355,6 @@ class PlayerEventHandler implements Listener
String logMessage = logMessageBuilder.toString(); String logMessage = logMessageBuilder.toString();
GriefPrevention.AddLogEntry(logMessage.toString());
Player [] players = GriefPrevention.instance.getServer().getOnlinePlayers(); Player [] players = GriefPrevention.instance.getServer().getOnlinePlayers();
for(int i = 0; i < players.length; i++) for(int i = 0; i < players.length; i++)
{ {
@ -381,7 +379,17 @@ class PlayerEventHandler implements Listener
if(!GriefPrevention.instance.config_spam_enabled) return; if(!GriefPrevention.instance.config_spam_enabled) return;
//if the slash command used is in the list of monitored commands, treat it like a chat message (see above) //if the slash command used is in the list of monitored commands, treat it like a chat message (see above)
if(GriefPrevention.instance.config_spam_monitorSlashCommands.contains(args[0])) boolean isMonitoredCommand = false;
for(String monitoredCommand : GriefPrevention.instance.config_spam_monitorSlashCommands)
{
if(args[0].equalsIgnoreCase(monitoredCommand))
{
isMonitoredCommand = true;
break;
}
}
if(isMonitoredCommand)
{ {
event.setCancelled(this.handlePlayerChat(event.getPlayer(), event.getMessage(), event)); event.setCancelled(this.handlePlayerChat(event.getPlayer(), event.getMessage(), event));
} }
@ -417,82 +425,18 @@ class PlayerEventHandler implements Listener
return; return;
} }
} }
//if logging-in account is banned, remember IP address for later
long now = Calendar.getInstance().getTimeInMillis();
if(GriefPrevention.instance.config_smartBan && event.getResult() == Result.KICK_BANNED)
{
this.tempBannedIps.add(new IpBanInfo(event.getAddress(), now + this.MILLISECONDS_IN_DAY, player.getName()));
}
} }
//remember the player's ip address //remember the player's ip address
PlayerData playerData = this.dataStore.getPlayerData(player.getName()); PlayerData playerData = this.dataStore.getPlayerData(player.getName());
playerData.ipAddress = event.getAddress(); 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 && !player.hasPlayedBefore())
{
//if logging-in account is banned, remember IP address for later
long now = Calendar.getInstance().getTimeInMillis();
if(event.getResult() == Result.KICK_BANNED)
{
this.tempBannedIps.add(new IpBanInfo(event.getAddress(), now + this.MILLISECONDS_IN_DAY, player.getName()));
}
//otherwise if not banned
else
{
//search temporarily banned IP addresses for this one
for(int i = 0; i < this.tempBannedIps.size(); i++)
{
IpBanInfo info = this.tempBannedIps.get(i);
String address = info.address.toString();
//eliminate any expired entries
if(now > info.expirationTimestamp)
{
this.tempBannedIps.remove(i--);
}
//if we find a match
else if(address.equals(playerData.ipAddress.toString()))
{
//if the account associated with the IP ban has been pardoned, remove all ip bans for that ip and we're done
OfflinePlayer bannedPlayer = GriefPrevention.instance.getServer().getOfflinePlayer(info.bannedAccountName);
if(!bannedPlayer.isBanned())
{
for(int j = 0; j < this.tempBannedIps.size(); j++)
{
IpBanInfo info2 = this.tempBannedIps.get(j);
if(info2.address.toString().equals(address))
{
OfflinePlayer bannedAccount = GriefPrevention.instance.getServer().getOfflinePlayer(info2.bannedAccountName);
bannedAccount.setBanned(false);
this.tempBannedIps.remove(j--);
}
}
break;
}
//otherwise if that account is still banned, ban this account, too
else
{
player.setBanned(true);
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);
}
}
break;
}
}
}
}
}
} }
//when a player spawns, conditionally apply temporary pvp protection //when a player spawns, conditionally apply temporary pvp protection
@ -508,18 +452,20 @@ class PlayerEventHandler implements Listener
@EventHandler(ignoreCancelled = true, priority = EventPriority.HIGHEST) @EventHandler(ignoreCancelled = true, priority = EventPriority.HIGHEST)
void onPlayerJoin(PlayerJoinEvent event) void onPlayerJoin(PlayerJoinEvent event)
{ {
String playerName = event.getPlayer().getName(); Player player = event.getPlayer();
String playerName = player.getName();
//note login time //note login time
long now = Calendar.getInstance().getTimeInMillis();
PlayerData playerData = this.dataStore.getPlayerData(playerName); PlayerData playerData = this.dataStore.getPlayerData(playerName);
playerData.lastSpawn = Calendar.getInstance().getTimeInMillis(); playerData.lastSpawn = now;
playerData.lastLogin = new Date(); playerData.lastLogin = new Date();
this.dataStore.savePlayerData(playerName, playerData); this.dataStore.savePlayerData(playerName, playerData);
//if player has never played on the server before, may need pvp protection //if player has never played on the server before, may need pvp protection
if(!event.getPlayer().hasPlayedBefore()) if(!player.hasPlayedBefore())
{ {
GriefPrevention.instance.checkPvpProtectionNeeded(event.getPlayer()); GriefPrevention.instance.checkPvpProtectionNeeded(player);
} }
//silence notifications when they're coming too fast //silence notifications when they're coming too fast
@ -527,6 +473,70 @@ class PlayerEventHandler implements Listener
{ {
event.setJoinMessage(null); event.setJoinMessage(null);
} }
//FEATURE: auto-ban accounts who use an IP address which was very recently used by another banned account
if(GriefPrevention.instance.config_smartBan && !player.hasPlayedBefore())
{
//search temporarily banned IP addresses for this one
for(int i = 0; i < this.tempBannedIps.size(); i++)
{
IpBanInfo info = this.tempBannedIps.get(i);
String address = info.address.toString();
//eliminate any expired entries
if(now > info.expirationTimestamp)
{
this.tempBannedIps.remove(i--);
}
//if we find a match
else if(address.equals(playerData.ipAddress.toString()))
{
//if the account associated with the IP ban has been pardoned, remove all ip bans for that ip and we're done
OfflinePlayer bannedPlayer = GriefPrevention.instance.getServer().getOfflinePlayer(info.bannedAccountName);
if(!bannedPlayer.isBanned())
{
for(int j = 0; j < this.tempBannedIps.size(); j++)
{
IpBanInfo info2 = this.tempBannedIps.get(j);
if(info2.address.toString().equals(address))
{
OfflinePlayer bannedAccount = GriefPrevention.instance.getServer().getOfflinePlayer(info2.bannedAccountName);
bannedAccount.setBanned(false);
this.tempBannedIps.remove(j--);
}
}
break;
}
//otherwise if that account is still banned, ban this account, too
else
{
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);
}
}
//ban player
PlayerKickBanTask task = new PlayerKickBanTask(player, "");
GriefPrevention.instance.getServer().getScheduler().scheduleSyncDelayedTask(GriefPrevention.instance, task, 10L);
//silence join message
event.setJoinMessage("");
break;
}
}
}
}
} }
//when a player dies... //when a player dies...
@ -576,6 +586,12 @@ class PlayerEventHandler implements Listener
String playerName = player.getName(); String playerName = player.getName();
PlayerData playerData = this.dataStore.getPlayerData(playerName); PlayerData playerData = this.dataStore.getPlayerData(playerName);
//FEATURE: claims where players have allowed explosions will revert back to not allowing them when the owner logs out
for(Claim claim : playerData.claims)
{
claim.areExplosivesAllowed = false;
}
//FEATURE: players in pvp combat when they log out will die //FEATURE: players in pvp combat when they log out will die
if(GriefPrevention.instance.config_pvp_punishLogout && playerData.inPvpCombat()) if(GriefPrevention.instance.config_pvp_punishLogout && playerData.inPvpCombat())
{ {
@ -658,14 +674,30 @@ class PlayerEventHandler implements Listener
@EventHandler(priority = EventPriority.LOWEST) @EventHandler(priority = EventPriority.LOWEST)
public void onPlayerTeleport(PlayerTeleportEvent event) public void onPlayerTeleport(PlayerTeleportEvent event)
{ {
Player player = event.getPlayer();
PlayerData playerData = this.dataStore.getPlayerData(player.getName());
//FEATURE: prevent players from using ender pearls to gain access to secured claims
if(event.getCause() == TeleportCause.ENDER_PEARL && GriefPrevention.instance.config_claims_enderPearlsRequireAccessTrust)
{
Claim toClaim = this.dataStore.getClaimAt(player.getLocation(), false, playerData.lastClaim);
if(toClaim != null)
{
playerData.lastClaim = toClaim;
String noAccessReason = toClaim.allowAccess(player);
if(noAccessReason != null)
{
GriefPrevention.sendMessage(player, TextMode.Err, noAccessReason);
event.setCancelled(true);
}
}
}
//FEATURE: prevent teleport abuse to win sieges //FEATURE: prevent teleport abuse to win sieges
//these rules only apply to non-ender-pearl teleportation //these rules only apply to non-ender-pearl teleportation
if(event.getCause() == TeleportCause.ENDER_PEARL) return; if(event.getCause() == TeleportCause.ENDER_PEARL) return;
Player player = event.getPlayer();
PlayerData playerData = this.dataStore.getPlayerData(player.getName());
Location source = event.getFrom(); Location source = event.getFrom();
Claim sourceClaim = this.dataStore.getClaimAt(source, false, playerData.lastClaim); Claim sourceClaim = this.dataStore.getClaimAt(source, false, playerData.lastClaim);
if(sourceClaim != null && sourceClaim.siegeData != null) if(sourceClaim != null && sourceClaim.siegeData != null)
@ -1526,7 +1558,7 @@ class PlayerEventHandler implements Listener
} }
//if in a creative mode world and shrinking an existing claim, restore any unclaimed area //if in a creative mode world and shrinking an existing claim, restore any unclaimed area
if(smaller && GriefPrevention.instance.creativeRulesApply(oldClaim.getLesserBoundaryCorner())) if(smaller && GriefPrevention.instance.config_claims_autoRestoreUnclaimedCreativeLand && GriefPrevention.instance.creativeRulesApply(oldClaim.getLesserBoundaryCorner()))
{ {
GriefPrevention.sendMessage(player, TextMode.Warn, Messages.UnclaimCleanupWarning); GriefPrevention.sendMessage(player, TextMode.Warn, Messages.UnclaimCleanupWarning);
GriefPrevention.instance.restoreClaim(oldClaim, 20L * 60 * 2); //2 minutes GriefPrevention.instance.restoreClaim(oldClaim, 20L * 60 * 2); //2 minutes