From dfc4264aecd5cef25b4fde0ab267174b67fccd3e Mon Sep 17 00:00:00 2001 From: ryanhamshire Date: Mon, 29 Dec 2014 19:37:12 -0800 Subject: [PATCH] Improved world guard compatibility. --- plugin.yml | 2 +- .../GriefPrevention/BlockEventHandler.java | 5 +- .../GriefPrevention/DataStore.java | 50 +++++++++++++++++-- .../GriefPrevention/Messages.java | 2 +- .../GriefPrevention/PlayerEventHandler.java | 45 +++++++++++------ 5 files changed, 81 insertions(+), 23 deletions(-) diff --git a/plugin.yml b/plugin.yml index 805acaf..333fe5c 100644 --- a/plugin.yml +++ b/plugin.yml @@ -1,6 +1,6 @@ name: GriefPrevention main: me.ryanhamshire.GriefPrevention.GriefPrevention -softdepend: [Vault, Multiverse-Core, My Worlds, MystCraft, Transporter, TheUnderground] +softdepend: [Vault, Multiverse-Core, My Worlds, MystCraft, Transporter, TheUnderground, WorldGuard, WorldEdit] dev-url: http://dev.bukkit.org/server-mods/grief-prevention loadbefore: [TheUnderground] version: 9.8 diff --git a/src/me/ryanhamshire/GriefPrevention/BlockEventHandler.java b/src/me/ryanhamshire/GriefPrevention/BlockEventHandler.java index 0f697bc..541e602 100644 --- a/src/me/ryanhamshire/GriefPrevention/BlockEventHandler.java +++ b/src/me/ryanhamshire/GriefPrevention/BlockEventHandler.java @@ -214,7 +214,7 @@ public class BlockEventHandler implements Listener //radius == 0 means protect ONLY the chest if(GriefPrevention.instance.config_claims_automaticClaimsForNewPlayersRadius == 0) { - this.dataStore.createClaim(block.getWorld(), block.getX(), block.getX(), block.getY(), block.getY(), block.getZ(), block.getZ(), player.getUniqueId(), null, null); + this.dataStore.createClaim(block.getWorld(), block.getX(), block.getX(), block.getY(), block.getY(), block.getZ(), block.getZ(), player.getUniqueId(), null, null, player); GriefPrevention.sendMessage(player, TextMode.Success, Messages.ChestClaimConfirmation); } @@ -228,7 +228,8 @@ public class BlockEventHandler implements Listener block.getY() - GriefPrevention.instance.config_claims_claimsExtendIntoGroundDistance, block.getY(), block.getZ() - radius, block.getZ() + radius, player.getUniqueId(), - null, null).succeeded) + null, null, + player).succeeded) { radius--; } diff --git a/src/me/ryanhamshire/GriefPrevention/DataStore.java b/src/me/ryanhamshire/GriefPrevention/DataStore.java index 09f4bbc..eacbed3 100644 --- a/src/me/ryanhamshire/GriefPrevention/DataStore.java +++ b/src/me/ryanhamshire/GriefPrevention/DataStore.java @@ -29,6 +29,14 @@ import org.bukkit.configuration.file.YamlConfiguration; import org.bukkit.entity.Player; import org.bukkit.inventory.ItemStack; +import com.sk89q.worldedit.BlockVector; +import com.sk89q.worldguard.LocalPlayer; +import com.sk89q.worldguard.bukkit.WorldGuardPlugin; +import com.sk89q.worldguard.protection.ApplicableRegionSet; +import com.sk89q.worldguard.protection.managers.RegionManager; +import com.sk89q.worldguard.protection.regions.ProtectedCuboidRegion; +import com.sk89q.worldguard.protection.regions.ProtectedRegion; + //singleton class which manages all GriefPrevention data (except for config options) public abstract class DataStore { @@ -73,7 +81,10 @@ public abstract class DataStore static final String SUBDIVISION_VIDEO_URL = "" + ChatColor.DARK_AQUA + ChatColor.UNDERLINE + "bit.ly/mcgpsub"; //list of UUIDs which are soft-muted - ConcurrentHashMap softMuteMap = new ConcurrentHashMap(); + ConcurrentHashMap softMuteMap = new ConcurrentHashMap(); + + //world guard reference, if available + boolean worldGuardHooked = false; protected int getSchemaVersion() { @@ -127,6 +138,13 @@ public abstract class DataStore //make a note of the data store schema version this.setSchemaVersion(latestSchemaVersion); + + //try to hook into world guard + worldGuardHooked = (GriefPrevention.instance.getServer().getPluginManager().getPlugin("WorldGuard") != null); + if(worldGuardHooked) + { + GriefPrevention.AddLogEntry("Successfully hooked into WorldGuard."); + } } private void loadSoftMutes() @@ -570,14 +588,16 @@ public abstract class DataStore //creates a claim. //if the new claim would overlap an existing claim, returns a failure along with a reference to the existing claim + //if the new claim would overlap a WorldGuard region where the player doesn't have permission to build, returns a failure with NULL for claim //otherwise, returns a success along with a reference to the new claim //use ownerName == "" for administrative claims //for top level claims, pass parent == NULL //DOES adjust claim blocks available on success (players can go into negative quantity available) + //DOES check for world guard regions where the player doesn't have permission //does NOT check a player has permission to create a claim, or enough claim blocks. //does NOT check minimum claim size constraints //does NOT visualize the new claim for any players - synchronized public CreateClaimResult createClaim(World world, int x1, int x2, int y1, int y2, int z1, int z2, UUID ownerID, Claim parent, Long id) + synchronized public CreateClaimResult createClaim(World world, int x1, int x2, int y1, int y2, int z1, int z2, UUID ownerID, Claim parent, Long id, Player creatingPlayer) { CreateClaimResult result = new CreateClaimResult(); @@ -661,6 +681,26 @@ public abstract class DataStore } } + //if worldguard is installed, also prevent claims from overlapping any worldguard regions + if(this.worldGuardHooked && creatingPlayer != null) + { + WorldGuardPlugin worldGuard = (WorldGuardPlugin)GriefPrevention.instance.getServer().getPluginManager().getPlugin("WorldGuard"); + Location lesser = newClaim.getLesserBoundaryCorner(); + Location greater = newClaim.getGreaterBoundaryCorner(); + for(int x = lesser.getBlockX(); x <= greater.getBlockX(); x++) + for(int z = lesser.getBlockZ(); z <= greater.getBlockZ(); z++) + for(int y = 0; y <= lesser.getWorld().getMaxHeight(); y++) + { + if(!worldGuard.canBuild(creatingPlayer, new Location(lesser.getWorld(), x, y, z))) + { + //result = fail, return null to indicate a region is in the way + result.succeeded = false; + result.claim = null; + return result; + } + } + } + //otherwise add this new claim to the data store to make it effective this.addClaim(newClaim, true); @@ -946,7 +986,7 @@ public abstract class DataStore //tries to resize a claim //see CreateClaim() for details on return value - synchronized public CreateClaimResult resizeClaim(Claim claim, int newx1, int newx2, int newy1, int newy2, int newz1, int newz2) + synchronized public CreateClaimResult resizeClaim(Claim claim, int newx1, int newx2, int newy1, int newy2, int newz1, int newz2, Player resizingPlayer) { //note any subdivisions before deleting the claim ArrayList subdivisions = new ArrayList(claim.children); @@ -955,7 +995,7 @@ public abstract class DataStore this.deleteClaim(claim); //try to create this new claim, ignoring the original when checking for overlap - CreateClaimResult result = this.createClaim(claim.getLesserBoundaryCorner().getWorld(), newx1, newx2, newy1, newy2, newz1, newz2, claim.ownerID, claim.parent, claim.id); + CreateClaimResult result = this.createClaim(claim.getLesserBoundaryCorner().getWorld(), newx1, newx2, newy1, newy2, newz1, newz2, claim.ownerID, claim.parent, claim.id, resizingPlayer); //if succeeded if(result.succeeded) @@ -1183,6 +1223,8 @@ public abstract class DataStore this.addDefault(defaults, Messages.AvoidGriefClaimLand, "Prevent grief! If you claim your land, you will be grief-proof.", null); this.addDefault(defaults, Messages.BecomeMayor, "Subdivide your land claim and become a mayor!", null); this.addDefault(defaults, Messages.ClaimCreationFailedOverClaimCountLimit, "You've reached your limit on land claims. Use /AbandonClaim to remove one before creating another.", null); + this.addDefault(defaults, Messages.CreateClaimFailOverlapRegion, "You can't claim all of this because you're not allowed to build here.", null); + this.addDefault(defaults, Messages.ResizeFailOverlapRegion, "You don't have permission to build there, so you can't claim that area.", null); //load the config file FileConfiguration config = YamlConfiguration.loadConfiguration(new File(messagesFilePath)); diff --git a/src/me/ryanhamshire/GriefPrevention/Messages.java b/src/me/ryanhamshire/GriefPrevention/Messages.java index 93fe13d..260eba7 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, SubdivisionVideo2, 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, CreativeBasicsVideo2, SurvivalBasicsVideo2, 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, AvoidGriefClaimLand, BecomeMayor, ClaimCreationFailedOverClaimCountLimit + 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, SubdivisionVideo2, 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, CreativeBasicsVideo2, SurvivalBasicsVideo2, 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, AvoidGriefClaimLand, BecomeMayor, ClaimCreationFailedOverClaimCountLimit, CreateClaimFailOverlapRegion, ResizeFailOverlapRegion } diff --git a/src/me/ryanhamshire/GriefPrevention/PlayerEventHandler.java b/src/me/ryanhamshire/GriefPrevention/PlayerEventHandler.java index 5c9f151..0aa14b3 100644 --- a/src/me/ryanhamshire/GriefPrevention/PlayerEventHandler.java +++ b/src/me/ryanhamshire/GriefPrevention/PlayerEventHandler.java @@ -1844,7 +1844,7 @@ class PlayerEventHandler implements Listener } //ask the datastore to try and resize the claim, this checks for conflicts with other claims - CreateClaimResult result = GriefPrevention.instance.dataStore.resizeClaim(playerData.claimResizing, newx1, newx2, newy1, newy2, newz1, newz2); + CreateClaimResult result = GriefPrevention.instance.dataStore.resizeClaim(playerData.claimResizing, newx1, newx2, newy1, newy2, newz1, newz2, player); if(result.succeeded) { @@ -1880,12 +1880,19 @@ class PlayerEventHandler implements Listener } else { - //inform player - GriefPrevention.sendMessage(player, TextMode.Err, Messages.ResizeFailOverlap); - - //show the player the conflicting claim - Visualization visualization = Visualization.FromClaim(result.claim, clickedBlock.getY(), VisualizationType.ErrorClaim, player.getLocation()); - Visualization.Apply(player, visualization); + if(result.claim != null) + { + //inform player + GriefPrevention.sendMessage(player, TextMode.Err, Messages.ResizeFailOverlap); + + //show the player the conflicting claim + Visualization visualization = Visualization.FromClaim(result.claim, clickedBlock.getY(), VisualizationType.ErrorClaim, player.getLocation()); + Visualization.Apply(player, visualization); + } + else + { + GriefPrevention.sendMessage(player, TextMode.Err, Messages.ResizeFailOverlapRegion); + } } return; @@ -1949,7 +1956,7 @@ class PlayerEventHandler implements Listener playerData.lastShovelLocation.getBlockZ(), clickedBlock.getZ(), null, //owner is not used for subdivisions playerData.claimSubdividing, - null); + null, player); //if it didn't succeed, tell the player why if(!result.succeeded) @@ -2068,23 +2075,31 @@ class PlayerEventHandler implements Listener playerID = null; } - //try to create a new claim (will return null if this claim overlaps another) + //try to create a new claim CreateClaimResult result = this.dataStore.createClaim( player.getWorld(), lastShovelLocation.getBlockX(), clickedBlock.getX(), lastShovelLocation.getBlockY() - GriefPrevention.instance.config_claims_claimsExtendIntoGroundDistance, clickedBlock.getY() - GriefPrevention.instance.config_claims_claimsExtendIntoGroundDistance, lastShovelLocation.getBlockZ(), clickedBlock.getZ(), playerID, - null, null); + null, null, + player); //if it didn't succeed, tell the player why if(!result.succeeded) { - GriefPrevention.sendMessage(player, TextMode.Err, Messages.CreateClaimFailOverlapShort); - - Visualization visualization = Visualization.FromClaim(result.claim, clickedBlock.getY(), VisualizationType.ErrorClaim, player.getLocation()); - Visualization.Apply(player, visualization); - + if(result.claim != null) + { + GriefPrevention.sendMessage(player, TextMode.Err, Messages.CreateClaimFailOverlapShort); + + Visualization visualization = Visualization.FromClaim(result.claim, clickedBlock.getY(), VisualizationType.ErrorClaim, player.getLocation()); + Visualization.Apply(player, visualization); + } + else + { + GriefPrevention.sendMessage(player, TextMode.Err, Messages.CreateClaimFailOverlapRegion); + } + return; }