From 4a426f64692d3bb5916d2d28e125d5cf6cf75167 Mon Sep 17 00:00:00 2001 From: ryanhamshire Date: Wed, 17 Dec 2014 21:19:47 -0800 Subject: [PATCH] Added /GivePet and tweaked pet protections. --- plugin.yml | 3 + .../GriefPrevention/DataStore.java | 4 + .../GriefPrevention/EntityEventHandler.java | 46 ++++---- .../GriefPrevention/GriefPrevention.java | 33 ++++++ .../GriefPrevention/Messages.java | 2 +- .../GriefPrevention/PlayerData.java | 4 + .../GriefPrevention/PlayerEventHandler.java | 100 ++++++++++-------- 7 files changed, 126 insertions(+), 66 deletions(-) diff --git a/plugin.yml b/plugin.yml index 69a38c6..84bf583 100644 --- a/plugin.yml +++ b/plugin.yml @@ -137,6 +137,9 @@ commands: description: Reloads Grief Prevention's configuration settings. Does NOT totally reload the entire plugin. usage: /gpreload permission: griefprevention.reload + givepet: + description: Allows a player to give away a pet he or she tamed. + usage: /GivePet permissions: griefprevention.createclaims: description: Grants permission to create claims. diff --git a/src/me/ryanhamshire/GriefPrevention/DataStore.java b/src/me/ryanhamshire/GriefPrevention/DataStore.java index 469a237..8651caf 100644 --- a/src/me/ryanhamshire/GriefPrevention/DataStore.java +++ b/src/me/ryanhamshire/GriefPrevention/DataStore.java @@ -1176,6 +1176,10 @@ public abstract class DataStore this.addDefault(defaults, Messages.AdvertiseACandACB, "You may use /ACB to give yourself more claim blocks, or /AdminClaims to create a free administrative claim.", null); this.addDefault(defaults, Messages.AdvertiseAdminClaims, "You could create an administrative land claim instead using /AdminClaims, which you'd share with other administrators.", null); this.addDefault(defaults, Messages.AdvertiseACB, "You may use /ACB to give yourself more claim blocks.", null); + this.addDefault(defaults, Messages.NotYourPet, "That belongs to {0} until it's given to you with /GivePet.", "0: owner name"); + this.addDefault(defaults, Messages.PetGiveawayConfirmation, "Pet transferred.", null); + this.addDefault(defaults, Messages.PetTransferCancellation, "Pet giveaway cancelled.", null); + this.addDefault(defaults, Messages.ReadyToTransferPet, "Ready to transfer! Right-click the pet you'd like to give away, or cancel with /GivePet cancel.", null); //load the config file FileConfiguration config = YamlConfiguration.loadConfiguration(new File(messagesFilePath)); diff --git a/src/me/ryanhamshire/GriefPrevention/EntityEventHandler.java b/src/me/ryanhamshire/GriefPrevention/EntityEventHandler.java index c7210ac..93ce35d 100644 --- a/src/me/ryanhamshire/GriefPrevention/EntityEventHandler.java +++ b/src/me/ryanhamshire/GriefPrevention/EntityEventHandler.java @@ -430,12 +430,33 @@ class EntityEventHandler implements Listener @EventHandler(ignoreCancelled = true, priority = EventPriority.HIGHEST) public void onEntityDamage (EntityDamageEvent event) { - //only actually interested in entities damaging entities (ignoring environmental damage) - if(!(event instanceof EntityDamageByEntityEvent)) return; - //monsters are never protected if(event.getEntity() instanceof Monster) return; + //protect pets from environmental damage types which could be easily caused by griefers + if(event.getEntity() instanceof Tameable && !GriefPrevention.instance.config_pvp_enabledWorlds.contains(event.getEntity().getWorld())) + { + Tameable tameable = (Tameable)event.getEntity(); + if(tameable.isTamed()) + { + DamageCause cause = event.getCause(); + if( cause != null && ( + cause == DamageCause.ENTITY_EXPLOSION || + cause == DamageCause.FALLING_BLOCK || + cause == DamageCause.FIRE || + cause == DamageCause.FIRE_TICK || + cause == DamageCause.LAVA || + cause == DamageCause.SUFFOCATION)) + { + event.setCancelled(true); + return; + } + } + } + + //the rest is only interested in entities damaging entities (ignoring environmental damage) + if(!(event instanceof EntityDamageByEntityEvent)) return; + EntityDamageByEntityEvent subEvent = (EntityDamageByEntityEvent) event; //determine which player is attacking, if any @@ -578,7 +599,7 @@ class EntityEventHandler implements Listener if ((subEvent.getEntity() instanceof Creature && GriefPrevention.instance.config_claims_protectCreatures)) { //if entity is tameable and has an owner, apply special rules - if(subEvent.getEntity() instanceof Tameable) + if(subEvent.getEntity() instanceof Tameable && !GriefPrevention.instance.config_pvp_enabledWorlds.contains(subEvent.getEntity().getWorld())) { Tameable tameable = (Tameable)subEvent.getEntity(); if(tameable.isTamed() && tameable.getOwner() != null) @@ -609,23 +630,6 @@ class EntityEventHandler implements Listener return; } } - - //also limit damage sources to prevent grief of pets by build (flint/steel, lava buckets, sand...) - else - { - DamageCause cause = event.getCause(); - if(cause != null && ( - cause == DamageCause.ENTITY_EXPLOSION || - cause == DamageCause.FALLING_BLOCK || - cause == DamageCause.FIRE || - cause == DamageCause.FIRE_TICK || - cause == DamageCause.LAVA || - cause == DamageCause.SUFFOCATION)) - { - event.setCancelled(true); - return; - } - } } } diff --git a/src/me/ryanhamshire/GriefPrevention/GriefPrevention.java b/src/me/ryanhamshire/GriefPrevention/GriefPrevention.java index c02a778..7c63fff 100644 --- a/src/me/ryanhamshire/GriefPrevention/GriefPrevention.java +++ b/src/me/ryanhamshire/GriefPrevention/GriefPrevention.java @@ -1919,6 +1919,39 @@ public class GriefPrevention extends JavaPlugin return true; } + //givepet + else if(cmd.getName().equalsIgnoreCase("givepet") && player != null) + { + //requires one parameter + if(args.length < 1) return false; + + PlayerData playerData = this.dataStore.getPlayerData(player.getUniqueId()); + + //special case: cancellation + if(args[0].equalsIgnoreCase("cancel")) + { + playerData.petGiveawayRecipient = null; + GriefPrevention.sendMessage(player, TextMode.Success, Messages.PetTransferCancellation); + return true; + } + + //find the specified player + OfflinePlayer targetPlayer = this.resolvePlayerByName(args[0]); + if(targetPlayer == null) + { + GriefPrevention.sendMessage(player, TextMode.Err, Messages.PlayerNotFound2); + return true; + } + + //remember the player's ID for later pet transfer + playerData.petGiveawayRecipient = targetPlayer; + + //send instructions + GriefPrevention.sendMessage(player, TextMode.Instr, Messages.ReadyToTransferPet); + + return true; + } + return false; } diff --git a/src/me/ryanhamshire/GriefPrevention/Messages.java b/src/me/ryanhamshire/GriefPrevention/Messages.java index 4104889..56cf561 100644 --- a/src/me/ryanhamshire/GriefPrevention/Messages.java +++ b/src/me/ryanhamshire/GriefPrevention/Messages.java @@ -20,5 +20,5 @@ package me.ryanhamshire.GriefPrevention; public enum Messages { - RespectingClaims, IgnoringClaims, SuccessfulAbandon, RestoreNatureActivate, RestoreNatureAggressiveActivate, FillModeActive, TransferClaimPermission, TransferClaimMissing, TransferClaimAdminOnly, PlayerNotFound2, TransferTopLevel, TransferSuccess, TrustListNoClaim, ClearPermsOwnerOnly, UntrustIndividualAllClaims, UntrustEveryoneAllClaims, NoPermissionTrust, ClearPermissionsOneClaim, UntrustIndividualSingleClaim, OnlySellBlocks, BlockPurchaseCost, ClaimBlockLimit, InsufficientFunds, PurchaseConfirmation, OnlyPurchaseBlocks, BlockSaleValue, NotEnoughBlocksForSale, BlockSaleConfirmation, AdminClaimsMode, BasicClaimsMode, SubdivisionMode, SubdivisionVideo, DeleteClaimMissing, DeletionSubdivisionWarning, DeleteSuccess, CantDeleteAdminClaim, DeleteAllSuccess, NoDeletePermission, AllAdminDeleted, AdjustBlocksSuccess, NotTrappedHere, 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, UnprotectedChestWarning, ThatPlayerPvPImmune, CantFightWhileImmune, NoDamageClaimedEntity, ShovelBasicClaimMode, RemainingBlocks, CreativeBasicsVideo, SurvivalBasicsVideo, 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, NoPistonsOutsideClaims, SoftMuted, UnSoftMuted, DropUnlockAdvertisement, PickupBlockedExplanation, DropUnlockConfirmation, AdvertiseACandACB, AdvertiseAdminClaims, AdvertiseACB + RespectingClaims, IgnoringClaims, SuccessfulAbandon, RestoreNatureActivate, RestoreNatureAggressiveActivate, FillModeActive, TransferClaimPermission, TransferClaimMissing, TransferClaimAdminOnly, PlayerNotFound2, TransferTopLevel, TransferSuccess, TrustListNoClaim, ClearPermsOwnerOnly, UntrustIndividualAllClaims, UntrustEveryoneAllClaims, NoPermissionTrust, ClearPermissionsOneClaim, UntrustIndividualSingleClaim, OnlySellBlocks, BlockPurchaseCost, ClaimBlockLimit, InsufficientFunds, PurchaseConfirmation, OnlyPurchaseBlocks, BlockSaleValue, NotEnoughBlocksForSale, BlockSaleConfirmation, AdminClaimsMode, BasicClaimsMode, SubdivisionMode, SubdivisionVideo, DeleteClaimMissing, DeletionSubdivisionWarning, DeleteSuccess, CantDeleteAdminClaim, DeleteAllSuccess, NoDeletePermission, AllAdminDeleted, AdjustBlocksSuccess, NotTrappedHere, 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, UnprotectedChestWarning, ThatPlayerPvPImmune, CantFightWhileImmune, NoDamageClaimedEntity, ShovelBasicClaimMode, RemainingBlocks, CreativeBasicsVideo, SurvivalBasicsVideo, 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, NoPistonsOutsideClaims, SoftMuted, UnSoftMuted, DropUnlockAdvertisement, PickupBlockedExplanation, DropUnlockConfirmation, AdvertiseACandACB, AdvertiseAdminClaims, AdvertiseACB, NotYourPet, PetGiveawayConfirmation, PetTransferCancellation, ReadyToTransferPet } diff --git a/src/me/ryanhamshire/GriefPrevention/PlayerData.java b/src/me/ryanhamshire/GriefPrevention/PlayerData.java index 102a645..07a230f 100644 --- a/src/me/ryanhamshire/GriefPrevention/PlayerData.java +++ b/src/me/ryanhamshire/GriefPrevention/PlayerData.java @@ -30,6 +30,7 @@ import me.ryanhamshire.GriefPrevention.SiegeData; import me.ryanhamshire.GriefPrevention.Visualization; import org.bukkit.Location; +import org.bukkit.OfflinePlayer; //holds all of GriefPrevention's player-tied data public class PlayerData @@ -117,6 +118,9 @@ public class PlayerData //message to send to player after he respawns String messageOnRespawn = null; + + //player which a pet will be given to when it's right-clicked + OfflinePlayer petGiveawayRecipient = null; //whether or not this player is "in" pvp combat public boolean inPvpCombat() diff --git a/src/me/ryanhamshire/GriefPrevention/PlayerEventHandler.java b/src/me/ryanhamshire/GriefPrevention/PlayerEventHandler.java index d1eef9f..cb677c5 100644 --- a/src/me/ryanhamshire/GriefPrevention/PlayerEventHandler.java +++ b/src/me/ryanhamshire/GriefPrevention/PlayerEventHandler.java @@ -825,15 +825,48 @@ class PlayerEventHandler implements Listener if(!GriefPrevention.instance.claimsEnabledForWorld(entity.getWorld())) return; - PlayerData playerData = this.dataStore.getPlayerData(player.getUniqueId()); - - //always allow interactions when player is in ignore claims mode - if(playerData.ignoreClaims) return; - //allow horse protection to be overridden to allow management from other plugins if (!GriefPrevention.instance.config_claims_protectHorses && entity instanceof Horse) return; - //don't allow interaction with item frames or armor stands in claimed areas without build permission + PlayerData playerData = this.dataStore.getPlayerData(player.getUniqueId()); + + //if entity is tameable and has an owner, apply special rules + if(entity instanceof Tameable && !GriefPrevention.instance.config_pvp_enabledWorlds.contains(entity.getLocation().getWorld())) + { + Tameable tameable = (Tameable)entity; + if(tameable.isTamed() && tameable.getOwner() != null) + { + UUID ownerID = tameable.getOwner().getUniqueId(); + + //if the player interacting is the owner or an admin in ignore claims mode, always allow + if(player.getUniqueId().equals(ownerID) || playerData.ignoreClaims) + { + //if giving away pet, do that instead + if(playerData.petGiveawayRecipient != null) + { + tameable.setOwner(playerData.petGiveawayRecipient); + playerData.petGiveawayRecipient = null; + GriefPrevention.sendMessage(player, TextMode.Success, Messages.PetGiveawayConfirmation); + event.setCancelled(true); + } + + return; + } + + //otherwise disallow + OfflinePlayer owner = GriefPrevention.instance.getServer().getOfflinePlayer(ownerID); + String ownerName = owner.getName(); + if(ownerName == null) ownerName = "someone"; + String message = GriefPrevention.instance.dataStore.getMessage(Messages.NotYourPet, ownerName); + if(player.hasPermission("griefprevention.ignoreclaims")) + message += " " + GriefPrevention.instance.dataStore.getMessage(Messages.IgnoreClaimsAdvertisement); + GriefPrevention.sendMessage(player, TextMode.Err, message); + event.setCancelled(true); + return; + } + } + + //don't allow interaction with item frames or armor stands in claimed areas without build permission if(entity.getType() == EntityType.ARMOR_STAND || entity instanceof Hanging) { String noBuildReason = GriefPrevention.instance.allowBuild(player, entity.getLocation(), Material.ITEM_FRAME); @@ -845,48 +878,27 @@ class PlayerEventHandler implements Listener } } - //don't allow container access during pvp combat - if((entity instanceof StorageMinecart || entity instanceof PoweredMinecart)) - { - if(playerData.siegeData != null) - { - GriefPrevention.sendMessage(player, TextMode.Err, Messages.SiegeNoContainers); - event.setCancelled(true); - return; - } - - if(playerData.inPvpCombat()) - { - GriefPrevention.sendMessage(player, TextMode.Err, Messages.PvPNoContainers); - event.setCancelled(true); - return; - } - } - - //if entity is tameable and has an owner, apply special rules - if(entity instanceof Tameable && !GriefPrevention.instance.config_pvp_enabledWorlds.contains(entity.getLocation().getWorld())) + //always allow interactions when player is in ignore claims mode + if(playerData.ignoreClaims) return; + + //don't allow container access during pvp combat + if((entity instanceof StorageMinecart || entity instanceof PoweredMinecart)) { - Tameable tameable = (Tameable)entity; - if(tameable.isTamed() && tameable.getOwner() != null) + if(playerData.siegeData != null) { - UUID ownerID = tameable.getOwner().getUniqueId(); - - //if the player interacting is the owner, always allow - if(player.getUniqueId().equals(ownerID)) return; - - //otherwise disallow - OfflinePlayer owner = GriefPrevention.instance.getServer().getOfflinePlayer(ownerID); - String ownerName = owner.getName(); - if(ownerName == null) ownerName = "someone"; - String message = GriefPrevention.instance.dataStore.getMessage(Messages.NoDamageClaimedEntity, ownerName); - if(player.hasPermission("griefprevention.ignoreclaims")) - message += " " + GriefPrevention.instance.dataStore.getMessage(Messages.IgnoreClaimsAdvertisement); - GriefPrevention.sendMessage(player, TextMode.Err, message); - event.setCancelled(true); - return; + GriefPrevention.sendMessage(player, TextMode.Err, Messages.SiegeNoContainers); + event.setCancelled(true); + return; } + + if(playerData.inPvpCombat()) + { + GriefPrevention.sendMessage(player, TextMode.Err, Messages.PvPNoContainers); + event.setCancelled(true); + return; + } } - + //if the entity is a vehicle and we're preventing theft in claims if(GriefPrevention.instance.config_claims_preventTheft && entity instanceof Vehicle) {