From 26efaf2b7386f05c74566c4715dc7068b6c806d8 Mon Sep 17 00:00:00 2001 From: bloodshot Date: Sat, 4 Jul 2020 21:06:59 -0400 Subject: [PATCH] Update for 1.4.7 * Fix multi-server permissions overwriting eachother when same contexts were used. * Fix economy resize claim message showing too many decimals for balance. * (Bukkit) Fix chunk tracking data not respecting world container argument. * (Bukkit) Fix deny messages not appearing for bucket interactions. * (Bukkit 1.16) Fix interact-block-secondary being triggered on non-interactable blocks. * (Sponge) Fix enter/exit messages being triggered by non-players. * (Sponge) Fix 'interact-entity-primary' not cancelling event if set to false. * (Sponge) Fix wrong id used for 'item-drop' flag. * (Sponge) Fix enderpearl being lost when teleport is cancelled. * (Sponge) Fix bucket protection. * Add greeting/farewell/name click support in /claiminfo. * Add 'player-endportal-use' and 'player-netherportal-use' flag definitions. * Remove 'player-portal-use' flag definition. * Cache player options during movement to avoid constant LP lookups. * Improve teleport handling. * Ignore air blocks during explosions. * Set block-modify to true by default for vanilla compatibility. * The 'portal-use' flag is no longer used and has been disabled by default. * (Sponge) 'entity-chunk-spawn' flag is disabled by default to avoid wrong usage. * (Sponge) Ignore items and projectiles during MoveEntityEvent. --- .../java/com/griefdefender/GDPlayerData.java | 18 ++ .../griefdefender/GriefDefenderPlugin.java | 3 +- .../com/griefdefender/cache/MessageCache.java | 14 +- .../griefdefender/command/ClaimFlagBase.java | 59 ++++-- .../command/ClaimOptionBase.java | 51 +++-- .../command/CommandClaimInfo.java | 40 +++- .../griefdefender/command/CommandHelper.java | 8 +- .../configuration/FlagStorage.java | 7 +- .../configuration/MessageStorage.java | 6 +- .../listener/BlockEventHandler.java | 3 + .../listener/CommonEntityEventHandler.java | 65 ++++-- .../listener/LuckPermsEventHandler.java | 19 +- .../listener/PlayerEventHandler.java | 63 +++--- .../permission/GDPermissionManager.java | 22 +- .../permission/flag/FlagContexts.java | 3 +- .../griefdefender/permission/flag/GDFlag.java | 1 - .../provider/LuckPermsProvider.java | 188 ++++++++++++------ .../provider/PermissionProvider.java | 16 +- .../permissionsex/PermissionsExProvider.java | 16 +- .../FlagDefinitionRegistryModule.java | 31 ++- .../griefdefender/storage/FileStorage.java | 2 +- .../griefdefender/util/PermissionUtil.java | 16 +- 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.8.8.json | 6 +- bukkit/src/main/resources/plugin.yml | 2 +- .../src/main/resources/assets/lang/de_DE.conf | 51 +++-- .../src/main/resources/assets/lang/en_US.conf | 13 +- .../src/main/resources/assets/lang/es_ES.conf | 23 ++- .../src/main/resources/assets/lang/fr_FR.conf | 13 +- .../src/main/resources/assets/lang/pl_PL.conf | 13 +- .../src/main/resources/assets/lang/ru_RU.conf | 13 +- gradle.properties | 2 +- .../java/com/griefdefender/GDPlayerData.java | 17 ++ .../griefdefender/GriefDefenderPlugin.java | 3 +- .../com/griefdefender/cache/MessageCache.java | 14 +- .../griefdefender/command/ClaimFlagBase.java | 58 ++++-- .../command/ClaimOptionBase.java | 50 +++-- .../command/CommandClaimInfo.java | 35 +++- .../griefdefender/command/CommandHelper.java | 8 +- .../configuration/FlagStorage.java | 7 +- .../configuration/MessageStorage.java | 6 +- .../listener/BlockEventHandler.java | 16 ++ .../listener/CommonEntityEventHandler.java | 64 ++++-- .../listener/EntityEventHandler.java | 102 +++++----- .../listener/LuckPermsEventHandler.java | 20 +- .../listener/PlayerEventHandler.java | 49 +++-- .../permission/GDPermissionManager.java | 29 +-- .../permission/flag/FlagContexts.java | 3 +- .../provider/LuckPermsProvider.java | 188 ++++++++++++------ .../provider/PermissionProvider.java | 16 +- .../FlagDefinitionRegistryModule.java | 31 ++- .../griefdefender/util/PermissionUtil.java | 16 +- 59 files changed, 1049 insertions(+), 518 deletions(-) diff --git a/bukkit/src/main/java/com/griefdefender/GDPlayerData.java b/bukkit/src/main/java/com/griefdefender/GDPlayerData.java index 1ff97a7..03530ab 100644 --- a/bukkit/src/main/java/com/griefdefender/GDPlayerData.java +++ b/bukkit/src/main/java/com/griefdefender/GDPlayerData.java @@ -57,6 +57,7 @@ import com.griefdefender.api.permission.option.type.CreateModeTypes; import com.griefdefender.api.permission.option.type.GameModeType; import com.griefdefender.api.permission.option.type.GameModeTypes; +import com.griefdefender.api.permission.option.type.WeatherType; import com.griefdefender.cache.EventResultCache; import com.griefdefender.cache.MessageCache; import com.griefdefender.cache.PermissionHolderCache; @@ -166,6 +167,14 @@ public class GDPlayerData implements PlayerData { public boolean userOptionBypassPlayerDenyGodmode = false; public boolean userOptionBypassPlayerGamemode = false; + // option cache + public Boolean optionNoFly = null; + public Boolean optionNoGodMode = null; + public Double optionFlySpeed = null; + public Double optionWalkSpeed = null; + public GameModeType optionGameModeType = null; + public WeatherType optionWeatherType = null; + public boolean dataInitialized = false; public boolean showNoClaimsFoundMessage = true; public boolean useRestoreSchematic = false; @@ -851,6 +860,15 @@ public void onClaimDelete() { this.claimSubdividing = null; } + public void resetOptionCache() { + this.optionNoFly = null; + this.optionNoGodMode = null; + this.optionFlySpeed = null; + this.optionWalkSpeed = null; + this.optionGameModeType = null; + this.optionWeatherType = null; + } + public void onDisconnect() { this.claimVisualRevertTasks.clear(); this.visualClaimBlocks.clear(); diff --git a/bukkit/src/main/java/com/griefdefender/GriefDefenderPlugin.java b/bukkit/src/main/java/com/griefdefender/GriefDefenderPlugin.java index 2ae020b..21257d7 100644 --- a/bukkit/src/main/java/com/griefdefender/GriefDefenderPlugin.java +++ b/bukkit/src/main/java/com/griefdefender/GriefDefenderPlugin.java @@ -193,6 +193,7 @@ import com.griefdefender.listener.PlayerEventHandler; import com.griefdefender.listener.WorldEventHandler; import com.griefdefender.permission.ContextGroupKeys; +import com.griefdefender.permission.GDPermissionGroup; import com.griefdefender.permission.GDPermissionHolder; import com.griefdefender.permission.GDPermissionManager; import com.griefdefender.permission.GDPermissionUser; @@ -500,7 +501,7 @@ public void onEnable(boolean reload) { } instance = this; timingManager = TimingManager.of(GDBootstrap.getInstance()); - DEFAULT_HOLDER = new GDPermissionHolder("default"); + DEFAULT_HOLDER = new GDPermissionGroup("default"); PUBLIC_USER = new GDPermissionUser(PUBLIC_UUID, PUBLIC_NAME); WORLD_USER = new GDPermissionUser(WORLD_USER_UUID, WORLD_USER_NAME); Guice.createInjector(Stage.PRODUCTION, new GriefDefenderImplModule()); diff --git a/bukkit/src/main/java/com/griefdefender/cache/MessageCache.java b/bukkit/src/main/java/com/griefdefender/cache/MessageCache.java index d2f562b..afe0352 100644 --- a/bukkit/src/main/java/com/griefdefender/cache/MessageCache.java +++ b/bukkit/src/main/java/com/griefdefender/cache/MessageCache.java @@ -80,6 +80,9 @@ public static MessageCache getInstance() { public Component CLAIMINFO_UI_CLAIM_EXPIRATION; public Component CLAIMINFO_UI_CLICK_ADMIN; public Component CLAIMINFO_UI_CLICK_BANK; + public Component CLAIMINFO_UI_CLICK_FAREWELL; + public Component CLAIMINFO_UI_CLICK_GREETING; + public Component CLAIMINFO_UI_CLICK_NAME; public Component CLAIMINFO_UI_CLICK_TOGGLE; public Component CLAIMINFO_UI_DENY_MESSAGES; public Component CLAIMINFO_UI_FLAG_OVERRIDES; @@ -100,6 +103,7 @@ public static MessageCache getInstance() { public Component CLAIMINFO_UI_TITLE_CLAIMINFO; public Component CLAIMINFO_UI_TOWN_SETTINGS; public Component CLAIMLIST_UI_CLICK_INFO; + public Component CLAIMLIST_UI_CLICK_PLAYER_LIST; public Component CLAIMLIST_UI_CLICK_PURCHASE; public Component CLAIMLIST_UI_CLICK_RENT; public Component CLAIMLIST_UI_CLICK_VIEW_CHILDREN; @@ -207,6 +211,7 @@ public static MessageCache getInstance() { public Component FLAG_DESCRIPTION_CUSTOM_PLAYER_BLOCK_PLACE; public Component FLAG_DESCRIPTION_CUSTOM_PLAYER_DAMAGE; public Component FLAG_DESCRIPTION_CUSTOM_PLAYER_ENDERPEARL_INTERACT; + public Component FLAG_DESCRIPTION_CUSTOM_PLAYER_ENDPORTAL_USE; public Component FLAG_DESCRIPTION_CUSTOM_PLAYER_ENTER; public Component FLAG_DESCRIPTION_CUSTOM_PLAYER_ENTITY_INTERACT; public Component FLAG_DESCRIPTION_CUSTOM_PLAYER_EXIT; @@ -215,12 +220,12 @@ public static MessageCache getInstance() { public Component FLAG_DESCRIPTION_CUSTOM_PLAYER_ITEMHANGING_PLACE; public Component FLAG_DESCRIPTION_CUSTOM_PLAYER_ITEM_DROP; public Component FLAG_DESCRIPTION_CUSTOM_PLAYER_ITEM_PICKUP; + public Component FLAG_DESCRIPTION_CUSTOM_PLAYER_NETHERPORTAL_USE; public Component FLAG_DESCRIPTION_CUSTOM_PLAYER_TELEPORT_FROM; public Component FLAG_DESCRIPTION_CUSTOM_PLAYER_TELEPORT_TO; public Component FLAG_DESCRIPTION_CUSTOM_PLAYER_VILLAGER_DAMAGE; public Component FLAG_DESCRIPTION_CUSTOM_PISTON_ITEM_SPAWN; public Component FLAG_DESCRIPTION_CUSTOM_PISTON_USE; - public Component FLAG_DESCRIPTION_CUSTOM_PLAYER_PORTAL_USE; public Component FLAG_DESCRIPTION_CUSTOM_PVP; public Component FLAG_DESCRIPTION_CUSTOM_RIDE; public Component FLAG_DESCRIPTION_CUSTOM_SLEEP; @@ -537,6 +542,9 @@ public void loadCache() { CLAIMINFO_UI_CLAIM_EXPIRATION = MessageStorage.MESSAGE_DATA.getMessage("claiminfo-ui-claim-expiration"); CLAIMINFO_UI_CLICK_ADMIN = MessageStorage.MESSAGE_DATA.getMessage("claiminfo-ui-click-admin"); CLAIMINFO_UI_CLICK_BANK = MessageStorage.MESSAGE_DATA.getMessage("claiminfo-ui-click-bank"); + CLAIMINFO_UI_CLICK_FAREWELL = MessageStorage.MESSAGE_DATA.getMessage("claiminfo-ui-click-farewell"); + CLAIMINFO_UI_CLICK_GREETING = MessageStorage.MESSAGE_DATA.getMessage("claiminfo-ui-click-greeting"); + CLAIMINFO_UI_CLICK_NAME = MessageStorage.MESSAGE_DATA.getMessage("claiminfo-ui-click-name"); CLAIMINFO_UI_CLICK_TOGGLE = MessageStorage.MESSAGE_DATA.getMessage("claiminfo-ui-click-toggle"); CLAIMINFO_UI_DENY_MESSAGES = MessageStorage.MESSAGE_DATA.getMessage("claiminfo-ui-deny-messages"); CLAIMINFO_UI_FLAG_OVERRIDES = MessageStorage.MESSAGE_DATA.getMessage("claiminfo-ui-flag-overrides"); @@ -557,6 +565,7 @@ public void loadCache() { CLAIMINFO_UI_TITLE_CLAIMINFO = MessageStorage.MESSAGE_DATA.getMessage("claiminfo-ui-title-claiminfo"); CLAIMINFO_UI_TOWN_SETTINGS = MessageStorage.MESSAGE_DATA.getMessage("claiminfo-ui-town-settings"); CLAIMLIST_UI_CLICK_INFO = MessageStorage.MESSAGE_DATA.getMessage("claimlist-ui-click-info"); + CLAIMLIST_UI_CLICK_PLAYER_LIST = MessageStorage.MESSAGE_DATA.getMessage("claimlist-ui-click-player-list"); CLAIMLIST_UI_CLICK_PURCHASE = MessageStorage.MESSAGE_DATA.getMessage("claimlist-ui-click-purchase"); CLAIMLIST_UI_CLICK_RENT = MessageStorage.MESSAGE_DATA.getMessage("claimlist-ui-click-rent"); CLAIMLIST_UI_CLICK_VIEW_CHILDREN = MessageStorage.MESSAGE_DATA.getMessage("claimlist-ui-click-view-children"); @@ -665,6 +674,7 @@ public void loadCache() { FLAG_DESCRIPTION_CUSTOM_PLAYER_BLOCK_INTERACT = MessageStorage.MESSAGE_DATA.getMessage("flag-description-custom-player-block-interact"); FLAG_DESCRIPTION_CUSTOM_PLAYER_DAMAGE = MessageStorage.MESSAGE_DATA.getMessage("flag-description-custom-player-damage"); FLAG_DESCRIPTION_CUSTOM_PLAYER_ENDERPEARL_INTERACT = MessageStorage.MESSAGE_DATA.getMessage("flag-description-custom-player-enderpearl-interact"); + FLAG_DESCRIPTION_CUSTOM_PLAYER_ENDPORTAL_USE = MessageStorage.MESSAGE_DATA.getMessage("flag-description-custom-player-endportal-use"); FLAG_DESCRIPTION_CUSTOM_PLAYER_ENTER = MessageStorage.MESSAGE_DATA.getMessage("flag-description-custom-player-enter"); FLAG_DESCRIPTION_CUSTOM_PLAYER_ENTITY_INTERACT = MessageStorage.MESSAGE_DATA.getMessage("flag-description-custom-player-entity-interact"); FLAG_DESCRIPTION_CUSTOM_PLAYER_EXIT = MessageStorage.MESSAGE_DATA.getMessage("flag-description-custom-player-exit"); @@ -673,7 +683,7 @@ public void loadCache() { FLAG_DESCRIPTION_CUSTOM_PLAYER_ITEMHANGING_PLACE = MessageStorage.MESSAGE_DATA.getMessage("flag-description-custom-player-itemhanging-place"); FLAG_DESCRIPTION_CUSTOM_PLAYER_ITEM_DROP = MessageStorage.MESSAGE_DATA.getMessage("flag-description-custom-player-item-drop"); FLAG_DESCRIPTION_CUSTOM_PLAYER_ITEM_PICKUP = MessageStorage.MESSAGE_DATA.getMessage("flag-description-custom-player-item-pickup"); - FLAG_DESCRIPTION_CUSTOM_PLAYER_PORTAL_USE = MessageStorage.MESSAGE_DATA.getMessage("flag-description-custom-player-portal-use"); + FLAG_DESCRIPTION_CUSTOM_PLAYER_NETHERPORTAL_USE = MessageStorage.MESSAGE_DATA.getMessage("flag-description-custom-player-netherportal-use"); FLAG_DESCRIPTION_CUSTOM_PLAYER_TELEPORT_FROM = MessageStorage.MESSAGE_DATA.getMessage("flag-description-custom-player-teleport-from"); FLAG_DESCRIPTION_CUSTOM_PLAYER_TELEPORT_TO = MessageStorage.MESSAGE_DATA.getMessage("flag-description-custom-player-teleport-to"); FLAG_DESCRIPTION_CUSTOM_PLAYER_VILLAGER_DAMAGE = MessageStorage.MESSAGE_DATA.getMessage("flag-description-custom-player-villager-damage"); diff --git a/bukkit/src/main/java/com/griefdefender/command/ClaimFlagBase.java b/bukkit/src/main/java/com/griefdefender/command/ClaimFlagBase.java index 5a6bc70..701f965 100644 --- a/bukkit/src/main/java/com/griefdefender/command/ClaimFlagBase.java +++ b/bukkit/src/main/java/com/griefdefender/command/ClaimFlagBase.java @@ -29,6 +29,7 @@ import com.github.benmanes.caffeine.cache.Cache; import com.github.benmanes.caffeine.cache.Caffeine; import com.google.common.collect.ImmutableMap; +import com.griefdefender.GDBootstrap; import com.griefdefender.GDPlayerData; import com.griefdefender.GriefDefenderPlugin; import com.griefdefender.api.GriefDefender; @@ -76,6 +77,8 @@ import net.kyori.text.event.HoverEvent; import net.kyori.text.format.TextColor; import net.kyori.text.format.TextDecoration; + +import org.bukkit.Bukkit; import org.bukkit.command.CommandSender; import org.bukkit.entity.Player; import org.bukkit.inventory.ItemStack; @@ -94,6 +97,7 @@ import java.util.TreeMap; import java.util.TreeSet; import java.util.UUID; +import java.util.concurrent.CompletableFuture; import java.util.concurrent.TimeUnit; import java.util.function.Consumer; @@ -1103,6 +1107,7 @@ 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()); @@ -1120,13 +1125,15 @@ private Consumer createCustomFlagConsumer(GDPermissionUser src, G return; } - PermissionResult result = GriefDefenderPlugin.getInstance().getPermissionProvider().setPermissionValue(GriefDefenderPlugin.DEFAULT_HOLDER, flag, newValue, newContexts); + result = GriefDefenderPlugin.getInstance().getPermissionProvider().setPermissionValue(GriefDefenderPlugin.DEFAULT_HOLDER, flag, newValue, newContexts); } - // Save after all permission changes have been made - GriefDefenderPlugin.getInstance().getPermissionProvider().save(GriefDefenderPlugin.DEFAULT_HOLDER); - GDCauseStackManager.getInstance().popCause(); - showCustomFlags(src, claim, flagGroup); + result.thenAccept(r -> { + Bukkit.getScheduler().runTask(GDBootstrap.getInstance(), () -> { + GDCauseStackManager.getInstance().popCause(); + showCustomFlags(src, claim, flagGroup); + }); + }); }; } @@ -1176,21 +1183,35 @@ private Consumer createFlagConsumer(GDPermissionUser src, GDClaim } if (displayType == MenuType.DEFAULT || (hasDefaultContext && src.getInternalPlayerData().canManageFlagDefaults)) { - PermissionResult result = PermissionUtil.getInstance().setTransientPermission(this.subject, flag.getPermission(), newValue, newContexts); - if (result.successful()) { - showFlagPermissions(src, claim, displayType); - return; + CompletableFuture future = PermissionUtil.getInstance().setPermissionValue(this.subject, flag.getPermission(), newValue, newContexts); + future.thenAccept(r -> { + Bukkit.getScheduler().runTask(GDBootstrap.getInstance(), () -> { + showFlagPermissions(src, claim, displayType); + }); + }); + return; + } + + final Context permServerContext = serverContext; + CompletableFuture future = PermissionUtil.getInstance().setPermissionValue(this.subject, flag, newValue, newContexts); + future.thenAcceptAsync(r -> { + if (!r.successful()) { + // Try again without server context + newContexts.remove(permServerContext); + CompletableFuture newFuture = PermissionUtil.getInstance().setPermissionValue(this.subject, flag, newValue, newContexts, false, true); + newFuture.thenAccept(r2 -> { + if (r2.successful()) { + Bukkit.getScheduler().runTask(GDBootstrap.getInstance(), () -> { + showFlagPermissions(src, claim, displayType); + }); + } + }); + } else { + Bukkit.getScheduler().runTask(GDBootstrap.getInstance(), () -> { + showFlagPermissions(src, claim, displayType); + }); } - } - PermissionResult result = PermissionUtil.getInstance().setPermissionValue(this.subject, flag, newValue, newContexts); - if (!result.successful()) { - // Try again without server context - newContexts.remove(serverContext); - result = PermissionUtil.getInstance().setPermissionValue(this.subject, flag, newValue, newContexts, false, true); - } - if (result.successful()) { - showFlagPermissions(src, claim, displayType); - } + }); }; } diff --git a/bukkit/src/main/java/com/griefdefender/command/ClaimOptionBase.java b/bukkit/src/main/java/com/griefdefender/command/ClaimOptionBase.java index 5becb60..49c10f0 100644 --- a/bukkit/src/main/java/com/griefdefender/command/ClaimOptionBase.java +++ b/bukkit/src/main/java/com/griefdefender/command/ClaimOptionBase.java @@ -31,6 +31,7 @@ import com.google.common.collect.ImmutableMap; import com.google.common.collect.Maps; import com.google.common.reflect.TypeToken; +import com.griefdefender.GDBootstrap; import com.griefdefender.GDPlayerData; import com.griefdefender.GriefDefenderPlugin; import com.griefdefender.api.GriefDefender; @@ -78,6 +79,8 @@ import net.kyori.text.event.HoverEvent; import net.kyori.text.format.TextColor; import net.kyori.text.format.TextDecoration; + +import org.bukkit.Bukkit; import org.bukkit.command.CommandSender; import org.bukkit.entity.Player; @@ -93,6 +96,7 @@ import java.util.Set; import java.util.TreeMap; import java.util.UUID; +import java.util.concurrent.CompletableFuture; import java.util.concurrent.TimeUnit; import java.util.function.Consumer; import java.util.regex.Matcher; @@ -874,25 +878,46 @@ private Consumer newOptionValueConsumer(GDPermissionUser src, GDC if (!hasServerContext && serverContext != null) { newContexts.add(serverContext); } - final PermissionResult result = PermissionUtil.getInstance().setOptionValue(this.subject, option.getPermission(), newValue, newContexts); - if (!result.successful()) { - // Try again without server context - newContexts.remove(serverContext); - PermissionUtil.getInstance().setOptionValue(this.subject, option.getPermission(), newValue, newContexts, false); - } - if (result.successful()) { - if (option == Options.PLAYER_WEATHER) { - CommonEntityEventHandler.getInstance().checkPlayerWeather(src, claim, claim, true); + final Context permServerContext = serverContext; + final String permValue = newValue; + final CompletableFuture future = PermissionUtil.getInstance().setOptionValue(this.subject, option.getPermission(), newValue, newContexts); + future.thenAcceptAsync(r -> { + if (!r.successful()) { + // Try again without server context + newContexts.remove(permServerContext); + CompletableFuture newFuture = PermissionUtil.getInstance().setOptionValue(this.subject, option.getPermission(), permValue, newContexts, false); + newFuture.thenAccept(r2 -> { + if (r2.successful()) { + Bukkit.getScheduler().runTask(GDBootstrap.getInstance(), () -> { + if (option == Options.PLAYER_WEATHER) { + CommonEntityEventHandler.getInstance().checkPlayerWeather(src, claim, claim, true); + } + showOptionPermissions(src, claim, displayType); + }); + } + }); + } else { + Bukkit.getScheduler().runTask(GDBootstrap.getInstance(), () -> { + if (option == Options.PLAYER_WEATHER) { + CommonEntityEventHandler.getInstance().checkPlayerWeather(src, claim, claim, true); + } + showOptionPermissions(src, claim, displayType); + }); } - } - showOptionPermissions(src, claim, displayType); + }); }; } private Consumer removeOptionValueConsumer(GDPermissionUser src, GDClaim claim, Option option, OptionContextHolder optionHolder, Set contexts, MenuType displayType) { return consumer -> { - PermissionUtil.getInstance().setOptionValue(this.subject, option.getPermission(), "undefined", contexts); - showOptionPermissions(src, claim, displayType); + final CompletableFuture future = PermissionUtil.getInstance().setOptionValue(this.subject, option.getPermission(), "undefined", contexts); + future.thenAccept(r -> { + if (r.successful()) { + Bukkit.getScheduler().runTask(GDBootstrap.getInstance(), () -> { + showOptionPermissions(src, claim, displayType); + }); + } + }); }; } diff --git a/bukkit/src/main/java/com/griefdefender/command/CommandClaimInfo.java b/bukkit/src/main/java/com/griefdefender/command/CommandClaimInfo.java index da48123..0e3e911 100644 --- a/bukkit/src/main/java/com/griefdefender/command/CommandClaimInfo.java +++ b/bukkit/src/main/java/com/griefdefender/command/CommandClaimInfo.java @@ -66,6 +66,8 @@ import net.kyori.text.event.HoverEvent; import net.kyori.text.format.TextColor; import net.kyori.text.format.TextDecoration; +import net.kyori.text.serializer.legacy.LegacyComponentSerializer; + import org.bukkit.Bukkit; import org.bukkit.Location; import org.bukkit.World; @@ -251,10 +253,16 @@ public void execute(CommandSender src, String[] args) { if (claim.isWilderness() && name == null) { name = TextComponent.of("Wilderness", TextColor.GREEN); } + Component nameText = name == null ? NONE : name; Component claimName = TextComponent.builder() - .append(MessageCache.getInstance().LABEL_NAME.color(TextColor.YELLOW)) + .append(MessageCache.getInstance().LABEL_NAME.color(TextColor.YELLOW) + .clickEvent(ClickEvent.suggestCommand("/claimname ")) + .hoverEvent(HoverEvent.showText(MessageCache.getInstance().CLAIMINFO_UI_CLICK_NAME))) .append(" : ", TextColor.YELLOW) - .append(name == null ? NONE : name).build(); + .append(nameText + .clickEvent(ClickEvent.suggestCommand(name == null ? "/claimname " : "/claimname " + LegacyComponentSerializer.legacy().serialize(name, '&'))) + .hoverEvent(HoverEvent.showText(MessageCache.getInstance().CLAIMINFO_UI_CLICK_NAME))) + .build(); Component worldName = TextComponent.builder() .append(MessageCache.getInstance().LABEL_WORLD.color(TextColor.YELLOW)) .append(" : ") @@ -476,22 +484,34 @@ public void execute(CommandSender src, String[] args) { .append(" : ") .append(getClickableInfoText(src, claim, INHERIT_PARENT, claim.getData().doesInheritParent() ? TextComponent.of("ON", TextColor.GREEN) : TextComponent.of("OFF", TextColor.RED))).build(); TextComponent.Builder expireBuilder = TextComponent.builder() - .append(MessageCache.getInstance().LABEL_EXPIRED.color(TextColor.YELLOW)) - .append(" : "); + .append(MessageCache.getInstance().LABEL_EXPIRED.color(TextColor.YELLOW)) + .append(" : "); if (isAdmin && claim.getData().isExpired()) { - expireBuilder.append(getClickableInfoText(src, claim, IS_EXPIRED, claim.getData().isExpired() ? TextComponent.of("YES", TextColor.RED) : TextComponent.of("NO", TextColor.GRAY))); + expireBuilder.append(getClickableInfoText(src, claim, IS_EXPIRED, claim.getData().isExpired() ? MessageCache.getInstance().LABEL_YES.color(TextColor.RED) : MessageCache.getInstance().LABEL_NO.color(TextColor.GRAY))); } else { - expireBuilder.append(claim.getData().isExpired() ? TextComponent.of("YES", TextColor.RED) : TextComponent.of("NO", TextColor.GRAY)); + expireBuilder.append(claim.getData().isExpired() ? MessageCache.getInstance().LABEL_YES.color(TextColor.RED) : MessageCache.getInstance().LABEL_NO.color(TextColor.GRAY)); } Component claimExpired = expireBuilder.build(); + Component farewellText = farewell == null ? NONE : farewell; + Component greetingText = greeting == null ? NONE : greeting; Component claimFarewell = TextComponent.builder() - .append(MessageCache.getInstance().LABEL_FAREWELL.color(TextColor.YELLOW)) + .append(MessageCache.getInstance().LABEL_FAREWELL.color(TextColor.YELLOW) + .clickEvent(ClickEvent.suggestCommand("/claimfarewell ")) + .hoverEvent(HoverEvent.showText(MessageCache.getInstance().CLAIMINFO_UI_CLICK_FAREWELL))) .append(" : ") - .append(farewell == null ? NONE : farewell).build(); + .append(farewellText + .clickEvent(ClickEvent.suggestCommand(farewell == null ? "/claimfarewell " : "/claimfarewell " + LegacyComponentSerializer.legacy().serialize(farewell, '&'))) + .hoverEvent(HoverEvent.showText(MessageCache.getInstance().CLAIMINFO_UI_CLICK_FAREWELL))) + .build(); Component claimGreeting = TextComponent.builder() - .append(MessageCache.getInstance().LABEL_GREETING.color(TextColor.YELLOW)) + .append(MessageCache.getInstance().LABEL_GREETING.color(TextColor.YELLOW) + .clickEvent(ClickEvent.suggestCommand("/claimgreeting ")) + .hoverEvent(HoverEvent.showText(MessageCache.getInstance().CLAIMINFO_UI_CLICK_GREETING))) .append(" : ") - .append(greeting == null ? NONE : greeting).build(); + .append(greetingText + .clickEvent(ClickEvent.suggestCommand(greeting == null ? "/claimgreeting " : "/claimgreeting " + LegacyComponentSerializer.legacy().serialize(greeting, '&'))) + .hoverEvent(HoverEvent.showText(MessageCache.getInstance().CLAIMINFO_UI_CLICK_GREETING))) + .build(); Component claimDenyMessages = TextComponent.builder() .append(MessageCache.getInstance().CLAIMINFO_UI_DENY_MESSAGES.color(TextColor.YELLOW)) .append(" : ") diff --git a/bukkit/src/main/java/com/griefdefender/command/CommandHelper.java b/bukkit/src/main/java/com/griefdefender/command/CommandHelper.java index daa9e10..53a8290 100644 --- a/bukkit/src/main/java/com/griefdefender/command/CommandHelper.java +++ b/bukkit/src/main/java/com/griefdefender/command/CommandHelper.java @@ -715,7 +715,9 @@ public static List generateClaimTextList(List claimsTextLi .append(claimSpawn != null ? claimSpawn.append(TextComponent.of(" ")) : TextComponent.of("")) .append(claimInfoCommandClick) .append(" : ", TextColor.WHITE) - .append(claim.getOwnerDisplayName().color(TextColor.GOLD)) + .append(claim.getOwnerDisplayName().color(TextColor.GOLD) + .clickEvent(ClickEvent.suggestCommand("/claimlist " + claim.getOwnerName())) + .hoverEvent(HoverEvent.showText(MessageCache.getInstance().CLAIMLIST_UI_CLICK_PLAYER_LIST))) .append(" ") .append(claimName == TextComponent.empty() ? TextComponent.of("") : claimName) .append(" ") @@ -730,7 +732,9 @@ public static List generateClaimTextList(List claimsTextLi .append(claimSpawn != null ? claimSpawn.append(TextComponent.of(" ")) : TextComponent.of("")) .append(claimInfoCommandClick) .append(" : ", TextColor.WHITE) - .append(claim.getOwnerDisplayName().color(TextColor.GOLD)) + .append(claim.getOwnerDisplayName().color(TextColor.GOLD) + .clickEvent(ClickEvent.suggestCommand("/claimlist " + claim.getOwnerName())) + .hoverEvent(HoverEvent.showText(MessageCache.getInstance().CLAIMLIST_UI_CLICK_PLAYER_LIST))) .append(" ") .append(claimName == TextComponent.empty() ? TextComponent.of("") : claimName) .append(buyClaim) diff --git a/bukkit/src/main/java/com/griefdefender/configuration/FlagStorage.java b/bukkit/src/main/java/com/griefdefender/configuration/FlagStorage.java index 0f6c231..9b2334e 100644 --- a/bukkit/src/main/java/com/griefdefender/configuration/FlagStorage.java +++ b/bukkit/src/main/java/com/griefdefender/configuration/FlagStorage.java @@ -28,6 +28,7 @@ import com.google.common.collect.Maps; import com.griefdefender.api.permission.flag.Flag; +import com.griefdefender.api.permission.flag.Flags; import com.griefdefender.configuration.category.ConfigCategory; import com.griefdefender.configuration.category.CustomFlagGroupDefinitionCategory; import com.griefdefender.configuration.category.DefaultFlagCategory; @@ -81,7 +82,11 @@ public class FlagStorage extends ConfigCategory { public FlagStorage() { for (Flag flag : FlagRegistryModule.getInstance().getAll()) { - this.control.put(flag.getName().toLowerCase(), true); + if (flag == Flags.ENTITY_CHUNK_SPAWN || flag == Flags.PORTAL_USE) { + this.control.put(flag.getName().toLowerCase(), false); + } else { + this.control.put(flag.getName().toLowerCase(), true); + } } } diff --git a/bukkit/src/main/java/com/griefdefender/configuration/MessageStorage.java b/bukkit/src/main/java/com/griefdefender/configuration/MessageStorage.java index 52c0c8e..45677d6 100644 --- a/bukkit/src/main/java/com/griefdefender/configuration/MessageStorage.java +++ b/bukkit/src/main/java/com/griefdefender/configuration/MessageStorage.java @@ -279,9 +279,11 @@ public class MessageStorage { public static final String PERMISSION_INVENTORY_OPEN = "permission-inventory-open"; public static final String PERMISSION_ITEM_DROP = "permission-item-drop"; public static final String PERMISSION_ITEM_USE = "permission-item-use"; - public static final String PERMISSION_PORTAL_ENTER = "permission-portal-enter"; - public static final String PERMISSION_PORTAL_EXIT = "permission-portal-exit"; + public static final String PERMISSION_PORTAL_FROM = "permission-portal-from"; + public static final String PERMISSION_PORTAL_TO = "permission-portal-to"; public static final String PERMISSION_PROTECTED_PORTAL = "permission-protected-portal"; + public static final String PERMISSION_TELEPORT_FROM = "permission-teleport-from"; + public static final String PERMISSION_TELEPORT_TO = "permission-teleport-to"; public static final String PERMISSION_TRUST = "permission-trust"; public static final String PLAYER_ACCRUED_BLOCKS_EXCEEDED = "player-accrued-blocks-exceeded"; public static final String PLAYER_NO_CLAIMS_TO_DELETE = "player-no-claims-to-delete"; diff --git a/bukkit/src/main/java/com/griefdefender/listener/BlockEventHandler.java b/bukkit/src/main/java/com/griefdefender/listener/BlockEventHandler.java index b3d3db8..aa17ec4 100644 --- a/bukkit/src/main/java/com/griefdefender/listener/BlockEventHandler.java +++ b/bukkit/src/main/java/com/griefdefender/listener/BlockEventHandler.java @@ -493,6 +493,9 @@ public void onExplosionEvent(BlockExplodeEvent event) { } for (Block block : event.blockList()) { final Location location = block.getLocation(); + if (location.getBlock().isEmpty()) { + continue; + } targetClaim = GriefDefenderPlugin.getInstance().dataStore.getClaimAt(location); if (denySurfaceExplosion && block.getWorld().getEnvironment() != Environment.NETHER && location.getBlockY() >= location.getWorld().getSeaLevel()) { filteredLocations.add(block); diff --git a/bukkit/src/main/java/com/griefdefender/listener/CommonEntityEventHandler.java b/bukkit/src/main/java/com/griefdefender/listener/CommonEntityEventHandler.java index aaaef4a..4b63efa 100644 --- a/bukkit/src/main/java/com/griefdefender/listener/CommonEntityEventHandler.java +++ b/bukkit/src/main/java/com/griefdefender/listener/CommonEntityEventHandler.java @@ -136,11 +136,6 @@ public boolean onEntityMove(Event event, Location fromLocation, Location toLocat if (!GriefDefenderPlugin.getInstance().claimsEnabledForWorld(world.getUID())) { return true; } - final boolean enterBlacklisted = GriefDefenderPlugin.isSourceIdBlacklisted(Flags.ENTER_CLAIM.getName(), targetEntity, world.getUID()); - final boolean exitBlacklisted = GriefDefenderPlugin.isSourceIdBlacklisted(Flags.EXIT_CLAIM.getName(), targetEntity, world.getUID()); - if (enterBlacklisted && exitBlacklisted) { - return true; - } GDClaim fromClaim = null; GDClaim toClaim = this.storage.getClaimAt(toLocation); @@ -243,13 +238,13 @@ public boolean onEntityMove(Event event, Location fromLocation, Location toLocat boolean enterCancelled = false; boolean exitCancelled = false; // enter - if (GDFlags.ENTER_CLAIM && !enterBlacklisted && GDPermissionManager.getInstance().getFinalPermission(event, toLocation, toClaim, Flags.ENTER_CLAIM, targetEntity, targetEntity, user, true) == Tristate.FALSE) { + if (GDFlags.ENTER_CLAIM && GDPermissionManager.getInstance().getFinalPermission(event, toLocation, toClaim, Flags.ENTER_CLAIM, targetEntity, targetEntity, user, true) == Tristate.FALSE) { enterCancelled = true; gpEvent.cancelled(true); } // exit - if (GDFlags.EXIT_CLAIM && !exitBlacklisted && GDPermissionManager.getInstance().getFinalPermission(event, fromLocation, fromClaim, Flags.EXIT_CLAIM, targetEntity, targetEntity, user, true) == Tristate.FALSE) { + if (GDFlags.EXIT_CLAIM && GDPermissionManager.getInstance().getFinalPermission(event, fromLocation, fromClaim, Flags.EXIT_CLAIM, targetEntity, targetEntity, user, true) == Tristate.FALSE) { exitCancelled = true; gpEvent.cancelled(true); } @@ -454,8 +449,10 @@ private void checkPlayerFlight(GDPermissionUser user, GDClaim fromClaim, GDClaim return; } - final Boolean noFly = GDPermissionManager.getInstance().getInternalOptionValue(TypeToken.of(Boolean.class), playerData.getSubject(), Options.PLAYER_DENY_FLIGHT, toClaim); - final boolean adminFly = playerData.userOptionBypassPlayerDenyFlight; + if (playerData.userOptionBypassPlayerDenyFlight) { + return; + } + boolean trustFly = false; if (toClaim.isBasicClaim() || (toClaim.parent != null && toClaim.parent.isBasicClaim()) || toClaim.isInTown()) { // check owner @@ -477,7 +474,13 @@ private void checkPlayerFlight(GDPermissionUser user, GDClaim fromClaim, GDClaim if (trustFly) { return; } - if (!adminFly && noFly) { + + Boolean noFly = playerData.optionNoFly; + if (noFly == null || fromClaim != toClaim) { + noFly = GDPermissionManager.getInstance().getInternalOptionValue(TypeToken.of(Boolean.class), playerData.getSubject(), Options.PLAYER_DENY_FLIGHT, toClaim); + playerData.optionNoFly = noFly; + } + if (noFly) { player.setAllowFlight(false); player.setFlying(false); playerData.ignoreFallDamage = true; @@ -504,7 +507,11 @@ private void checkPlayerGodMode(GDPermissionUser user, GDClaim fromClaim, GDClai return; } - final Boolean noGodMode = GDPermissionManager.getInstance().getInternalOptionValue(TypeToken.of(Boolean.class), playerData.getSubject(), Options.PLAYER_DENY_GODMODE, toClaim); + Boolean noGodMode = playerData.optionNoGodMode; + if (noGodMode == null || fromClaim != toClaim) { + noGodMode = GDPermissionManager.getInstance().getInternalOptionValue(TypeToken.of(Boolean.class), playerData.getSubject(), Options.PLAYER_DENY_GODMODE, toClaim); + playerData.optionNoGodMode = noGodMode; + } final boolean bypassOption = playerData.userOptionBypassPlayerDenyGodmode; if (!bypassOption && noGodMode) { player.setInvulnerable(false); @@ -527,7 +534,11 @@ private void checkPlayerGameMode(GDPermissionUser user, GDClaim fromClaim, GDCla final GDPlayerData playerData = user.getInternalPlayerData(); final GameMode currentGameMode = player.getGameMode(); - final GameModeType gameModeType = GDPermissionManager.getInstance().getInternalOptionValue(TypeToken.of(GameModeType.class), playerData.getSubject(), Options.PLAYER_GAMEMODE, toClaim); + GameModeType gameModeType = playerData.optionGameModeType; + if (gameModeType == null || fromClaim != toClaim) { + gameModeType = GDPermissionManager.getInstance().getInternalOptionValue(TypeToken.of(GameModeType.class), playerData.getSubject(), Options.PLAYER_GAMEMODE, toClaim); + playerData.optionGameModeType = gameModeType; + } if (gameModeType == GameModeTypes.UNDEFINED && playerData.lastGameMode != GameModeTypes.UNDEFINED) { player.setGameMode(PlayerUtil.GAMEMODE_MAP.get(playerData.lastGameMode)); return; @@ -562,7 +573,11 @@ private void checkPlayerFlySpeed(GDPermissionUser user, GDClaim fromClaim, GDCla final GDPlayerData playerData = user.getInternalPlayerData(); final float currentFlySpeed = player.getFlySpeed(); - final double flySpeed = GDPermissionManager.getInstance().getInternalOptionValue(TypeToken.of(Double.class), playerData.getSubject(), Options.PLAYER_FLY_SPEED, toClaim); + Double flySpeed = playerData.optionFlySpeed; + if (flySpeed == null || fromClaim != toClaim) { + flySpeed = GDPermissionManager.getInstance().getInternalOptionValue(TypeToken.of(Double.class), playerData.getSubject(), Options.PLAYER_FLY_SPEED, toClaim); + playerData.optionFlySpeed = flySpeed; + } if (flySpeed <= 0) { String configValue = GriefDefenderPlugin.getOptionConfig().getConfig().vanillaFallbackMap.get(Options.PLAYER_FLY_SPEED.getName().toLowerCase()); Double defaultFlySpeed = null; @@ -585,11 +600,11 @@ private void checkPlayerFlySpeed(GDPermissionUser user, GDClaim fromClaim, GDCla } if (flySpeed > 0) { - if (currentFlySpeed != ((float) flySpeed)) { - player.setFlySpeed((float) flySpeed); + if (currentFlySpeed != flySpeed.floatValue()) { + player.setFlySpeed(flySpeed.floatValue()); final Component message = GriefDefenderPlugin.getInstance().messageData.getMessage(MessageStorage.OPTION_APPLY_PLAYER_FLY_SPEED, ImmutableMap.of( - "speed", flySpeed)); + "speed", flySpeed.floatValue())); GriefDefenderPlugin.sendMessage(player, message); } } @@ -610,7 +625,11 @@ private void checkPlayerWalkSpeed(GDPermissionUser user, GDClaim fromClaim, GDCl final GDPlayerData playerData = user.getInternalPlayerData(); final float currentWalkSpeed = player.getWalkSpeed(); - final double walkSpeed = GDPermissionManager.getInstance().getInternalOptionValue(TypeToken.of(Double.class), playerData.getSubject(), Options.PLAYER_WALK_SPEED, toClaim); + Double walkSpeed = user.getInternalPlayerData().optionWalkSpeed; + if (walkSpeed == null || fromClaim != toClaim) { + walkSpeed = GDPermissionManager.getInstance().getInternalOptionValue(TypeToken.of(Double.class), playerData.getSubject(), Options.PLAYER_WALK_SPEED, toClaim); + user.getInternalPlayerData().optionWalkSpeed = walkSpeed; + } if (walkSpeed <= 0) { String configValue = GriefDefenderPlugin.getOptionConfig().getConfig().vanillaFallbackMap.get(Options.PLAYER_WALK_SPEED.getName().toLowerCase()); Double defaultWalkSpeed = null; @@ -633,11 +652,11 @@ private void checkPlayerWalkSpeed(GDPermissionUser user, GDClaim fromClaim, GDCl } if (walkSpeed > 0) { - if (currentWalkSpeed != ((float) walkSpeed)) { - player.setWalkSpeed((float) walkSpeed); + if (currentWalkSpeed != walkSpeed.floatValue()) { + player.setWalkSpeed(walkSpeed.floatValue()); final Component message = GriefDefenderPlugin.getInstance().messageData.getMessage(MessageStorage.OPTION_APPLY_PLAYER_WALK_SPEED, ImmutableMap.of( - "speed", walkSpeed)); + "speed", walkSpeed.floatValue())); GriefDefenderPlugin.sendMessage(player, message); } } @@ -657,7 +676,11 @@ public void checkPlayerWeather(GDPermissionUser user, GDClaim fromClaim, GDClaim } final GDPlayerData playerData = user.getInternalPlayerData(); - final WeatherType weatherType = GDPermissionManager.getInstance().getInternalOptionValue(TypeToken.of(WeatherType.class), playerData.getSubject(), Options.PLAYER_WEATHER, toClaim); + WeatherType weatherType = playerData.optionWeatherType; + if (weatherType == null || fromClaim != toClaim) { + weatherType = GDPermissionManager.getInstance().getInternalOptionValue(TypeToken.of(WeatherType.class), playerData.getSubject(), Options.PLAYER_WEATHER, toClaim); + playerData.optionWeatherType = weatherType; + } if (weatherType == null || weatherType == WeatherTypes.UNDEFINED) { player.resetPlayerWeather(); return; diff --git a/bukkit/src/main/java/com/griefdefender/listener/LuckPermsEventHandler.java b/bukkit/src/main/java/com/griefdefender/listener/LuckPermsEventHandler.java index 7037c7d..71d292a 100644 --- a/bukkit/src/main/java/com/griefdefender/listener/LuckPermsEventHandler.java +++ b/bukkit/src/main/java/com/griefdefender/listener/LuckPermsEventHandler.java @@ -24,9 +24,11 @@ */ package com.griefdefender.listener; -import com.griefdefender.GriefDefenderPlugin; +import org.bukkit.Bukkit; +import org.bukkit.entity.Player; + import com.griefdefender.cache.PermissionHolderCache; -import com.griefdefender.permission.GDPermissionHolder; +import com.griefdefender.permission.GDPermissionUser; import net.luckperms.api.LuckPerms; import net.luckperms.api.event.group.GroupDataRecalculateEvent; @@ -43,13 +45,16 @@ public LuckPermsEventHandler(LuckPerms luckPermsApi) { } public void onGroupDataRecalculate(GroupDataRecalculateEvent event) { - final GDPermissionHolder holder = PermissionHolderCache.getInstance().getOrCreateGroup(event.getGroup().getName()); - PermissionHolderCache.getInstance().getOrCreatePermissionCache(holder).invalidateAll(); + for (Player player : Bukkit.getOnlinePlayers()) { + final GDPermissionUser user = PermissionHolderCache.getInstance().getOrCreateUser(player); + user.getInternalPlayerData().resetOptionCache(); + } } public void onUserDataRecalculate(UserDataRecalculateEvent event) { - final GDPermissionHolder holder = PermissionHolderCache.getInstance().getOrCreateUser(event.getUser().getUniqueId()); - PermissionHolderCache.getInstance().getOrCreatePermissionCache(holder).invalidateAll(); - PermissionHolderCache.getInstance().getOrCreatePermissionCache(GriefDefenderPlugin.DEFAULT_HOLDER).invalidateAll(); + final GDPermissionUser user = PermissionHolderCache.getInstance().getOrCreateUser(event.getUser().getUniqueId()); + if (user.getOnlinePlayer() != null) { + user.getInternalPlayerData().resetOptionCache(); + } } } diff --git a/bukkit/src/main/java/com/griefdefender/listener/PlayerEventHandler.java b/bukkit/src/main/java/com/griefdefender/listener/PlayerEventHandler.java index 9bd558c..19fddbe 100644 --- a/bukkit/src/main/java/com/griefdefender/listener/PlayerEventHandler.java +++ b/bukkit/src/main/java/com/griefdefender/listener/PlayerEventHandler.java @@ -696,11 +696,14 @@ public void onPlayerBucketEvent(PlayerBucketEvent event) { final Object source = player; final Location location = clickedBlock.getLocation(); final GDClaim claim = this.dataStore.getClaimAt(location); - final TrustType trustType = NMSUtil.getInstance().isTileInventory(location) || clickedBlock != null && clickedBlock.getType() == Material.ENDER_CHEST ? TrustTypes.CONTAINER : TrustTypes.ACCESSOR; - - Tristate result = GDPermissionManager.getInstance().getFinalPermission(event, location, claim, Flags.INTERACT_BLOCK_SECONDARY, source, clickedBlock, player, trustType, true); + Tristate result = GDPermissionManager.getInstance().getFinalPermission(event, location, claim, Flags.INTERACT_BLOCK_SECONDARY, source, clickedBlock, player, TrustTypes.BUILDER, true); if (result == Tristate.FALSE) { event.setCancelled(true); + final Component message = GriefDefenderPlugin.getInstance().messageData.getMessage(MessageStorage.PERMISSION_INTERACT_ITEM_BLOCK, + ImmutableMap.of( + "item", "minecraft:" + event.getBucket().name().toLowerCase().toLowerCase(), + "block", BlockTypeRegistryModule.getInstance().getNMSKey(clickedBlock))); + GriefDefenderPlugin.sendClaimDenyMessage(claim, player, message); GDTimings.PLAYER_INTERACT_BLOCK_SECONDARY_EVENT.stopTiming(); return; } @@ -712,16 +715,20 @@ public void onPlayerBucketEvent(PlayerBucketEvent event) { result = GDPermissionManager.getInstance().getFinalPermission(event, location, claim, Flags.BLOCK_PLACE, source, event.getBucket().name().toLowerCase().replace("_bucket", ""), player, TrustTypes.BUILDER, true); if (result == Tristate.FALSE) { event.setCancelled(true); - return; } } else if (event instanceof PlayerBucketFillEvent) { // check block break result = GDPermissionManager.getInstance().getFinalPermission(event, location, claim, Flags.BLOCK_BREAK, source, event.getBlockClicked(), player, TrustTypes.BUILDER, true); if (result == Tristate.FALSE) { event.setCancelled(true); - return; } } + if (event.isCancelled()) { + final Component message = GriefDefenderPlugin.getInstance().messageData.getMessage(MessageStorage.PERMISSION_BUILD, + ImmutableMap.of( + "player", claim.getOwnerDisplayName())); + GriefDefenderPlugin.sendClaimDenyMessage(claim, player, message); + } } public void onPlayerInteractBlockPrimary(PlayerInteractEvent event, Player player) { @@ -927,6 +934,10 @@ public void onPlayerTeleport(PlayerTeleportEvent event) { final TeleportCause type = event.getCause(); final Location sourceLocation = event.getFrom(); final Location destination = event.getTo(); + Object source = type; + if (type == TeleportCause.UNKNOWN && !sourceLocation.getWorld().getUID().equals(destination.getWorld().getUID())) { + source = destination.getWorld().getEnvironment().name().toLowerCase().replace("the_", "") + "_portal"; + } final GDPlayerData playerData = GriefDefenderPlugin.getInstance().dataStore.getOrCreatePlayerData(player.getWorld(), player.getUniqueId()); final GDClaim sourceClaim = this.dataStore.getClaimAtPlayer(playerData, player.getLocation()); if (playerData.inPvpCombat() && GDOptions.isOptionEnabled(Options.PVP_COMBAT_TELEPORT)) { @@ -954,18 +965,17 @@ public void onPlayerTeleport(PlayerTeleportEvent event) { } if (sourceClaim != null) { - final Component message = GriefDefenderPlugin.getInstance().messageData.getMessage(MessageStorage.PERMISSION_PORTAL_EXIT, + Component message = null; + if (type == TeleportCause.END_PORTAL || type == TeleportCause.NETHER_PORTAL || source != type) { + message = GriefDefenderPlugin.getInstance().messageData.getMessage(MessageStorage.PERMISSION_PORTAL_FROM, ImmutableMap.of( "player", sourceClaim.getOwnerDisplayName())); - if (GDFlags.ENTITY_TELEPORT_FROM && !teleportFromBlacklisted && GDPermissionManager.getInstance().getFinalPermission(event, sourceLocation, sourceClaim, Flags.ENTITY_TELEPORT_FROM, type, player, player, TrustTypes.ACCESSOR, true) == Tristate.FALSE) { - if (player != null) { - GriefDefenderPlugin.sendMessage(player, message); - } - - event.setCancelled(true); - GDTimings.ENTITY_TELEPORT_EVENT.stopTiming(); - return; - } else if (GDFlags.EXIT_CLAIM && !teleportFromBlacklisted && GDPermissionManager.getInstance().getFinalPermission(event, sourceLocation, sourceClaim, Flags.EXIT_CLAIM, type, player, player, TrustTypes.ACCESSOR, true) == Tristate.FALSE) { + } else { + message = GriefDefenderPlugin.getInstance().messageData.getMessage(MessageStorage.PERMISSION_TELEPORT_FROM, + ImmutableMap.of( + "player", sourceClaim.getOwnerDisplayName())); + } + if (GDFlags.ENTITY_TELEPORT_FROM && !teleportFromBlacklisted && GDPermissionManager.getInstance().getFinalPermission(event, sourceLocation, sourceClaim, Flags.ENTITY_TELEPORT_FROM, source, player, player, TrustTypes.ACCESSOR, true) == Tristate.FALSE) { if (player != null) { GriefDefenderPlugin.sendMessage(player, message); } @@ -985,18 +995,17 @@ public void onPlayerTeleport(PlayerTeleportEvent event) { final GDClaim toClaim = this.dataStore.getClaimAt(destination); if (toClaim != null) { - final Component message = GriefDefenderPlugin.getInstance().messageData.getMessage(MessageStorage.PERMISSION_PORTAL_ENTER, + Component message = null; + if (type == TeleportCause.END_PORTAL || type == TeleportCause.NETHER_PORTAL || source != type) { + message = GriefDefenderPlugin.getInstance().messageData.getMessage(MessageStorage.PERMISSION_PORTAL_TO, ImmutableMap.of( "player", toClaim.getOwnerDisplayName())); - if (GDFlags.ENTITY_TELEPORT_TO && !teleportToBlacklisted && GDPermissionManager.getInstance().getFinalPermission(event, destination, toClaim, Flags.ENTITY_TELEPORT_TO, type, player, player, TrustTypes.ACCESSOR, true) == Tristate.FALSE) { - if (player != null) { - GriefDefenderPlugin.sendMessage(player, message); - } - - event.setCancelled(true); - GDTimings.ENTITY_TELEPORT_EVENT.stopTiming(); - return; - } else if (GDFlags.ENTER_CLAIM && !teleportToBlacklisted && GDPermissionManager.getInstance().getFinalPermission(event, destination, toClaim, Flags.ENTER_CLAIM, type, player, player, TrustTypes.ACCESSOR, true) == Tristate.FALSE) { + } else { + message = GriefDefenderPlugin.getInstance().messageData.getMessage(MessageStorage.PERMISSION_TELEPORT_TO, + ImmutableMap.of( + "player", toClaim.getOwnerDisplayName())); + } + if (GDFlags.ENTITY_TELEPORT_TO && !teleportToBlacklisted && GDPermissionManager.getInstance().getFinalPermission(event, destination, toClaim, Flags.ENTITY_TELEPORT_TO, source, player, player, TrustTypes.ACCESSOR, true) == Tristate.FALSE) { if (player != null) { GriefDefenderPlugin.sendMessage(player, message); } @@ -1564,13 +1573,13 @@ private void handleResizeFinish(PlayerInteractEvent event, Player player, Locati if (GriefDefenderPlugin.CLAIM_BLOCK_SYSTEM == ClaimBlockSystem.VOLUME) { final double claimableChunks = claimBlocksRemaining / 65536.0; final Map params = ImmutableMap.of( - "balance", String.valueOf("$" + vaultProvider.getBalance(player)), + "balance", "$" + String.format("%.2f", vaultProvider.getBalance(player)), "chunk-amount", Math.round(claimableChunks * 100.0)/100.0, "block-amount", claimBlocksRemaining); GriefDefenderPlugin.sendMessage(player, GriefDefenderPlugin.getInstance().messageData.getMessage(MessageStorage.ECONOMY_MODE_RESIZE_SUCCESS_3D, params)); } else { final Map params = ImmutableMap.of( - "balance", String.valueOf("$" + vaultProvider.getBalance(player)), + "balance", "$" + String.format("%.2f", vaultProvider.getBalance(player)), "block-amount", claimBlocksRemaining); GriefDefenderPlugin.sendMessage(player, GriefDefenderPlugin.getInstance().messageData.getMessage(MessageStorage.ECONOMY_MODE_RESIZE_SUCCESS_2D, params)); } diff --git a/bukkit/src/main/java/com/griefdefender/permission/GDPermissionManager.java b/bukkit/src/main/java/com/griefdefender/permission/GDPermissionManager.java index 195f3ce..761ba35 100644 --- a/bukkit/src/main/java/com/griefdefender/permission/GDPermissionManager.java +++ b/bukkit/src/main/java/com/griefdefender/permission/GDPermissionManager.java @@ -728,6 +728,10 @@ public Set getPermissionContexts(GDClaim claim, Object obj, boolean isS final DamageCause damageCause = (DamageCause) obj; String id = damageCause.name().toLowerCase(); return populateEventSourceTargetContext(contexts, id, isSource); + } else if (obj instanceof TeleportCause) { + final TeleportCause teleportCause = (TeleportCause) obj; + String id = teleportCause.name().toLowerCase(); + return populateEventSourceTargetContext(contexts, id, isSource); } else if (obj instanceof SpawnReason) { return populateEventSourceTargetContext(contexts, "spawnreason:" + ((SpawnReason) obj).name().toLowerCase(), isSource); } else if (obj instanceof CreatureSpawner) { @@ -1145,8 +1149,7 @@ public CompletableFuture setPermission(Subject subject, Flag f return result; } - result.complete(PermissionUtil.getInstance().setPermissionValue((GDPermissionHolder) subject, flag, value, contexts)); - return result; + return PermissionUtil.getInstance().setPermissionValue((GDPermissionHolder) subject, flag, value, contexts); } // internal @@ -1556,14 +1559,12 @@ public CompletableFuture setFlagPermission(Flag flag, Subject @Override public CompletableFuture setOption(Option option, String value, Set contexts) { - final PermissionResult result = PermissionUtil.getInstance().setOptionValue(GriefDefenderPlugin.DEFAULT_HOLDER, option.getPermission(), value, contexts); - return CompletableFuture.completedFuture(result); + return PermissionUtil.getInstance().setOptionValue(GriefDefenderPlugin.DEFAULT_HOLDER, option.getPermission(), value, contexts); } @Override public CompletableFuture setOption(Option option, Subject subject, String value, Set contexts) { - final PermissionResult result = PermissionUtil.getInstance().setOptionValue((GDPermissionHolder) subject, option.getPermission(), value, contexts); - return CompletableFuture.completedFuture(result); + return PermissionUtil.getInstance().setOptionValue((GDPermissionHolder) subject, option.getPermission(), value, contexts); } @Override @@ -1596,16 +1597,17 @@ public T getActiveOptionValue(TypeToken type, Option option, Subject s public CompletableFuture setFlagDefinition(Subject subject, FlagDefinition flagDefinition, Tristate value) { final Set contexts = new HashSet<>(); contexts.addAll(flagDefinition.getContexts()); - PermissionResult result = null; + PermissionResult result = new GDPermissionResult(ResultTypes.SUCCESS, TextComponent.builder().append("SUCCESS").build()); CompletableFuture future = new CompletableFuture<>(); for (FlagData flagData : flagDefinition.getFlagData()) { final Set flagContexts = new HashSet<>(contexts); flagContexts.addAll(flagData.getContexts()); - result = PermissionUtil.getInstance().setPermissionValue((GDPermissionHolder) subject, flagData.getFlag(), value, flagContexts); - if (!result.successful()) { + // TODO - Add method that supports multiple permissions + PermissionUtil.getInstance().setPermissionValue((GDPermissionHolder) subject, flagData.getFlag(), value, flagContexts); + /*if (!result.successful()) { future.complete(result); return future; - } + }*/ } future.complete(result); diff --git a/bukkit/src/main/java/com/griefdefender/permission/flag/FlagContexts.java b/bukkit/src/main/java/com/griefdefender/permission/flag/FlagContexts.java index 01a9e42..1e28d46 100644 --- a/bukkit/src/main/java/com/griefdefender/permission/flag/FlagContexts.java +++ b/bukkit/src/main/java/com/griefdefender/permission/flag/FlagContexts.java @@ -33,6 +33,7 @@ public class FlagContexts { public static final Context SOURCE_CREEPER = new Context(ContextKeys.SOURCE, "minecraft:creeper"); public static final Context SOURCE_ENDERDRAGON = new Context(ContextKeys.SOURCE, "minecraft:enderdragon"); public static final Context SOURCE_ENDERMAN = new Context(ContextKeys.SOURCE, "minecraft:enderman"); + public static final Context SOURCE_END_PORTAL = new Context(ContextKeys.SOURCE, "minecraft:end_portal"); public static final Context SOURCE_FALL = new Context(ContextKeys.SOURCE, "minecraft:fall"); public static final Context SOURCE_FALLING_BLOCK = new Context(ContextKeys.SOURCE, "minecraft:falling_block"); public static final Context SOURCE_FIRE = new Context(ContextKeys.SOURCE, "minecraft:fire"); @@ -44,6 +45,7 @@ public class FlagContexts { public static final Context SOURCE_LAVA_1_12 = new Context(ContextKeys.SOURCE, "minecraft:flowing_lava"); public static final Context SOURCE_LIGHTNING_BOLT = new Context(ContextKeys.SOURCE, "minecraft:lightning_bolt"); public static final Context SOURCE_MAGMA_BLOCK = new Context(ContextKeys.SOURCE, "minecraft:magma_block"); + public static final Context SOURCE_NETHER_PORTAL = new Context(ContextKeys.SOURCE, "minecraft:nether_portal"); public static final Context SOURCE_PISTON = new Context(ContextKeys.SOURCE, "minecraft:piston"); public static final Context SOURCE_PISTON_STICKY = new Context(ContextKeys.SOURCE, "minecraft:sticky_piston"); public static final Context SOURCE_PLAYER = new Context(ContextKeys.SOURCE, "minecraft:player"); @@ -99,7 +101,6 @@ public class FlagContexts { public static final Context TARGET_TYPE_FOOD = new Context(ContextKeys.TARGET, "#food"); public static final Context TARGET_TYPE_MONSTER = new Context(ContextKeys.TARGET, "#monster"); public static final Context TARGET_TYPE_MUSHROOM = new Context(ContextKeys.TARGET, "#mushroom"); - public static final Context TARGET_TYPE_PORTAL = new Context(ContextKeys.TARGET, "#portal"); public static final Context TARGET_TYPE_VEHICLE = new Context(ContextKeys.TARGET, "#vehicle"); public static final Context USED_ITEM_LAVA_BUCKET = new Context(ContextKeys.USED_ITEM, "minecraft:lava_bucket"); diff --git a/bukkit/src/main/java/com/griefdefender/permission/flag/GDFlag.java b/bukkit/src/main/java/com/griefdefender/permission/flag/GDFlag.java index 9f58a85..d3e68ba 100644 --- a/bukkit/src/main/java/com/griefdefender/permission/flag/GDFlag.java +++ b/bukkit/src/main/java/com/griefdefender/permission/flag/GDFlag.java @@ -84,7 +84,6 @@ public boolean getDefaultClaimTypeValue(ClaimType type) { if (type == null || type != ClaimTypes.WILDERNESS) { switch (this.name) { case "block-break" : - case "block-modify" : case "block-place" : case "collide-block" : case "collide-entity" : diff --git a/bukkit/src/main/java/com/griefdefender/provider/LuckPermsProvider.java b/bukkit/src/main/java/com/griefdefender/provider/LuckPermsProvider.java index 5c6daa5..79b58e2 100644 --- a/bukkit/src/main/java/com/griefdefender/provider/LuckPermsProvider.java +++ b/bukkit/src/main/java/com/griefdefender/provider/LuckPermsProvider.java @@ -36,6 +36,8 @@ import com.griefdefender.cache.PermissionHolderCache; import com.griefdefender.claim.ClaimContextCalculator; import com.griefdefender.claim.GDClaim; +import com.griefdefender.listener.LuckPermsEventHandler; +import com.griefdefender.permission.GDPermissionGroup; import com.griefdefender.permission.GDPermissionHolder; import com.griefdefender.permission.GDPermissionResult; import com.griefdefender.permission.GDPermissionUser; @@ -75,8 +77,10 @@ import java.util.TreeMap; import java.util.UUID; import java.util.Map.Entry; +import java.util.Optional; import java.util.concurrent.CompletableFuture; import java.util.concurrent.ExecutionException; +import java.util.function.Function; import java.util.function.Predicate; import org.bukkit.Bukkit; @@ -107,6 +111,7 @@ public int compare(Set s1, Set s2) { public LuckPermsProvider() { this.luckPermsApi = Bukkit.getServicesManager().getRegistration(LuckPerms.class).getProvider(); this.luckPermsApi.getContextManager().registerCalculator(new ClaimContextCalculator()); + new LuckPermsEventHandler(this.luckPermsApi); } public LuckPerms getApi() { @@ -662,37 +667,119 @@ public List getOptionValueList(GDPermissionHolder holder, Option option, return list; } - public PermissionResult setOptionValue(GDPermissionHolder holder, String key, String value, Set contexts, boolean check) { - DataMutateResult result = null; + public CompletableFuture setOptionValue(GDPermissionHolder holder, String key, String value, Set contexts, boolean check) { if (check) { // If no server context exists, add global this.checkServerContext(contexts); } ImmutableContextSet set = this.getLPContexts(contexts).immutableCopy(); - final PermissionHolder permissionHolder = this.getLuckPermsHolder(holder); - if (permissionHolder == null) { - new GDPermissionResult(ResultTypes.FAILURE); - } - final Option option = OptionRegistryModule.getInstance().getById(key).orElse(null); if (option == null) { new GDPermissionResult(ResultTypes.FAILURE); } final Node node = MetaNode.builder().key(key).value(value).context(set).build(); + if (holder instanceof GDPermissionGroup) { + return this.luckPermsApi.getGroupManager().loadGroup(holder.getFriendlyName()).thenApplyAsync((Function, ? extends PermissionResult>) lpHolder -> { + final Group group = lpHolder.orElse(null); + if (group != null) { + return this.applyOptionNode(holder, group, node, option, value); + } + return new GDPermissionResult(ResultTypes.FAILURE, TextComponent.builder().append("COULD NOT LOAD GROUP " + holder.getFriendlyName()).build()); + }); + } else { + return this.luckPermsApi.getUserManager().loadUser(((GDPermissionUser) holder).getUniqueId()).thenApplyAsync((Function) lpHolder -> { + return this.applyOptionNode(holder, lpHolder, node, option, value); + }); + } + } + + public CompletableFuture setPermissionValue(GDPermissionHolder holder, String permission, Tristate value, Set contexts, boolean check, boolean save) { + if (check) { + // If no server context exists, add global + this.checkServerContext(contexts); + } + ImmutableContextSet set = this.getLPContexts(contexts).immutableCopy(); + final Node node = this.luckPermsApi.getNodeBuilderRegistry().forPermission().permission(permission).value(value.asBoolean()).context(set).build(); + + if (holder instanceof GDPermissionGroup) { + return this.luckPermsApi.getGroupManager().loadGroup(holder.getFriendlyName()).thenApplyAsync((Function, ? extends PermissionResult>) lpHolder -> { + final Group group = lpHolder.orElse(null); + if (group != null) { + return this.applyPermissionNode(holder, group, node, value, save); + } + return new GDPermissionResult(ResultTypes.FAILURE, TextComponent.builder().append("COULD NOT LOAD GROUP " + holder.getFriendlyName()).build()); + }); + } else { + return this.luckPermsApi.getUserManager().loadUser(((GDPermissionUser) holder).getUniqueId()).thenApplyAsync((Function) lpHolder -> { + return this.applyPermissionNode(holder, lpHolder, node, value, save); + }); + } + } + + public CompletableFuture setTransientOption(GDPermissionHolder holder, String permission, String value, Set contexts) { + // If no server context exists, add global + this.checkServerContext(contexts); + MutableContextSet contextSet = this.getLPContexts(contexts); + + Node node = null; + if (value == null) { + node = this.luckPermsApi.getNodeBuilderRegistry().forMeta().key(permission).context(contextSet).build(); + } else { + node = this.luckPermsApi.getNodeBuilderRegistry().forMeta().key(permission).value(value).context(contextSet).build(); + } + final Node permissionNode = node; + if (holder instanceof GDPermissionGroup) { + return this.luckPermsApi.getGroupManager().loadGroup(holder.getFriendlyName()).thenApplyAsync((Function, ? extends PermissionResult>) lpHolder -> { + final Group group = lpHolder.orElse(null); + if (group != null) { + return this.applyTransientOptionNode(holder, group, permissionNode, value); + } + return new GDPermissionResult(ResultTypes.FAILURE, TextComponent.builder().append("COULD NOT LOAD GROUP " + holder.getFriendlyName()).build()); + }); + } else { + return this.luckPermsApi.getUserManager().loadUser(((GDPermissionUser) holder).getUniqueId()).thenApplyAsync((Function) lpHolder -> { + return this.applyTransientOptionNode(holder, lpHolder, permissionNode, value); + }); + } + } + + public CompletableFuture setTransientPermission(GDPermissionHolder holder, String permission, Tristate value, Set contexts) { + // If no server context exists, add global + this.checkServerContext(contexts); + MutableContextSet contextSet = this.getLPContexts(contexts); + final Node node = this.luckPermsApi.getNodeBuilderRegistry().forPermission().permission(permission).value(value.asBoolean()).context(contextSet).build(); + + if (holder instanceof GDPermissionGroup) { + return this.luckPermsApi.getGroupManager().loadGroup(holder.getFriendlyName()).thenApplyAsync((Function, ? extends PermissionResult>) lpHolder -> { + final Group group = lpHolder.orElse(null); + if (group != null) { + return this.applyTransientPermissionNode(holder, group, node, value); + } + return new GDPermissionResult(ResultTypes.FAILURE, TextComponent.builder().append("COULD NOT LOAD GROUP " + holder.getFriendlyName()).build()); + }); + } else { + return this.luckPermsApi.getUserManager().loadUser(((GDPermissionUser) holder).getUniqueId()).thenApplyAsync((Function) lpHolder -> { + return this.applyTransientPermissionNode(holder, lpHolder, node, value); + }); + } + } + + public PermissionResult applyOptionNode(GDPermissionHolder holder, PermissionHolder lpHolder, Node node, Option option, String value) { + DataMutateResult result = null; if (!value.equalsIgnoreCase("undefined")) { if (!option.multiValued()) { - this.clearMeta(permissionHolder, key, set); + this.clearMeta(lpHolder, option.getPermission(), node.getContexts()); } - result = permissionHolder.data().add(node); + result = lpHolder.data().add(node); } else { - this.clearMeta(permissionHolder, key, set); - this.savePermissionHolder(permissionHolder); + this.clearMeta(lpHolder, option.getPermission(), node.getContexts()); + this.savePermissionHolder(lpHolder); return new GDPermissionResult(ResultTypes.SUCCESS); } if (result != null) { if (result.wasSuccessful()) { - this.savePermissionHolder(permissionHolder); + this.savePermissionHolder(lpHolder); return new GDPermissionResult(ResultTypes.SUCCESS, TextComponent.builder().append(result.name()).build()); } return new GDPermissionResult(ResultTypes.FAILURE, TextComponent.builder().append(result.name()).build()); @@ -701,27 +788,34 @@ public PermissionResult setOptionValue(GDPermissionHolder holder, String key, St return new GDPermissionResult(ResultTypes.FAILURE); } - public PermissionResult setPermissionValue(GDPermissionHolder holder, String permission, Tristate value, Set contexts, boolean check, boolean save) { + public PermissionResult applyTransientOptionNode(GDPermissionHolder holder, PermissionHolder lpHolder, Node node, String value) { DataMutateResult result = null; - if (check) { - // If no server context exists, add global - this.checkServerContext(contexts); - } - ImmutableContextSet set = this.getLPContexts(contexts).immutableCopy(); - final Node node = this.luckPermsApi.getNodeBuilderRegistry().forPermission().permission(permission).value(value.asBoolean()).context(set).build(); - final PermissionHolder permissionHolder = this.getLuckPermsHolder(holder); - if (permissionHolder == null) { - return new GDPermissionResult(ResultTypes.FAILURE); + if (value == null) { + result = lpHolder.transientData().remove(node); + } else { + result = lpHolder.transientData().add(node); } + if (result != null) { + if (result.wasSuccessful()) { + return new GDPermissionResult(ResultTypes.SUCCESS, TextComponent.builder().append(result.name()).build()); + } + return new GDPermissionResult(ResultTypes.FAILURE, TextComponent.builder().append(result.name()).build()); + } + + return new GDPermissionResult(ResultTypes.FAILURE); + } + + public PermissionResult applyPermissionNode(GDPermissionHolder holder, PermissionHolder lpHolder, Node node, Tristate value, boolean save) { + DataMutateResult result = null; if (value == Tristate.UNDEFINED) { - result = permissionHolder.data().remove(node); + result = lpHolder.data().remove(node); } else { - result = permissionHolder.data().add(node); + result = lpHolder.data().add(node); } if (result.wasSuccessful()) { - if (permissionHolder instanceof Group) { + if (holder instanceof Group) { // If a group is changed, we invalidate all cache PermissionHolderCache.getInstance().invalidateAllPermissionCache(); } else { @@ -730,7 +824,7 @@ public PermissionResult setPermissionValue(GDPermissionHolder holder, String per } if (save) { - this.savePermissionHolder(permissionHolder); + this.savePermissionHolder(lpHolder); } return new GDPermissionResult(ResultTypes.SUCCESS, TextComponent.builder().append(result.name()).build()); @@ -739,46 +833,12 @@ public PermissionResult setPermissionValue(GDPermissionHolder holder, String per return new GDPermissionResult(ResultTypes.FAILURE, TextComponent.builder().append(result.name()).build()); } - public PermissionResult setTransientOption(GDPermissionHolder holder, String permission, String value, Set contexts) { - // If no server context exists, add global - this.checkServerContext(contexts); - MutableContextSet contextSet = this.getLPContexts(contexts); - final PermissionHolder permissionHolder = this.getLuckPermsHolder(holder); - if (permissionHolder == null) { - return new GDPermissionResult(ResultTypes.FAILURE, TextComponent.builder().append("invalid").build()); - } - + public PermissionResult applyTransientPermissionNode(GDPermissionHolder holder, PermissionHolder lpHolder, Node node, Tristate value) { DataMutateResult result = null; - if (value == null) { - final Node node = this.luckPermsApi.getNodeBuilderRegistry().forMeta().key(permission).context(contextSet).build(); - result = permissionHolder.transientData().remove(node); + if (value == null || value == Tristate.UNDEFINED) { + result = lpHolder.transientData().remove(node); } else { - final Node node = this.luckPermsApi.getNodeBuilderRegistry().forMeta().key(permission).value(value).context(contextSet).build(); - result = permissionHolder.transientData().add(node); - } - - if (result.wasSuccessful()) { - return new GDPermissionResult(ResultTypes.SUCCESS, TextComponent.builder().append(result.name()).build()); - } - return new GDPermissionResult(ResultTypes.FAILURE, TextComponent.builder().append(result.name()).build()); - } - - public PermissionResult setTransientPermission(GDPermissionHolder holder, String permission, Tristate value, Set contexts) { - // If no server context exists, add global - this.checkServerContext(contexts); - MutableContextSet contextSet = this.getLPContexts(contexts); - final PermissionHolder permissionHolder = this.getLuckPermsHolder(holder); - if (permissionHolder == null) { - return new GDPermissionResult(ResultTypes.FAILURE, TextComponent.builder().append("invalid").build()); - } - - DataMutateResult result = null; - if (value == Tristate.UNDEFINED) { - final Node node = this.luckPermsApi.getNodeBuilderRegistry().forPermission().permission(permission).value(value.asBoolean()).context(contextSet).build(); - result = permissionHolder.transientData().remove(node); - } else { - final PermissionNode node = this.luckPermsApi.getNodeBuilderRegistry().forPermission().permission(permission).value(value.asBoolean()).context(contextSet).build(); - result = permissionHolder.transientData().add(node); + result = lpHolder.transientData().add(node); } if (result.wasSuccessful()) { diff --git a/bukkit/src/main/java/com/griefdefender/provider/PermissionProvider.java b/bukkit/src/main/java/com/griefdefender/provider/PermissionProvider.java index 6754398..d8c9b1f 100644 --- a/bukkit/src/main/java/com/griefdefender/provider/PermissionProvider.java +++ b/bukkit/src/main/java/com/griefdefender/provider/PermissionProvider.java @@ -297,7 +297,7 @@ public enum PermissionDataType { * @param check Whether to check and apply a server context if none exists * @return The permission result */ - default PermissionResult setOptionValue(GDPermissionHolder holder, String permission, String value, Set contexts) { + default CompletableFuture setOptionValue(GDPermissionHolder holder, String permission, String value, Set contexts) { return this.setOptionValue(holder, permission, value, contexts, true); } @@ -311,7 +311,7 @@ default PermissionResult setOptionValue(GDPermissionHolder holder, String permis * @param check Whether to check and apply a server context if none exists * @return The permission result */ - PermissionResult setOptionValue(GDPermissionHolder holder, String permission, String value, Set contexts, boolean check); + CompletableFuture setOptionValue(GDPermissionHolder holder, String permission, String value, Set contexts, boolean check); /** * Sets a permission and value with contexts to a holder. @@ -322,7 +322,7 @@ default PermissionResult setOptionValue(GDPermissionHolder holder, String permis * @param contexts The contexts * @return The permission result */ - default PermissionResult setPermissionValue(GDPermissionHolder holder, Flag flag, Tristate value, Set contexts) { + default CompletableFuture setPermissionValue(GDPermissionHolder holder, Flag flag, Tristate value, Set contexts) { return this.setPermissionValue(holder, flag.getPermission(), value, contexts, true, true); } @@ -337,7 +337,7 @@ default PermissionResult setPermissionValue(GDPermissionHolder holder, Flag flag * @param save Whether a save should occur * @return The permission result */ - default PermissionResult setPermissionValue(GDPermissionHolder holder, Flag flag, Tristate value, Set contexts, boolean check, boolean save) { + default CompletableFuture setPermissionValue(GDPermissionHolder holder, Flag flag, Tristate value, Set contexts, boolean check, boolean save) { return this.setPermissionValue(holder, flag.getPermission(), value, contexts, check, save); } @@ -350,7 +350,7 @@ default PermissionResult setPermissionValue(GDPermissionHolder holder, Flag flag * @param contexts The contexts * @return Whether the set permission operation was successful */ - default PermissionResult setPermissionValue(GDPermissionHolder holder, String permission, Tristate value, Set contexts) { + default CompletableFuture setPermissionValue(GDPermissionHolder holder, String permission, Tristate value, Set contexts) { return this.setPermissionValue(holder, permission, value, contexts, true, true); } @@ -365,7 +365,7 @@ default PermissionResult setPermissionValue(GDPermissionHolder holder, String pe * @param save Whether a save should occur * @return Whether the set permission operation was successful */ - PermissionResult setPermissionValue(GDPermissionHolder holder, String permission, Tristate value, Set contexts, boolean check, boolean save); + CompletableFuture setPermissionValue(GDPermissionHolder holder, String permission, Tristate value, Set contexts, boolean check, boolean save); /** * Sets a transient option and value with contexts to a holder. @@ -376,7 +376,7 @@ default PermissionResult setPermissionValue(GDPermissionHolder holder, String pe * @param contexts The contexts * @return Whether the set permission operation was successful */ - PermissionResult setTransientOption(GDPermissionHolder holder, String permission, String value, Set contexts); + CompletableFuture setTransientOption(GDPermissionHolder holder, String permission, String value, Set contexts); /** * Sets a transient permission and value with contexts to a holder. @@ -387,7 +387,7 @@ default PermissionResult setPermissionValue(GDPermissionHolder holder, String pe * @param contexts The contexts * @return Whether the set permission operation was successful */ - PermissionResult setTransientPermission(GDPermissionHolder holder, String permission, Tristate value, Set contexts); + CompletableFuture setTransientPermission(GDPermissionHolder holder, String permission, Tristate value, Set contexts); /** * Refreshes all cached permission data of holder. diff --git a/bukkit/src/main/java/com/griefdefender/provider/permissionsex/PermissionsExProvider.java b/bukkit/src/main/java/com/griefdefender/provider/permissionsex/PermissionsExProvider.java index 8f8c012..dbb9725 100644 --- a/bukkit/src/main/java/com/griefdefender/provider/permissionsex/PermissionsExProvider.java +++ b/bukkit/src/main/java/com/griefdefender/provider/permissionsex/PermissionsExProvider.java @@ -396,18 +396,18 @@ public List getOptionValueList(GDPermissionHolder holder, Option option, } @Override - public PermissionResult setOptionValue(GDPermissionHolder holder, String permission, String value, Set contexts, boolean check) { - return convertResult(holderToPEXSubject(holder).data().update(data -> data.setOption(contextsGDToPEX(contexts), permission, value))).join(); + public CompletableFuture setOptionValue(GDPermissionHolder holder, String permission, String value, Set contexts, boolean check) { + return convertResult(holderToPEXSubject(holder).data().update(data -> data.setOption(contextsGDToPEX(contexts), permission, value))); } @Override - public PermissionResult setTransientOption(GDPermissionHolder holder, String permission, String value, Set contexts) { - return convertResult(holderToPEXSubject(holder).transientData().update(data -> data.setOption(contextsGDToPEX(contexts), permission, value))).join(); + public CompletableFuture setTransientOption(GDPermissionHolder holder, String permission, String value, Set contexts) { + return convertResult(holderToPEXSubject(holder).transientData().update(data -> data.setOption(contextsGDToPEX(contexts), permission, value))); } @Override - public PermissionResult setTransientPermission(GDPermissionHolder holder, String permission, Tristate value, Set contexts) { - return convertResult(holderToPEXSubject(holder).transientData().update(data -> data.setPermission(contextsGDToPEX(contexts), permission, pValFromBool(value.asBoolean())))).join(); + public CompletableFuture setTransientPermission(GDPermissionHolder holder, String permission, Tristate value, Set contexts) { + return convertResult(holderToPEXSubject(holder).transientData().update(data -> data.setPermission(contextsGDToPEX(contexts), permission, pValFromBool(value.asBoolean())))); } @Override @@ -417,8 +417,8 @@ public void refreshCachedData(GDPermissionHolder holder) { } @Override - public PermissionResult setPermissionValue(GDPermissionHolder holder, String permission, Tristate value, Set contexts, boolean check, boolean save) { - return convertResult(holderToPEXSubject(holder).data().update(data -> data.setPermission(contextsGDToPEX(contexts), permission, intFromTristate(value)))).join(); + public CompletableFuture setPermissionValue(GDPermissionHolder holder, String permission, Tristate value, Set contexts, boolean check, boolean save) { + return convertResult(holderToPEXSubject(holder).data().update(data -> data.setPermission(contextsGDToPEX(contexts), permission, intFromTristate(value)))); } @Override diff --git a/bukkit/src/main/java/com/griefdefender/registry/FlagDefinitionRegistryModule.java b/bukkit/src/main/java/com/griefdefender/registry/FlagDefinitionRegistryModule.java index dea0f72..9027715 100644 --- a/bukkit/src/main/java/com/griefdefender/registry/FlagDefinitionRegistryModule.java +++ b/bukkit/src/main/java/com/griefdefender/registry/FlagDefinitionRegistryModule.java @@ -776,20 +776,39 @@ public void registerDefaults() { .build()); flagContexts = new HashSet<>(); - flagContexts.add(FlagContexts.SOURCE_PLAYER); - flagContexts.add(FlagContexts.TARGET_TYPE_PORTAL); + flagContexts.add(FlagContexts.SOURCE_END_PORTAL); + flagContexts.add(FlagContexts.TARGET_PLAYER); this.registerCustomType( definitionBuilder .reset() - .name("player-portal-use") + .name("player-endportal-use") .admin(true) - .context(ClaimContexts.USER_DEFAULT_CONTEXT) + .context(ClaimContexts.GLOBAL_DEFAULT_CONTEXT) .defaultValue(Tristate.TRUE) - .description(MessageCache.getInstance().FLAG_DESCRIPTION_CUSTOM_PLAYER_PORTAL_USE) + .description(MessageCache.getInstance().FLAG_DESCRIPTION_CUSTOM_PLAYER_ENDPORTAL_USE) .group("admin") .flagData(flagDataBuilder .reset() - .flag(Flags.INTERACT_BLOCK_SECONDARY) + .flag(Flags.ENTITY_TELEPORT_FROM) + .contexts(flagContexts) + .build()) + .build()); + + flagContexts = new HashSet<>(); + flagContexts.add(FlagContexts.SOURCE_NETHER_PORTAL); + flagContexts.add(FlagContexts.TARGET_PLAYER); + this.registerCustomType( + definitionBuilder + .reset() + .name("player-netherportal-use") + .admin(true) + .context(ClaimContexts.GLOBAL_DEFAULT_CONTEXT) + .defaultValue(Tristate.TRUE) + .description(MessageCache.getInstance().FLAG_DESCRIPTION_CUSTOM_PLAYER_NETHERPORTAL_USE) + .group("admin") + .flagData(flagDataBuilder + .reset() + .flag(Flags.ENTITY_TELEPORT_FROM) .contexts(flagContexts) .build()) .build()); diff --git a/bukkit/src/main/java/com/griefdefender/storage/FileStorage.java b/bukkit/src/main/java/com/griefdefender/storage/FileStorage.java index 2c51515..738a137 100644 --- a/bukkit/src/main/java/com/griefdefender/storage/FileStorage.java +++ b/bukkit/src/main/java/com/griefdefender/storage/FileStorage.java @@ -83,7 +83,7 @@ public void initialize() throws Exception { worldsDataFolder.mkdirs(); } - rootWorldSavePath = new File(".").toPath(); + rootWorldSavePath = Bukkit.getWorldContainer().toPath(); super.initialize(); } diff --git a/bukkit/src/main/java/com/griefdefender/util/PermissionUtil.java b/bukkit/src/main/java/com/griefdefender/util/PermissionUtil.java index 4690a3b..f1a3214 100644 --- a/bukkit/src/main/java/com/griefdefender/util/PermissionUtil.java +++ b/bukkit/src/main/java/com/griefdefender/util/PermissionUtil.java @@ -196,35 +196,35 @@ public List getOptionValueList(GDPermissionHolder holder, Option option, return PERMISSION_PROVIDER.getOptionValueList(holder, option, contexts); } - public PermissionResult setOptionValue(GDPermissionHolder holder, String permission, String value, Set contexts) { + public CompletableFuture setOptionValue(GDPermissionHolder holder, String permission, String value, Set contexts) { return PERMISSION_PROVIDER.setOptionValue(holder, permission, value, contexts, true); } - public PermissionResult setOptionValue(GDPermissionHolder holder, String permission, String value, Set contexts, boolean check) { + public CompletableFuture setOptionValue(GDPermissionHolder holder, String permission, String value, Set contexts, boolean check) { return PERMISSION_PROVIDER.setOptionValue(holder, permission, value, contexts, check); } - public PermissionResult setPermissionValue(GDPermissionHolder holder, Flag flag, Tristate value, Set contexts) { + public CompletableFuture setPermissionValue(GDPermissionHolder holder, Flag flag, Tristate value, Set contexts) { return PERMISSION_PROVIDER.setPermissionValue(holder, flag, value, contexts, true, true); } - public PermissionResult setPermissionValue(GDPermissionHolder holder, String permission, Tristate value, Set contexts) { + public CompletableFuture setPermissionValue(GDPermissionHolder holder, String permission, Tristate value, Set contexts) { return PERMISSION_PROVIDER.setPermissionValue(holder, permission, value, contexts, true, true); } - public PermissionResult setPermissionValue(GDPermissionHolder holder, Flag flag, Tristate value, Set contexts, boolean check, boolean save) { + public CompletableFuture setPermissionValue(GDPermissionHolder holder, Flag flag, Tristate value, Set contexts, boolean check, boolean save) { return PERMISSION_PROVIDER.setPermissionValue(holder, flag, value, contexts, check, save); } - public PermissionResult setPermissionValue(GDPermissionHolder holder, String permission, Tristate value, Set contexts, boolean check, boolean save) { + public CompletableFuture setPermissionValue(GDPermissionHolder holder, String permission, Tristate value, Set contexts, boolean check, boolean save) { return PERMISSION_PROVIDER.setPermissionValue(holder, permission, value, contexts, check, save); } - public PermissionResult setTransientOption(GDPermissionHolder holder, String permission, String value, Set contexts) { + public CompletableFuture setTransientOption(GDPermissionHolder holder, String permission, String value, Set contexts) { return PERMISSION_PROVIDER.setTransientOption(holder, permission, value, contexts); } - public PermissionResult setTransientPermission(GDPermissionHolder holder, String permission, Tristate value, Set contexts) { + public CompletableFuture setTransientPermission(GDPermissionHolder holder, String permission, Tristate value, Set contexts) { return PERMISSION_PROVIDER.setTransientPermission(holder, permission, value, contexts); } diff --git a/bukkit/src/main/resources/1.12.2.json b/bukkit/src/main/resources/1.12.2.json index dd9ba3a..b8c0bb8 100644 --- a/bukkit/src/main/resources/1.12.2.json +++ b/bukkit/src/main/resources/1.12.2.json @@ -3,9 +3,9 @@ "libraries": [ { "name": "com.griefdefender:adapter:1.12.2", - "sha1": "f1068dec6ed4290f45a14d295704cb068b37103c", - "path": "com/griefdefender/adapter/1.12.2-SNAPSHOT/adapter-1.12.2-20200628.025305-44.jar", - "url": "https://repo.glaremasters.me/repository/bloodshot/com/griefdefender/adapter/1.12.2-SNAPSHOT/adapter-1.12.2-20200628.025305-44.jar" + "sha1": "7bb52199ac2ba62ee6ab92fcc16b19ba5a8c0280", + "path": "com/griefdefender/adapter/1.12.2-SNAPSHOT/adapter-1.12.2-20200703.183356-45.jar", + "url": "https://repo.glaremasters.me/repository/bloodshot/com/griefdefender/adapter/1.12.2-SNAPSHOT/adapter-1.12.2-20200703.183356-45.jar" }, { "name": "com.griefdefender:api:1.0.0", diff --git a/bukkit/src/main/resources/1.13.2.json b/bukkit/src/main/resources/1.13.2.json index fb27878..7f89df1 100644 --- a/bukkit/src/main/resources/1.13.2.json +++ b/bukkit/src/main/resources/1.13.2.json @@ -3,9 +3,9 @@ "libraries": [ { "name": "com.griefdefender:adapter:1.13.2", - "sha1": "9cb084ca06beab1b1407f4b8354f7ac77aac0a57", - "path": "com/griefdefender/adapter/1.13.2-SNAPSHOT/adapter-1.13.2-20200628.025121-42.jar", - "url": "https://repo.glaremasters.me/repository/bloodshot/com/griefdefender/adapter/1.13.2-SNAPSHOT/adapter-1.13.2-20200628.025121-42.jar" + "sha1": "0b655bd8f4c3a2839dcae0d68c26817ee2043e79", + "path": "com/griefdefender/adapter/1.13.2-SNAPSHOT/adapter-1.13.2-20200703.183307-43.jar", + "url": "https://repo.glaremasters.me/repository/bloodshot/com/griefdefender/adapter/1.13.2-SNAPSHOT/adapter-1.13.2-20200703.183307-43.jar" }, { "name": "com.griefdefender:api:1.0.0", diff --git a/bukkit/src/main/resources/1.14.2.json b/bukkit/src/main/resources/1.14.2.json index 4bcb735..5c23718 100644 --- a/bukkit/src/main/resources/1.14.2.json +++ b/bukkit/src/main/resources/1.14.2.json @@ -3,9 +3,9 @@ "libraries": [ { "name": "com.griefdefender:adapter:1.14.2", - "sha1": "1b1c97781dbe10493a2f3b5ebb629b69cfaf5722", - "path": "com/griefdefender/adapter/1.14.2-SNAPSHOT/adapter-1.14.2-20200628.024848-42.jar", - "url": "https://repo.glaremasters.me/repository/bloodshot/com/griefdefender/adapter/1.14.2-SNAPSHOT/adapter-1.14.2-20200628.024848-42.jar" + "sha1": "fd7308666a4538c5f08bd6bdf37fe852ffd9c0d0", + "path": "com/griefdefender/adapter/1.14.2-SNAPSHOT/adapter-1.14.2-20200703.183227-43.jar", + "url": "https://repo.glaremasters.me/repository/bloodshot/com/griefdefender/adapter/1.14.2-SNAPSHOT/adapter-1.14.2-20200703.183227-43.jar" }, { "name": "com.griefdefender:api:1.0.0", diff --git a/bukkit/src/main/resources/1.14.3.json b/bukkit/src/main/resources/1.14.3.json index fdda87a..2f4c228 100644 --- a/bukkit/src/main/resources/1.14.3.json +++ b/bukkit/src/main/resources/1.14.3.json @@ -3,9 +3,9 @@ "libraries": [ { "name": "com.griefdefender:adapter:1.14.3", - "sha1": "9728a87ee02b837a4583762194ee472ff99ea6db", - "path": "com/griefdefender/adapter/1.14.3-SNAPSHOT/adapter-1.14.3-20200628.024742-44.jar", - "url": "https://repo.glaremasters.me/repository/bloodshot/com/griefdefender/adapter/1.14.3-SNAPSHOT/adapter-1.14.3-20200628.024742-44.jar" + "sha1": "700f476c968c0b2dca09ae5d1a0fc7ba1195a5c1", + "path": "com/griefdefender/adapter/1.14.3-SNAPSHOT/adapter-1.14.3-20200703.183150-45.jar", + "url": "https://repo.glaremasters.me/repository/bloodshot/com/griefdefender/adapter/1.14.3-SNAPSHOT/adapter-1.14.3-20200703.183150-45.jar" }, { "name": "com.griefdefender:api:1.0.0", diff --git a/bukkit/src/main/resources/1.14.4.json b/bukkit/src/main/resources/1.14.4.json index 45f0468..a47697d 100644 --- a/bukkit/src/main/resources/1.14.4.json +++ b/bukkit/src/main/resources/1.14.4.json @@ -3,9 +3,9 @@ "libraries": [ { "name": "com.griefdefender:adapter:1.14.4", - "sha1": "4a160936b918e9b6accbee8111abe87ddc2060b1", - "path": "com/griefdefender/adapter/1.14.4-SNAPSHOT/adapter-1.14.4-20200628.024718-42.jar", - "url": "https://repo.glaremasters.me/repository/bloodshot/com/griefdefender/adapter/1.14.4-SNAPSHOT/adapter-1.14.4-20200628.024718-42.jar" + "sha1": "da17aa7a08dbf7012fc731e77a56f1ef560f082d", + "path": "com/griefdefender/adapter/1.14.4-SNAPSHOT/adapter-1.14.4-20200703.183119-43.jar", + "url": "https://repo.glaremasters.me/repository/bloodshot/com/griefdefender/adapter/1.14.4-SNAPSHOT/adapter-1.14.4-20200703.183119-43.jar" }, { "name": "com.griefdefender:api:1.0.0", diff --git a/bukkit/src/main/resources/1.15.2.json b/bukkit/src/main/resources/1.15.2.json index 7af3d17..e6a516e 100644 --- a/bukkit/src/main/resources/1.15.2.json +++ b/bukkit/src/main/resources/1.15.2.json @@ -3,9 +3,9 @@ "libraries": [ { "name": "com.griefdefender:adapter:1.15.2", - "sha1": "99d5fceed1e2797047f0c7e88c848ccad1ec504a", - "path": "com/griefdefender/adapter/1.15.2-SNAPSHOT/adapter-1.15.2-20200628.024612-25.jar", - "url": "https://repo.glaremasters.me/repository/bloodshot/com/griefdefender/adapter/1.15.2-SNAPSHOT/adapter-1.15.2-20200628.024612-25.jar" + "sha1": "a7c58074cf314d67de4fa49675681965f3cb7d48", + "path": "com/griefdefender/adapter/1.15.2-SNAPSHOT/adapter-1.15.2-20200703.183009-26.jar", + "url": "https://repo.glaremasters.me/repository/bloodshot/com/griefdefender/adapter/1.15.2-SNAPSHOT/adapter-1.15.2-20200703.183009-26.jar" }, { "name": "com.griefdefender:api:1.0.0", diff --git a/bukkit/src/main/resources/1.15.json b/bukkit/src/main/resources/1.15.json index 2875726..63a169d 100644 --- a/bukkit/src/main/resources/1.15.json +++ b/bukkit/src/main/resources/1.15.json @@ -3,9 +3,9 @@ "libraries": [ { "name": "com.griefdefender:adapter:1.15", - "sha1": "b9ed30a85daf0e3bc711621be29e4feff64b8cec", - "path": "com/griefdefender/adapter/1.15-SNAPSHOT/adapter-1.15-20200628.024650-25.jar", - "url": "https://repo.glaremasters.me/repository/bloodshot/com/griefdefender/adapter/1.15-SNAPSHOT/adapter-1.15-20200628.024650-25.jar" + "sha1": "0e0eba8652e6a2b88bb462fc775ba70dccb93d8e", + "path": "com/griefdefender/adapter/1.15-SNAPSHOT/adapter-1.15-20200703.183045-26.jar", + "url": "https://repo.glaremasters.me/repository/bloodshot/com/griefdefender/adapter/1.15-SNAPSHOT/adapter-1.15-20200703.183045-26.jar" }, { "name": "com.griefdefender:api:1.0.0", diff --git a/bukkit/src/main/resources/1.16.1.json b/bukkit/src/main/resources/1.16.1.json index d5c51e6..228e8be 100644 --- a/bukkit/src/main/resources/1.16.1.json +++ b/bukkit/src/main/resources/1.16.1.json @@ -3,9 +3,9 @@ "libraries": [ { "name": "com.griefdefender:adapter:1.16.1", - "sha1": "a6b330cf3e61ef87410e359d367d5076e4ac87ff", - "path": "com/griefdefender/adapter/1.16.1-SNAPSHOT/adapter-1.16.1-20200628.024544-5.jar", - "url": "https://repo.glaremasters.me/repository/bloodshot/com/griefdefender/adapter/1.16.1-SNAPSHOT/adapter-1.16.1-20200628.024544-5.jar" + "sha1": "29795458f87a4aa2c6b6d0d753fda369c8207195", + "path": "com/griefdefender/adapter/1.16.1-SNAPSHOT/adapter-1.16.1-20200703.182855-6.jar", + "url": "https://repo.glaremasters.me/repository/bloodshot/com/griefdefender/adapter/1.16.1-SNAPSHOT/adapter-1.16.1-20200703.182855-6.jar" }, { "name": "com.griefdefender:api:1.0.0", diff --git a/bukkit/src/main/resources/1.8.8.json b/bukkit/src/main/resources/1.8.8.json index 552d220..9d917cc 100644 --- a/bukkit/src/main/resources/1.8.8.json +++ b/bukkit/src/main/resources/1.8.8.json @@ -3,9 +3,9 @@ "libraries": [ { "name": "com.griefdefender:adapter:1.8.8", - "sha1": "fb8afde03ae6cde9bf76b1bd0d2cbea0517df5b4", - "path": "com/griefdefender/adapter/1.8.8-SNAPSHOT/adapter-1.8.8-20200628.025347-42.jar", - "url": "https://repo.glaremasters.me/repository/bloodshot/com/griefdefender/adapter/1.8.8-SNAPSHOT/adapter-1.8.8-20200628.025347-42.jar" + "sha1": "263b5c05c6bffb979742e67eeb29fa2ecf5bb0e3", + "path": "com/griefdefender/adapter/1.8.8-SNAPSHOT/adapter-1.8.8-20200703.183440-43.jar", + "url": "https://repo.glaremasters.me/repository/bloodshot/com/griefdefender/adapter/1.8.8-SNAPSHOT/adapter-1.8.8-20200703.183440-43.jar" }, { "name": "com.griefdefender:api:1.0.0", diff --git a/bukkit/src/main/resources/plugin.yml b/bukkit/src/main/resources/plugin.yml index e9fa398..8cbe7bb 100644 --- a/bukkit/src/main/resources/plugin.yml +++ b/bukkit/src/main/resources/plugin.yml @@ -3,5 +3,5 @@ main: com.griefdefender.GDBootstrap softdepend: [dynmap, PlaceholderAPI, WorldEdit, WorldGuard, Vault] depend: [LuckPerms] load: STARTUP -version: '1.4.6' +version: '1.4.7' api-version: 1.13 diff --git a/common/src/main/resources/assets/lang/de_DE.conf b/common/src/main/resources/assets/lang/de_DE.conf index b1f8a59..6c9ce69 100644 --- a/common/src/main/resources/assets/lang/de_DE.conf +++ b/common/src/main/resources/assets/lang/de_DE.conf @@ -59,8 +59,8 @@ GriefDefender { } messages { abandon-all-delay-warning="&aDiese Grundstücke wurden erst kürzlich erstellt und können daher nicht entfernt werden." - abandon-all-success="&aAll your claims have been abandoned. You now have &6{amount}&a available claim blocks." - abandon-all-success-world="&aAll your claims have been abandoned in &6{world}&a. You now have &6{amount}&a available claim blocks." + abandon-all-success="&aAlle deine Grundstücke wurden gelöscht. Du hast jetzt wieder &6{amount}&a verfügbare Baublöcke." + abandon-all-success-world="&aAlle deine Grundstücke in der Welt &6{world}&a wurden gelöscht. Du hast nun &6{amount}&a verfügbare Baublöcke." abandon-all-warning="&6Bist du dir sicher, dass du &cALLE&6 deine Grundstücke löschen willst?" abandon-all-warning-world="&6Bist du dir sicher, dass du &cALLE&6 deine Grundstücke löschen willst auf &a{world}&6?" abandon-claim-delay-warning="&aDieses Grundstück ist noch neu und kann erst am &6{date}&a entfernt werden." @@ -71,8 +71,8 @@ GriefDefender { abandon-top-level="&cDieses Grundstück kann nicht entfernt werden. Es existieren untergeordnete Grundstücke. Um es zu löschen, nutze &f/abandontop&c." abandon-town-children="&cYDu hast keine Berechtigungen eine Stadt mit Teilgrundstücken zu entfernen, welche dir nicht gehören. Benutze &f/ignoreclaims&c oder lasse den Teilgrundstück Besitzer sein Grundstück entfernen. Wenn du die Stadt auflösen willst, ohne die Teilgrundstücke, benutze &f/abandon&c." abandon-warning="&6Bist du dir sicher, dass du das Grundstück entfernen möchtest? Es wird dann nicht länger geschützt." - abandon-world-success="&aAbandoned all player claims in &6{world}&a." - abandon-world-warning="&6Are you sure you want to abandon &cALL&6 user claims in &a{world}&6?" + abandon-world-success="&aAlle SpielerGrundstücke in &6{world}&a gelöscht." + abandon-world-warning="&6Bist du dir sicher, dass du &cALLE&6 SpielerGrundstücke in &a{world}&6 löschen möchtest?" adjust-accrued-blocks-success="&6{player}&a's angesammelte Blöcke wurden auf &6{amount}&a angepasst. Neue Anzahl: &6{total}&a." adjust-bonus-blocks-success="&6{player}&a's Bonusblöcke wurden auf &6{amount}&a angepasst. Neue Anzahl: &6{total}&a." bank-click-view-transactions="Klicken, um Banktransaktionen anzuzeigen." @@ -137,6 +137,9 @@ GriefDefender { claiminfo-ui-click-admin="Hier klicken für die Admin Einstellungen" claiminfo-ui-click-bank="Hier klicken für Bank Informationen" claiminfo-ui-click-change-claim="Hier klicken um die Grundstücksart in {type} zu ändern" + claiminfo-ui-click-farewell="Click here to change farewell message" + claiminfo-ui-click-greeting="Click here to change greeting message" + claiminfo-ui-click-name="Click here to change claim name" claiminfo-ui-click-toggle="Klicken, um umzuschalten" claiminfo-ui-deny-messages="Nachrichten ausschalten" claiminfo-ui-flag-overrides="Override Einstellungen" @@ -157,6 +160,7 @@ GriefDefender { claiminfo-ui-title-claiminfo="Informationen zum Grundstück" claiminfo-ui-town-settings="Einstellungen der Stadt" claimlist-ui-click-info="Klicke hier für weitere Informationen" + claimlist-ui-click-player-list="Click here to show player claim list" claimlist-ui-click-purchase="Zum Kaufen des Grundstückes hier klicken" claimlist-ui-click-rent="Zum Mieten klicken" claimlist-ui-click-teleport-target="Klicke, um dich zu {name}&f {target}&f in &6{world} zu teleportieren" @@ -212,7 +216,7 @@ GriefDefender { command-player-not-found="&cSpieler '&6{player}&c' nicht gefunden." command-world-not-found="&cWelt '&6{world}&c' nicht gefunden." command-worldedit-missing="&cDieser Befehl benötigt installiertes WorldEdit auf dem Server." - confirm-not-found="No confirmation found." + confirm-not-found="Keine Bestätigung gefunden." create-cancel="&cDie Erstellung des Grundstückes wurde abgebrochen." create-cuboid-disabled="&cDas Erstellen von 3D Grundstücken ist ausgeschaltet.\nDu musst ein Admin sein, um die Funktion zu nutzen oder sie auf einem deiner Grundstücke nutzen." create-failed-claim-limit="&cDu hast die Grenze von &a{limit}&c deiner {type}&c Grundstücke erreicht. Nutze &f/abandon&c um eines zu entfernen, bevor du ein neues erstellst." @@ -259,9 +263,9 @@ GriefDefender { economy-block-purchase-limit="&cDie neue Anzahl Baublöcke &a{total}&c ist größer als das Maximum &a{limit}&c. Transaktion abgebrochen." economy-block-sale-confirmation="&6{deposit}&a verkauft. Du hast nun &6{amount}&a Baublöcke." economy-block-sell-error="&cKonnte die Baublöcke nicht verkaufen. Meldung: &f{reason}&c." - economy-block-transfer-cancel="&cTransfer cancelled. Could not locate any players with remaining claim blocks." - economy-block-transfer-success="&aTransfer complete. You have successfully transferred &6{count}&a players remaining claimblocks into currency." - economy-block-transfer-warning="&6Are you sure you want to transfer &cALL&6 player remaining claim blocks into currency? This will reset each player's accrued and bonus blocks to 0 after transfer. \n\nClick confirm to proceed." + economy-block-transfer-cancel="&cTransaktion abgebrochen. Konnte keine Spieler mit Baublöcken finden." + economy-block-transfer-success="&aTransaktion erfolgreich. Du hast erfolgreich die Baublöcke von &6{count}&a Spielern in Währung umgewandelt." + economy-block-transfer-warning="&6Bist du dir sicher, dass du &cALLE&6 Baublöcke deiner Spieler in Währund umwandeln willst? Alle angesammelten und Bonusblöcke werden auf 0 gesetzt. \n\nKlicke auf Bestätigen um fortzufahren." economy-claim-abandon-success="&aGrundstück aufgegeben. Du hast '&6{amount}&a' Baublöcke zurückerhalten." economy-claim-abandon-success-world="&aGrundstück aufgegeben auf &6{world}&a. Du hast '&6{amount}&a' Baublöcke zurückerhalten." economy-claim-buy-cancelled="&cKauf abgebrochen! Konnte das Grundstück von &6{player}&c nicht kaufen. Meldung: &a{result}" @@ -304,8 +308,8 @@ GriefDefender { economy-claim-sale-confirmed="&aDu hast dein Grundstück erfolgreich für &6{amount}&a zum Verkauf angeboten." economy-claim-sale-invalid-price="&cDer Verkaufspreis &a{amount}&c muss größer sein als &a0&c." economy-claim-sold="&aDein Grundstück wurde verkauft! &6{amount}&a wurde an dich überwiesen. Dein neuer Kontostand ist: &6{balance}&a." - economy-deposit-error="&cCould not deposit funds. Reason: &f{reason}&c." - economy-mode-block-cost-not-set="&cEconomy mode is enabled but the current price for blocks is &6{price}&c.\nRaise the value for option 'economy-block-cost' in 'options.conf' or via '/gd option claim' command." + economy-deposit-error="&cEinzahlung fehlgeschlagen. Grund: &f{reason}&c." + economy-mode-block-cost-not-set="&cEconomy Modus ist aktiviert aber der momentane Preis ist &6{price}&c.\nErhöhe den Wert für 'economy-block-cost' in der 'options.conf' oder mit dem Befehl '/gd option claim'." economy-mode-block-sale-confirmation="&aErfolgreich &6{deposit}&a verkauft. Dein Kontostand ist nun &6{balance}&a. Du hast jetzt genug Geld, um dir &6{amount}&a Baublöcke zu kaufen." economy-mode-not-enabled="&cEconomy mode is not enabled." economy-mode-resize-success-2d="&aGrundstücksgröße erfolgreich geändert. Neuer Kontostand: &6{balance}&a. Du hast genug Geld, um dir &6{block-amount} &aBaublöcke zu kaufen." @@ -344,7 +348,7 @@ GriefDefender { flag-description-custom-creeper-entity-explosion="Kontrolliert, ob Creeper Schaden verursachen können." flag-description-custom-crop-growth="Kontrolliert, ob Weizensamen wachsen können." flag-description-custom-damage-animals="Kontrolliert, ob Tiere geschädigt werden können." - flag-description-custom-endcrystal-use="Controls whether endcrystals can be placed or broken." + flag-description-custom-endcrystal-use="Kontrolliert, ob Enderkristalle platziert und zerstört werden können." flag-description-custom-enderman-grief="Kontrolliert, ob Enderman Blöcke stehlen können." flag-description-custom-entity-armorstand-damage="Controls whether entities can deal damage to armorstands." flag-description-custom-entity-itemframe-damage="Controls whether entities can deal damage to item frames." @@ -374,6 +378,7 @@ GriefDefender { flag-description-custom-player-block-place="Kontrolliert, ob ein Block platziert werden kann." flag-description-custom-player-damage="Kontrolliert, ob Spieler überhaupt Schaden nehmen können." flag-description-custom-player-enderpearl-interact="Kontrolliert, ob Enderperlen genutzt werden können." + flag-description-custom-player-endportal-use="Kontrolliert, ob Spieler End Portale nutzen können." flag-description-custom-player-enter="Kontrolliert, ob ein Spieler das Grundstück betreten kann." flag-description-custom-player-entity-interact="Kontrolliert, ob Spieler mit Entitäten interagieren können.\n&bBeispiel&f: Hat keinen Einfluss auf Entitäten mit Inventarplätzen, bspw. Pferde." flag-description-custom-player-exit="Kontrolliert, ob ein Spieler das Grundstück verlassen kann." @@ -381,10 +386,10 @@ GriefDefender { flag-description-custom-player-itemframe-interact="Kontrolliert, ob Spieler mit Rahmen (Item) interagieren können." flag-description-custom-player-item-drop="Kontrolliert, ob Spieler Gegenstände fallen lassen können." flag-description-custom-player-item-pickup="Kontrolliert, ob Spieler Gegenstände aufheben können." - flag-description-custom-player-portal-use="Kontrolliert, ob Spieler Portale nutzen können." + flag-description-custom-player-netherportal-use="Kontrolliert, ob Spieler Nether Portale nutzen können." flag-description-custom-player-teleport-from="Kontrolliert, ob sich Spieler aus dem Grundstück rausteleportieren können." flag-description-custom-player-teleport-to="Kontrolliert, ob sich Spieler zu diesem Grundstück teleportieren können." - flag-description-custom-player-villager-damage="Controls whether players can deal damage to villagers." + flag-description-custom-player-villager-damage="Kontrolliert, ob Spieler Villagern Schaden zufügen können." flag-description-custom-pvp="Kontrolliert, ob PVP erlaubt ist." flag-description-custom-ride="Kontrolliert, ob das Aufsitzen und Fortbewegen mit Tieren und Fortbewegungsmitteln möglich ist." flag-description-custom-sleep="Kontrolliert, ob Spieler in Betten schlafen können." @@ -397,7 +402,7 @@ GriefDefender { flag-description-custom-spawn-aquatic="Kontrolliert, ob Lebewesen im Wasser - etwa Tintenfische - spawnen." flag-description-custom-tnt-block-explosion="Kontrolliert, ob TNT Blöcke zerstören kann." flag-description-custom-tnt-entity-explosion="Kontrolliert, ob TNT Schaden anrichtet." - flag-description-custom-turtle-egg-hatch="Controls whether turtle eggs can hatch." + flag-description-custom-turtle-egg-hatch="Kontrolliert, ob aus Eiern Schildkröten schlüpfen können." flag-description-custom-use="Kontrolliert, ob Spieler nicht-Inventarblöcke auf dem Grundstück benutzen können." flag-description-custom-vehicle-use="Kontrolliert, ob Fahrzeuge platziert, zerstört und benutzt werden können." flag-description-custom-villager-farm="Kontrolliert, ob Villager mit Pflanzen und Setzlingen interagieren können." @@ -490,7 +495,7 @@ GriefDefender { label-minutes=Minuten label-name=Name label-no=Nein - label-none=none + label-none=nichts label-output=Ausgabe label-owner=Eigentümer label-permission=Berechtigung @@ -630,10 +635,12 @@ GriefDefender { permission-player-admin-flags="&cDu hast keine Berechtigung die Einstellungen für einen Admin zu ändern." permission-player-option="&cDu hast keine Berechtigung Spieleroptionen zu verwalten." permission-player-view-others="&cDu hast keine Berechtigung dir andere Spieler anzeigen zu lassen." - permission-portal-enter="&cDu kannst dieses Portal nicht benutzen. Du brauchst die Berechtigung von &6{player}&c um das Grundstück zu betreten." - permission-portal-exit="&cDu kannst dieses Portal nicht benutzen. Du brauchst die Berechtigung von &6{player}&c um das Grundstück zu verlassen." + permission-portal-from="&cYou can't use this portal because you don't have &6{player}'s &cpermission to teleport from this claim." + permission-portal-to="&cYou can't use this portal because you don't have &6{player}'s &cpermission to teleport to the destination claim." permission-protected-portal="&cDu kannst dieses Portal nicht benutzen. Das Grundstück gehört &6{player}&c." permission-tax="&cDu hast keine Berechtigung Steuern dieses Grundstückes zu verwalten." + permission-teleport-from="&cYou don't have &6{player}'s &cpermission to teleport from this claim." + permission-teleport-to="&cYou don't have &6{player}'s &cpermission to teleport to the destination claim." permission-trust="&cDir fehlt &6{player}s&c Berechtigung Berechtigungen zu verwalten." permission-visual-claims-nearby="&cDu hast keine Berechtigung dir Grundstücke in der Nähe anzeigen zu lassen." player-accrued-blocks-exceeded="&cSpieler &6{player}&c hat eine Maximalgrenze von &6{total}&c und würde mit zusätzlichen &6{amount}&c Baublöcken diese überschreiten.\nVersuche eine niedrige Anzahl oder lasse einen Admin die Aktion vornehmen." @@ -676,7 +683,7 @@ GriefDefender { registry-block-not-found="&cDer Block {id}&c konnte nicht gefunden werden." registry-entity-not-found="&cDas Objekt {id}&c konnte nicht gefunden werden." registry-item-not-found="&cDer Gegenstand {id}&c konnte nicht gefunden werden." - rent-system-disabled="&cThe rent system is not enabled." + rent-system-disabled="&cDas Mieten von Grundstücken ist deaktiviert." rent-ui-click-cancel="Hier klicken zum Abbrechen" rent-ui-click-rent="Zum Mieten hier klicken" rent-ui-end-date="Enddatum" @@ -688,7 +695,7 @@ GriefDefender { rent-ui-return-info="Zurück zu den Miet Informationen" rent-ui-start-date="Startdatum" rent-ui-title-transactions="Mietzins Transaktionen" - rent-ui-view-transactions="View Transactions" + rent-ui-view-transactions="Transaktionen anzeigen" resize-overlap="&cDie Größe hierher zu ändern, würde ein anderes Grundstück überlappen." resize-overlap-subdivision="&cDu kannst hier keine Unterteilung erstellen, sie würde eine bestehende überlappen. Du könntest diese mit &f/abandon&c löschen, oder vorher verkleinern." resize-same-location="&cDu musst eine andere Position wählen, um das Grundstück zu verändern." @@ -699,11 +706,11 @@ GriefDefender { result-type-change-not-admin="&cDu brauchst Adminrechte um ein {type}&c Grundstück zu erstellen." result-type-child-same="{type}&c Grundstücke können keine {type}&c Untergrundstücke haben." result-type-create-deny="{type}s&c können nicht in {target_type} erstellt werden." - result-type-fail=FAIL + result-type-fail=FEHLGESCHLAGEN result-type-no-children="{type}s&c kann keine Untergrundstücke enthalten." result-type-only-subdivision="{type}s&c kann nur Untergrundstücke enthalten." result-type-requires-owner="&cKonnte {type} Grundstück nicht zu {target_type} konvertieren. Du musst Eigentümer sein." - result-type-success=SUCCESS + result-type-success=ERFOLGREICH schematic-abandon-all-restore-warning="&6Bist du dir sicher, dass du &cALL&6 Grundstücke &nlöschen&6 willst? &cALLE DATEN GEHEN VERLOREN&f!!&6 Alle Grundstücke werden bei Bestätigung zurückgesetzt." schematic-abandon-all-restore-warning-world="&6Bist du dir sicher, dass du &cALL&6 Grundstücke &nlöschen&6 willst auf &a{world}? &cALLE DATEN GEHEN VERLOREN&f!!&6 Alle Grundstücke werden bei Bestätigung zurückgesetzt." schematic-abandon-restore-warning="&6Bist du dir sicher, dass du das Grundstück &nlöschen&6 willst? &cALLE DATEN GEHEN VERLOREN&f!!&6 Das Grundstück wird bei Bestätigung zurückgesetzt." @@ -781,6 +788,6 @@ GriefDefender { untrust-no-claims="&cDu hast keine Grundstücke mit Rechten für andere Spieler." untrust-owner="&6{owner}&a ist der Eigentümer. Du kannst ihm nicht die Erlaubnis für das Grundstück entziehen." untrust-self="&cDu kannst dir nicht selbst die Rechte für Grundstücke entziehen." - visual-update-in-progress="&aUpdating claim visuals. Pending: &6{count}&a visual blocks. Please wait." + visual-update-in-progress="&aErneuere Grundstücksvisualisierung. Verbleibend: &6{count}&a Blöcke. Bitte warten..." } } diff --git a/common/src/main/resources/assets/lang/en_US.conf b/common/src/main/resources/assets/lang/en_US.conf index 9dcb640..49e97a1 100644 --- a/common/src/main/resources/assets/lang/en_US.conf +++ b/common/src/main/resources/assets/lang/en_US.conf @@ -137,6 +137,9 @@ GriefDefender { claiminfo-ui-click-admin="Click here to view admin settings" claiminfo-ui-click-bank="Click here to check bank information" claiminfo-ui-click-change-claim="Click here to change claim to {type}" + claiminfo-ui-click-farewell="Click here to change farewell message" + claiminfo-ui-click-greeting="Click here to change greeting message" + claiminfo-ui-click-name="Click here to change claim name" claiminfo-ui-click-toggle="Click here to toggle value" claiminfo-ui-deny-messages="Deny Messages" claiminfo-ui-flag-overrides="Flag Overrides" @@ -157,6 +160,7 @@ GriefDefender { claiminfo-ui-title-claiminfo="Claim Info" claiminfo-ui-town-settings="Town Settings" claimlist-ui-click-info="Click to check more info" + claimlist-ui-click-player-list="Click here to show player claim list" claimlist-ui-click-purchase="Click here to purchase claim" claimlist-ui-click-rent="Click here to rent claim" claimlist-ui-click-teleport-target="Click here to teleport to {name}&f {target}&f in &6{world}" @@ -374,6 +378,7 @@ GriefDefender { flag-description-custom-player-block-place="Controls whether players can place blocks." flag-description-custom-player-damage="Controls whether players can be damaged." flag-description-custom-player-enderpearl-interact="Controls whether players can use an enderpearl." + flag-description-custom-player-endportal-use="Controls whether players can use end portal." flag-description-custom-player-enter="Controls whether a player can enter this claim." flag-description-custom-player-entity-interact="Controls whether players can interact with entities.\n&bNote&f: This does not include chest access with entities such as horses." flag-description-custom-player-exit="Controls whether a player can exit this claim." @@ -381,7 +386,7 @@ GriefDefender { flag-description-custom-player-item-drop="Controls whether players can drop items." flag-description-custom-player-item-pickup="Controls whether players can pickup items." flag-description-custom-player-itemframe-interact="Controls whether players can interact with item frames." - flag-description-custom-player-portal-use="Controls whether players can use portals." + flag-description-custom-player-netherportal-use="Controls whether players can use nether portal." flag-description-custom-player-teleport-from="Controls whether players can teleport from this claim." flag-description-custom-player-teleport-to="Controls whether players can teleport to this claim." flag-description-custom-player-villager-damage="Controls whether players can deal damage to villagers." @@ -630,10 +635,12 @@ GriefDefender { permission-player-admin-flags="&cYou don't have permission to change flags on an admin player." permission-player-option="&cYou don't have permission to assign an option to a player." permission-player-view-others="&cYou don't have permission to view other players." - permission-portal-enter="&cYou can't use this portal because you don't have &6{player}'s &cpermission to enter the destination claim." - permission-portal-exit="&cYou can't use this portal because you don't have &6{player}'s &cpermission to exit the destination claim." + permission-portal-from="&cYou can't use this portal because you don't have &6{player}'s &cpermission to teleport from this claim." + permission-portal-to="&cYou can't use this portal because you don't have &6{player}'s &cpermission to teleport to the destination claim." permission-protected-portal="&cYou don't have permission to use portals in this claim owned by &6{player}'s&c." permission-tax="&cYou don't have permission to manage tax in this claim." + permission-teleport-from="&cYou don't have &6{player}'s &cpermission to teleport from this claim." + permission-teleport-to="&cYou don't have &6{player}'s &cpermission to teleport to the destination claim." permission-trust="&cYou don't have &6{player}'s&c permission to manage permissions here." permission-visual-claims-nearby="&cYou don't have permission to visualize nearby claims." player-accrued-blocks-exceeded="&cPlayer &6{player}&c has a total of &6{total}&c and will exceed the maximum allowed accrued claim blocks if granted an additional &6{amount}&c of blocks.\nEither lower the amount or have an admin grant the user with an override." diff --git a/common/src/main/resources/assets/lang/es_ES.conf b/common/src/main/resources/assets/lang/es_ES.conf index c684891..888ea6b 100644 --- a/common/src/main/resources/assets/lang/es_ES.conf +++ b/common/src/main/resources/assets/lang/es_ES.conf @@ -137,6 +137,9 @@ GriefDefender { claiminfo-ui-click-admin="Click aquí para ver la configuracion de Administrador" claiminfo-ui-click-bank="Click aquí para comprobar la información del Banco" claiminfo-ui-click-change-claim="Click aquí para cambiar el tipo de Claim a {type}" + claiminfo-ui-click-farewell="Click aquí para cambiar el mensaje de despedida" + claiminfo-ui-click-greeting="Click aquí para cambiar el mensaje de bienvenida" + claiminfo-ui-click-name="Click aquí para cambiar el nombre de tu protección" claiminfo-ui-click-toggle="Click aquí para ACTIVAR/DESACTIVAR el valor" claiminfo-ui-deny-messages="Denegar Mensajes" claiminfo-ui-flag-overrides="Sobrescribir Flags" @@ -157,6 +160,7 @@ GriefDefender { claiminfo-ui-title-claiminfo="&6&lINFORMACION DEL TERRENO" claiminfo-ui-town-settings="Configuración de Ciudad" claimlist-ui-click-info="Click aquí para comprobar más información" + claimlist-ui-click-player-list="Click aquí para ver la lista de protecciones de un jugador" claimlist-ui-click-purchase="Click aquí para comprar el terreno" claimlist-ui-click-rent="Click aqui para rentar esta Claim" claimlist-ui-click-teleport-target="Click aquí para teletransportar a {name}&f ► {target}&f ► &6{world}" @@ -374,6 +378,7 @@ GriefDefender { flag-description-custom-player-block-place="Controla si se pueden colocar bloques." flag-description-custom-player-damage="Controla si los jugadores son inmunes ante cualquier daño." flag-description-custom-player-enderpearl-interact="Controla si las perlas de Ender pueden ser usadas." + flag-description-custom-player-endportal-use="Controla si los jugadores pueden utilizar portales del End." flag-description-custom-player-enter="Controla si un jugador puede entrar a este terreno." flag-description-custom-player-entity-interact="Controla si un jugador puede interactuar con las entidades.\n&4&l[NOTA] &cEsto NO incluye el acceso a los cofres en entidades como los Caballos." flag-description-custom-player-exit="Controla si un jugador puede salir de este terreno." @@ -381,7 +386,7 @@ GriefDefender { flag-description-custom-player-itemframe-interact="Controla si los jugadores pueden interactuar con marcos(item frames)." flag-description-custom-player-item-drop="Controla si un jugador puede tirar objetos al suelo." flag-description-custom-player-item-pickup="Controla si un jugador puede recoger objetos del suelo." - flag-description-custom-player-portal-use="Controla si los portales pueden ser usados." + flag-description-custom-player-netherportal-use="Controla si los jugadores pueden utilizar portales del Nether." flag-description-custom-player-teleport-from="Controla si los jugadores puede ser teletransportados desde este terreno." flag-description-custom-player-teleport-to="Controla si los jugadores pueden teletransportarse a este terreno." flag-description-custom-player-villager-damage="Controla si los jugadores pueden causar daño a los aldeanos." @@ -472,7 +477,7 @@ GriefDefender { label-context=Contexto label-created=Creado label-day=Día - label-days=Días + label-days=Días label-default=Predeterminado label-displaying=Mostrando label-expired=Expirado @@ -482,12 +487,12 @@ GriefDefender { label-greeting=Bienvenida label-group=Grupo label-hour=Hora - label-hours=Horas + label-hours=Horas label-inherit=Heredante label-location=Localización label-managers=ADMINISTRAR label-minute=Minuto - label-minutes=Minutos + label-minutes=Minutos label-name=Nombre label-no=No label-none=Ninguno @@ -505,8 +510,8 @@ GriefDefender { label-schematic=Plano label-source=Fuente label-spawn=Spawn - label-status=Estado - label-target=Objetivo + label-status=Estado + label-target=Objetivo label-trust=Confianza label-type=Tipo label-unknown=Desconocido @@ -630,10 +635,12 @@ GriefDefender { permission-player-admin-flags="&4&l[PERMISO-DENEGADO] &cNo puedes &ncambiar&c los Flags de un Administrador." permission-player-option="&4&l[PERMISO-DENEGADO] &cNo puedes &nasignar&c una Opción a un jugador." permission-player-view-others="&4&l[PERMISO-DENEGADO] &cNo puedes &nver&c a otros jugadores." - permission-portal-enter="&4&l[ACCESO-DENEGADO] &cNo puedes usar este portal porque no tienes permiso de &6&o{player}&c para ENTRAR al terreno destinado." - permission-portal-exit="&4&l[ACCESO-DENEGADO] &cNo puedes usar este portal porque no tieness permiso de &6&o{player}&c para SALIR al terreno destinado." + permission-portal-from="&4&l[ACCESO-DENEGADO] &cNo puedes utilizar este portal porque no tienes permiso de &6&o{player} &cpara teletransportarte desde esta claim." + permission-portal-to="&4&l[ACCESO-DENEGADO] &cNo puedes utilizar este portal porque no tienes permiso de &6&o{player} &cpara teletransportarte al punto de destino." permission-protected-portal="&4&l[USO-DENEGADO] &cNo puedes usar los Portales de este terreno porque es propiedad de ➜ &6&o{player}&c." permission-tax="&cNo tienes los permisos para administrar los impuestos en esta claim." + permission-teleport-from="&4&l[ACCESO-DENEGADO] &cNo tienes permiso de &6&o{player} &cpara teletransportarte desde esta claim." + permission-teleport-to="&4&l[ACCESO-DENEGADO] &cNo tienes permiso de &6&o{player} &cpara teletransportarte al punto de destino." permission-trust="&4&l[PERMISO-DENEGADO] &cNo puedes &nadministras&c los permisos de este terreno porque &6&o{player}&c no te considera de confianza." permission-visual-claims-nearby="&4&l[PERMISO-DENEGADO] &cNo puedes &nvisualizar&c los terrenos cercanos." player-accrued-blocks-exceeded="&cEl jugador &6&o{player}&c tiene un total de &6&o{total}CB's&c y ha excedido el máximo permitido de &lCBA's &r&c(&nClaim Block Adquiridos&r&c) que garantiza &a&l+&6&o{amount} &abloques adicionales&c.\n&4&l[NOTA] &cReduzca la cantidad general o que un &4Administrador&c disminuya al Jugador la cantidad excedida de CB's." diff --git a/common/src/main/resources/assets/lang/fr_FR.conf b/common/src/main/resources/assets/lang/fr_FR.conf index 8b060d7..efb68ae 100644 --- a/common/src/main/resources/assets/lang/fr_FR.conf +++ b/common/src/main/resources/assets/lang/fr_FR.conf @@ -137,6 +137,9 @@ GriefDefender { claiminfo-ui-click-admin="Clique ici pour voir les paramètres admin" claiminfo-ui-click-bank="Clique ici pour vérifier les informations bancaire" claiminfo-ui-click-change-claim="Clique ici pour changer le terrain à {type}" + claiminfo-ui-click-farewell="Click here to change farewell message" + claiminfo-ui-click-greeting="Click here to change greeting message" + claiminfo-ui-click-name="Click here to change claim name" claiminfo-ui-click-toggle="Clique ici pour basculer la valeur" claiminfo-ui-deny-messages="Messages de refus" claiminfo-ui-flag-overrides="Marque outrepassant" @@ -157,6 +160,7 @@ GriefDefender { claiminfo-ui-title-claiminfo="Information du terrain" claiminfo-ui-town-settings="Paramètre de la ville" claimlist-ui-click-info="Clique ici pour voir plus d'informations" + claimlist-ui-click-player-list="Click here to show player claim list" claimlist-ui-click-purchase="Clique ici pour acheter le terrain" claimlist-ui-click-rent="Clique ici pour louer un terrain" claimlist-ui-click-teleport-target="Clique ici pour te téléporter à {name}&f {target}&f dans &6{world}" @@ -374,6 +378,7 @@ GriefDefender { flag-description-custom-player-block-place="Contrôle si un bloc peut être placé par un joueur." flag-description-custom-player-damage="Contrôle si un joueur peut prendre des dégâts." flag-description-custom-player-enderpearl-interact="Contrôle si une enderpearl peut être utilisée par un joueur." + flag-description-custom-player-endportal-use="Contrôle si un end portail peut être utilisé par un joueur." flag-description-custom-player-enter="Contrôle si un joueur peut entrer dans une protection." flag-description-custom-player-entity-interact="Contrôle si un joueur peut intéragir avec une entité.\n&bNote&f: Cela n'inclut PAS l'accès au coffre des entités comme les chevaux." flag-description-custom-player-exit="Contrôle si un joueur peut sortir de la protection." @@ -381,7 +386,7 @@ GriefDefender { flag-description-custom-player-item-drop="Contrôle si un joueur peut jeter un objet." flag-description-custom-player-item-pickup="Contrôle si un joueur peut ramasser un objet." flag-description-custom-player-itemframe-interact="Contrôle si un joueur pour intéragir avec les cadres." - flag-description-custom-player-portal-use="Contrôle si un portail peut être utilisé par un joueur." + flag-description-custom-player-netherportal-use="Contrôle si un nether portail peut être utilisé par un joueur." flag-description-custom-player-teleport-from="Contrôle si les joueurs peuvent se téléporter depuis la protection." flag-description-custom-player-teleport-to="Contrôle si les joueur peuvent se téléporter vers la protection." flag-description-custom-player-villager-damage="Contrôle si le joueur peut infliger des dégâts au villageois." @@ -630,10 +635,12 @@ GriefDefender { permission-player-admin-flags="&cTu n'as pas la permission de changer un flag sur un joueur admin." permission-player-option="&cTu n'as pas la permission pour assigner une option sur un joueur." permission-player-view-others="&cTu n'as pas la permission pour voir les autres joueurs." - permission-portal-enter="&cTu ne peut pas utiliser le portail car tu n'as pas la permission de &6{player}&c d'entrer dans la protection de destination." - permission-portal-exit="&cTu ne peut pas utiliser le portail car tu n'as pas la permission de &6{player}&c pour sortir de la protection de destination." + permission-portal-from="&cYou can't use this portal because you don't have &6{player}'s &cpermission to teleport from this claim." + permission-portal-to="&cYou can't use this portal because you don't have &6{player}'s &cpermission to teleport to the destination claim." permission-protected-portal="&cTu n'as pas la permission d'utiliser les portails dans les protections appartenant à &6{player}&c." permission-tax="&cYou don't have permission to manage tax in this claim." + permission-teleport-from="&cYou don't have &6{player}'s &cpermission to teleport from this claim." + permission-teleport-to="&cYou don't have &6{player}'s &cpermission to teleport to the destination claim." permission-trust="&cTu n'as pas la permission de &6{player}&c pour gérer les permissions ici." permission-visual-claims-nearby="&cTu n'as pas la permission pour voir les protections à proximité." player-accrued-blocks-exceeded="&cLe joueur &6{player}&c a un total de &6{total}&c et vas dépasser le maximum autorisé de blocs de protection gagnés s'il est donné un nombre additionnel de &6{amount}&c bloc.\nDescends le nombre ou demande un admin de donner à l'utilisateur un outrepassement." diff --git a/common/src/main/resources/assets/lang/pl_PL.conf b/common/src/main/resources/assets/lang/pl_PL.conf index 0b4db37..0e9e5e1 100644 --- a/common/src/main/resources/assets/lang/pl_PL.conf +++ b/common/src/main/resources/assets/lang/pl_PL.conf @@ -137,6 +137,9 @@ GriefDefender { claiminfo-ui-click-admin="Kliknij tu aby wyświetlić ustawienia administracyjne" claiminfo-ui-click-bank="Kliknij tutaj aby zobaczyć informacje o banku" claiminfo-ui-click-change-claim="Kliknij tutaj aby zmienić typ działki na {type}" + claiminfo-ui-click-farewell="Click here to change farewell message" + claiminfo-ui-click-greeting="Click here to change greeting message" + claiminfo-ui-click-name="Click here to change claim name" claiminfo-ui-click-toggle="Kliknij tu aby przełączyć wartość" claiminfo-ui-deny-messages="Wiadomości Odmowne" claiminfo-ui-flag-overrides="Nadpisanie Flag" @@ -157,6 +160,7 @@ GriefDefender { claiminfo-ui-title-claiminfo="Informacje o Działce" claiminfo-ui-town-settings="Ustawienia Miasta" claimlist-ui-click-info="Kliknij po więcej informacji" + claimlist-ui-click-player-list="Click here to show player claim list" claimlist-ui-click-purchase="Kliknij aby kupić działkę" claimlist-ui-click-rent="Kliknij aby wynająć działkę" claimlist-ui-click-teleport-target="Kliknij aby teleportować się do {name}&f {target}&f w świecie &6{world}" @@ -374,6 +378,7 @@ GriefDefender { flag-description-custom-player-block-place="Ustala, czy gracz może stawiać bloki." flag-description-custom-player-damage="Ustala, czy gracz może otrzymywać obrażenia." flag-description-custom-player-enderpearl-interact="Ustala, czy gracz może używać perły kresu." + flag-description-custom-player-endportal-use="Ustala, czy gracze mogą używać end portali." flag-description-custom-player-enter="Ustala, czy gracz może wchodzić na działkę." flag-description-custom-player-entity-interact="Ustala, czy gracz może wchodzić w interakcję z obiektami.\n&bUwaga&f: Nie dotyczy pojemników na obiektach np. na koniach." flag-description-custom-player-exit="Ustala, czy gracz może wyjść z działki." @@ -381,7 +386,7 @@ GriefDefender { flag-description-custom-player-item-drop="Ustala, czy gracz może wyrzucać rzeczy." flag-description-custom-player-item-pickup="Ustala, czy gracz może podnosić rzeczy." flag-description-custom-player-itemframe-interact="Ustala, czy gracz może wejśc w interakcje z ramką." - flag-description-custom-player-portal-use="Ustala, czy gracze mogą używać portali." + flag-description-custom-player-netherportal-use="Ustala, czy gracze mogą używać nether portali." flag-description-custom-player-teleport-from="Ustala, czy gracze mogą teleportować się będąc na działce." flag-description-custom-player-teleport-to="Ustala, czy gracze mogą teleportować się na tę działkę." flag-description-custom-player-villager-damage="Controls whether players can deal damage to villagers." @@ -630,10 +635,12 @@ GriefDefender { permission-player-admin-flags="&cNie masz permisji do zmiany flag na graczu, który ma uprawnienia administratora." permission-player-option="&cNie masz permisji aby przypisywać opcje do graczy." permission-player-view-others="&cNie masz permisji do sprawdzania innych graczy." - permission-portal-enter="&cNie możesz użyć tego portalu. &6{player} &cnie przyznaje Ci do tego permisji." - permission-portal-exit="&cNie możesz użyć tego portalu, ponieważ nie masz permisji od &6{player} &cna przebywanie na działce, która jest po drugiej stronie portalu." + permission-portal-from="&cYou can't use this portal because you don't have &6{player}'s &cpermission to teleport from this claim." + permission-portal-to="&cYou can't use this portal because you don't have &6{player}'s &cpermission to teleport to the destination claim." permission-protected-portal="&cNie masz permisji do używania portali na działce należącej do &6{player}&c." permission-tax="&cYou don't have permission to manage tax in this claim." + permission-teleport-from="&cYou don't have &6{player}'s &cpermission to teleport from this claim." + permission-teleport-to="&cYou don't have &6{player}'s &cpermission to teleport to the destination claim." permission-trust="&cNie masz permisji od &6{player}&c do zarządzania permisjami." permission-visual-claims-nearby="&cNie masz permisji do wizualizacji pobliskich działek." player-accrued-blocks-exceeded="&cGracz &6{player}&c posiada łącznie &6{total}&c szt. bloków i przekroczy limit, jeżeli dostanie dodatkowe &6{amount}&c szt. bloków.\nZmniejsz liczbę, albo użyj komendy nadpisującej." diff --git a/common/src/main/resources/assets/lang/ru_RU.conf b/common/src/main/resources/assets/lang/ru_RU.conf index 25e4a3c..bf0589c 100644 --- a/common/src/main/resources/assets/lang/ru_RU.conf +++ b/common/src/main/resources/assets/lang/ru_RU.conf @@ -137,6 +137,9 @@ GriefDefender { claiminfo-ui-click-admin="Нажмите, чтобы отобразить администраторские настройки" claiminfo-ui-click-bank="Нажмите, чтобы проверить банковскую информацию" claiminfo-ui-click-change-claim="Нажмите, чтобы изменить вид региона на {type}" + claiminfo-ui-click-farewell="Click here to change farewell message" + claiminfo-ui-click-greeting="Click here to change greeting message" + claiminfo-ui-click-name="Click here to change claim name" claiminfo-ui-click-toggle="Нажмите, чтобы переключить значение" claiminfo-ui-deny-messages="Сообщения об отклонении" claiminfo-ui-flag-overrides="Переопределения флагов" @@ -157,6 +160,7 @@ GriefDefender { claiminfo-ui-title-claiminfo="Информация о регионе" claiminfo-ui-town-settings="Настройки города" claimlist-ui-click-info="Нажмите, чтобы увидеть больше информации" + claimlist-ui-click-player-list="Click here to show player claim list" claimlist-ui-click-purchase="Нажмите, чтобы приобрести регион" claimlist-ui-click-rent="Click here to rent claim" claimlist-ui-click-teleport-target="Нажмите, чтобы телепортироваться к {name}&f {target}&f в &6{world}" @@ -374,6 +378,7 @@ GriefDefender { flag-description-custom-player-block-place="Управляет возможностью игрока установки блоков." flag-description-custom-player-damage="Управляет неуязвимостью игроков." flag-description-custom-player-enderpearl-interact="Управляет возможностью пользоваться Жемчугом Края." + flag-description-custom-player-endportal-use="Управляет возможностью использования конечные порталы." flag-description-custom-player-enter="Управляет возможностью входа сущности в регион." flag-description-custom-player-entity-interact="Управляет возможностью игроков взаимодействовать с сущностями.\n&bПримечание&f: сюда не входит доступ к сущностям с инвентарём, таким, как лошади." flag-description-custom-player-exit="Управляет возможностью игрока выйти из региона." @@ -381,7 +386,7 @@ GriefDefender { flag-description-custom-player-itemframe-interact="Controls whether players can interact with item frames." flag-description-custom-player-item-drop="Управляет возможностью игроков выбрасывать предметы." flag-description-custom-player-item-pickup="Управляет возможностью игроков подбирать предметы." - flag-description-custom-player-portal-use="Управляет возможностью использования порталов." + flag-description-custom-player-netherportal-use="Управляет возможностью использования нижние порталы." flag-description-custom-player-teleport-from="Управляет возможностью игроков телепортироваться из региона." flag-description-custom-player-teleport-to="Управляет возможностью игроков телепортироваться в регион." flag-description-custom-player-villager-damage="Controls whether players can deal damage to villagers." @@ -630,10 +635,12 @@ GriefDefender { permission-player-admin-flags="&cУ вас нет разрешения на изменение флагов для членов администрации." permission-player-option="&cУ вас нет разрешения на установку опции на игрока." permission-player-view-others="&cУ вас нет разрешения на просмотр других игроков." - permission-portal-enter="&cВы не можете воспользоваться этим порталом, потому что у вас нет разрешения от игрока &6{player}&c на вход в регион в месте назначения." - permission-portal-exit="&cВы не можете воспользоваться этим порталом, потому что у вас нет разрешения от игрока &6{player}&c на выход из региона." + permission-portal-from="&cYou can't use this portal because you don't have &6{player}'s &cpermission to teleport from this claim." + permission-portal-to="&cYou can't use this portal because you don't have &6{player}'s &cpermission to teleport to the destination claim." permission-protected-portal="&cУ вас нет разрешения от игрока &6{player}&c на использование портала в этом регионе." permission-tax="&cYou don't have permission to manage tax in this claim." + permission-teleport-from="&cYou don't have &6{player}'s &cpermission to teleport from this claim." + permission-teleport-to="&cYou don't have &6{player}'s &cpermission to teleport to the destination claim." permission-trust="&cУ вас нет разрешения от игрока &6{player}&c на изменение разрешений в этом регионе." permission-visual-claims-nearby="&cУ вас нет разрешения на отображение регионов поблизости." player-accrued-blocks-exceeded="&cУ игрока &6{player}&c есть &6{total}&c блоков и добавление ему ещё &6{amount}&c блоков превысит максимальное возможное количество.\n. Уменьшите добавляемое количество или попросите администратора выдать игроку нужное количество блоков." diff --git a/gradle.properties b/gradle.properties index 8c64643..6dc0084 100644 --- a/gradle.properties +++ b/gradle.properties @@ -2,7 +2,7 @@ name=GriefDefender group=com.griefdefender url=https://github.com/bloodmc/GriefDefender -version=1.4.6 +version=1.4.7 apiVersion=1.0.0-20200528.202302-24 # Bukkit adapterVersion=1.16.1-20200628.024544-5 diff --git a/sponge/src/main/java/com/griefdefender/GDPlayerData.java b/sponge/src/main/java/com/griefdefender/GDPlayerData.java index a4be422..2ba836e 100644 --- a/sponge/src/main/java/com/griefdefender/GDPlayerData.java +++ b/sponge/src/main/java/com/griefdefender/GDPlayerData.java @@ -170,6 +170,14 @@ public class GDPlayerData implements PlayerData { public boolean userOptionBypassPlayerDenyGodmode = false; public boolean userOptionBypassPlayerGamemode = false; + // option cache + public Boolean optionNoFly = null; + public Boolean optionNoGodMode = null; + public Double optionFlySpeed = null; + public Double optionWalkSpeed = null; + public GameModeType optionGameModeType = null; + public WeatherType optionWeatherType = null; + public boolean dataInitialized = false; public boolean showNoClaimsFoundMessage = true; public boolean useRestoreSchematic = false; @@ -857,6 +865,15 @@ public void onClaimDelete() { this.claimSubdividing = null; } + public void resetOptionCache() { + this.optionNoFly = null; + this.optionNoGodMode = null; + this.optionFlySpeed = null; + this.optionWalkSpeed = null; + this.optionGameModeType = null; + this.optionWeatherType = null; + } + public void onDisconnect() { this.claimVisualRevertTasks.clear(); this.visualClaimBlocks.clear(); diff --git a/sponge/src/main/java/com/griefdefender/GriefDefenderPlugin.java b/sponge/src/main/java/com/griefdefender/GriefDefenderPlugin.java index 55a3417..aa489f3 100644 --- a/sponge/src/main/java/com/griefdefender/GriefDefenderPlugin.java +++ b/sponge/src/main/java/com/griefdefender/GriefDefenderPlugin.java @@ -165,6 +165,7 @@ import com.griefdefender.listener.WorldEventHandler; import com.griefdefender.migrator.GPSpongeMigrator; import com.griefdefender.permission.ContextGroupKeys; +import com.griefdefender.permission.GDPermissionGroup; import com.griefdefender.permission.GDPermissionHolder; import com.griefdefender.permission.GDPermissionManager; import com.griefdefender.permission.GDPermissionUser; @@ -555,7 +556,7 @@ public void onPreInit(GamePreInitializationEvent event, Logger logger, Path path instance = this; this.getLogger().info("GriefDefender boot start."); this.getLogger().info("Finished loading configuration."); - DEFAULT_HOLDER = new GDPermissionHolder("default"); + DEFAULT_HOLDER = new GDPermissionGroup("default"); PUBLIC_USER = new GDPermissionUser(PUBLIC_UUID, PUBLIC_NAME); WORLD_USER = new GDPermissionUser(WORLD_USER_UUID, WORLD_USER_NAME); this.getLogger().info("Registering GriefDefender API..."); diff --git a/sponge/src/main/java/com/griefdefender/cache/MessageCache.java b/sponge/src/main/java/com/griefdefender/cache/MessageCache.java index d2f562b..afe0352 100644 --- a/sponge/src/main/java/com/griefdefender/cache/MessageCache.java +++ b/sponge/src/main/java/com/griefdefender/cache/MessageCache.java @@ -80,6 +80,9 @@ public static MessageCache getInstance() { public Component CLAIMINFO_UI_CLAIM_EXPIRATION; public Component CLAIMINFO_UI_CLICK_ADMIN; public Component CLAIMINFO_UI_CLICK_BANK; + public Component CLAIMINFO_UI_CLICK_FAREWELL; + public Component CLAIMINFO_UI_CLICK_GREETING; + public Component CLAIMINFO_UI_CLICK_NAME; public Component CLAIMINFO_UI_CLICK_TOGGLE; public Component CLAIMINFO_UI_DENY_MESSAGES; public Component CLAIMINFO_UI_FLAG_OVERRIDES; @@ -100,6 +103,7 @@ public static MessageCache getInstance() { public Component CLAIMINFO_UI_TITLE_CLAIMINFO; public Component CLAIMINFO_UI_TOWN_SETTINGS; public Component CLAIMLIST_UI_CLICK_INFO; + public Component CLAIMLIST_UI_CLICK_PLAYER_LIST; public Component CLAIMLIST_UI_CLICK_PURCHASE; public Component CLAIMLIST_UI_CLICK_RENT; public Component CLAIMLIST_UI_CLICK_VIEW_CHILDREN; @@ -207,6 +211,7 @@ public static MessageCache getInstance() { public Component FLAG_DESCRIPTION_CUSTOM_PLAYER_BLOCK_PLACE; public Component FLAG_DESCRIPTION_CUSTOM_PLAYER_DAMAGE; public Component FLAG_DESCRIPTION_CUSTOM_PLAYER_ENDERPEARL_INTERACT; + public Component FLAG_DESCRIPTION_CUSTOM_PLAYER_ENDPORTAL_USE; public Component FLAG_DESCRIPTION_CUSTOM_PLAYER_ENTER; public Component FLAG_DESCRIPTION_CUSTOM_PLAYER_ENTITY_INTERACT; public Component FLAG_DESCRIPTION_CUSTOM_PLAYER_EXIT; @@ -215,12 +220,12 @@ public static MessageCache getInstance() { public Component FLAG_DESCRIPTION_CUSTOM_PLAYER_ITEMHANGING_PLACE; public Component FLAG_DESCRIPTION_CUSTOM_PLAYER_ITEM_DROP; public Component FLAG_DESCRIPTION_CUSTOM_PLAYER_ITEM_PICKUP; + public Component FLAG_DESCRIPTION_CUSTOM_PLAYER_NETHERPORTAL_USE; public Component FLAG_DESCRIPTION_CUSTOM_PLAYER_TELEPORT_FROM; public Component FLAG_DESCRIPTION_CUSTOM_PLAYER_TELEPORT_TO; public Component FLAG_DESCRIPTION_CUSTOM_PLAYER_VILLAGER_DAMAGE; public Component FLAG_DESCRIPTION_CUSTOM_PISTON_ITEM_SPAWN; public Component FLAG_DESCRIPTION_CUSTOM_PISTON_USE; - public Component FLAG_DESCRIPTION_CUSTOM_PLAYER_PORTAL_USE; public Component FLAG_DESCRIPTION_CUSTOM_PVP; public Component FLAG_DESCRIPTION_CUSTOM_RIDE; public Component FLAG_DESCRIPTION_CUSTOM_SLEEP; @@ -537,6 +542,9 @@ public void loadCache() { CLAIMINFO_UI_CLAIM_EXPIRATION = MessageStorage.MESSAGE_DATA.getMessage("claiminfo-ui-claim-expiration"); CLAIMINFO_UI_CLICK_ADMIN = MessageStorage.MESSAGE_DATA.getMessage("claiminfo-ui-click-admin"); CLAIMINFO_UI_CLICK_BANK = MessageStorage.MESSAGE_DATA.getMessage("claiminfo-ui-click-bank"); + CLAIMINFO_UI_CLICK_FAREWELL = MessageStorage.MESSAGE_DATA.getMessage("claiminfo-ui-click-farewell"); + CLAIMINFO_UI_CLICK_GREETING = MessageStorage.MESSAGE_DATA.getMessage("claiminfo-ui-click-greeting"); + CLAIMINFO_UI_CLICK_NAME = MessageStorage.MESSAGE_DATA.getMessage("claiminfo-ui-click-name"); CLAIMINFO_UI_CLICK_TOGGLE = MessageStorage.MESSAGE_DATA.getMessage("claiminfo-ui-click-toggle"); CLAIMINFO_UI_DENY_MESSAGES = MessageStorage.MESSAGE_DATA.getMessage("claiminfo-ui-deny-messages"); CLAIMINFO_UI_FLAG_OVERRIDES = MessageStorage.MESSAGE_DATA.getMessage("claiminfo-ui-flag-overrides"); @@ -557,6 +565,7 @@ public void loadCache() { CLAIMINFO_UI_TITLE_CLAIMINFO = MessageStorage.MESSAGE_DATA.getMessage("claiminfo-ui-title-claiminfo"); CLAIMINFO_UI_TOWN_SETTINGS = MessageStorage.MESSAGE_DATA.getMessage("claiminfo-ui-town-settings"); CLAIMLIST_UI_CLICK_INFO = MessageStorage.MESSAGE_DATA.getMessage("claimlist-ui-click-info"); + CLAIMLIST_UI_CLICK_PLAYER_LIST = MessageStorage.MESSAGE_DATA.getMessage("claimlist-ui-click-player-list"); CLAIMLIST_UI_CLICK_PURCHASE = MessageStorage.MESSAGE_DATA.getMessage("claimlist-ui-click-purchase"); CLAIMLIST_UI_CLICK_RENT = MessageStorage.MESSAGE_DATA.getMessage("claimlist-ui-click-rent"); CLAIMLIST_UI_CLICK_VIEW_CHILDREN = MessageStorage.MESSAGE_DATA.getMessage("claimlist-ui-click-view-children"); @@ -665,6 +674,7 @@ public void loadCache() { FLAG_DESCRIPTION_CUSTOM_PLAYER_BLOCK_INTERACT = MessageStorage.MESSAGE_DATA.getMessage("flag-description-custom-player-block-interact"); FLAG_DESCRIPTION_CUSTOM_PLAYER_DAMAGE = MessageStorage.MESSAGE_DATA.getMessage("flag-description-custom-player-damage"); FLAG_DESCRIPTION_CUSTOM_PLAYER_ENDERPEARL_INTERACT = MessageStorage.MESSAGE_DATA.getMessage("flag-description-custom-player-enderpearl-interact"); + FLAG_DESCRIPTION_CUSTOM_PLAYER_ENDPORTAL_USE = MessageStorage.MESSAGE_DATA.getMessage("flag-description-custom-player-endportal-use"); FLAG_DESCRIPTION_CUSTOM_PLAYER_ENTER = MessageStorage.MESSAGE_DATA.getMessage("flag-description-custom-player-enter"); FLAG_DESCRIPTION_CUSTOM_PLAYER_ENTITY_INTERACT = MessageStorage.MESSAGE_DATA.getMessage("flag-description-custom-player-entity-interact"); FLAG_DESCRIPTION_CUSTOM_PLAYER_EXIT = MessageStorage.MESSAGE_DATA.getMessage("flag-description-custom-player-exit"); @@ -673,7 +683,7 @@ public void loadCache() { FLAG_DESCRIPTION_CUSTOM_PLAYER_ITEMHANGING_PLACE = MessageStorage.MESSAGE_DATA.getMessage("flag-description-custom-player-itemhanging-place"); FLAG_DESCRIPTION_CUSTOM_PLAYER_ITEM_DROP = MessageStorage.MESSAGE_DATA.getMessage("flag-description-custom-player-item-drop"); FLAG_DESCRIPTION_CUSTOM_PLAYER_ITEM_PICKUP = MessageStorage.MESSAGE_DATA.getMessage("flag-description-custom-player-item-pickup"); - FLAG_DESCRIPTION_CUSTOM_PLAYER_PORTAL_USE = MessageStorage.MESSAGE_DATA.getMessage("flag-description-custom-player-portal-use"); + FLAG_DESCRIPTION_CUSTOM_PLAYER_NETHERPORTAL_USE = MessageStorage.MESSAGE_DATA.getMessage("flag-description-custom-player-netherportal-use"); FLAG_DESCRIPTION_CUSTOM_PLAYER_TELEPORT_FROM = MessageStorage.MESSAGE_DATA.getMessage("flag-description-custom-player-teleport-from"); FLAG_DESCRIPTION_CUSTOM_PLAYER_TELEPORT_TO = MessageStorage.MESSAGE_DATA.getMessage("flag-description-custom-player-teleport-to"); FLAG_DESCRIPTION_CUSTOM_PLAYER_VILLAGER_DAMAGE = MessageStorage.MESSAGE_DATA.getMessage("flag-description-custom-player-villager-damage"); diff --git a/sponge/src/main/java/com/griefdefender/command/ClaimFlagBase.java b/sponge/src/main/java/com/griefdefender/command/ClaimFlagBase.java index e1d8d74..46d3ac0 100644 --- a/sponge/src/main/java/com/griefdefender/command/ClaimFlagBase.java +++ b/sponge/src/main/java/com/griefdefender/command/ClaimFlagBase.java @@ -29,6 +29,7 @@ import com.github.benmanes.caffeine.cache.Cache; import com.github.benmanes.caffeine.cache.Caffeine; import com.google.common.collect.ImmutableMap; +import com.griefdefender.GDBootstrap; import com.griefdefender.GDPlayerData; import com.griefdefender.GriefDefenderPlugin; import com.griefdefender.api.GriefDefender; @@ -76,6 +77,7 @@ import net.kyori.text.event.HoverEvent; import net.kyori.text.format.TextColor; import net.kyori.text.format.TextDecoration; +import org.spongepowered.api.Sponge; import org.spongepowered.api.command.CommandSource; import org.spongepowered.api.entity.living.player.Player; import org.spongepowered.api.item.inventory.ItemStack; @@ -94,6 +96,7 @@ import java.util.TreeMap; import java.util.TreeSet; import java.util.UUID; +import java.util.concurrent.CompletableFuture; import java.util.concurrent.TimeUnit; import java.util.function.Consumer; @@ -1103,6 +1106,7 @@ 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()); @@ -1120,13 +1124,15 @@ private Consumer createCustomFlagConsumer(GDPermissionUser src, G return; } - PermissionResult result = GriefDefenderPlugin.getInstance().getPermissionProvider().setPermissionValue(GriefDefenderPlugin.DEFAULT_HOLDER, flag, newValue, newContexts); + result = GriefDefenderPlugin.getInstance().getPermissionProvider().setPermissionValue(GriefDefenderPlugin.DEFAULT_HOLDER, flag, newValue, newContexts); } - // Save after all permission changes have been made - GriefDefenderPlugin.getInstance().getPermissionProvider().save(GriefDefenderPlugin.DEFAULT_HOLDER); - GDCauseStackManager.getInstance().popCause(); - showCustomFlags(src, claim, flagGroup); + result.thenAccept(r -> { + Sponge.getScheduler().createSyncExecutor(GDBootstrap.getInstance()).execute(() -> { + GDCauseStackManager.getInstance().popCause(); + showCustomFlags(src, claim, flagGroup); + }); + }); }; } @@ -1176,21 +1182,35 @@ private Consumer createFlagConsumer(GDPermissionUser src, GDClaim } if (displayType == MenuType.DEFAULT || (hasDefaultContext && src.getInternalPlayerData().canManageFlagDefaults)) { - PermissionResult result = PermissionUtil.getInstance().setTransientPermission(this.subject, flag.getPermission(), newValue, newContexts); - if (result.successful()) { - showFlagPermissions(src, claim, displayType); - return; + CompletableFuture future = PermissionUtil.getInstance().setPermissionValue(this.subject, flag.getPermission(), newValue, newContexts); + future.thenAccept(r -> { + Sponge.getScheduler().createSyncExecutor(GDBootstrap.getInstance()).execute(() -> { + showFlagPermissions(src, claim, displayType); + }); + }); + return; + } + + final Context permServerContext = serverContext; + CompletableFuture future = PermissionUtil.getInstance().setPermissionValue(this.subject, flag, newValue, newContexts); + future.thenAcceptAsync(r -> { + if (!r.successful()) { + // Try again without server context + newContexts.remove(permServerContext); + CompletableFuture newFuture = PermissionUtil.getInstance().setPermissionValue(this.subject, flag, newValue, newContexts, false, true); + newFuture.thenAccept(r2 -> { + if (r2.successful()) { + Sponge.getScheduler().createSyncExecutor(GDBootstrap.getInstance()).execute(() -> { + showFlagPermissions(src, claim, displayType); + }); + } + }); + } else { + Sponge.getScheduler().createSyncExecutor(GDBootstrap.getInstance()).execute(() -> { + showFlagPermissions(src, claim, displayType); + }); } - } - PermissionResult result = PermissionUtil.getInstance().setPermissionValue(this.subject, flag, newValue, newContexts); - if (!result.successful()) { - // Try again without server context - newContexts.remove(serverContext); - result = PermissionUtil.getInstance().setPermissionValue(this.subject, flag, newValue, newContexts, false, true); - } - if (result.successful()) { - showFlagPermissions(src, claim, displayType); - } + }); }; } diff --git a/sponge/src/main/java/com/griefdefender/command/ClaimOptionBase.java b/sponge/src/main/java/com/griefdefender/command/ClaimOptionBase.java index dfb2446..c3e196a 100644 --- a/sponge/src/main/java/com/griefdefender/command/ClaimOptionBase.java +++ b/sponge/src/main/java/com/griefdefender/command/ClaimOptionBase.java @@ -31,6 +31,7 @@ import com.google.common.collect.ImmutableMap; import com.google.common.collect.Maps; import com.google.common.reflect.TypeToken; +import com.griefdefender.GDBootstrap; import com.griefdefender.GDPlayerData; import com.griefdefender.GriefDefenderPlugin; import com.griefdefender.api.GriefDefender; @@ -78,6 +79,7 @@ import net.kyori.text.event.HoverEvent; import net.kyori.text.format.TextColor; import net.kyori.text.format.TextDecoration; +import org.spongepowered.api.Sponge; import org.spongepowered.api.command.CommandSource; import org.spongepowered.api.entity.living.player.Player; @@ -93,6 +95,7 @@ import java.util.Set; import java.util.TreeMap; import java.util.UUID; +import java.util.concurrent.CompletableFuture; import java.util.concurrent.TimeUnit; import java.util.function.Consumer; import java.util.regex.Matcher; @@ -874,25 +877,46 @@ private Consumer newOptionValueConsumer(GDPermissionUser src, GDC if (!hasServerContext && serverContext != null) { newContexts.add(serverContext); } - final PermissionResult result = PermissionUtil.getInstance().setOptionValue(this.subject, option.getPermission(), newValue, newContexts); - if (!result.successful()) { - // Try again without server context - newContexts.remove(serverContext); - PermissionUtil.getInstance().setOptionValue(this.subject, option.getPermission(), newValue, newContexts, false); - } - if (result.successful()) { - if (option == Options.PLAYER_WEATHER) { - CommonEntityEventHandler.getInstance().checkPlayerWeather(src, claim, claim, true); + final Context permServerContext = serverContext; + final String permValue = newValue; + final CompletableFuture future = PermissionUtil.getInstance().setOptionValue(this.subject, option.getPermission(), newValue, newContexts); + future.thenAcceptAsync(r -> { + if (!r.successful()) { + // Try again without server context + newContexts.remove(permServerContext); + CompletableFuture newFuture = PermissionUtil.getInstance().setOptionValue(this.subject, option.getPermission(), permValue, newContexts, false); + newFuture.thenAccept(r2 -> { + if (r2.successful()) { + Sponge.getScheduler().createSyncExecutor(GDBootstrap.getInstance()).execute(() -> { + if (option == Options.PLAYER_WEATHER) { + CommonEntityEventHandler.getInstance().checkPlayerWeather(src, claim, claim, true); + } + showOptionPermissions(src, claim, displayType); + }); + } + }); + } else { + Sponge.getScheduler().createSyncExecutor(GDBootstrap.getInstance()).execute(() -> { + if (option == Options.PLAYER_WEATHER) { + CommonEntityEventHandler.getInstance().checkPlayerWeather(src, claim, claim, true); + } + showOptionPermissions(src, claim, displayType); + }); } - } - showOptionPermissions(src, claim, displayType); + }); }; } private Consumer removeOptionValueConsumer(GDPermissionUser src, GDClaim claim, Option option, OptionContextHolder optionHolder, Set contexts, MenuType displayType) { return consumer -> { - PermissionUtil.getInstance().setOptionValue(this.subject, option.getPermission(), "undefined", contexts); - showOptionPermissions(src, claim, displayType); + final CompletableFuture future = PermissionUtil.getInstance().setOptionValue(this.subject, option.getPermission(), "undefined", contexts); + future.thenAccept(r -> { + if (r.successful()) { + Sponge.getScheduler().createSyncExecutor(GDBootstrap.getInstance()).execute(() -> { + showOptionPermissions(src, claim, displayType); + }); + } + }); }; } diff --git a/sponge/src/main/java/com/griefdefender/command/CommandClaimInfo.java b/sponge/src/main/java/com/griefdefender/command/CommandClaimInfo.java index a271127..48c98cf 100644 --- a/sponge/src/main/java/com/griefdefender/command/CommandClaimInfo.java +++ b/sponge/src/main/java/com/griefdefender/command/CommandClaimInfo.java @@ -60,6 +60,7 @@ import net.kyori.text.event.HoverEvent; import net.kyori.text.format.TextColor; import net.kyori.text.format.TextDecoration; +import net.kyori.text.serializer.legacy.LegacyComponentSerializer; import org.spongepowered.api.Sponge; import org.spongepowered.api.command.CommandSource; import org.spongepowered.api.entity.living.player.Player; @@ -243,10 +244,16 @@ public void execute(CommandSource src, String[] args) { if (claim.isWilderness() && name == null) { name = TextComponent.of("Wilderness", TextColor.GREEN); } + Component nameText = name == null ? NONE : name; Component claimName = TextComponent.builder() - .append(MessageCache.getInstance().LABEL_NAME.color(TextColor.YELLOW)) + .append(MessageCache.getInstance().LABEL_NAME.color(TextColor.YELLOW) + .clickEvent(ClickEvent.suggestCommand("/claimname ")) + .hoverEvent(HoverEvent.showText(MessageCache.getInstance().CLAIMINFO_UI_CLICK_NAME))) .append(" : ", TextColor.YELLOW) - .append(name == null ? NONE : name).build(); + .append(nameText + .clickEvent(ClickEvent.suggestCommand(name == null ? "/claimname " : "/claimname " + LegacyComponentSerializer.legacy().serialize(name, '&'))) + .hoverEvent(HoverEvent.showText(MessageCache.getInstance().CLAIMINFO_UI_CLICK_NAME))) + .build(); Component worldName = TextComponent.builder() .append(MessageCache.getInstance().LABEL_WORLD.color(TextColor.YELLOW)) .append(" : ") @@ -471,19 +478,31 @@ public void execute(CommandSource src, String[] args) { .append(MessageCache.getInstance().LABEL_EXPIRED.color(TextColor.YELLOW)) .append(" : "); if (isAdmin && claim.getData().isExpired()) { - expireBuilder.append(getClickableInfoText(src, claim, IS_EXPIRED, claim.getData().isExpired() ? TextComponent.of("YES", TextColor.RED) : TextComponent.of("NO", TextColor.GRAY))); + expireBuilder.append(getClickableInfoText(src, claim, IS_EXPIRED, claim.getData().isExpired() ? MessageCache.getInstance().LABEL_YES.color(TextColor.RED) : MessageCache.getInstance().LABEL_NO.color(TextColor.GRAY))); } else { - expireBuilder.append(claim.getData().isExpired() ? TextComponent.of("YES", TextColor.RED) : TextComponent.of("NO", TextColor.GRAY)); + expireBuilder.append(claim.getData().isExpired() ? MessageCache.getInstance().LABEL_YES.color(TextColor.RED) : MessageCache.getInstance().LABEL_NO.color(TextColor.GRAY)); } Component claimExpired = expireBuilder.build(); + Component farewellText = farewell == null ? NONE : farewell; + Component greetingText = greeting == null ? NONE : greeting; Component claimFarewell = TextComponent.builder() - .append(MessageCache.getInstance().LABEL_FAREWELL.color(TextColor.YELLOW)) + .append(MessageCache.getInstance().LABEL_FAREWELL.color(TextColor.YELLOW) + .clickEvent(ClickEvent.suggestCommand("/claimfarewell ")) + .hoverEvent(HoverEvent.showText(MessageCache.getInstance().CLAIMINFO_UI_CLICK_FAREWELL))) .append(" : ") - .append(farewell == null ? NONE : farewell).build(); + .append(farewellText + .clickEvent(ClickEvent.suggestCommand(farewell == null ? "/claimfarewell " : "/claimfarewell " + LegacyComponentSerializer.legacy().serialize(farewell, '&'))) + .hoverEvent(HoverEvent.showText(MessageCache.getInstance().CLAIMINFO_UI_CLICK_FAREWELL))) + .build(); Component claimGreeting = TextComponent.builder() - .append(MessageCache.getInstance().LABEL_GREETING.color(TextColor.YELLOW)) + .append(MessageCache.getInstance().LABEL_GREETING.color(TextColor.YELLOW) + .clickEvent(ClickEvent.suggestCommand("/claimgreeting ")) + .hoverEvent(HoverEvent.showText(MessageCache.getInstance().CLAIMINFO_UI_CLICK_GREETING))) .append(" : ") - .append(greeting == null ? NONE : greeting).build(); + .append(greetingText + .clickEvent(ClickEvent.suggestCommand(greeting == null ? "/claimgreeting " : "/claimgreeting " + LegacyComponentSerializer.legacy().serialize(greeting, '&'))) + .hoverEvent(HoverEvent.showText(MessageCache.getInstance().CLAIMINFO_UI_CLICK_GREETING))) + .build(); Component claimDenyMessages = TextComponent.builder() .append(MessageCache.getInstance().CLAIMINFO_UI_DENY_MESSAGES.color(TextColor.YELLOW)) .append(" : ") diff --git a/sponge/src/main/java/com/griefdefender/command/CommandHelper.java b/sponge/src/main/java/com/griefdefender/command/CommandHelper.java index e39012c..9858d0d 100644 --- a/sponge/src/main/java/com/griefdefender/command/CommandHelper.java +++ b/sponge/src/main/java/com/griefdefender/command/CommandHelper.java @@ -725,7 +725,9 @@ public static List generateClaimTextList(List claimsTextLi .append(claimSpawn != null ? claimSpawn.append(TextComponent.of(" ")) : TextComponent.of("")) .append(claimInfoCommandClick) .append(" : ", TextColor.WHITE) - .append(claim.getOwnerDisplayName().color(TextColor.GOLD)) + .append(claim.getOwnerDisplayName().color(TextColor.GOLD) + .clickEvent(ClickEvent.suggestCommand("/claimlist " + claim.getOwnerName())) + .hoverEvent(HoverEvent.showText(MessageCache.getInstance().CLAIMLIST_UI_CLICK_PLAYER_LIST))) .append(" ") .append(claimName == TextComponent.empty() ? TextComponent.of("") : claimName) .append(" ") @@ -740,7 +742,9 @@ public static List generateClaimTextList(List claimsTextLi .append(claimSpawn != null ? claimSpawn.append(TextComponent.of(" ")) : TextComponent.of("")) .append(claimInfoCommandClick) .append(" : ", TextColor.WHITE) - .append(claim.getOwnerDisplayName().color(TextColor.GOLD)) + .append(claim.getOwnerDisplayName().color(TextColor.GOLD) + .clickEvent(ClickEvent.suggestCommand("/claimlist " + claim.getOwnerName())) + .hoverEvent(HoverEvent.showText(MessageCache.getInstance().CLAIMLIST_UI_CLICK_PLAYER_LIST))) .append(" ") .append(claimName == TextComponent.empty() ? TextComponent.of("") : claimName) .append(buyClaim) diff --git a/sponge/src/main/java/com/griefdefender/configuration/FlagStorage.java b/sponge/src/main/java/com/griefdefender/configuration/FlagStorage.java index 0f6c231..9b2334e 100644 --- a/sponge/src/main/java/com/griefdefender/configuration/FlagStorage.java +++ b/sponge/src/main/java/com/griefdefender/configuration/FlagStorage.java @@ -28,6 +28,7 @@ import com.google.common.collect.Maps; import com.griefdefender.api.permission.flag.Flag; +import com.griefdefender.api.permission.flag.Flags; import com.griefdefender.configuration.category.ConfigCategory; import com.griefdefender.configuration.category.CustomFlagGroupDefinitionCategory; import com.griefdefender.configuration.category.DefaultFlagCategory; @@ -81,7 +82,11 @@ public class FlagStorage extends ConfigCategory { public FlagStorage() { for (Flag flag : FlagRegistryModule.getInstance().getAll()) { - this.control.put(flag.getName().toLowerCase(), true); + if (flag == Flags.ENTITY_CHUNK_SPAWN || flag == Flags.PORTAL_USE) { + this.control.put(flag.getName().toLowerCase(), false); + } else { + this.control.put(flag.getName().toLowerCase(), true); + } } } diff --git a/sponge/src/main/java/com/griefdefender/configuration/MessageStorage.java b/sponge/src/main/java/com/griefdefender/configuration/MessageStorage.java index b1a6ecd..7bbbb27 100644 --- a/sponge/src/main/java/com/griefdefender/configuration/MessageStorage.java +++ b/sponge/src/main/java/com/griefdefender/configuration/MessageStorage.java @@ -277,9 +277,11 @@ public class MessageStorage { public static final String PERMISSION_INVENTORY_OPEN = "permission-inventory-open"; public static final String PERMISSION_ITEM_DROP = "permission-item-drop"; public static final String PERMISSION_ITEM_USE = "permission-item-use"; - public static final String PERMISSION_PORTAL_ENTER = "permission-portal-enter"; - public static final String PERMISSION_PORTAL_EXIT = "permission-portal-exit"; + public static final String PERMISSION_PORTAL_FROM = "permission-portal-from"; + public static final String PERMISSION_PORTAL_TO = "permission-portal-to"; public static final String PERMISSION_PROTECTED_PORTAL = "permission-protected-portal"; + public static final String PERMISSION_TELEPORT_FROM = "permission-teleport-from"; + public static final String PERMISSION_TELEPORT_TO = "permission-teleport-to"; public static final String PERMISSION_TRUST = "permission-trust"; public static final String PLAYER_ACCRUED_BLOCKS_EXCEEDED = "player-accrued-blocks-exceeded"; public static final String PLAYER_NO_CLAIMS_TO_DELETE = "player-no-claims-to-delete"; diff --git a/sponge/src/main/java/com/griefdefender/listener/BlockEventHandler.java b/sponge/src/main/java/com/griefdefender/listener/BlockEventHandler.java index 873ecdd..54f1975 100644 --- a/sponge/src/main/java/com/griefdefender/listener/BlockEventHandler.java +++ b/sponge/src/main/java/com/griefdefender/listener/BlockEventHandler.java @@ -93,6 +93,8 @@ import org.spongepowered.api.event.cause.EventContextKeys; import org.spongepowered.api.event.filter.cause.Root; import org.spongepowered.api.event.world.ExplosionEvent; +import org.spongepowered.api.item.ItemTypes; +import org.spongepowered.api.item.inventory.ItemStackSnapshot; import org.spongepowered.api.text.Text; import org.spongepowered.api.util.Direction; import org.spongepowered.api.world.DimensionTypes; @@ -434,6 +436,10 @@ public void onBlockCollide(CollideBlockEvent event, @Root Entity source) { if (gdBlock != null && !gdBlock.isCollidable()) { return; } + if (event.getTargetBlock().getType() == BlockTypes.PORTAL) { + // ignore as we handle this with entity-teleport-from + return; + } if (GriefDefenderPlugin.isSourceIdBlacklisted(Flags.COLLIDE_BLOCK.getName(), source.getType().getId(), source.getWorld().getProperties())) { return; } @@ -644,6 +650,9 @@ public void onExplosionDetonate(ExplosionEvent.Detonate event) { denySurfaceExplosion = !GriefDefenderPlugin.getActiveConfig(world.getUniqueId()).getConfig().claim.explosionBlockSurfaceBlacklist.contains("any"); } for (Location location : event.getAffectedLocations()) { + if (location.getBlockType().equals(BlockTypes.AIR)) { + continue; + } targetClaim = GriefDefenderPlugin.getInstance().dataStore.getClaimAt(location, targetClaim); if (denySurfaceExplosion && world.getDimension().getType() != DimensionTypes.NETHER && location.getBlockY() >= world.getSeaLevel()) { filteredLocations.add(location); @@ -769,6 +778,13 @@ public void onBlockPlace(ChangeBlockEvent.Place event) { return; } + ItemStackSnapshot itemSnapshot = event.getContext().get(EventContextKeys.USED_ITEM).orElse(null); + if (itemSnapshot != null) { + if (itemSnapshot.getType().equals(ItemTypes.BUCKET)) { + // Sponge bug - empty buckets should never fire a block place + return; + } + } GDTimings.BLOCK_PLACE_EVENT.startTimingIfSync(); GDClaim sourceClaim = null; LocatableBlock locatable = null; diff --git a/sponge/src/main/java/com/griefdefender/listener/CommonEntityEventHandler.java b/sponge/src/main/java/com/griefdefender/listener/CommonEntityEventHandler.java index 2b1bccf..e7667c3 100644 --- a/sponge/src/main/java/com/griefdefender/listener/CommonEntityEventHandler.java +++ b/sponge/src/main/java/com/griefdefender/listener/CommonEntityEventHandler.java @@ -24,7 +24,6 @@ */ package com.griefdefender.listener; -import java.lang.ref.WeakReference; import java.util.ArrayList; import java.util.HashSet; import java.util.List; @@ -35,9 +34,11 @@ import org.spongepowered.api.Sponge; import org.spongepowered.api.data.key.Keys; import org.spongepowered.api.entity.Entity; +import org.spongepowered.api.entity.Item; import org.spongepowered.api.entity.living.player.Player; import org.spongepowered.api.entity.living.player.gamemode.GameMode; import org.spongepowered.api.entity.living.player.gamemode.GameModes; +import org.spongepowered.api.entity.projectile.Projectile; import org.spongepowered.api.event.entity.MoveEntityEvent; import org.spongepowered.api.item.inventory.ItemStack; import org.spongepowered.api.text.Text; @@ -70,7 +71,6 @@ import com.griefdefender.internal.util.VecHelper; import com.griefdefender.permission.GDPermissionManager; import com.griefdefender.permission.GDPermissionUser; -import com.griefdefender.permission.GDPermissions; import com.griefdefender.permission.flag.GDFlags; import com.griefdefender.permission.option.GDOptions; import com.griefdefender.permission.option.OptionContexts; @@ -104,6 +104,9 @@ public CommonEntityEventHandler() { } public boolean onEntityMove(MoveEntityEvent event, Location fromLocation, Location toLocation, Entity targetEntity){ + if (targetEntity instanceof Item || targetEntity instanceof Projectile) { + return true; + } if ((!GDFlags.ENTER_CLAIM && !GDFlags.EXIT_CLAIM) || fromLocation.getBlockPosition().equals(toLocation.getBlockPosition())) { return true; } @@ -112,11 +115,6 @@ public boolean onEntityMove(MoveEntityEvent event, Location fromLocation, if (!GriefDefenderPlugin.getInstance().claimsEnabledForWorld(world.getUniqueId())) { return true; } - final boolean enterBlacklisted = GriefDefenderPlugin.isSourceIdBlacklisted(Flags.ENTER_CLAIM.getName(), targetEntity, world.getProperties()); - final boolean exitBlacklisted = GriefDefenderPlugin.isSourceIdBlacklisted(Flags.EXIT_CLAIM.getName(), targetEntity, world.getProperties()); - if (enterBlacklisted && exitBlacklisted) { - return true; - } GDTimings.ENTITY_MOVE_EVENT.startTimingIfSync(); Player player = null; @@ -160,7 +158,7 @@ public boolean onEntityMove(MoveEntityEvent event, Location fromLocation, if (fromClaim != toClaim) { GDBorderClaimEvent gpEvent = new GDBorderClaimEvent(targetEntity, fromClaim, toClaim); // enter - if (GDFlags.ENTER_CLAIM && !enterBlacklisted && GDPermissionManager.getInstance().getFinalPermission(event, toLocation, toClaim, Flags.ENTER_CLAIM, targetEntity, targetEntity, user) == Tristate.FALSE) { + if (GDFlags.ENTER_CLAIM && GDPermissionManager.getInstance().getFinalPermission(event, toLocation, toClaim, Flags.ENTER_CLAIM, targetEntity, targetEntity, user) == Tristate.FALSE) { gpEvent.cancelled(true); if (event != null) { event.setCancelled(true); @@ -168,7 +166,7 @@ public boolean onEntityMove(MoveEntityEvent event, Location fromLocation, } // exit - if (GDFlags.EXIT_CLAIM && !exitBlacklisted && GDPermissionManager.getInstance().getFinalPermission(event, fromLocation, fromClaim, Flags.EXIT_CLAIM, targetEntity, targetEntity, user) == Tristate.FALSE) { + if (GDFlags.EXIT_CLAIM && GDPermissionManager.getInstance().getFinalPermission(event, fromLocation, fromClaim, Flags.EXIT_CLAIM, targetEntity, targetEntity, user) == Tristate.FALSE) { gpEvent.cancelled(true); if (event != null) { event.setCancelled(true); @@ -297,13 +295,13 @@ public boolean onEntityMove(MoveEntityEvent event, Location fromLocation, boolean enterCancelled = false; boolean exitCancelled = false; // enter - if (GDFlags.ENTER_CLAIM && !enterBlacklisted && GDPermissionManager.getInstance().getFinalPermission(event, toLocation, toClaim, Flags.ENTER_CLAIM, targetEntity, targetEntity, user, true) == Tristate.FALSE) { + if (GDFlags.ENTER_CLAIM && GDPermissionManager.getInstance().getFinalPermission(event, toLocation, toClaim, Flags.ENTER_CLAIM, targetEntity, targetEntity, user, true) == Tristate.FALSE) { enterCancelled = true; gpEvent.cancelled(true); } // exit - if (GDFlags.EXIT_CLAIM && !exitBlacklisted && GDPermissionManager.getInstance().getFinalPermission(event, fromLocation, fromClaim, Flags.EXIT_CLAIM, targetEntity, targetEntity, user, true) == Tristate.FALSE) { + if (GDFlags.EXIT_CLAIM && GDPermissionManager.getInstance().getFinalPermission(event, fromLocation, fromClaim, Flags.EXIT_CLAIM, targetEntity, targetEntity, user, true) == Tristate.FALSE) { exitCancelled = true; gpEvent.cancelled(true); } @@ -517,8 +515,10 @@ private void checkPlayerFlight(GDPermissionUser user, GDClaim fromClaim, GDClaim return; } - final Boolean noFly = GDPermissionManager.getInstance().getInternalOptionValue(TypeToken.of(Boolean.class), playerData.getSubject(), Options.PLAYER_DENY_FLIGHT, toClaim); - final boolean adminFly = playerData.userOptionBypassPlayerDenyFlight; + if (playerData.userOptionBypassPlayerDenyFlight) { + return; + } + boolean trustFly = false; if (toClaim.isBasicClaim() || (toClaim.parent != null && toClaim.parent.isBasicClaim()) || toClaim.isInTown()) { // check owner @@ -540,7 +540,13 @@ private void checkPlayerFlight(GDPermissionUser user, GDClaim fromClaim, GDClaim if (trustFly) { return; } - if (!adminFly && noFly) { + + Boolean noFly = playerData.optionNoFly; + if (noFly == null || fromClaim != toClaim) { + noFly = GDPermissionManager.getInstance().getInternalOptionValue(TypeToken.of(Boolean.class), playerData.getSubject(), Options.PLAYER_DENY_FLIGHT, toClaim); + playerData.optionNoFly = noFly; + } + if (noFly) { player.offer(Keys.CAN_FLY, false); player.offer(Keys.IS_FLYING, false); playerData.ignoreFallDamage = true; @@ -574,7 +580,11 @@ private void checkPlayerGodMode(GDPermissionUser user, GDClaim fromClaim, GDClai return; } - final Boolean noGodMode = GDPermissionManager.getInstance().getInternalOptionValue(TypeToken.of(Boolean.class), playerData.getSubject(), Options.PLAYER_DENY_GODMODE, toClaim); + Boolean noGodMode = playerData.optionNoGodMode; + if (noGodMode == null || fromClaim != toClaim) { + noGodMode = GDPermissionManager.getInstance().getInternalOptionValue(TypeToken.of(Boolean.class), playerData.getSubject(), Options.PLAYER_DENY_GODMODE, toClaim); + playerData.optionNoGodMode = noGodMode; + } final boolean bypassOption = playerData.userOptionBypassPlayerDenyGodmode; if (!bypassOption && noGodMode) { player.offer(Keys.INVULNERABLE, false); @@ -597,7 +607,11 @@ private void checkPlayerGameMode(GDPermissionUser user, GDClaim fromClaim, GDCla final GDPlayerData playerData = user.getInternalPlayerData(); final GameMode currentGameMode = player.get(Keys.GAME_MODE).get(); - final GameModeType gameModeType = GDPermissionManager.getInstance().getInternalOptionValue(TypeToken.of(GameModeType.class), playerData.getSubject(), Options.PLAYER_GAMEMODE, toClaim); + GameModeType gameModeType = playerData.optionGameModeType; + if (gameModeType == null || fromClaim != toClaim) { + gameModeType = GDPermissionManager.getInstance().getInternalOptionValue(TypeToken.of(GameModeType.class), playerData.getSubject(), Options.PLAYER_GAMEMODE, toClaim); + playerData.optionGameModeType = gameModeType; + } if (gameModeType == GameModeTypes.UNDEFINED && playerData.lastGameMode != GameModeTypes.UNDEFINED) { player.offer(Keys.GAME_MODE, PlayerUtil.GAMEMODE_MAP.get(playerData.lastGameMode)); return; @@ -632,7 +646,11 @@ private void checkPlayerFlySpeed(GDPermissionUser user, GDClaim fromClaim, GDCla final GDPlayerData playerData = user.getInternalPlayerData(); final double currentFlySpeed = Math.round(player.get(Keys.FLYING_SPEED).get() * 100.0) / 100.0; - final double flySpeed = GDPermissionManager.getInstance().getInternalOptionValue(TypeToken.of(Double.class), playerData.getSubject(), Options.PLAYER_FLY_SPEED, toClaim); + Double flySpeed = playerData.optionFlySpeed; + if (flySpeed == null || fromClaim != toClaim) { + flySpeed = GDPermissionManager.getInstance().getInternalOptionValue(TypeToken.of(Double.class), playerData.getSubject(), Options.PLAYER_FLY_SPEED, toClaim); + playerData.optionFlySpeed = flySpeed; + } if (flySpeed <= 0) { String configValue = GriefDefenderPlugin.getOptionConfig().getConfig().vanillaFallbackMap.get(Options.PLAYER_FLY_SPEED.getName().toLowerCase()); Double defaultFlySpeed = null; @@ -680,7 +698,11 @@ private void checkPlayerWalkSpeed(GDPermissionUser user, GDClaim fromClaim, GDCl final GDPlayerData playerData = user.getInternalPlayerData(); final double currentWalkSpeed = Math.round(player.get(Keys.WALKING_SPEED).get() * 100.0) / 100.0; - final double walkSpeed = GDPermissionManager.getInstance().getInternalOptionValue(TypeToken.of(Double.class), playerData.getSubject(), Options.PLAYER_WALK_SPEED, toClaim); + Double walkSpeed = user.getInternalPlayerData().optionWalkSpeed; + if (walkSpeed == null || fromClaim != toClaim) { + walkSpeed = GDPermissionManager.getInstance().getInternalOptionValue(TypeToken.of(Double.class), playerData.getSubject(), Options.PLAYER_WALK_SPEED, toClaim); + user.getInternalPlayerData().optionWalkSpeed = walkSpeed; + } if (walkSpeed <= 0) { String configValue = GriefDefenderPlugin.getOptionConfig().getConfig().vanillaFallbackMap.get(Options.PLAYER_WALK_SPEED.getName().toLowerCase()); Double defaultWalkSpeed = null; @@ -727,7 +749,11 @@ public void checkPlayerWeather(GDPermissionUser user, GDClaim fromClaim, GDClaim } final GDPlayerData playerData = user.getInternalPlayerData(); - final WeatherType weatherType = GDPermissionManager.getInstance().getInternalOptionValue(TypeToken.of(WeatherType.class), playerData.getSubject(), Options.PLAYER_WEATHER, toClaim); + WeatherType weatherType = playerData.optionWeatherType; + if (weatherType == null || fromClaim != toClaim) { + weatherType = GDPermissionManager.getInstance().getInternalOptionValue(TypeToken.of(WeatherType.class), playerData.getSubject(), Options.PLAYER_WEATHER, toClaim); + playerData.optionWeatherType = weatherType; + } if (weatherType == null || weatherType == WeatherTypes.UNDEFINED) { NMSUtil.getInstance().resetPlayerWeather(user); return; diff --git a/sponge/src/main/java/com/griefdefender/listener/EntityEventHandler.java b/sponge/src/main/java/com/griefdefender/listener/EntityEventHandler.java index b6db94f..fbeb5dd 100644 --- a/sponge/src/main/java/com/griefdefender/listener/EntityEventHandler.java +++ b/sponge/src/main/java/com/griefdefender/listener/EntityEventHandler.java @@ -65,6 +65,7 @@ import org.spongepowered.api.entity.living.player.User; import org.spongepowered.api.entity.living.player.gamemode.GameMode; import org.spongepowered.api.entity.living.player.gamemode.GameModes; +import org.spongepowered.api.entity.projectile.EnderPearl; import org.spongepowered.api.entity.projectile.Projectile; import org.spongepowered.api.event.Event; import org.spongepowered.api.event.Listener; @@ -701,8 +702,7 @@ public void onEntityTeleport(MoveEntityEvent.Teleport event) { } final boolean teleportFromBlacklisted = GriefDefenderPlugin.isSourceIdBlacklisted(Flags.ENTITY_TELEPORT_FROM.getName(), entity, entity.getWorld().getProperties()); final boolean teleportToBlacklisted = GriefDefenderPlugin.isSourceIdBlacklisted(Flags.ENTITY_TELEPORT_TO.getName(), entity, entity.getWorld().getProperties()); - final boolean portalUseBlacklisted = GriefDefenderPlugin.isSourceIdBlacklisted(Flags.PORTAL_USE.getName(), entity, entity.getWorld().getProperties()); - if (teleportFromBlacklisted && teleportToBlacklisted && portalUseBlacklisted) { + if (teleportFromBlacklisted && teleportToBlacklisted) { return; } @@ -729,6 +729,9 @@ public void onEntityTeleport(MoveEntityEvent.Teleport event) { } } else { user = PermissionHolderCache.getInstance().getOrCreateUser(entity.getCreator().orElse(null)); + if (user != null && user.getOnlinePlayer() != null) { + player = user.getOnlinePlayer(); + } } if (user == null) { @@ -745,7 +748,7 @@ public void onEntityTeleport(MoveEntityEvent.Teleport event) { // Handle BorderClaimEvent if (!CommonEntityEventHandler.getInstance().onEntityMove(event, sourceLocation, destination, entity)) { event.setCancelled(true); - GDTimings.ENTITY_TELEPORT_EVENT.stopTiming(); + GDTimings.ENTITY_TELEPORT_EVENT.stopTimingIfSync(); return; } @@ -758,26 +761,38 @@ public void onEntityTeleport(MoveEntityEvent.Teleport event) { sourceClaim = this.dataStore.getClaimAt(sourceLocation); } + Object source = type; + if (type.equals(TeleportTypes.PORTAL) || type.equals((TeleportTypes.UNKNOWN)) && !sourceLocation.getExtent().getUniqueId().equals(destination.getExtent().getUniqueId())) { + source = destination.getExtent().getDimension().getType().getName().toLowerCase().replace("the_", "") + "_portal"; + } if (sourceClaim != null) { - if (GDFlags.ENTITY_TELEPORT_FROM && !teleportFromBlacklisted && GDPermissionManager.getInstance().getFinalPermission(event, sourceLocation, sourceClaim, Flags.ENTITY_TELEPORT_FROM, type, entity, user, TrustTypes.ACCESSOR, true) == Tristate.FALSE) { - boolean cancelled = true; - if (GDFlags.PORTAL_USE && type.equals(TeleportTypes.PORTAL)) { - if (portalUseBlacklisted || GDPermissionManager.getInstance().getFinalPermission(event, sourceLocation, sourceClaim, Flags.PORTAL_USE, type, entity, user) == Tristate.TRUE) { - cancelled = false; - } - } - if (cancelled) { - final Component message = GriefDefenderPlugin.getInstance().messageData.getMessage(MessageStorage.PERMISSION_PORTAL_EXIT, + if (GDFlags.ENTITY_TELEPORT_FROM && !teleportFromBlacklisted && GDPermissionManager.getInstance().getFinalPermission(event, sourceLocation, sourceClaim, Flags.ENTITY_TELEPORT_FROM, source, entity, user, TrustTypes.ACCESSOR, true) == Tristate.FALSE) { + if (player != null) { + Component message = null; + if (type == TeleportTypes.PORTAL || source != type) { + message = GriefDefenderPlugin.getInstance().messageData.getMessage(MessageStorage.PERMISSION_PORTAL_FROM, ImmutableMap.of( - "player", sourceClaim.getOwnerName())); - if (player != null) { - GriefDefenderPlugin.sendMessage(player, message); + "player", sourceClaim.getOwnerDisplayName())); + } else { + message = GriefDefenderPlugin.getInstance().messageData.getMessage(MessageStorage.PERMISSION_TELEPORT_FROM, + ImmutableMap.of( + "player", sourceClaim.getOwnerDisplayName())); } - event.setCancelled(true); - GDTimings.ENTITY_TELEPORT_EVENT.stopTimingIfSync(); - return; + final GameMode gameMode = player.get(Keys.GAME_MODE).orElse(null); + if (gameMode == GameModes.SURVIVAL) { + final Entity last = cause.last(Entity.class).orElse(null); + if (last != null && last instanceof EnderPearl) { + player.getInventory().offer(ItemStack.of(ItemTypes.ENDER_PEARL, 1)); + } + } + + GriefDefenderPlugin.sendMessage(player, message); } + + event.setCancelled(true); + GDTimings.ENTITY_TELEPORT_EVENT.stopTimingIfSync(); + return; } } @@ -789,28 +804,33 @@ public void onEntityTeleport(MoveEntityEvent.Teleport event) { final GDClaim toClaim = this.dataStore.getClaimAt(destination); if (toClaim != null) { - if (GDFlags.ENTITY_TELEPORT_TO && !teleportToBlacklisted && GDPermissionManager.getInstance().getFinalPermission(event, destination, toClaim, Flags.ENTITY_TELEPORT_TO, type, entity, user, TrustTypes.ACCESSOR, true) == Tristate.FALSE) { - boolean cancelled = true; - if (GDFlags.PORTAL_USE && type.equals(TeleportTypes.PORTAL)) { - if (portalUseBlacklisted || GDPermissionManager.getInstance().getFinalPermission(event, destination, toClaim, Flags.PORTAL_USE, type, entity, user, TrustTypes.ACCESSOR, true) == Tristate.TRUE) { - cancelled = false; - } - } - if (cancelled) { - final Component message = GriefDefenderPlugin.getInstance().messageData.getMessage(MessageStorage.PERMISSION_PORTAL_ENTER, + if (GDFlags.ENTITY_TELEPORT_TO && !teleportToBlacklisted && GDPermissionManager.getInstance().getFinalPermission(event, destination, toClaim, Flags.ENTITY_TELEPORT_TO, source, entity, user, TrustTypes.ACCESSOR, true) == Tristate.FALSE) { + if (player != null) { + Component message = null; + if (type == TeleportTypes.PORTAL || source != type) { + message = GriefDefenderPlugin.getInstance().messageData.getMessage(MessageStorage.PERMISSION_PORTAL_TO, ImmutableMap.of( - "player", toClaim.getOwnerName())); - if (player != null) { - GriefDefenderPlugin.sendMessage(player, message); + "player", toClaim.getOwnerDisplayName())); + } else { + message = GriefDefenderPlugin.getInstance().messageData.getMessage(MessageStorage.PERMISSION_TELEPORT_TO, + ImmutableMap.of( + "player", toClaim.getOwnerDisplayName())); } - - if (type.equals(EntityTypes.ENDER_PEARL)) { - player.getInventory().offer(ItemStack.of(ItemTypes.ENDER_PEARL, 1)); + + final GameMode gameMode = player.get(Keys.GAME_MODE).orElse(null); + if (gameMode == GameModes.SURVIVAL) { + final Entity last = cause.last(Entity.class).orElse(null); + if (last != null && last instanceof EnderPearl) { + player.getInventory().offer(ItemStack.of(ItemTypes.ENDER_PEARL, 1)); + } } - event.setCancelled(true); - GDTimings.ENTITY_TELEPORT_EVENT.stopTimingIfSync(); - return; + + GriefDefenderPlugin.sendMessage(player, message); } + + event.setCancelled(true); + GDTimings.ENTITY_TELEPORT_EVENT.stopTimingIfSync(); + return; } } @@ -841,12 +861,7 @@ public void onEntityTeleport(MoveEntityEvent.Teleport event) { playerData.inTown = false; } } - // TODO - /*if (event.getCause().first(PortalTeleportCause.class).isPresent()) { - // FEATURE: when players get trapped in a nether portal, send them back through to the other side - CheckForPortalTrapTask task = new CheckForPortalTrapTask(player, event.getFromTransform().getLocation()); - Sponge.getGame().getScheduler().createTaskBuilder().delayTicks(200).execute(task).submit(GriefDefender.instance); - }*/ + GDTimings.ENTITY_TELEPORT_EVENT.stopTimingIfSync(); } @@ -856,9 +871,6 @@ public void onEntityCollideEntity(CollideEntityEvent event) { if (!GDFlags.COLLIDE_ENTITY || event instanceof CollideEntityEvent.Impact) { return; } - //if (GriefDefenderPlugin.isSourceIdBlacklisted(ClaimFlag.ENTITY_COLLIDE_ENTITY.toString(), event.getSource(), event.getEntities().get(0).getWorld().getProperties())) { - // return; - //} Object rootCause = event.getCause().root(); final boolean isRootEntityItemFrame = rootCause instanceof ItemFrame; diff --git a/sponge/src/main/java/com/griefdefender/listener/LuckPermsEventHandler.java b/sponge/src/main/java/com/griefdefender/listener/LuckPermsEventHandler.java index 272a126..c93291c 100644 --- a/sponge/src/main/java/com/griefdefender/listener/LuckPermsEventHandler.java +++ b/sponge/src/main/java/com/griefdefender/listener/LuckPermsEventHandler.java @@ -24,13 +24,16 @@ */ package com.griefdefender.listener; -import com.griefdefender.GriefDefenderPlugin; import com.griefdefender.cache.PermissionHolderCache; -import com.griefdefender.permission.GDPermissionHolder; +import com.griefdefender.permission.GDPermissionUser; + import net.luckperms.api.LuckPerms; import net.luckperms.api.event.group.GroupDataRecalculateEvent; import net.luckperms.api.event.user.UserDataRecalculateEvent; +import org.spongepowered.api.Sponge; +import org.spongepowered.api.entity.living.player.Player; + public class LuckPermsEventHandler { private final LuckPerms luckPermsApi; @@ -42,13 +45,16 @@ public LuckPermsEventHandler(LuckPerms luckPermsApi) { } public void onGroupDataRecalculate(GroupDataRecalculateEvent event) { - final GDPermissionHolder holder = PermissionHolderCache.getInstance().getOrCreateGroup(event.getGroup().getName()); - PermissionHolderCache.getInstance().getOrCreatePermissionCache(holder).invalidateAll(); + for (Player player : Sponge.getServer().getOnlinePlayers()) { + final GDPermissionUser user = PermissionHolderCache.getInstance().getOrCreateUser(player); + user.getInternalPlayerData().resetOptionCache(); + } } public void onUserDataRecalculate(UserDataRecalculateEvent event) { - final GDPermissionHolder holder = PermissionHolderCache.getInstance().getOrCreateUser(event.getUser().getUniqueId()); - PermissionHolderCache.getInstance().getOrCreatePermissionCache(holder).invalidateAll(); - PermissionHolderCache.getInstance().getOrCreatePermissionCache(GriefDefenderPlugin.DEFAULT_HOLDER).invalidateAll(); + final GDPermissionUser user = PermissionHolderCache.getInstance().getOrCreateUser(event.getUser().getUniqueId()); + if (user.getOnlinePlayer() != null) { + user.getInternalPlayerData().resetOptionCache(); + } } } diff --git a/sponge/src/main/java/com/griefdefender/listener/PlayerEventHandler.java b/sponge/src/main/java/com/griefdefender/listener/PlayerEventHandler.java index a083c78..480419b 100644 --- a/sponge/src/main/java/com/griefdefender/listener/PlayerEventHandler.java +++ b/sponge/src/main/java/com/griefdefender/listener/PlayerEventHandler.java @@ -91,6 +91,7 @@ import org.spongepowered.api.data.type.HandType; import org.spongepowered.api.data.type.HandTypes; import org.spongepowered.api.entity.Entity; +import org.spongepowered.api.entity.Item; import org.spongepowered.api.entity.living.ArmorStand; import org.spongepowered.api.entity.living.Living; import org.spongepowered.api.entity.living.player.Player; @@ -563,21 +564,25 @@ public void onPlayerDispenseItem(DropItemEvent.Dispense event, @Root Entity spaw Player player = user instanceof Player ? (Player) user : null; GDPlayerData playerData = this.dataStore.getOrCreatePlayerData(world, user.getUniqueId()); - for (Entity entityItem : event.getEntities()) { - if (GriefDefenderPlugin.isTargetIdBlacklisted(Flags.ITEM_DROP.toString(), entityItem, world.getProperties())) { + for (Entity entity : event.getEntities()) { + if (!(entity instanceof Item)) { + continue; + } + final Item item = (Item) entity; + if (GriefDefenderPlugin.isTargetIdBlacklisted(Flags.ITEM_DROP.toString(), item, world.getProperties())) { continue; } - Location location = entityItem.getLocation(); + Location location = item.getLocation(); GDClaim claim = this.dataStore.getClaimAtPlayer(playerData, location); if (claim != null) { - if (GDPermissionManager.getInstance().getFinalPermission(event, location, claim, Flags.ITEM_DROP, user, entityItem, user, TrustTypes.ACCESSOR, true) == Tristate.FALSE) { + if (GDPermissionManager.getInstance().getFinalPermission(event, location, claim, Flags.ITEM_DROP, user, item, user, TrustTypes.ACCESSOR, true) == Tristate.FALSE) { event.setCancelled(true); if (spawncause instanceof Player) { final Component message = GriefDefenderPlugin.getInstance().messageData.getMessage(MessageStorage.PERMISSION_ITEM_DROP, ImmutableMap.of( "player", claim.getOwnerName(), - "item", entityItem.getType().getId())); + "item", item.getItemType().getId())); GriefDefenderPlugin.sendClaimDenyMessage(claim, player, message); } GDTimings.PLAYER_DISPENSE_ITEM_EVENT.stopTimingIfSync(); @@ -739,6 +744,7 @@ public void onPlayerInteractEntity(InteractEntityEvent.Primary event, @First Pla playerData.petRecipientUniqueId = null; GriefDefenderPlugin.sendMessage(player, MessageCache.getInstance().COMMAND_PET_TRANSFER_CANCEL); event.setCancelled(true); + GDTimings.PLAYER_INTERACT_ENTITY_PRIMARY_EVENT.stopTimingIfSync(); return; } if (targetEntity instanceof Living && targetEntity.get(Keys.TAMED_OWNER).isPresent()) { @@ -776,17 +782,14 @@ public void onPlayerInteractEntity(InteractEntityEvent.Primary event, @First Pla Tristate result = GDPermissionManager.getInstance().getFinalPermission(event, location, claim, Flags.INTERACT_ENTITY_PRIMARY, source, targetEntity, player, TrustTypes.ACCESSOR, true); if (result == Tristate.FALSE) { - if (GDPermissionManager.getInstance().getFinalPermission(event, location, claim, Flags.ENTITY_DAMAGE, source, targetEntity, player, TrustTypes.ACCESSOR, true) != Tristate.TRUE) { - final Component message = GriefDefenderPlugin.getInstance().messageData.getMessage(MessageStorage.CLAIM_PROTECTED_ENTITY, - ImmutableMap.of( - "player", claim.getOwnerName())); - GriefDefenderPlugin.sendMessage(player, message); - event.setCancelled(true); - this.sendInteractEntityDenyMessage(itemInHand, targetEntity, claim, player, handType); - GDTimings.PLAYER_INTERACT_ENTITY_PRIMARY_EVENT.stopTimingIfSync(); - return; - } + final Component message = GriefDefenderPlugin.getInstance().messageData.getMessage(MessageStorage.CLAIM_PROTECTED_ENTITY, + ImmutableMap.of( + "player", claim.getOwnerName())); + GriefDefenderPlugin.sendMessage(player, message); + event.setCancelled(true); + this.sendInteractEntityDenyMessage(itemInHand, targetEntity, claim, player, handType); } + GDTimings.PLAYER_INTERACT_ENTITY_PRIMARY_EVENT.stopTimingIfSync(); } @Listener(order = Order.FIRST, beforeModifications = true) @@ -1256,6 +1259,18 @@ public InteractEvent handleItemInteract(HandInteractEvent event, Player player, event.setCancelled(true); } lastInteractItemCancelled = true; + return event; + } + if (!itemInHand.isEmpty() && itemInHand.getType().equals(ItemTypes.BUCKET)) { + if (GDPermissionManager.getInstance().getFinalPermission(event, location, claim,Flags.INTERACT_BLOCK_SECONDARY, itemInHand, blockSnapshot, player, TrustTypes.ACCESSOR, true) == Tristate.FALSE) { + final Component message = GriefDefenderPlugin.getInstance().messageData.getMessage(MessageStorage.PERMISSION_INTERACT_ITEM_BLOCK, + ImmutableMap.of( + "item", itemInHand.getType().getId(), + "block", blockSnapshot.getState().getType().getId())); + GriefDefenderPlugin.sendClaimDenyMessage(claim, player, message); + event.setCancelled(true); + lastInteractItemCancelled = true; + } } } return event; @@ -1770,13 +1785,13 @@ private void handleResizeFinish(InteractEvent event, Player player, Location params = ImmutableMap.of( - "balance", String.valueOf("$" + currentFunds.intValue()), + "balance", "$" + String.format("%.2f", currentFunds.intValue()), "chunk-amount", Math.round(claimableChunks * 100.0)/100.0, "block-amount", claimBlocksRemaining); GriefDefenderPlugin.sendMessage(player, GriefDefenderPlugin.getInstance().messageData.getMessage(MessageStorage.ECONOMY_MODE_RESIZE_SUCCESS_3D, params)); } else { final Map params = ImmutableMap.of( - "balance", String.valueOf("$" + currentFunds.intValue()), + "balance", "$" + String.format("%.2f", currentFunds.intValue()), "block-amount", claimBlocksRemaining); GriefDefenderPlugin.sendMessage(player, GriefDefenderPlugin.getInstance().messageData.getMessage(MessageStorage.ECONOMY_MODE_RESIZE_SUCCESS_2D, params)); } diff --git a/sponge/src/main/java/com/griefdefender/permission/GDPermissionManager.java b/sponge/src/main/java/com/griefdefender/permission/GDPermissionManager.java index 40be4b4..eb016b2 100644 --- a/sponge/src/main/java/com/griefdefender/permission/GDPermissionManager.java +++ b/sponge/src/main/java/com/griefdefender/permission/GDPermissionManager.java @@ -89,6 +89,7 @@ import org.spongepowered.api.data.key.Keys; import org.spongepowered.api.entity.Entity; import org.spongepowered.api.entity.EntityType; +import org.spongepowered.api.entity.Item; import org.spongepowered.api.entity.living.Living; import org.spongepowered.api.entity.living.player.Player; import org.spongepowered.api.entity.living.player.User; @@ -595,7 +596,10 @@ public String getPermissionIdentifier(Object obj) { public String getPermissionIdentifier(Object obj, boolean isSource) { if (obj != null) { - if (obj instanceof Entity) { + if (obj instanceof Item) { + final String id = ((Item) obj).getItemType().getId(); + return populateEventSourceTarget(id, isSource); + } else if (obj instanceof Entity) { return populateEventSourceTarget(NMSUtil.getInstance().getEntityId((Entity) obj, isSource), isSource); } else if (obj instanceof EntityType) { final String id = ((EntityType) obj).getId(); @@ -679,7 +683,10 @@ public Set getPermissionContexts(GDClaim claim, Object obj, boolean isS } if (obj != null) { - if (obj instanceof Entity) { + if (obj instanceof Item) { + final String id = ((Item) obj).getItemType().getId(); + return populateEventSourceTargetContext(contexts, id, isSource); + } else if (obj instanceof Entity) { final Entity targetEntity = (Entity) obj; final String id = NMSUtil.getInstance().getEntityId((Entity) obj); final String modId = NMSUtil.getInstance().getEntityModId(id); @@ -1062,8 +1069,7 @@ public CompletableFuture setPermission(Subject subject, Flag f return result; } - result.complete(PermissionUtil.getInstance().setPermissionValue((GDPermissionHolder) subject, flag, value, contexts)); - return result; + return PermissionUtil.getInstance().setPermissionValue((GDPermissionHolder) subject, flag, value, contexts); } // internal @@ -1477,14 +1483,12 @@ public CompletableFuture setFlagPermission(Flag flag, Subject @Override public CompletableFuture setOption(Option option, String value, Set contexts) { - final PermissionResult result = PermissionUtil.getInstance().setOptionValue(GriefDefenderPlugin.DEFAULT_HOLDER, option.getPermission(), value, contexts); - return CompletableFuture.completedFuture(result); + return PermissionUtil.getInstance().setOptionValue(GriefDefenderPlugin.DEFAULT_HOLDER, option.getPermission(), value, contexts); } @Override public CompletableFuture setOption(Option option, Subject subject, String value, Set contexts) { - final PermissionResult result = PermissionUtil.getInstance().setOptionValue((GDPermissionHolder) subject, option.getPermission(), value, contexts); - return CompletableFuture.completedFuture(result); + return PermissionUtil.getInstance().setOptionValue((GDPermissionHolder) subject, option.getPermission(), value, contexts); } @Override @@ -1517,16 +1521,17 @@ public T getActiveOptionValue(TypeToken type, Option option, Subject s public CompletableFuture setFlagDefinition(Subject subject, FlagDefinition flagDefinition, Tristate value) { final Set contexts = new HashSet<>(); contexts.addAll(flagDefinition.getContexts()); - PermissionResult result = null; + PermissionResult result = new GDPermissionResult(ResultTypes.SUCCESS, TextComponent.builder().append("SUCCESS").build()); CompletableFuture future = new CompletableFuture<>(); for (FlagData flagData : flagDefinition.getFlagData()) { final Set flagContexts = new HashSet<>(contexts); flagContexts.addAll(flagData.getContexts()); - result = PermissionUtil.getInstance().setPermissionValue((GDPermissionHolder) subject, flagData.getFlag(), value, flagContexts); - if (!result.successful()) { + // TODO - Add method that supports multiple permissions + PermissionUtil.getInstance().setPermissionValue((GDPermissionHolder) subject, flagData.getFlag(), value, flagContexts); + /*if (!result.successful()) { future.complete(result); return future; - } + }*/ } future.complete(result); diff --git a/sponge/src/main/java/com/griefdefender/permission/flag/FlagContexts.java b/sponge/src/main/java/com/griefdefender/permission/flag/FlagContexts.java index 01a9e42..1e28d46 100644 --- a/sponge/src/main/java/com/griefdefender/permission/flag/FlagContexts.java +++ b/sponge/src/main/java/com/griefdefender/permission/flag/FlagContexts.java @@ -33,6 +33,7 @@ public class FlagContexts { public static final Context SOURCE_CREEPER = new Context(ContextKeys.SOURCE, "minecraft:creeper"); public static final Context SOURCE_ENDERDRAGON = new Context(ContextKeys.SOURCE, "minecraft:enderdragon"); public static final Context SOURCE_ENDERMAN = new Context(ContextKeys.SOURCE, "minecraft:enderman"); + public static final Context SOURCE_END_PORTAL = new Context(ContextKeys.SOURCE, "minecraft:end_portal"); public static final Context SOURCE_FALL = new Context(ContextKeys.SOURCE, "minecraft:fall"); public static final Context SOURCE_FALLING_BLOCK = new Context(ContextKeys.SOURCE, "minecraft:falling_block"); public static final Context SOURCE_FIRE = new Context(ContextKeys.SOURCE, "minecraft:fire"); @@ -44,6 +45,7 @@ public class FlagContexts { public static final Context SOURCE_LAVA_1_12 = new Context(ContextKeys.SOURCE, "minecraft:flowing_lava"); public static final Context SOURCE_LIGHTNING_BOLT = new Context(ContextKeys.SOURCE, "minecraft:lightning_bolt"); public static final Context SOURCE_MAGMA_BLOCK = new Context(ContextKeys.SOURCE, "minecraft:magma_block"); + public static final Context SOURCE_NETHER_PORTAL = new Context(ContextKeys.SOURCE, "minecraft:nether_portal"); public static final Context SOURCE_PISTON = new Context(ContextKeys.SOURCE, "minecraft:piston"); public static final Context SOURCE_PISTON_STICKY = new Context(ContextKeys.SOURCE, "minecraft:sticky_piston"); public static final Context SOURCE_PLAYER = new Context(ContextKeys.SOURCE, "minecraft:player"); @@ -99,7 +101,6 @@ public class FlagContexts { public static final Context TARGET_TYPE_FOOD = new Context(ContextKeys.TARGET, "#food"); public static final Context TARGET_TYPE_MONSTER = new Context(ContextKeys.TARGET, "#monster"); public static final Context TARGET_TYPE_MUSHROOM = new Context(ContextKeys.TARGET, "#mushroom"); - public static final Context TARGET_TYPE_PORTAL = new Context(ContextKeys.TARGET, "#portal"); public static final Context TARGET_TYPE_VEHICLE = new Context(ContextKeys.TARGET, "#vehicle"); public static final Context USED_ITEM_LAVA_BUCKET = new Context(ContextKeys.USED_ITEM, "minecraft:lava_bucket"); diff --git a/sponge/src/main/java/com/griefdefender/provider/LuckPermsProvider.java b/sponge/src/main/java/com/griefdefender/provider/LuckPermsProvider.java index 031c1b1..8f250a0 100644 --- a/sponge/src/main/java/com/griefdefender/provider/LuckPermsProvider.java +++ b/sponge/src/main/java/com/griefdefender/provider/LuckPermsProvider.java @@ -35,6 +35,8 @@ import com.griefdefender.api.permission.option.Option; import com.griefdefender.cache.PermissionHolderCache; import com.griefdefender.claim.GDClaim; +import com.griefdefender.listener.LuckPermsEventHandler; +import com.griefdefender.permission.GDPermissionGroup; import com.griefdefender.permission.GDPermissionHolder; import com.griefdefender.permission.GDPermissionResult; import com.griefdefender.permission.GDPermissionUser; @@ -74,8 +76,10 @@ import java.util.TreeMap; import java.util.UUID; import java.util.Map.Entry; +import java.util.Optional; import java.util.concurrent.CompletableFuture; import java.util.concurrent.ExecutionException; +import java.util.function.Function; import java.util.function.Predicate; import org.checkerframework.checker.nullness.qual.NonNull; @@ -106,6 +110,7 @@ public int compare(Set s1, Set s2) { public LuckPermsProvider() { final ProviderRegistration service = Sponge.getServiceManager().getRegistration(LuckPerms.class).orElse(null); this.luckPermsApi = service.getProvider(); + new LuckPermsEventHandler(this.luckPermsApi); } public LuckPerms getApi() { @@ -656,37 +661,119 @@ public List getOptionValueList(GDPermissionHolder holder, Option option, return list; } - public PermissionResult setOptionValue(GDPermissionHolder holder, String key, String value, Set contexts, boolean check) { - DataMutateResult result = null; + public CompletableFuture setOptionValue(GDPermissionHolder holder, String key, String value, Set contexts, boolean check) { if (check) { // If no server context exists, add global this.checkServerContext(contexts); } ImmutableContextSet set = this.getLPContexts(contexts).immutableCopy(); - final PermissionHolder permissionHolder = this.getLuckPermsHolder(holder); - if (permissionHolder == null) { - new GDPermissionResult(ResultTypes.FAILURE); - } - final Option option = OptionRegistryModule.getInstance().getById(key).orElse(null); if (option == null) { new GDPermissionResult(ResultTypes.FAILURE); } final Node node = MetaNode.builder().key(key).value(value).context(set).build(); + if (holder instanceof GDPermissionGroup) { + return this.luckPermsApi.getGroupManager().loadGroup(holder.getFriendlyName()).thenApplyAsync((Function, ? extends PermissionResult>) lpHolder -> { + final Group group = lpHolder.orElse(null); + if (group != null) { + return this.applyOptionNode(holder, group, node, option, value); + } + return new GDPermissionResult(ResultTypes.FAILURE, TextComponent.builder().append("COULD NOT LOAD GROUP " + holder.getFriendlyName()).build()); + }); + } else { + return this.luckPermsApi.getUserManager().loadUser(((GDPermissionUser) holder).getUniqueId()).thenApplyAsync((Function) lpHolder -> { + return this.applyOptionNode(holder, lpHolder, node, option, value); + }); + } + } + + public CompletableFuture setPermissionValue(GDPermissionHolder holder, String permission, Tristate value, Set contexts, boolean check, boolean save) { + if (check) { + // If no server context exists, add global + this.checkServerContext(contexts); + } + ImmutableContextSet set = this.getLPContexts(contexts).immutableCopy(); + final Node node = this.luckPermsApi.getNodeBuilderRegistry().forPermission().permission(permission).value(value.asBoolean()).context(set).build(); + + if (holder instanceof GDPermissionGroup) { + return this.luckPermsApi.getGroupManager().loadGroup(holder.getFriendlyName()).thenApplyAsync((Function, ? extends PermissionResult>) lpHolder -> { + final Group group = lpHolder.orElse(null); + if (group != null) { + return this.applyPermissionNode(holder, group, node, value, save); + } + return new GDPermissionResult(ResultTypes.FAILURE, TextComponent.builder().append("COULD NOT LOAD GROUP " + holder.getFriendlyName()).build()); + }); + } else { + return this.luckPermsApi.getUserManager().loadUser(((GDPermissionUser) holder).getUniqueId()).thenApplyAsync((Function) lpHolder -> { + return this.applyPermissionNode(holder, lpHolder, node, value, save); + }); + } + } + + public CompletableFuture setTransientOption(GDPermissionHolder holder, String permission, String value, Set contexts) { + // If no server context exists, add global + this.checkServerContext(contexts); + MutableContextSet contextSet = this.getLPContexts(contexts); + + Node node = null; + if (value == null) { + node = this.luckPermsApi.getNodeBuilderRegistry().forMeta().key(permission).context(contextSet).build(); + } else { + node = this.luckPermsApi.getNodeBuilderRegistry().forMeta().key(permission).value(value).context(contextSet).build(); + } + final Node permissionNode = node; + if (holder instanceof GDPermissionGroup) { + return this.luckPermsApi.getGroupManager().loadGroup(holder.getFriendlyName()).thenApplyAsync((Function, ? extends PermissionResult>) lpHolder -> { + final Group group = lpHolder.orElse(null); + if (group != null) { + return this.applyTransientOptionNode(holder, group, permissionNode, value); + } + return new GDPermissionResult(ResultTypes.FAILURE, TextComponent.builder().append("COULD NOT LOAD GROUP " + holder.getFriendlyName()).build()); + }); + } else { + return this.luckPermsApi.getUserManager().loadUser(((GDPermissionUser) holder).getUniqueId()).thenApplyAsync((Function) lpHolder -> { + return this.applyTransientOptionNode(holder, lpHolder, permissionNode, value); + }); + } + } + + public CompletableFuture setTransientPermission(GDPermissionHolder holder, String permission, Tristate value, Set contexts) { + // If no server context exists, add global + this.checkServerContext(contexts); + MutableContextSet contextSet = this.getLPContexts(contexts); + final Node node = this.luckPermsApi.getNodeBuilderRegistry().forPermission().permission(permission).value(value.asBoolean()).context(contextSet).build(); + + if (holder instanceof GDPermissionGroup) { + return this.luckPermsApi.getGroupManager().loadGroup(holder.getFriendlyName()).thenApplyAsync((Function, ? extends PermissionResult>) lpHolder -> { + final Group group = lpHolder.orElse(null); + if (group != null) { + return this.applyTransientPermissionNode(holder, group, node, value); + } + return new GDPermissionResult(ResultTypes.FAILURE, TextComponent.builder().append("COULD NOT LOAD GROUP " + holder.getFriendlyName()).build()); + }); + } else { + return this.luckPermsApi.getUserManager().loadUser(((GDPermissionUser) holder).getUniqueId()).thenApplyAsync((Function) lpHolder -> { + return this.applyTransientPermissionNode(holder, lpHolder, node, value); + }); + } + } + + public PermissionResult applyOptionNode(GDPermissionHolder holder, PermissionHolder lpHolder, Node node, Option option, String value) { + DataMutateResult result = null; if (!value.equalsIgnoreCase("undefined")) { if (!option.multiValued()) { - this.clearMeta(permissionHolder, key, set); + this.clearMeta(lpHolder, option.getPermission(), node.getContexts()); } - result = permissionHolder.data().add(node); + result = lpHolder.data().add(node); } else { - this.clearMeta(permissionHolder, key, set); - this.savePermissionHolder(permissionHolder); + this.clearMeta(lpHolder, option.getPermission(), node.getContexts()); + this.savePermissionHolder(lpHolder); return new GDPermissionResult(ResultTypes.SUCCESS); } if (result != null) { if (result.wasSuccessful()) { - this.savePermissionHolder(permissionHolder); + this.savePermissionHolder(lpHolder); return new GDPermissionResult(ResultTypes.SUCCESS, TextComponent.builder().append(result.name()).build()); } return new GDPermissionResult(ResultTypes.FAILURE, TextComponent.builder().append(result.name()).build()); @@ -695,27 +782,34 @@ public PermissionResult setOptionValue(GDPermissionHolder holder, String key, St return new GDPermissionResult(ResultTypes.FAILURE); } - public PermissionResult setPermissionValue(GDPermissionHolder holder, String permission, Tristate value, Set contexts, boolean check, boolean save) { + public PermissionResult applyTransientOptionNode(GDPermissionHolder holder, PermissionHolder lpHolder, Node node, String value) { DataMutateResult result = null; - if (check) { - // If no server context exists, add global - this.checkServerContext(contexts); - } - ImmutableContextSet set = this.getLPContexts(contexts).immutableCopy(); - final Node node = this.luckPermsApi.getNodeBuilderRegistry().forPermission().permission(permission).value(value.asBoolean()).context(set).build(); - final PermissionHolder permissionHolder = this.getLuckPermsHolder(holder); - if (permissionHolder == null) { - return new GDPermissionResult(ResultTypes.FAILURE); + if (value == null) { + result = lpHolder.transientData().remove(node); + } else { + result = lpHolder.transientData().add(node); } + if (result != null) { + if (result.wasSuccessful()) { + return new GDPermissionResult(ResultTypes.SUCCESS, TextComponent.builder().append(result.name()).build()); + } + return new GDPermissionResult(ResultTypes.FAILURE, TextComponent.builder().append(result.name()).build()); + } + + return new GDPermissionResult(ResultTypes.FAILURE); + } + + public PermissionResult applyPermissionNode(GDPermissionHolder holder, PermissionHolder lpHolder, Node node, Tristate value, boolean save) { + DataMutateResult result = null; if (value == Tristate.UNDEFINED) { - result = permissionHolder.data().remove(node); + result = lpHolder.data().remove(node); } else { - result = permissionHolder.data().add(node); + result = lpHolder.data().add(node); } if (result.wasSuccessful()) { - if (permissionHolder instanceof Group) { + if (holder instanceof Group) { // If a group is changed, we invalidate all cache PermissionHolderCache.getInstance().invalidateAllPermissionCache(); } else { @@ -724,7 +818,7 @@ public PermissionResult setPermissionValue(GDPermissionHolder holder, String per } if (save) { - this.savePermissionHolder(permissionHolder); + this.savePermissionHolder(lpHolder); } return new GDPermissionResult(ResultTypes.SUCCESS, TextComponent.builder().append(result.name()).build()); @@ -733,46 +827,12 @@ public PermissionResult setPermissionValue(GDPermissionHolder holder, String per return new GDPermissionResult(ResultTypes.FAILURE, TextComponent.builder().append(result.name()).build()); } - public PermissionResult setTransientOption(GDPermissionHolder holder, String permission, String value, Set contexts) { - // If no server context exists, add global - this.checkServerContext(contexts); - MutableContextSet contextSet = this.getLPContexts(contexts); - final PermissionHolder permissionHolder = this.getLuckPermsHolder(holder); - if (permissionHolder == null) { - return new GDPermissionResult(ResultTypes.FAILURE, TextComponent.builder().append("invalid").build()); - } - + public PermissionResult applyTransientPermissionNode(GDPermissionHolder holder, PermissionHolder lpHolder, Node node, Tristate value) { DataMutateResult result = null; - if (value == null) { - final Node node = this.luckPermsApi.getNodeBuilderRegistry().forMeta().key(permission).context(contextSet).build(); - result = permissionHolder.transientData().remove(node); + if (value == null || value == Tristate.UNDEFINED) { + result = lpHolder.transientData().remove(node); } else { - final Node node = this.luckPermsApi.getNodeBuilderRegistry().forMeta().key(permission).value(value).context(contextSet).build(); - result = permissionHolder.transientData().add(node); - } - - if (result.wasSuccessful()) { - return new GDPermissionResult(ResultTypes.SUCCESS, TextComponent.builder().append(result.name()).build()); - } - return new GDPermissionResult(ResultTypes.FAILURE, TextComponent.builder().append(result.name()).build()); - } - - public PermissionResult setTransientPermission(GDPermissionHolder holder, String permission, Tristate value, Set contexts) { - // If no server context exists, add global - this.checkServerContext(contexts); - MutableContextSet contextSet = this.getLPContexts(contexts); - final PermissionHolder permissionHolder = this.getLuckPermsHolder(holder); - if (permissionHolder == null) { - return new GDPermissionResult(ResultTypes.FAILURE, TextComponent.builder().append("invalid").build()); - } - - DataMutateResult result = null; - if (value == Tristate.UNDEFINED) { - final Node node = this.luckPermsApi.getNodeBuilderRegistry().forPermission().permission(permission).value(value.asBoolean()).context(contextSet).build(); - result = permissionHolder.transientData().remove(node); - } else { - final PermissionNode node = this.luckPermsApi.getNodeBuilderRegistry().forPermission().permission(permission).value(value.asBoolean()).context(contextSet).build(); - result = permissionHolder.transientData().add(node); + result = lpHolder.transientData().add(node); } if (result.wasSuccessful()) { diff --git a/sponge/src/main/java/com/griefdefender/provider/PermissionProvider.java b/sponge/src/main/java/com/griefdefender/provider/PermissionProvider.java index 6754398..d8c9b1f 100644 --- a/sponge/src/main/java/com/griefdefender/provider/PermissionProvider.java +++ b/sponge/src/main/java/com/griefdefender/provider/PermissionProvider.java @@ -297,7 +297,7 @@ public enum PermissionDataType { * @param check Whether to check and apply a server context if none exists * @return The permission result */ - default PermissionResult setOptionValue(GDPermissionHolder holder, String permission, String value, Set contexts) { + default CompletableFuture setOptionValue(GDPermissionHolder holder, String permission, String value, Set contexts) { return this.setOptionValue(holder, permission, value, contexts, true); } @@ -311,7 +311,7 @@ default PermissionResult setOptionValue(GDPermissionHolder holder, String permis * @param check Whether to check and apply a server context if none exists * @return The permission result */ - PermissionResult setOptionValue(GDPermissionHolder holder, String permission, String value, Set contexts, boolean check); + CompletableFuture setOptionValue(GDPermissionHolder holder, String permission, String value, Set contexts, boolean check); /** * Sets a permission and value with contexts to a holder. @@ -322,7 +322,7 @@ default PermissionResult setOptionValue(GDPermissionHolder holder, String permis * @param contexts The contexts * @return The permission result */ - default PermissionResult setPermissionValue(GDPermissionHolder holder, Flag flag, Tristate value, Set contexts) { + default CompletableFuture setPermissionValue(GDPermissionHolder holder, Flag flag, Tristate value, Set contexts) { return this.setPermissionValue(holder, flag.getPermission(), value, contexts, true, true); } @@ -337,7 +337,7 @@ default PermissionResult setPermissionValue(GDPermissionHolder holder, Flag flag * @param save Whether a save should occur * @return The permission result */ - default PermissionResult setPermissionValue(GDPermissionHolder holder, Flag flag, Tristate value, Set contexts, boolean check, boolean save) { + default CompletableFuture setPermissionValue(GDPermissionHolder holder, Flag flag, Tristate value, Set contexts, boolean check, boolean save) { return this.setPermissionValue(holder, flag.getPermission(), value, contexts, check, save); } @@ -350,7 +350,7 @@ default PermissionResult setPermissionValue(GDPermissionHolder holder, Flag flag * @param contexts The contexts * @return Whether the set permission operation was successful */ - default PermissionResult setPermissionValue(GDPermissionHolder holder, String permission, Tristate value, Set contexts) { + default CompletableFuture setPermissionValue(GDPermissionHolder holder, String permission, Tristate value, Set contexts) { return this.setPermissionValue(holder, permission, value, contexts, true, true); } @@ -365,7 +365,7 @@ default PermissionResult setPermissionValue(GDPermissionHolder holder, String pe * @param save Whether a save should occur * @return Whether the set permission operation was successful */ - PermissionResult setPermissionValue(GDPermissionHolder holder, String permission, Tristate value, Set contexts, boolean check, boolean save); + CompletableFuture setPermissionValue(GDPermissionHolder holder, String permission, Tristate value, Set contexts, boolean check, boolean save); /** * Sets a transient option and value with contexts to a holder. @@ -376,7 +376,7 @@ default PermissionResult setPermissionValue(GDPermissionHolder holder, String pe * @param contexts The contexts * @return Whether the set permission operation was successful */ - PermissionResult setTransientOption(GDPermissionHolder holder, String permission, String value, Set contexts); + CompletableFuture setTransientOption(GDPermissionHolder holder, String permission, String value, Set contexts); /** * Sets a transient permission and value with contexts to a holder. @@ -387,7 +387,7 @@ default PermissionResult setPermissionValue(GDPermissionHolder holder, String pe * @param contexts The contexts * @return Whether the set permission operation was successful */ - PermissionResult setTransientPermission(GDPermissionHolder holder, String permission, Tristate value, Set contexts); + CompletableFuture setTransientPermission(GDPermissionHolder holder, String permission, Tristate value, Set contexts); /** * Refreshes all cached permission data of holder. diff --git a/sponge/src/main/java/com/griefdefender/registry/FlagDefinitionRegistryModule.java b/sponge/src/main/java/com/griefdefender/registry/FlagDefinitionRegistryModule.java index dea0f72..9027715 100644 --- a/sponge/src/main/java/com/griefdefender/registry/FlagDefinitionRegistryModule.java +++ b/sponge/src/main/java/com/griefdefender/registry/FlagDefinitionRegistryModule.java @@ -776,20 +776,39 @@ public void registerDefaults() { .build()); flagContexts = new HashSet<>(); - flagContexts.add(FlagContexts.SOURCE_PLAYER); - flagContexts.add(FlagContexts.TARGET_TYPE_PORTAL); + flagContexts.add(FlagContexts.SOURCE_END_PORTAL); + flagContexts.add(FlagContexts.TARGET_PLAYER); this.registerCustomType( definitionBuilder .reset() - .name("player-portal-use") + .name("player-endportal-use") .admin(true) - .context(ClaimContexts.USER_DEFAULT_CONTEXT) + .context(ClaimContexts.GLOBAL_DEFAULT_CONTEXT) .defaultValue(Tristate.TRUE) - .description(MessageCache.getInstance().FLAG_DESCRIPTION_CUSTOM_PLAYER_PORTAL_USE) + .description(MessageCache.getInstance().FLAG_DESCRIPTION_CUSTOM_PLAYER_ENDPORTAL_USE) .group("admin") .flagData(flagDataBuilder .reset() - .flag(Flags.INTERACT_BLOCK_SECONDARY) + .flag(Flags.ENTITY_TELEPORT_FROM) + .contexts(flagContexts) + .build()) + .build()); + + flagContexts = new HashSet<>(); + flagContexts.add(FlagContexts.SOURCE_NETHER_PORTAL); + flagContexts.add(FlagContexts.TARGET_PLAYER); + this.registerCustomType( + definitionBuilder + .reset() + .name("player-netherportal-use") + .admin(true) + .context(ClaimContexts.GLOBAL_DEFAULT_CONTEXT) + .defaultValue(Tristate.TRUE) + .description(MessageCache.getInstance().FLAG_DESCRIPTION_CUSTOM_PLAYER_NETHERPORTAL_USE) + .group("admin") + .flagData(flagDataBuilder + .reset() + .flag(Flags.ENTITY_TELEPORT_FROM) .contexts(flagContexts) .build()) .build()); diff --git a/sponge/src/main/java/com/griefdefender/util/PermissionUtil.java b/sponge/src/main/java/com/griefdefender/util/PermissionUtil.java index 615dc02..9ed049a 100644 --- a/sponge/src/main/java/com/griefdefender/util/PermissionUtil.java +++ b/sponge/src/main/java/com/griefdefender/util/PermissionUtil.java @@ -190,35 +190,35 @@ public List getOptionValueList(GDPermissionHolder holder, Option option, return PERMISSION_PROVIDER.getOptionValueList(holder, option, contexts); } - public PermissionResult setOptionValue(GDPermissionHolder holder, String permission, String value, Set contexts) { + public CompletableFuture setOptionValue(GDPermissionHolder holder, String permission, String value, Set contexts) { return PERMISSION_PROVIDER.setOptionValue(holder, permission, value, contexts, true); } - public PermissionResult setOptionValue(GDPermissionHolder holder, String permission, String value, Set contexts, boolean check) { + public CompletableFuture setOptionValue(GDPermissionHolder holder, String permission, String value, Set contexts, boolean check) { return PERMISSION_PROVIDER.setOptionValue(holder, permission, value, contexts, check); } - public PermissionResult setPermissionValue(GDPermissionHolder holder, Flag flag, Tristate value, Set contexts) { + public CompletableFuture setPermissionValue(GDPermissionHolder holder, Flag flag, Tristate value, Set contexts) { return PERMISSION_PROVIDER.setPermissionValue(holder, flag, value, contexts, true, true); } - public PermissionResult setPermissionValue(GDPermissionHolder holder, String permission, Tristate value, Set contexts) { + public CompletableFuture setPermissionValue(GDPermissionHolder holder, String permission, Tristate value, Set contexts) { return PERMISSION_PROVIDER.setPermissionValue(holder, permission, value, contexts, true, true); } - public PermissionResult setPermissionValue(GDPermissionHolder holder, Flag flag, Tristate value, Set contexts, boolean check, boolean save) { + public CompletableFuture setPermissionValue(GDPermissionHolder holder, Flag flag, Tristate value, Set contexts, boolean check, boolean save) { return PERMISSION_PROVIDER.setPermissionValue(holder, flag, value, contexts, check, save); } - public PermissionResult setPermissionValue(GDPermissionHolder holder, String permission, Tristate value, Set contexts, boolean check, boolean save) { + public CompletableFuture setPermissionValue(GDPermissionHolder holder, String permission, Tristate value, Set contexts, boolean check, boolean save) { return PERMISSION_PROVIDER.setPermissionValue(holder, permission, value, contexts, check, save); } - public PermissionResult setTransientOption(GDPermissionHolder holder, String permission, String value, Set contexts) { + public CompletableFuture setTransientOption(GDPermissionHolder holder, String permission, String value, Set contexts) { return PERMISSION_PROVIDER.setTransientOption(holder, permission, value, contexts); } - public PermissionResult setTransientPermission(GDPermissionHolder holder, String permission, Tristate value, Set contexts) { + public CompletableFuture setTransientPermission(GDPermissionHolder holder, String permission, Tristate value, Set contexts) { return PERMISSION_PROVIDER.setTransientPermission(holder, permission, value, contexts); }