From e8e57c5f5d1089cfc58fa8cd9e4a5f1afca4fa8a Mon Sep 17 00:00:00 2001 From: bloodshot Date: Sun, 16 Aug 2020 00:39:38 -0400 Subject: [PATCH] Update for 1.5.0 * Fix blockstate id lookup not using proper id when block data was different than actual block. * Fix block-break showing air as target when source block broke on its own. * Fix race condition when migrating GP Bukkit playerdata. * Fix race condition during flag definition saves. * Fix wrong owner showing in claim when non-owner changes claim type. * Fix explosions causing no sound when cancelling event. * Fix rent min message showing max. * Fix rent min payment not being applied as credit. * Fix rent restore not working on rent end. * Fix sell sign not working when rent system was disabled. * Fix '/abandonall' not giving all money back when using economy mode. * Fix '/claimsell' requiring for sale to be turned on. * Fix '/givepet' taming pets without owner. * Fix explosion sounds not triggering on cancel. * Fix pvp 'allow-fly' only affecting creative mode. * Fix confirmation message not showing after abandoning a subdivision. * Fix wrong location being checked when placing water/lava with bucket. * Fix dynmap owner style colors not being used. * Fix NPE when using /reload. * Fix ghost claim overlap error when creating claim. * Fix user showing up as cause when using rtp. * Fix high memory usage caused by GDClaimManager fastutil usage. * (Bukkit) Fix NPE during InventoryMoveItemEvent. * (Sponge) Fix explosion-surface being triggered with no settings. * Refactor CompletableFuture handling when applying LP permissions and meta to avoid race conditions. * Remove owner override context for flag definition 'fire-spread' as it doesn't affect global overrides. * Change flag definition 'turtle-egg-hatch' target from 'air' to 'turtle-egg-hatch' * Change flag definition 'snow-melt' target from 'air' to 'snow' * Change onPlayerInteractBlockSecondary event priority from lowest to low in order to support plugins that need to cancel early. * Add support for CustomItems. Any customitem used in game will show up in debug as customitems:. You can also use customitems for modification and investigation tool in config. * Add support for Slimefun4. Any slimefun item/block used in game will show up in debug as slimefun:. You can also use slimefun items for modification and investigation tool in config. * Add '/acball' command for adjusting all online players' bonus blocks. * Add '/claiminvestigate' command to investigate claims. * Add '/claimtool' to toggle claim tool usage. * Add source/target any contexts to flag definitions. * Add 'piston-protection-in-claims' setting to control piston protection within claims. * Add pvp setting 'combat-logout' to determine if a player should be killed on logout during combat. Default 'false'. * Add `projectile-impact-entity` to `endcrystal-use` flag definition. * Add aquatic target for `monster-animal-damage` flag definition. * Add `restrict-world-max-height` to determine if claiming should be restricted to world max height. Default 'true'. * Add ability to control dynmap color settings by claim type. * Add permission griefdefender.user.claim.command.info.teleport.inside which controls whether a player can ONLY teleport within the claim they are in. This is useful if players become trapped. Note: This does not allow players to teleport to any other claim except the one they are in. It can only be used if the player cannot build in claim. * Add permission griefdefender.user.claim.command.info.others.creation-date to control whether a player sees creation date in /claiminfo * Add permission griefdefender.user.claim.command.info.others.last-active to control whether a player sees last active date in /claiminfo * Add permission griefdefender.user.claim.command.info.others.claim-uuid to control whether a player sees claim uuid in /claiminfo * All flag definitions will now persist. * Refresh player option cache on permission change. * Show TP info in '/claiminfo' when player does not have TP permission. * (Sponge) Use 'tnt' as identifier instead of 'primedtnt' to match bukkit. * (Sponge) Use 'item_frame' as identifier instead of 'itemframe' to match bukkit. --- .../java/com/griefdefender/GDBootstrap.java | 2 + .../java/com/griefdefender/GDDebugData.java | 3 +- .../java/com/griefdefender/GDPlayerData.java | 17 +- .../griefdefender/GriefDefenderPlugin.java | 80 +++- .../com/griefdefender/cache/MessageCache.java | 6 + .../cache/PermissionHolderCache.java | 19 - .../java/com/griefdefender/claim/GDClaim.java | 12 + .../griefdefender/claim/GDClaimManager.java | 16 +- .../griefdefender/command/ClaimFlagBase.java | 56 ++- .../command/ClaimOptionBase.java | 2 +- .../CommandAdjustBonusClaimBlocks.java | 15 +- .../CommandAdjustBonusClaimBlocksAll.java | 107 ++++++ .../command/CommandClaimAbandon.java | 10 +- .../command/CommandClaimAbandonAll.java | 3 +- .../command/CommandClaimInfo.java | 86 +++-- .../command/CommandClaimInvestigate.java | 210 +++++++++++ .../command/CommandClaimOption.java | 2 +- .../command/CommandClaimSell.java | 4 - .../command/CommandClaimTool.java | 56 +++ .../griefdefender/command/CommandHelper.java | 8 +- .../command/CommandRestoreNature.java | 2 +- .../configuration/EconomyDataConfig.java | 4 - .../configuration/MessageStorage.java | 5 + .../configuration/OptionStorage.java | 2 +- .../configuration/category/ClaimCategory.java | 4 + .../CustomFlagGroupDefinitionCategory.java | 26 +- .../category/DynmapCategory.java | 18 + .../category/DynmapOwnerStyleCategory.java | 25 ++ .../configuration/category/PvpCategory.java | 3 + .../event/GDCauseStackManager.java | 3 + .../listener/BlockEventHandler.java | 26 +- .../listener/CommonBlockEventHandler.java | 14 +- .../listener/CommonEntityEventHandler.java | 13 +- .../listener/EntityEventHandler.java | 10 +- .../listener/LuckPermsEventHandler.java | 15 + .../listener/PlayerEventHandler.java | 98 ++--- .../migrator/GriefPreventionMigrator.java | 83 ++++- .../permission/GDPermissionManager.java | 129 +++++-- .../permission/GDPermissions.java | 12 +- .../permission/flag/FlagContexts.java | 2 + .../provider/DynmapProvider.java | 46 ++- .../provider/LuckPermsProvider.java | 351 ++++++++++++----- .../provider/PermissionProvider.java | 28 ++ .../provider/SlimefunProvider.java | 95 +++++ .../permissionsex/PermissionsExProvider.java | 21 ++ .../FlagDefinitionRegistryModule.java | 212 ++++++++--- .../griefdefender/storage/BaseStorage.java | 11 +- .../com/griefdefender/task/RentApplyTask.java | 156 ++++---- .../com/griefdefender/util/EconomyUtil.java | 7 +- .../griefdefender/util/PermissionUtil.java | 65 +++- .../com/griefdefender/util/PlayerUtil.java | 50 +++ .../java/com/griefdefender/util/SignUtil.java | 4 +- bukkit/src/main/resources/1.12.2.json | 6 +- bukkit/src/main/resources/1.13.2.json | 6 +- bukkit/src/main/resources/1.14.2.json | 6 +- bukkit/src/main/resources/1.14.3.json | 6 +- bukkit/src/main/resources/1.14.4.json | 6 +- bukkit/src/main/resources/1.15.2.json | 6 +- bukkit/src/main/resources/1.15.json | 6 +- bukkit/src/main/resources/1.16.1.json | 6 +- bukkit/src/main/resources/1.16.2.json | 264 +++++++++++++ bukkit/src/main/resources/1.8.8.json | 6 +- bukkit/src/main/resources/plugin.yml | 2 +- .../src/main/resources/assets/lang/de_DE.conf | 7 + .../src/main/resources/assets/lang/en_US.conf | 7 + .../src/main/resources/assets/lang/es_ES.conf | 7 + .../src/main/resources/assets/lang/fr_FR.conf | 7 + .../src/main/resources/assets/lang/pl_PL.conf | 7 + .../src/main/resources/assets/lang/ru_RU.conf | 7 + gradle.properties | 6 +- .../java/com/griefdefender/GDDebugData.java | 3 +- .../java/com/griefdefender/GDPlayerData.java | 17 +- .../griefdefender/GriefDefenderPlugin.java | 63 +++- .../com/griefdefender/cache/MessageCache.java | 6 + .../cache/PermissionHolderCache.java | 17 - .../java/com/griefdefender/claim/GDClaim.java | 12 + .../griefdefender/claim/GDClaimManager.java | 16 +- .../griefdefender/command/ClaimFlagBase.java | 55 ++- .../command/ClaimOptionBase.java | 2 +- .../CommandAdjustBonusClaimBlocks.java | 13 +- .../CommandAdjustBonusClaimBlocksAll.java | 106 ++++++ .../command/CommandClaimAbandon.java | 10 +- .../command/CommandClaimAbandonAll.java | 3 +- .../command/CommandClaimInfo.java | 86 +++-- .../command/CommandClaimInvestigate.java | 207 ++++++++++ .../command/CommandClaimOption.java | 2 +- .../command/CommandClaimSell.java | 4 - .../command/CommandClaimTool.java | 56 +++ .../griefdefender/command/CommandHelper.java | 8 +- .../configuration/EconomyDataConfig.java | 4 - .../configuration/MessageStorage.java | 5 + .../configuration/OptionStorage.java | 2 +- .../configuration/category/ClaimCategory.java | 2 + .../CustomFlagGroupDefinitionCategory.java | 26 +- .../category/DynmapCategory.java | 18 + .../category/DynmapOwnerStyleCategory.java | 25 ++ .../configuration/category/PvpCategory.java | 3 + .../listener/BlockEventHandler.java | 10 +- .../listener/CommonEntityEventHandler.java | 41 +- .../listener/EntityEventHandler.java | 6 +- .../listener/LuckPermsEventHandler.java | 15 + .../listener/PlayerEventHandler.java | 66 +--- .../migrator/GPBukkitMigrator.java | 83 ++++- .../permission/GDPermissionManager.java | 119 ++++-- .../permission/GDPermissions.java | 12 +- .../permission/flag/FlagContexts.java | 3 + .../provider/DynmapProvider.java | 46 ++- .../provider/LuckPermsProvider.java | 352 +++++++++++++----- .../provider/PermissionProvider.java | 28 ++ .../FlagDefinitionRegistryModule.java | 212 ++++++++--- .../griefdefender/storage/BaseStorage.java | 10 +- .../com/griefdefender/task/RentApplyTask.java | 156 ++++---- .../com/griefdefender/util/EconomyUtil.java | 9 +- .../griefdefender/util/PermissionUtil.java | 65 +++- .../com/griefdefender/util/PlayerUtil.java | 51 +++ .../java/com/griefdefender/util/SignUtil.java | 2 +- 116 files changed, 3577 insertions(+), 1102 deletions(-) create mode 100644 bukkit/src/main/java/com/griefdefender/command/CommandAdjustBonusClaimBlocksAll.java create mode 100644 bukkit/src/main/java/com/griefdefender/command/CommandClaimInvestigate.java create mode 100644 bukkit/src/main/java/com/griefdefender/command/CommandClaimTool.java create mode 100644 bukkit/src/main/java/com/griefdefender/provider/SlimefunProvider.java create mode 100644 bukkit/src/main/resources/1.16.2.json create mode 100644 sponge/src/main/java/com/griefdefender/command/CommandAdjustBonusClaimBlocksAll.java create mode 100644 sponge/src/main/java/com/griefdefender/command/CommandClaimInvestigate.java create mode 100644 sponge/src/main/java/com/griefdefender/command/CommandClaimTool.java diff --git a/bukkit/src/main/java/com/griefdefender/GDBootstrap.java b/bukkit/src/main/java/com/griefdefender/GDBootstrap.java index f8cd71a..be87707 100644 --- a/bukkit/src/main/java/com/griefdefender/GDBootstrap.java +++ b/bukkit/src/main/java/com/griefdefender/GDBootstrap.java @@ -95,6 +95,8 @@ public void onEnable() { bukkitJsonVersion = "1.15"; } else if (Bukkit.getVersion().contains("1.16.1")) { bukkitJsonVersion = "1.16.1"; + } else if (Bukkit.getVersion().contains("1.16.2")) { + bukkitJsonVersion = "1.16.2"; } else { this.getLogger().severe("Detected unsupported version '" + Bukkit.getVersion() + "'. GriefDefender only supports 1.8.8, 1.12.2, 1.13.2, 1.14.x, 1.15.0-1.15.2, 1.16.1. GriefDefender will NOT load."); return; diff --git a/bukkit/src/main/java/com/griefdefender/GDDebugData.java b/bukkit/src/main/java/com/griefdefender/GDDebugData.java index d3cb948..9acadd7 100644 --- a/bukkit/src/main/java/com/griefdefender/GDDebugData.java +++ b/bukkit/src/main/java/com/griefdefender/GDDebugData.java @@ -185,6 +185,7 @@ public void pasteRecords() { final String SOURCE = PlainComponentSerializer.INSTANCE.serialize(MessageCache.getInstance().LABEL_SOURCE); final String TARGET = PlainComponentSerializer.INSTANCE.serialize(MessageCache.getInstance().LABEL_TARGET); final String USER = PlainComponentSerializer.INSTANCE.serialize(MessageCache.getInstance().LABEL_USER); + final String GROUP = PlainComponentSerializer.INSTANCE.serialize(MessageCache.getInstance().LABEL_GROUP); final String CONTEXT = PlainComponentSerializer.INSTANCE.serialize(MessageCache.getInstance().LABEL_CONTEXT); final String RESULT = PlainComponentSerializer.INSTANCE.serialize(MessageCache.getInstance().LABEL_RESULT); debugOutput.add("| " + RECORD_END + " | " + DATE_FORMAT.format(new Date(endTime)) + "|"); @@ -192,7 +193,7 @@ public void pasteRecords() { debugOutput.add("| " + TIME_ELAPSED + " | " + elapsed + " seconds" + "|"); debugOutput.add(""); debugOutput.add("### " + OUTPUT) ; - debugOutput.add("| " + FLAG + " | " + TRUST + " | " + SOURCE + " | " + TARGET + " | " + LOCATION + " | " + USER + " | " + CONTEXT + " | " + RESULT + " |"); + debugOutput.add("| " + FLAG + " | " + TRUST + " | " + SOURCE + " | " + TARGET + " | " + LOCATION + " | " + USER + "/" + GROUP + " | " + CONTEXT + " | " + RESULT + " |"); debugOutput.add("|------|-------|--------|--------|----------|------|----------|--------|"); debugOutput.addAll(this.records); diff --git a/bukkit/src/main/java/com/griefdefender/GDPlayerData.java b/bukkit/src/main/java/com/griefdefender/GDPlayerData.java index 03530ab..e87ac18 100644 --- a/bukkit/src/main/java/com/griefdefender/GDPlayerData.java +++ b/bukkit/src/main/java/com/griefdefender/GDPlayerData.java @@ -91,6 +91,7 @@ public class GDPlayerData implements PlayerData { public Location lastValidInspectLocation; public Location lastNonAirInspectLocation; public boolean claimMode = false; + public boolean claimTool = true; public ShovelType shovelMode = ShovelTypes.BASIC; public GDClaim claimResizing; @@ -178,7 +179,7 @@ public class GDPlayerData implements PlayerData { public boolean dataInitialized = false; public boolean showNoClaimsFoundMessage = true; public boolean useRestoreSchematic = false; - private boolean checkedDimensionHeight = false; + private final int worldMaxHeight; public GDPlayerData(UUID worldUniqueId, String worldName, UUID playerUniqueId, Set claims) { this.worldUniqueId = worldUniqueId; @@ -199,6 +200,7 @@ public GDPlayerData(UUID worldUniqueId, String worldName, UUID playerUniqueId, S contexts.add(new Context("server", PermissionUtil.getInstance().getServerName())); } } + this.worldMaxHeight = GriefDefenderPlugin.getInstance().dataStore.getClaimWorldManager(this.worldUniqueId).getWorldMaxHeight(); this.optionContexts = contexts; this.refreshPlayerOptions(); } @@ -238,7 +240,6 @@ public void refreshPlayerOptions() { this.userOptionBypassPlayerGamemode = PermissionUtil.getInstance().getPermissionValue(subject, GDPermissions.BYPASS_OPTION + "." + Options.PLAYER_GAMEMODE.getName().toLowerCase(), activeContexts).asBoolean(); this.playerID = subject.getUniqueId(); this.dataInitialized = true; - this.checkedDimensionHeight = false; }); } @@ -699,15 +700,8 @@ public int getMinClaimZ(ClaimType type) { @Override public int getMaxClaimLevel() { int maxClaimLevel = GDPermissionManager.getInstance().getInternalOptionValue(TypeToken.of(Integer.class), this.getSubject(), Options.MAX_LEVEL); - if (!this.checkedDimensionHeight) { - final World world = Bukkit.getServer().getWorld(this.worldUniqueId); - if (world != null) { - final int buildHeight = world.getMaxHeight() - 1; - if (buildHeight < maxClaimLevel) { - maxClaimLevel = buildHeight; - } - } - this.checkedDimensionHeight = true; + if (this.worldMaxHeight > -1 && this.worldMaxHeight < maxClaimLevel) { + maxClaimLevel = this.worldMaxHeight; } return maxClaimLevel; } @@ -876,6 +870,7 @@ public void onDisconnect() { this.createBlockVisualRevertRunnables.clear(); this.queuedVisuals.clear(); this.claimMode = false; + this.claimTool = true; this.debugClaimPermissions = false; this.ignoreClaims = false; this.lastShovelLocation = null; diff --git a/bukkit/src/main/java/com/griefdefender/GriefDefenderPlugin.java b/bukkit/src/main/java/com/griefdefender/GriefDefenderPlugin.java index 21257d7..39643d8 100644 --- a/bukkit/src/main/java/com/griefdefender/GriefDefenderPlugin.java +++ b/bukkit/src/main/java/com/griefdefender/GriefDefenderPlugin.java @@ -81,6 +81,7 @@ import com.griefdefender.claim.GDClaim; import com.griefdefender.claim.GDClaimManager; import com.griefdefender.command.CommandAdjustBonusClaimBlocks; +import com.griefdefender.command.CommandAdjustBonusClaimBlocksAll; import com.griefdefender.command.CommandCallback; import com.griefdefender.command.CommandClaimAbandon; import com.griefdefender.command.CommandClaimAbandonAll; @@ -111,6 +112,7 @@ import com.griefdefender.command.CommandClaimIgnore; import com.griefdefender.command.CommandClaimInfo; import com.griefdefender.command.CommandClaimInherit; +import com.griefdefender.command.CommandClaimInvestigate; import com.griefdefender.command.CommandClaimList; import com.griefdefender.command.CommandClaimMode; import com.griefdefender.command.CommandClaimName; @@ -128,6 +130,7 @@ import com.griefdefender.command.CommandClaimSpawn; import com.griefdefender.command.CommandClaimSubdivision; import com.griefdefender.command.CommandClaimTax; +import com.griefdefender.command.CommandClaimTool; import com.griefdefender.command.CommandClaimTown; import com.griefdefender.command.CommandClaimTransfer; import com.griefdefender.command.CommandClaimUnban; @@ -204,6 +207,7 @@ import com.griefdefender.provider.LuckPermsProvider; import com.griefdefender.provider.PermissionProvider; import com.griefdefender.provider.PlaceholderProvider; +import com.griefdefender.provider.SlimefunProvider; import com.griefdefender.provider.VaultProvider; import com.griefdefender.registry.ChatTypeRegistryModule; import com.griefdefender.registry.ClaimTypeRegistryModule; @@ -273,7 +277,18 @@ public class GriefDefenderPlugin { public static final String PUBLIC_NAME = "[GDPublic]"; public static final String WORLD_USER_NAME = "[GDWorld]"; - public static GDPermissionHolder DEFAULT_HOLDER; + public static final String DEFAULT_GROUP_NAME = "default"; + public static final String GD_CLAIM_GROUP_NAME = "griefdefender_claim"; + public static final String GD_DEFAULT_GROUP_NAME = "griefdefender_default"; + public static final String GD_DEFINITION_GROUP_NAME = "griefdefender_definition"; + public static final String GD_OPTION_GROUP_NAME = "griefdefender_option"; + public static final String GD_OVERRIDE_GROUP_NAME = "griefdefender_override"; + public static GDPermissionGroup DEFAULT_HOLDER; + public static GDPermissionGroup GD_DEFAULT_HOLDER; + public static GDPermissionGroup GD_CLAIM_HOLDER; + public static GDPermissionGroup GD_DEFINITION_HOLDER; + public static GDPermissionGroup GD_OPTION_HOLDER; + public static GDPermissionGroup GD_OVERRIDE_HOLDER; private PaperCommandManager commandManager; private static TimingManager timingManager; @@ -285,14 +300,16 @@ public class GriefDefenderPlugin { private WorldGuardProvider worldGuardProvider; private VaultProvider vaultProvider; private PermissionProvider permissionProvider; + private SlimefunProvider slimefunProvider; private List runningTasks = new ArrayList<>(); public Executor executor; public GDBlockType createVisualBlock; - public GDItemType modificationTool; - public GDItemType investigationTool; + public String modificationTool; + public String investigationTool; + public boolean isCustomItemsInstalled = false; public static boolean debugLogging = false; public static boolean debugActive = false; @@ -315,15 +332,16 @@ public Path getConfigPath() { public static void addEventLogEntry(Event event, Claim claim, Location location, String sourceId, String targetId, GDPermissionHolder permissionSubject, String permission, String trust, Tristate result, Set contexts) { final String eventName = event.getClass().getSimpleName().replace('$', '.').replace(".Impl", ""); final String eventLocation = location == null ? "none" : VecHelper.toVector3i(location).toString(); + final GDPermissionHolder debugHolder = PermissionUtil.getInstance().getGDPermissionHolder(permissionSubject, contexts); for (GDDebugData debugEntry : GriefDefenderPlugin.getInstance().getDebugUserMap().values()) { final CommandSender debugSource = debugEntry.getSource(); final GDPermissionUser debugUser = debugEntry.getUser(); if (debugUser != null) { - if (permissionSubject == null) { + if (debugHolder == null) { continue; } // Check event source user - if (!permissionSubject.getIdentifier().equals(debugUser.getUniqueId().toString())) { + if (!debugHolder.getIdentifier().equals(debugUser.getUniqueId().toString())) { continue; } } else if (debugEntry.getClaimUniqueId() != null) { @@ -358,9 +376,9 @@ public static void addEventLogEntry(Event event, Claim claim, Location location, } } - String messageUser = permissionSubject.getFriendlyName(); - if (permissionSubject instanceof GDPermissionUser) { - messageUser = ((GDPermissionUser) permissionSubject).getName(); + String messageUser = debugHolder.getFriendlyName().replaceAll("griefdefender_", ""); + if (debugHolder instanceof GDPermissionUser) { + messageUser = ((GDPermissionUser) debugHolder).getName(); } // record @@ -501,7 +519,28 @@ public void onEnable(boolean reload) { } instance = this; timingManager = TimingManager.of(GDBootstrap.getInstance()); - DEFAULT_HOLDER = new GDPermissionGroup("default"); + DEFAULT_HOLDER = new GDPermissionGroup(DEFAULT_GROUP_NAME); + GD_DEFAULT_HOLDER = new GDPermissionGroup(GD_DEFAULT_GROUP_NAME); + GD_CLAIM_HOLDER = new GDPermissionGroup(GD_CLAIM_GROUP_NAME); + GD_DEFINITION_HOLDER = new GDPermissionGroup(GD_DEFINITION_GROUP_NAME); + GD_OPTION_HOLDER = new GDPermissionGroup(GD_OPTION_GROUP_NAME); + GD_OVERRIDE_HOLDER = new GDPermissionGroup(GD_OVERRIDE_GROUP_NAME); + if (!this.permissionProvider.hasGroupSubject(GD_OPTION_GROUP_NAME)) { + this.permissionProvider.createDefaultGroup(GD_OPTION_GROUP_NAME); + } + if (!this.permissionProvider.hasGroupSubject(GD_CLAIM_GROUP_NAME)) { + this.permissionProvider.createDefaultGroup(GD_CLAIM_GROUP_NAME); + } + if (!this.permissionProvider.hasGroupSubject(GD_OVERRIDE_GROUP_NAME)) { + this.permissionProvider.createDefaultGroup(GD_OVERRIDE_GROUP_NAME); + } + if (!this.permissionProvider.hasGroupSubject(GD_DEFAULT_GROUP_NAME)) { + this.permissionProvider.createDefaultGroup(GD_DEFAULT_GROUP_NAME); + } + if (!this.permissionProvider.hasGroupSubject(GD_DEFINITION_GROUP_NAME)) { + this.permissionProvider.createDefaultGroup(GD_DEFINITION_GROUP_NAME); + } + this.permissionProvider.refreshCachedData(DEFAULT_HOLDER); PUBLIC_USER = new GDPermissionUser(PUBLIC_UUID, PUBLIC_NAME); WORLD_USER = new GDPermissionUser(WORLD_USER_UUID, WORLD_USER_NAME); Guice.createInjector(Stage.PRODUCTION, new GriefDefenderImplModule()); @@ -528,8 +567,6 @@ public void onEnable(boolean reload) { this.loadConfig(); - this.executor = Executors.newFixedThreadPool(GriefDefenderPlugin.getGlobalConfig().getConfig().thread.numExecutorThreads); - if (Bukkit.getPluginManager().getPlugin("Vault") != null) { this.vaultProvider = new VaultProvider(); this.getLogger().info("Detected Vault. Checking for compatible economy plugin..."); @@ -567,6 +604,12 @@ public void onEnable(boolean reload) { new PlaceholderProvider(); this.getLogger().info("GriefDefender PlaceholderAPI expansion enabled!"); } + if (Bukkit.getPluginManager().getPlugin("CustomItems") != null) { + this.isCustomItemsInstalled = true; + } + if (Bukkit.getPluginManager().getPlugin("Slimefun") != null) { + this.slimefunProvider = new SlimefunProvider(); + } if (getMajorMinecraftVersion() > 13) { this.tagProvider = new GDTagProvider(); @@ -702,6 +745,7 @@ public void registerBaseCommands() { manager.getCommandReplacements().addReplacement("griefdefender", "gd|griefdefender"); manager.registerCommand(new CommandAccessTrust()); manager.registerCommand(new CommandAdjustBonusClaimBlocks()); + manager.registerCommand(new CommandAdjustBonusClaimBlocksAll()); manager.registerCommand(new CommandCallback()); manager.registerCommand(new CommandClaimAbandon()); manager.registerCommand(new CommandClaimAbandonAll()); @@ -732,6 +776,7 @@ public void registerBaseCommands() { manager.registerCommand(new CommandClaimIgnore()); manager.registerCommand(new CommandClaimInfo()); manager.registerCommand(new CommandClaimInherit()); + manager.registerCommand(new CommandClaimInvestigate()); manager.registerCommand(new CommandClaimList()); manager.registerCommand(new CommandClaimMode()); manager.registerCommand(new CommandClaimName()); @@ -749,6 +794,7 @@ public void registerBaseCommands() { manager.registerCommand(new CommandClaimSpawn()); manager.registerCommand(new CommandClaimSubdivision()); manager.registerCommand(new CommandClaimTax()); + manager.registerCommand(new CommandClaimTool()); manager.registerCommand(new CommandClaimTown()); manager.registerCommand(new CommandClaimTransfer()); manager.registerCommand(new CommandClaimUnban()); @@ -1010,6 +1056,9 @@ public void loadConfig() { messageStorage = new MessageStorage(localePath); messageData = messageStorage.getConfig(); MessageCache.getInstance().loadCache(); + if (this.executor == null) { + this.executor = Executors.newFixedThreadPool(GriefDefenderPlugin.getGlobalConfig().getConfig().thread.numExecutorThreads); + } flagConfig = new FlagConfig(this.getConfigPath().resolve("flags.conf")); // FlagDefinition registry needs to init after config load FlagDefinitionRegistryModule.getInstance().registerDefaults(); @@ -1023,12 +1072,11 @@ public void loadConfig() { BaseStorage.globalConfig.save(); BaseStorage.USE_GLOBAL_PLAYER_STORAGE = !BaseStorage.globalConfig.getConfig().playerdata.useWorldPlayerData(); GDFlags.populateFlagStatus(); - PermissionHolderCache.getInstance().getOrCreatePermissionCache(GriefDefenderPlugin.DEFAULT_HOLDER).invalidateAll(); CLAIM_BLOCK_SYSTEM = BaseStorage.globalConfig.getConfig().playerdata.claimBlockSystem; final GDBlockType defaultCreateVisualBlock = BlockTypeRegistryModule.getInstance().getById("minecraft:diamond_block").orElse(null); this.createVisualBlock = BlockTypeRegistryModule.getInstance().getById(BaseStorage.globalConfig.getConfig().visual.claimCreateStartBlock).orElse(defaultCreateVisualBlock); - this.modificationTool = ItemTypeRegistryModule.getInstance().getById(BaseStorage.globalConfig.getConfig().claim.modificationTool).orElse(null); - this.investigationTool = ItemTypeRegistryModule.getInstance().getById(BaseStorage.globalConfig.getConfig().claim.investigationTool).orElse(null); + this.modificationTool = BaseStorage.globalConfig.getConfig().claim.modificationTool; + this.investigationTool = BaseStorage.globalConfig.getConfig().claim.investigationTool; if (this.dataStore != null) { for (World world : Bukkit.getServer().getWorlds()) { final String dimType = world.getEnvironment().name().toLowerCase(); @@ -1277,6 +1325,10 @@ public PermissionProvider getPermissionProvider() { return this.permissionProvider; } + public SlimefunProvider getSlimefunProvider() { + return this.slimefunProvider; + } + public static int getMajorMinecraftVersion() { final String version = Bukkit.getVersion(); if (version.contains("1.8.8")) { diff --git a/bukkit/src/main/java/com/griefdefender/cache/MessageCache.java b/bukkit/src/main/java/com/griefdefender/cache/MessageCache.java index afe0352..ae4c93a 100644 --- a/bukkit/src/main/java/com/griefdefender/cache/MessageCache.java +++ b/bukkit/src/main/java/com/griefdefender/cache/MessageCache.java @@ -112,6 +112,7 @@ public static MessageCache getInstance() { public Component CLAIMLIST_UI_RETURN_CLAIMSLIST; public Component CLAIMLIST_UI_TITLE; public Component CLAIMLIST_UI_TITLE_CHILD_CLAIMS; + public Component CLAIMTOOL_NOT_ENABLED; public Component COMMAND_CLAIMBUY_TITLE; public Component COMMAND_CLAIMCLEAR_UUID_DENY; public Component COMMAND_CLAIMFLAGDEBUG_DISABLED; @@ -122,6 +123,8 @@ public static MessageCache getInstance() { public Component COMMAND_CLAIMINHERIT_ENABLED; public Component COMMAND_CLAIMMODE_DISABLED; public Component COMMAND_CLAIMMODE_ENABLED; + public Component COMMAND_CLAIMTOOL_DISABLED; + public Component COMMAND_CLAIMTOOL_ENABLED; public Component COMMAND_CUBOID_DISABLED; public Component COMMAND_CUBOID_ENABLED; public Component COMMAND_INHERIT_ONLY_CHILD; @@ -574,6 +577,7 @@ public void loadCache() { CLAIMLIST_UI_RETURN_CLAIMSLIST = MessageStorage.MESSAGE_DATA.getMessage("claimlist-ui-return-claimlist"); CLAIMLIST_UI_TITLE = MessageStorage.MESSAGE_DATA.getMessage("claimlist-ui-title"); CLAIMLIST_UI_TITLE_CHILD_CLAIMS = MessageStorage.MESSAGE_DATA.getMessage("claimlist-ui-title-child-claims"); + CLAIMTOOL_NOT_ENABLED = MessageStorage.MESSAGE_DATA.getMessage("claimtool-not-enabled"); COMMAND_CLAIMBUY_TITLE = MessageStorage.MESSAGE_DATA.getMessage("command-claimbuy-title"); COMMAND_CLAIMCLEAR_UUID_DENY = MessageStorage.MESSAGE_DATA.getMessage("command-claimclear-uuid-deny"); COMMAND_CLAIMFLAGDEBUG_DISABLED = MessageStorage.MESSAGE_DATA.getMessage("command-claimflagdebug-disabled"); @@ -584,6 +588,8 @@ public void loadCache() { COMMAND_CLAIMINHERIT_ENABLED = MessageStorage.MESSAGE_DATA.getMessage("command-claiminherit-enabled"); COMMAND_CLAIMMODE_DISABLED = MessageStorage.MESSAGE_DATA.getMessage("command-claimmode-disabled"); COMMAND_CLAIMMODE_ENABLED = MessageStorage.MESSAGE_DATA.getMessage("command-claimmode-enabled"); + COMMAND_CLAIMTOOL_DISABLED = MessageStorage.MESSAGE_DATA.getMessage("command-claimtool-disabled"); + COMMAND_CLAIMTOOL_ENABLED = MessageStorage.MESSAGE_DATA.getMessage("command-claimtool-enabled"); COMMAND_CUBOID_DISABLED = MessageStorage.MESSAGE_DATA.getMessage("command-cuboid-disabled"); COMMAND_CUBOID_ENABLED = MessageStorage.MESSAGE_DATA.getMessage("command-cuboid-enabled"); COMMAND_INHERIT_ONLY_CHILD = MessageStorage.MESSAGE_DATA.getMessage("command-inherit-only-child"); diff --git a/bukkit/src/main/java/com/griefdefender/cache/PermissionHolderCache.java b/bukkit/src/main/java/com/griefdefender/cache/PermissionHolderCache.java index cf0a610..0e05345 100644 --- a/bukkit/src/main/java/com/griefdefender/cache/PermissionHolderCache.java +++ b/bukkit/src/main/java/com/griefdefender/cache/PermissionHolderCache.java @@ -27,17 +27,14 @@ import com.github.benmanes.caffeine.cache.Cache; import com.github.benmanes.caffeine.cache.Caffeine; import com.griefdefender.GriefDefenderPlugin; -import com.griefdefender.api.Tristate; import com.griefdefender.permission.GDPermissionGroup; import com.griefdefender.permission.GDPermissionHolder; import com.griefdefender.permission.GDPermissionUser; import com.griefdefender.util.PermissionUtil; -import org.bukkit.Bukkit; import org.bukkit.OfflinePlayer; import java.util.UUID; -import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.TimeUnit; public class PermissionHolderCache { @@ -47,7 +44,6 @@ public class PermissionHolderCache { .build(); private final Cache groupCache = Caffeine.newBuilder().expireAfterAccess(10, TimeUnit.MINUTES) .build(); - private final ConcurrentHashMap> permissionCache = new ConcurrentHashMap<>(); public GDPermissionUser getOrCreateUser(OfflinePlayer user) { if (user == null) { @@ -120,21 +116,6 @@ public GDPermissionHolder getOrCreateHolder(String identifier) { return this.getOrCreateUser(uuid); } - public Cache getOrCreatePermissionCache(GDPermissionHolder holder) { - Cache cache = this.permissionCache.get(holder); - if (cache == null) { - cache = Caffeine.newBuilder().expireAfterAccess(10, TimeUnit.MINUTES).build(); - this.permissionCache.put(holder, cache); - } - return cache; - } - - public void invalidateAllPermissionCache() { - for (Cache cache : this.permissionCache.values()) { - cache.invalidateAll(); - } - } - static { instance = new PermissionHolderCache(); } diff --git a/bukkit/src/main/java/com/griefdefender/claim/GDClaim.java b/bukkit/src/main/java/com/griefdefender/claim/GDClaim.java index af949dd..7878f1a 100644 --- a/bukkit/src/main/java/com/griefdefender/claim/GDClaim.java +++ b/bukkit/src/main/java/com/griefdefender/claim/GDClaim.java @@ -1115,6 +1115,18 @@ public ClaimResult checkArea(boolean resize) { continue; } + // validate this claim exists + boolean claimExists = false; + for (Claim claim : this.worldClaimManager.getWorldClaims()) { + if (claim.getUniqueId().equals(chunkClaim.getUniqueId())) { + claimExists = true; + break; + } + } + if (!claimExists) { + //GriefDefenderPlugin.getInstance().getLogger().warning("Detected Ghost chunk claim with the following data [UUID: " + chunkClaim.getUniqueId() + ", Owner: " + chunkClaim.getOwnerName() + ", Type: " + chunkClaim.getType().getName() + "]. Ignoring..."); + continue; + } // First check if new claim is crossing another if (this.isBandingAcross(gpChunkClaim) || gpChunkClaim.isBandingAcross(this)) { return new GDClaimResult(gpChunkClaim, ClaimResultType.OVERLAPPING_CLAIM); diff --git a/bukkit/src/main/java/com/griefdefender/claim/GDClaimManager.java b/bukkit/src/main/java/com/griefdefender/claim/GDClaimManager.java index d3781de..0f8b0ac 100644 --- a/bukkit/src/main/java/com/griefdefender/claim/GDClaimManager.java +++ b/bukkit/src/main/java/com/griefdefender/claim/GDClaimManager.java @@ -51,7 +51,6 @@ import com.griefdefender.util.BlockUtil; import com.griefdefender.util.Direction; -import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap; import net.kyori.text.Component; import net.kyori.text.TextComponent; import net.kyori.text.serializer.plain.PlainComponentSerializer; @@ -69,6 +68,7 @@ import java.nio.file.Path; import java.util.ArrayList; import java.util.Collections; +import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; @@ -81,6 +81,7 @@ public class GDClaimManager implements ClaimManager { private static final BaseStorage DATASTORE = GriefDefenderPlugin.getInstance().dataStore; private UUID worldUniqueId; private String worldName; + private final int worldMaxHeight; // Player UUID -> player data private Map playerDataList = Maps.newHashMap(); @@ -89,10 +90,10 @@ public class GDClaimManager implements ClaimManager { // Claim UUID -> Claim private Map claimUniqueIdMap = Maps.newHashMap(); // String -> Claim - private Map> chunksToClaimsMap = new Long2ObjectOpenHashMap<>(4096); + private Map> chunksToClaimsMap = new HashMap<>(); // Entity Index public PlayerIndexStorage playerIndexStorage; - private Map chunksToGDChunks = new Long2ObjectOpenHashMap<>(4096); + private Map chunksToGDChunks = new HashMap<>(); private GDClaim theWildernessClaim; @@ -100,6 +101,11 @@ public GDClaimManager(World world) { this.worldUniqueId = world.getUID(); this.worldName = world.getName(); this.playerIndexStorage = new PlayerIndexStorage(world); + if (GriefDefenderPlugin.getActiveConfig(this.worldUniqueId).getConfig().claim.restrictWorldMaxHeight) { + this.worldMaxHeight = world.getMaxHeight() - 1; + } else { + this.worldMaxHeight = -1; + } } public GDPlayerData getOrCreatePlayerData(UUID playerUniqueId) { @@ -652,6 +658,10 @@ public UUID getWorldId() { return this.worldUniqueId; } + public int getWorldMaxHeight() { + return this.worldMaxHeight; + } + public GDChunk getChunk(Chunk chunk) { return this.getChunk(chunk, true); } diff --git a/bukkit/src/main/java/com/griefdefender/command/ClaimFlagBase.java b/bukkit/src/main/java/com/griefdefender/command/ClaimFlagBase.java index 701f965..4062262 100644 --- a/bukkit/src/main/java/com/griefdefender/command/ClaimFlagBase.java +++ b/bukkit/src/main/java/com/griefdefender/command/ClaimFlagBase.java @@ -42,6 +42,7 @@ import com.griefdefender.api.permission.ResultTypes; import com.griefdefender.api.permission.flag.Flag; import com.griefdefender.api.permission.flag.FlagData; +import com.griefdefender.api.permission.flag.Flags; import com.griefdefender.cache.MessageCache; import com.griefdefender.cache.PermissionHolderCache; import com.griefdefender.claim.GDClaim; @@ -426,7 +427,7 @@ protected void showFlagPermissions(GDPermissionUser src, GDClaim claim, MenuType overrideContexts.add(claim.getOverrideClaimContext()); Map filteredContextMap = new HashMap<>(); - for (Map.Entry, Map> mapEntry : PermissionUtil.getInstance().getTransientPermissions(this.subject).entrySet()) { + for (Map.Entry, Map> mapEntry : PermissionUtil.getInstance().getTransientPermissions(GriefDefenderPlugin.GD_DEFAULT_HOLDER).entrySet()) { final Set contextSet = mapEntry.getKey(); if (contextSet.contains(claim.getDefaultTypeContext())) { this.addFilteredContexts(filteredContextMap, contextSet, MenuType.DEFAULT, mapEntry.getValue()); @@ -436,7 +437,7 @@ protected void showFlagPermissions(GDPermissionUser src, GDClaim claim, MenuType } final List inheritParents = claim.getInheritedParents(); - for (Map.Entry, Map> mapEntry : PermissionUtil.getInstance().getPermanentPermissions(this.subject).entrySet()) { + for (Map.Entry, Map> mapEntry : PermissionUtil.getInstance().getAllPermanentPermissions().entrySet()) { final Set contextSet = mapEntry.getKey(); if (contextSet.contains(claim.getDefaultTypeContext())) { this.addFilteredContexts(filteredContextMap, contextSet, MenuType.DEFAULT, mapEntry.getValue()); @@ -627,17 +628,21 @@ private Component getCustomClickableText(GDPermissionUser src, GDClaim claim, GD boolean hasHover = false; TextComponent.Builder hoverBuilder = TextComponent.builder(); final Player player = src.getOnlinePlayer(); + final boolean canIgnoreClaim = src.getInternalPlayerData().canIgnoreClaim(claim); boolean hasEditPermission = true; - Component denyReason = claim.allowEdit(player); - if (denyReason != null) { - hasEditPermission = false; - hasHover = true; + Component denyReason = null; + if (!canIgnoreClaim) { + denyReason = claim.allowEdit(player); + if (denyReason != null) { + hasEditPermission = false; + hasHover = true; + } } final boolean isAdminGroup = GriefDefenderPlugin.getFlagConfig().getConfig().customFlags.getGroups().get(flagGroup).isAdminGroup(); final String permission = isAdminGroup ? GDPermissions.FLAG_CUSTOM_ADMIN_BASE : GDPermissions.FLAG_CUSTOM_USER_BASE; // check flag perm - if (!player.hasPermission(permission + "." + flagGroup + "." + customFlag.getName())) { + if (!canIgnoreClaim && !player.hasPermission(permission + "." + flagGroup + "." + customFlag.getName())) { hoverBuilder.append(MessageCache.getInstance().PERMISSION_FLAG_USE).append("\n"); hasEditPermission = false; hasHover = true; @@ -654,8 +659,7 @@ private Component getCustomClickableText(GDPermissionUser src, GDClaim claim, GD hasOverride = true; hasEditPermission = false; } else if (activeData.getType() == GDActiveFlagData.Type.OWNER_OVERRIDE_PARENT_INHERIT || activeData.getType() == GDActiveFlagData.Type.CLAIM_PARENT_INHERIT) { - if (claim.allowEdit(src) != null) { - hasEditPermission = false; + if (!hasEditPermission) { parentInheritUniqueId = activeData.getInheritParentUniqueId(); parentInheritFriendlyType = activeData.getInheritParentFriendlyType(); } @@ -913,14 +917,14 @@ public GDActiveFlagData getActiveDefinitionResult(GDClaim claim, GDFlagDefinitio if (!claim.isWilderness()) { permissionContexts.add(ClaimContexts.GLOBAL_DEFAULT_CONTEXT); permissionContexts.add(ClaimContexts.USER_DEFAULT_CONTEXT); - result = PermissionUtil.getInstance().getPermissionValue(claim, (GDPermissionHolder) flagDefinition.getSubject(), flagData.getFlag().getPermission(), permissionContexts, PermissionDataType.ALL); + result = PermissionUtil.getInstance().getPermissionValue(claim, (GDPermissionHolder) flagDefinition.getSubject(), flagData.getFlag().getPermission(), permissionContexts, PermissionDataType.PERSISTENT); if (result != Tristate.UNDEFINED) { return new GDActiveFlagData(flagDefinition, flagData, result, permissionContexts, GDActiveFlagData.Type.DEFAULT); } permissionContexts.remove(ClaimContexts.USER_DEFAULT_CONTEXT); } else { permissionContexts.add(ClaimContexts.GLOBAL_DEFAULT_CONTEXT); - result = PermissionUtil.getInstance().getPermissionValue(claim, (GDPermissionHolder) flagDefinition.getSubject(), flagData.getFlag().getPermission(), permissionContexts, PermissionDataType.ALL); + result = PermissionUtil.getInstance().getPermissionValue(claim, (GDPermissionHolder) flagDefinition.getSubject(), flagData.getFlag().getPermission(), permissionContexts, PermissionDataType.PERSISTENT); if (result != Tristate.UNDEFINED) { return new GDActiveFlagData(flagDefinition, flagData, result, permissionContexts, GDActiveFlagData.Type.DEFAULT); } @@ -928,6 +932,7 @@ public GDActiveFlagData getActiveDefinitionResult(GDClaim claim, GDFlagDefinitio permissionContexts.remove(ClaimContexts.GLOBAL_DEFAULT_CONTEXT); permissionContexts.add(claim.getDefaultTypeContext()); + permissionContexts.add(ClaimContexts.USER_DEFAULT_CONTEXT); result = PermissionUtil.getInstance().getPermissionValue(claim, (GDPermissionHolder) flagDefinition.getSubject(), flagData.getFlag().getPermission(), permissionContexts, PermissionDataType.TRANSIENT); if (result != Tristate.UNDEFINED) { return new GDActiveFlagData(flagDefinition, flagData, result, permissionContexts, GDActiveFlagData.Type.DEFAULT); @@ -1084,11 +1089,11 @@ public int compare(Context o1, Context o2) { return textBuilder.build(); } - private Consumer createCustomFlagConsumer(GDPermissionUser src, GDClaim claim, GDFlagDefinition customFlag, Tristate currentValue, String flagGroup) { + private Consumer createCustomFlagConsumer(GDPermissionUser src, GDClaim claim, GDFlagDefinition flagDefinition, Tristate currentValue, String flagGroup) { final Player player = src.getOnlinePlayer(); return consumer -> { GDCauseStackManager.getInstance().pushCause(player); - Set definitionContexts = new HashSet<>(customFlag.getContexts()); + Set definitionContexts = new HashSet<>(flagDefinition.getContexts()); boolean addClaimContext = false; boolean addClaimOverrideContext = false; final Iterator iterator = definitionContexts.iterator(); @@ -1107,28 +1112,15 @@ private Consumer createCustomFlagConsumer(GDPermissionUser src, G } else if (addClaimContext) { definitionContexts.add(claim.getContext()); } - CompletableFuture result = null; - for (FlagData flagData : customFlag.getFlagData()) { - final Set newContexts = new HashSet<>(definitionContexts); - newContexts.addAll(flagData.getContexts()); - Tristate newValue = Tristate.UNDEFINED; - if (currentValue == Tristate.TRUE) { - newValue = Tristate.FALSE; - } else { - newValue = Tristate.TRUE; - } - final Flag flag = flagData.getFlag(); - GDFlagPermissionEvent.Set event = new GDFlagPermissionEvent.Set(this.subject, flagData.getFlag(), newValue, newContexts); - GriefDefender.getEventManager().post(event); - if (event.cancelled()) { - return; - } - - result = GriefDefenderPlugin.getInstance().getPermissionProvider().setPermissionValue(GriefDefenderPlugin.DEFAULT_HOLDER, flag, newValue, newContexts); + Tristate newValue = Tristate.UNDEFINED; + if (currentValue == Tristate.TRUE) { + newValue = Tristate.FALSE; + } else { + newValue = Tristate.TRUE; } - result.thenAccept(r -> { + PermissionUtil.getInstance().setFlagDefinition(GriefDefenderPlugin.GD_DEFINITION_HOLDER, flagDefinition, newValue, definitionContexts, false).thenAccept(r -> { Bukkit.getScheduler().runTask(GDBootstrap.getInstance(), () -> { GDCauseStackManager.getInstance().popCause(); showCustomFlags(src, claim, flagGroup); diff --git a/bukkit/src/main/java/com/griefdefender/command/ClaimOptionBase.java b/bukkit/src/main/java/com/griefdefender/command/ClaimOptionBase.java index 49c10f0..38fcae2 100644 --- a/bukkit/src/main/java/com/griefdefender/command/ClaimOptionBase.java +++ b/bukkit/src/main/java/com/griefdefender/command/ClaimOptionBase.java @@ -385,7 +385,7 @@ protected void showOptionPermissions(GDPermissionUser src, GDClaim claim, MenuTy overrideContexts.add(claim.getOverrideClaimContext()); Map filteredContextMap = new HashMap<>(); - for (Map.Entry, Map> mapEntry : PermissionUtil.getInstance().getTransientOptions(this.subject).entrySet()) { + for (Map.Entry, Map> mapEntry : PermissionUtil.getInstance().getTransientOptions(GriefDefenderPlugin.GD_OPTION_HOLDER).entrySet()) { final Set contextSet = mapEntry.getKey(); if (contextSet.contains(claim.getDefaultTypeContext()) || (contextSet.contains(ClaimContexts.GLOBAL_DEFAULT_CONTEXT) || (!claim.isWilderness() && contextSet.contains(ClaimContexts.USER_DEFAULT_CONTEXT)))) { this.addFilteredContexts(src, filteredContextMap, contextSet, MenuType.DEFAULT, mapEntry.getValue()); diff --git a/bukkit/src/main/java/com/griefdefender/command/CommandAdjustBonusClaimBlocks.java b/bukkit/src/main/java/com/griefdefender/command/CommandAdjustBonusClaimBlocks.java index 34e0dd9..d20bd54 100644 --- a/bukkit/src/main/java/com/griefdefender/command/CommandAdjustBonusClaimBlocks.java +++ b/bukkit/src/main/java/com/griefdefender/command/CommandAdjustBonusClaimBlocks.java @@ -53,7 +53,7 @@ public class CommandAdjustBonusClaimBlocks extends BaseCommand { @CommandCompletion("@gdplayers @gddummy") @CommandAlias("acb|adjustclaimblocks") - @Description("Updates a player's accrued claim block total") + @Description("Adjusts a player's bonus claim block total by amount specified") @Syntax(" ") @Subcommand("player adjustbonusblocks") public void execute(CommandSender src, OfflinePlayer user, int amount, @Optional String worldName) { @@ -70,19 +70,14 @@ public void execute(CommandSender src, OfflinePlayer user, int amount, @Optional return; } - // parse the adjustment amount - int adjustment = amount; - //User user = args.getOne("user").get(); - - // give blocks to player GDPlayerData playerData = GriefDefenderPlugin.getInstance().dataStore.getOrCreatePlayerData(world.getUID(), user.getUniqueId()); - playerData.setBonusClaimBlocks(playerData.getBonusClaimBlocks() + adjustment); + playerData.setBonusClaimBlocks(playerData.getBonusClaimBlocks() + amount); final Component message = GriefDefenderPlugin.getInstance().messageData.getMessage(MessageStorage.ADJUST_BONUS_BLOCKS_SUCCESS, ImmutableMap.of( "player", user.getName(), - "amount", adjustment, - "total", playerData.getBonusClaimBlocks())); + "amount", amount, + "total", playerData.getBonusClaimBlocks() + amount)); TextAdapter.sendComponent(src, message); GriefDefenderPlugin.getInstance().getLogger().info( - src.getName() + " adjusted " + user.getName() + "'s bonus claim blocks by " + adjustment + "."); + src.getName() + " adjusted " + user.getName() + "'s bonus claim blocks by " + amount + "."); } } diff --git a/bukkit/src/main/java/com/griefdefender/command/CommandAdjustBonusClaimBlocksAll.java b/bukkit/src/main/java/com/griefdefender/command/CommandAdjustBonusClaimBlocksAll.java new file mode 100644 index 0000000..fe7ddfe --- /dev/null +++ b/bukkit/src/main/java/com/griefdefender/command/CommandAdjustBonusClaimBlocksAll.java @@ -0,0 +1,107 @@ +/* + * This file is part of GriefDefender, licensed under the MIT License (MIT). + * + * Copyright (c) bloodmc + * Copyright (c) contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package com.griefdefender.command; + +import co.aikar.commands.BaseCommand; +import co.aikar.commands.annotation.CommandAlias; +import co.aikar.commands.annotation.CommandPermission; +import co.aikar.commands.annotation.Description; +import co.aikar.commands.annotation.Subcommand; +import co.aikar.commands.annotation.Syntax; + +import com.google.common.collect.ImmutableMap; +import com.griefdefender.GDPlayerData; +import com.griefdefender.GriefDefenderPlugin; +import com.griefdefender.cache.MessageCache; +import com.griefdefender.configuration.MessageStorage; +import com.griefdefender.permission.GDPermissions; +import com.griefdefender.text.action.GDCallbackHolder; + +import net.kyori.text.Component; +import net.kyori.text.TextComponent; +import net.kyori.text.adapter.bukkit.TextAdapter; +import net.kyori.text.event.ClickEvent; +import net.kyori.text.event.HoverEvent; +import net.kyori.text.format.TextColor; + +import java.util.function.Consumer; + +import org.bukkit.Bukkit; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; + +@CommandAlias("%griefdefender") +@CommandPermission(GDPermissions.COMMAND_SET_ACCRUED_CLAIM_BLOCKS_ALL) +public class CommandAdjustBonusClaimBlocksAll extends BaseCommand { + + @CommandAlias("acball|adjustclaimblocksall") + @Description("Adjusts bonus claim block total for all online players by amount specified") + @Syntax("") + @Subcommand("player adjustbonusblocksall") + public void execute(CommandSender src, int amount) { + if (!(src instanceof Player)) { + updateOnlinePlayerBonusBlocks(src, amount); + return; + } + + final Component message = GriefDefenderPlugin.getInstance().messageData.getMessage(MessageStorage.ADJUST_BONUS_BLOCKS_ALL_WARNING, ImmutableMap.of( + "amount", amount)); + final Component confirmationText = TextComponent.builder() + .append(message) + .append(TextComponent.builder() + .append("\n[") + .append(MessageCache.getInstance().LABEL_CONFIRM.color(TextColor.GREEN)) + .append("]\n") + .clickEvent(ClickEvent.runCommand(GDCallbackHolder.getInstance().createCallbackRunCommand(src, createConfirmationConsumer(src, amount), true))) + .hoverEvent(HoverEvent.showText(MessageCache.getInstance().UI_CLICK_CONFIRM)).build()) + .build(); + TextAdapter.sendComponent(src, confirmationText); + } + + private static Consumer createConfirmationConsumer(CommandSender src, int amount) { + return confirm -> { + updateOnlinePlayerBonusBlocks(src, amount); + }; + } + + private static void updateOnlinePlayerBonusBlocks(CommandSender src, int amount) { + int count = 0; + for (Player player : Bukkit.getOnlinePlayers()) { + // give blocks to player + GDPlayerData playerData = GriefDefenderPlugin.getInstance().dataStore.getOrCreateGlobalPlayerData(player.getUniqueId()); + playerData.setBonusClaimBlocks(playerData.getBonusClaimBlocks() + amount); + count++; + } + + final Component message = GriefDefenderPlugin.getInstance().messageData.getMessage(MessageStorage.ADJUST_BONUS_BLOCKS_ALL_SUCCESS, ImmutableMap.of( + "count", count, + "amount", amount)); + TextAdapter.sendComponent(src, message); + GriefDefenderPlugin.getInstance().getLogger().info( + src.getName() + " adjusted " + count + " online player's bonus claim blocks by " + amount + "."); + } +} + + diff --git a/bukkit/src/main/java/com/griefdefender/command/CommandClaimAbandon.java b/bukkit/src/main/java/com/griefdefender/command/CommandClaimAbandon.java index 54d2b0c..2eb2bc7 100644 --- a/bukkit/src/main/java/com/griefdefender/command/CommandClaimAbandon.java +++ b/bukkit/src/main/java/com/griefdefender/command/CommandClaimAbandon.java @@ -188,7 +188,15 @@ private static Consumer createConfirmationConsumer(Player source, playerData.townChat = false; } - if (!claim.isSubdivision() && !claim.isAdminClaim()) { + if (claim.isSubdivision()) { + int remainingBlocks = playerData.getRemainingClaimBlocks(); + final Component message = GriefDefenderPlugin.getInstance().messageData.getMessage(MessageStorage.ABANDON_SUCCESS, ImmutableMap.of( + "amount", remainingBlocks)); + GriefDefenderPlugin.sendMessage(source, message); + return; + } + + if (!claim.isAdminClaim()) { final double abandonReturnRatio = GDPermissionManager.getInstance().getInternalOptionValue(TypeToken.of(Double.class), user, Options.ABANDON_RETURN_RATIO, claim); if (GriefDefenderPlugin.getInstance().isEconomyModeEnabled()) { final Economy economy = GriefDefenderPlugin.getInstance().getVaultProvider().getApi(); diff --git a/bukkit/src/main/java/com/griefdefender/command/CommandClaimAbandonAll.java b/bukkit/src/main/java/com/griefdefender/command/CommandClaimAbandonAll.java index c3a6cb3..1bb9c93 100644 --- a/bukkit/src/main/java/com/griefdefender/command/CommandClaimAbandonAll.java +++ b/bukkit/src/main/java/com/griefdefender/command/CommandClaimAbandonAll.java @@ -185,7 +185,8 @@ private static Consumer createConfirmationConsumer(GDPermissionUs } final double abandonReturnRatio = GDPermissionManager.getInstance().getInternalOptionValue(TypeToken.of(Double.class), user, Options.ABANDON_RETURN_RATIO, claim); if (GriefDefenderPlugin.getInstance().isEconomyModeEnabled()) { - refund += claim.getClaimBlocks() * abandonReturnRatio; + final double requiredClaimBlocks = claim.getClaimBlocks() * abandonReturnRatio; + refund += requiredClaimBlocks * ((GDClaim) claim).getOwnerEconomyBlockCost(); } else { playerData.setAccruedClaimBlocks(playerData.getAccruedClaimBlocks() - ((int) Math.ceil(claim.getClaimBlocks() * (1 - abandonReturnRatio)))); } diff --git a/bukkit/src/main/java/com/griefdefender/command/CommandClaimInfo.java b/bukkit/src/main/java/com/griefdefender/command/CommandClaimInfo.java index 0e3e911..a1e2e1a 100644 --- a/bukkit/src/main/java/com/griefdefender/command/CommandClaimInfo.java +++ b/bukkit/src/main/java/com/griefdefender/command/CommandClaimInfo.java @@ -186,6 +186,7 @@ public void execute(CommandSender src, String[] args) { final GDPermissionUser owner = PermissionHolderCache.getInstance().getOrCreateUser(claim.getOwnerUniqueId()); final UUID ownerUniqueId = claim.getOwnerUniqueId(); final boolean isAdmin = playerData.canManageAdminClaims; + final boolean canPlayerTeleport = (player != null && PermissionUtil.getInstance().canPlayerTeleport(player, gdClaim)) ? true : false; // if not owner of claim, validate perms if (!isAdmin && !player.getUniqueId().equals(claim.getOwnerUniqueId())) { if (!gdClaim.getInternalClaimData().getContainers().contains(player.getUniqueId()) @@ -521,66 +522,72 @@ public void execute(CommandSender src, String[] args) { .append(" : ") .append(getClickableInfoText(src, claim, RAID_OVERRIDE, GDPermissionManager.getInstance().getInternalOptionValue(TypeToken.of(Boolean.class), owner, Options.RAID, gdClaim) == true ? TextComponent.of("ON", TextColor.GREEN) : TextComponent.of("OFF", TextColor.RED))).build(); Component claimSpawn = null; - if (claim.getData().getSpawnPos().isPresent() && player != null && PermissionUtil.getInstance().canPlayerTeleport(player, gdClaim)) { + if (claim.getData().getSpawnPos().isPresent() && player != null) { Vector3i spawnPos = claim.getData().getSpawnPos().get(); Location spawnLoc = new Location(gdClaim.getWorld(), spawnPos.getX(), spawnPos.getY(), spawnPos.getZ()); - claimSpawn = TextComponent.builder() + TextComponent.Builder spawnBuilder = TextComponent.builder() .append(MessageCache.getInstance().LABEL_SPAWN.color(TextColor.GREEN)) .append(" : ") - .append(spawnPos.toString(), TextColor.GRAY) - .clickEvent(ClickEvent.runCommand(GDCallbackHolder.getInstance().createCallbackRunCommand(CommandHelper.createTeleportConsumer(player, spawnLoc, claim, true)))) - .hoverEvent(HoverEvent.showText(MessageCache.getInstance().CLAIMINFO_UI_TELEPORT_SPAWN)) - .build(); + .append(spawnPos.toString(), TextColor.GRAY); + if (canPlayerTeleport) { + spawnBuilder.clickEvent(ClickEvent.runCommand(GDCallbackHolder.getInstance().createCallbackRunCommand(CommandHelper.createTeleportConsumer(player, spawnLoc, claim, true)))) + .hoverEvent(HoverEvent.showText(MessageCache.getInstance().CLAIMINFO_UI_TELEPORT_SPAWN)); + } + claimSpawn = spawnBuilder.build(); } Component southCorners = null; Component northCorners = null; - if (!claim.isWilderness() && player != null && PermissionUtil.getInstance().canPlayerTeleport(player, gdClaim)) { - Component southWestCorner = TextComponent.builder() + if (!claim.isWilderness() && player != null) { + TextComponent.Builder southWestCorner = TextComponent.builder() .append("SW", TextColor.LIGHT_PURPLE) .append(" : ") - .append(VecHelper.toVector3i(southWest).toString(), TextColor.GRAY) - .append(" ") + .append(VecHelper.toVector3i(southWest).toString(), TextColor.GRAY); + if (canPlayerTeleport) { + southWestCorner.append(" ") .clickEvent(ClickEvent.runCommand(GDCallbackHolder.getInstance().createCallbackRunCommand(CommandHelper.createTeleportConsumer(player, southWest, claim)))) .hoverEvent(HoverEvent.showText(MessageStorage.MESSAGE_DATA.getMessage(MessageStorage.CLAIMINFO_UI_TELEPORT_DIRECTION, - ImmutableMap.of("direction", TextComponent.of("SW").color(TextColor.AQUA))))) - .build(); - Component southEastCorner = TextComponent.builder() + ImmutableMap.of("direction", TextComponent.of("SW").color(TextColor.AQUA))))); + } + TextComponent.Builder southEastCorner = TextComponent.builder() .append("SE", TextColor.LIGHT_PURPLE) .append(" : ") - .append(VecHelper.toVector3i(southEast).toString(), TextColor.GRAY) - .append(" ") + .append(VecHelper.toVector3i(southEast).toString(), TextColor.GRAY); + if (canPlayerTeleport) { + southEastCorner.append(" ") .clickEvent(ClickEvent.runCommand(GDCallbackHolder.getInstance().createCallbackRunCommand(CommandHelper.createTeleportConsumer(player, southEast, claim)))) .hoverEvent(HoverEvent.showText(MessageStorage.MESSAGE_DATA.getMessage(MessageStorage.CLAIMINFO_UI_TELEPORT_DIRECTION, - ImmutableMap.of("direction", TextComponent.of("SE").color(TextColor.AQUA))))) - .build(); + ImmutableMap.of("direction", TextComponent.of("SE").color(TextColor.AQUA))))); + } southCorners = TextComponent.builder() .append(MessageCache.getInstance().CLAIMINFO_UI_SOUTH_CORNERS.color(TextColor.YELLOW)) .append(" : ") - .append(southWestCorner) - .append(southEastCorner).build(); - Component northWestCorner = TextComponent.builder() + .append(southWestCorner.build()) + .append(southEastCorner.build()).build(); + TextComponent.Builder northWestCorner = TextComponent.builder() .append("NW", TextColor.LIGHT_PURPLE) .append(" : ") - .append(VecHelper.toVector3i(northWest).toString(), TextColor.GRAY) - .append(" ") + .append(VecHelper.toVector3i(northWest).toString(), TextColor.GRAY); + if (canPlayerTeleport) { + northWestCorner.append(" ") .clickEvent(ClickEvent.runCommand(GDCallbackHolder.getInstance().createCallbackRunCommand(CommandHelper.createTeleportConsumer(player, northWest, claim)))) .hoverEvent(HoverEvent.showText(MessageStorage.MESSAGE_DATA.getMessage(MessageStorage.CLAIMINFO_UI_TELEPORT_DIRECTION, - ImmutableMap.of("direction", TextComponent.of("NW").color(TextColor.AQUA))))) - .build(); - Component northEastCorner = TextComponent.builder() + ImmutableMap.of("direction", TextComponent.of("NW").color(TextColor.AQUA))))); + } + TextComponent.Builder northEastCorner = TextComponent.builder() .append("NE", TextColor.LIGHT_PURPLE) .append(" : ") - .append(VecHelper.toVector3i(northEast).toString(), TextColor.GRAY) - .append(" ") + .append(VecHelper.toVector3i(northEast).toString(), TextColor.GRAY); + if (canPlayerTeleport) { + northEastCorner.append(" ") .clickEvent(ClickEvent.runCommand(GDCallbackHolder.getInstance().createCallbackRunCommand(CommandHelper.createTeleportConsumer(player, northEast, claim)))) .hoverEvent(HoverEvent.showText(MessageStorage.MESSAGE_DATA.getMessage(MessageStorage.CLAIMINFO_UI_TELEPORT_DIRECTION, - ImmutableMap.of("direction", TextComponent.of("NE").color(TextColor.AQUA))))) - .build(); + ImmutableMap.of("direction", TextComponent.of("NE").color(TextColor.AQUA))))); + } northCorners = TextComponent.builder() .append(MessageCache.getInstance().CLAIMINFO_UI_NORTH_CORNERS.color(TextColor.YELLOW)) .append(" : ") - .append(northWestCorner) - .append(northEastCorner).build(); + .append(northWestCorner.build()) + .append(northEastCorner.build()).build(); } Component dateCreated = TextComponent.builder() .append(MessageCache.getInstance().LABEL_CREATED.color(TextColor.YELLOW)) @@ -654,9 +661,17 @@ public void execute(CommandSender src, String[] args) { } textList.add(claimGreeting); textList.add(claimFarewell); - textList.add(dateCreated); - textList.add(dateLastActive); - textList.add(claimId); + if (allowEdit == null || isAdmin) { + if (src.hasPermission(GDPermissions.COMMAND_CLAIM_INFO_OTHERS_CREATION_DATE)) { + textList.add(dateCreated); + } + if (src.hasPermission(GDPermissions.COMMAND_CLAIM_INFO_OTHERS_LAST_ACTIVE)) { + textList.add(dateLastActive); + } + if (src.hasPermission(GDPermissions.COMMAND_CLAIM_INFO_OTHERS_CLAIM_UUID)) { + textList.add(claimId); + } + } if (northCorners != null && southCorners != null) { textList.add(northCorners); textList.add(southCorners); @@ -879,7 +894,8 @@ private static Consumer createClaimTypeConsumer(CommandSender src TextAdapter.sendComponent(src, MessageCache.getInstance().CLAIM_NOT_YOURS); return; } - final ClaimResult result = claim.changeType(clicked, Optional.of(player.getUniqueId()), src); + // Use same claim owner when changing claim type + final ClaimResult result = claim.changeType(clicked, Optional.empty(), src); if (result.successful()) { CommandHelper.executeCommand(src, "claiminfo", gpClaim.getUniqueId().toString()); } else { diff --git a/bukkit/src/main/java/com/griefdefender/command/CommandClaimInvestigate.java b/bukkit/src/main/java/com/griefdefender/command/CommandClaimInvestigate.java new file mode 100644 index 0000000..e8aad01 --- /dev/null +++ b/bukkit/src/main/java/com/griefdefender/command/CommandClaimInvestigate.java @@ -0,0 +1,210 @@ +/* + * This file is part of GriefDefender, licensed under the MIT License (MIT). + * + * Copyright (c) bloodmc + * Copyright (c) contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package com.griefdefender.command; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +import org.bukkit.Location; +import org.bukkit.entity.Player; +import org.bukkit.event.block.Action; + +import com.google.common.collect.ImmutableMap; +import com.google.common.reflect.TypeToken; +import com.griefdefender.GDPlayerData; +import com.griefdefender.GriefDefenderPlugin; +import com.griefdefender.api.claim.Claim; +import com.griefdefender.api.permission.option.Options; +import com.griefdefender.api.permission.option.type.CreateModeTypes; +import com.griefdefender.cache.MessageCache; +import com.griefdefender.claim.GDClaim; +import com.griefdefender.configuration.MessageStorage; +import com.griefdefender.internal.provider.GDWorldEditProvider; +import com.griefdefender.internal.visual.GDClaimVisual; +import com.griefdefender.permission.GDPermissionManager; +import com.griefdefender.permission.GDPermissions; +import com.griefdefender.util.BlockUtil; +import com.griefdefender.util.PlayerUtil; + +import co.aikar.commands.BaseCommand; +import co.aikar.commands.annotation.CommandAlias; +import co.aikar.commands.annotation.CommandPermission; +import co.aikar.commands.annotation.Description; +import co.aikar.commands.annotation.Optional; +import co.aikar.commands.annotation.Subcommand; +import co.aikar.commands.annotation.Syntax; +import net.kyori.text.Component; +import net.kyori.text.TextComponent; +import net.kyori.text.format.TextColor; + +@CommandAlias("%griefdefender") +@CommandPermission(GDPermissions.COMMAND_CLAIM_INVESTIGATE) +public class CommandClaimInvestigate extends BaseCommand { + + @CommandAlias("claiminvestigate") + @Description("Investigates the target or nearby claims.") + @Syntax("[area|hide|hideall]") + @Subcommand("claim investigate") + public void execute(Player player, @Optional String cmd) { + final GDPlayerData playerData = GriefDefenderPlugin.getInstance().dataStore.getOrCreatePlayerData(player.getWorld(), player.getUniqueId()); + if (!playerData.queuedVisuals.isEmpty()) { + final Component message = GriefDefenderPlugin.getInstance().messageData.getMessage(MessageStorage.VISUAL_UPDATE_IN_PROGRESS, + ImmutableMap.of( + "count", playerData.queuedVisuals.size())); + GriefDefenderPlugin.sendMessage(player, message); + return; + } + + final GDWorldEditProvider worldEditProvider = GriefDefenderPlugin.getInstance().getWorldEditProvider(); + if (cmd != null && cmd.equalsIgnoreCase("hideall")) { + if (worldEditProvider != null) { + worldEditProvider.revertVisuals(player, playerData, null); + } + playerData.revertAllVisuals(); + return; + } + final boolean hideTargetClaimVisual = cmd != null && cmd.equalsIgnoreCase("hide"); + final boolean checkArea = cmd != null && cmd.equalsIgnoreCase("area"); + GDClaim claim = null; + Location location = null; + if (hideTargetClaimVisual || checkArea) { + final int maxDistance = GDPermissionManager.getInstance().getInternalOptionValue(TypeToken.of(Integer.class), player, Options.RADIUS_INSPECT); + claim = PlayerUtil.getInstance().findNearbyClaim(player, playerData, maxDistance, hideTargetClaimVisual); + if (checkArea) { + if (!playerData.canIgnoreClaim(claim) && !player.hasPermission(GDPermissions.VISUALIZE_CLAIMS_NEARBY)) { + GriefDefenderPlugin.sendMessage(player, MessageCache.getInstance().PERMISSION_VISUAL_CLAIMS_NEARBY); + return; + } + + Location nearbyLocation = playerData.lastValidInspectLocation != null ? playerData.lastValidInspectLocation : player.getLocation(); + Set claims = BlockUtil.getInstance().getNearbyClaims(nearbyLocation, maxDistance, true); + List visualClaims = new ArrayList<>(); + for (Claim nearbyClaim : claims) { + if (!((GDClaim) nearbyClaim).hasActiveVisual(player)) { + visualClaims.add(nearbyClaim); + } + } + int height = (int) (playerData.lastValidInspectLocation != null ? playerData.lastValidInspectLocation.getBlockY() : PlayerUtil.getInstance().getEyeHeight(player)); + + boolean hideBorders = worldEditProvider != null && + worldEditProvider.hasCUISupport(player) && + GriefDefenderPlugin.getActiveConfig(player.getWorld().getUID()).getConfig().visual.hideBorders; + if (!hideBorders) { + for (Claim visualClaim : visualClaims) { + final GDClaimVisual visual = ((GDClaim) visualClaim).getVisualizer(); + visual.createClaimBlockVisuals(playerData.getClaimCreateMode() == CreateModeTypes.VOLUME ? height : PlayerUtil.getInstance().getEyeHeight(player), player.getLocation(), playerData); + visual.apply(player); + } + } + + final Component message = GriefDefenderPlugin.getInstance().messageData.getMessage(MessageStorage.CLAIM_SHOW_NEARBY, + ImmutableMap.of( + "amount", claims.size())); + GriefDefenderPlugin.sendMessage(player, message); + if (!claims.isEmpty()) { + if (worldEditProvider != null && !visualClaims.isEmpty()) { + worldEditProvider.visualizeClaims(visualClaims, player, playerData, true); + } + CommandHelper.showClaims(player, claims); + } + return; + } + if (claim != null && claim.isWilderness()) { + playerData.lastValidInspectLocation = null; + GriefDefenderPlugin.sendMessage(player, GriefDefenderPlugin.getInstance().messageData.getMessage(MessageStorage.BLOCK_NOT_CLAIMED)); + return; + } + } else { + boolean ignoreAir = false; + if (worldEditProvider != null) { + // Ignore air so players can use client-side WECUI block target which uses max reach distance + if (worldEditProvider.hasCUISupport(player) && playerData.getClaimCreateMode() == CreateModeTypes.VOLUME && playerData.lastShovelLocation != null) { + ignoreAir = true; + } + } + final int distance = !ignoreAir ? 100 : 5; + location = BlockUtil.getInstance().getTargetBlock(player, playerData, distance, ignoreAir).orElse(null); + if (location == null) { + return; + } + + claim = GriefDefenderPlugin.getInstance().dataStore.getClaimAtPlayer(location, playerData, true); + if (claim.isWilderness()) { + GriefDefenderPlugin.sendMessage(player, GriefDefenderPlugin.getInstance().messageData.getMessage(MessageStorage.BLOCK_NOT_CLAIMED)); + return; + } + } + + // Handle left-click visual revert + if (claim != null && !claim.isWilderness() && hideTargetClaimVisual) { + if (claim.hasActiveVisual(player)) { + final int maxDistance = GDPermissionManager.getInstance().getInternalOptionValue(TypeToken.of(Integer.class), player, Options.RADIUS_INSPECT); + if (!((GDClaim) claim).children.isEmpty()) { + claim = PlayerUtil.getInstance().findNearbyClaim(player, playerData, maxDistance, true); + } + if (!claim.hasActiveVisual(player) && claim.parent != null) { + GDClaim parent = claim.parent; + while (parent != null) { + if (parent.hasActiveVisual(player)) { + claim = parent; + parent = null; + } else { + parent = parent.parent; + } + } + } + if (claim != null && claim.hasActiveVisual(player)) { + playerData.revertClaimVisual(claim); + } + return; + } + } + + int height = PlayerUtil.getInstance().getEyeHeight(player); + if (playerData.lastValidInspectLocation != null || location != null) { + height = playerData.lastValidInspectLocation != null ? playerData.lastValidInspectLocation.getBlockY() : location.getBlockY(); + } + + if (claim != null) { + // always show visual borders for resize purposes + final GDClaimVisual visual = claim.getVisualizer(); + visual.createClaimBlockVisuals(playerData.getClaimCreateMode() == CreateModeTypes.VOLUME ? height : PlayerUtil.getInstance().getEyeHeight(player), player.getLocation(), playerData); + visual.apply(player); + if (worldEditProvider != null) { + worldEditProvider.displayClaimCUIVisual(claim, player, playerData, true); + } + Set claims = new HashSet<>(); + claims.add(claim); + playerData.showNoClaimsFoundMessage = false; + CommandHelper.showClaims(player, claims); + Component message = GriefDefenderPlugin.getInstance().messageData.getMessage(MessageStorage.BLOCK_CLAIMED, + ImmutableMap.of( + "player", claim.getOwnerDisplayName())); + GriefDefenderPlugin.sendMessage(player, message); + } + } +} diff --git a/bukkit/src/main/java/com/griefdefender/command/CommandClaimOption.java b/bukkit/src/main/java/com/griefdefender/command/CommandClaimOption.java index e408f5a..361641f 100644 --- a/bukkit/src/main/java/com/griefdefender/command/CommandClaimOption.java +++ b/bukkit/src/main/java/com/griefdefender/command/CommandClaimOption.java @@ -51,7 +51,7 @@ public CommandClaimOption() { @Syntax("[