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.
This commit is contained in:
bloodshot 2020-07-04 21:06:59 -04:00
parent a496b7fd6c
commit 26efaf2b73
59 changed files with 1049 additions and 518 deletions

View File

@ -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();

View File

@ -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());

View File

@ -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");

View File

@ -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<CommandSender> createCustomFlagConsumer(GDPermissionUser src, G
} else if (addClaimContext) {
definitionContexts.add(claim.getContext());
}
CompletableFuture<PermissionResult> result = null;
for (FlagData flagData : customFlag.getFlagData()) {
final Set<Context> newContexts = new HashSet<>(definitionContexts);
newContexts.addAll(flagData.getContexts());
@ -1120,13 +1125,15 @@ private Consumer<CommandSender> 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<CommandSender> 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<PermissionResult> 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<PermissionResult> future = PermissionUtil.getInstance().setPermissionValue(this.subject, flag, newValue, newContexts);
future.thenAcceptAsync(r -> {
if (!r.successful()) {
// Try again without server context
newContexts.remove(permServerContext);
CompletableFuture<PermissionResult> 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);
}
});
};
}

View File

@ -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<CommandSender> 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<PermissionResult> 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<PermissionResult> 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<CommandSender> removeOptionValueConsumer(GDPermissionUser src, GDClaim claim, Option option, OptionContextHolder optionHolder, Set<Context> contexts, MenuType displayType) {
return consumer -> {
PermissionUtil.getInstance().setOptionValue(this.subject, option.getPermission(), "undefined", contexts);
showOptionPermissions(src, claim, displayType);
final CompletableFuture<PermissionResult> 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);
});
}
});
};
}

View File

@ -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(" : ")

View File

@ -715,7 +715,9 @@ public static List<Component> generateClaimTextList(List<Component> 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<Component> generateClaimTextList(List<Component> 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)

View File

@ -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);
}
}
}

View File

@ -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";

View File

@ -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);

View File

@ -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;

View File

@ -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();
}
}
}

View File

@ -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<String, Object> 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<String, Object> 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));
}

View File

@ -728,6 +728,10 @@ public Set<Context> 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<PermissionResult> 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<PermissionResult> setFlagPermission(Flag flag, Subject
@Override
public CompletableFuture<PermissionResult> setOption(Option option, String value, Set<Context> 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<PermissionResult> setOption(Option option, Subject subject, String value, Set<Context> 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> T getActiveOptionValue(TypeToken<T> type, Option<T> option, Subject s
public CompletableFuture<PermissionResult> setFlagDefinition(Subject subject, FlagDefinition flagDefinition, Tristate value) {
final Set<Context> contexts = new HashSet<>();
contexts.addAll(flagDefinition.getContexts());
PermissionResult result = null;
PermissionResult result = new GDPermissionResult(ResultTypes.SUCCESS, TextComponent.builder().append("SUCCESS").build());
CompletableFuture<PermissionResult> future = new CompletableFuture<>();
for (FlagData flagData : flagDefinition.getFlagData()) {
final Set<Context> 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);

View File

@ -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");

View File

@ -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" :

View File

@ -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<Context> s1, Set<Context> 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<String> getOptionValueList(GDPermissionHolder holder, Option option,
return list;
}
public PermissionResult setOptionValue(GDPermissionHolder holder, String key, String value, Set<Context> contexts, boolean check) {
DataMutateResult result = null;
public CompletableFuture<PermissionResult> setOptionValue(GDPermissionHolder holder, String key, String value, Set<Context> 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<? super Optional<Group>, ? 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<? super User, ? extends PermissionResult>) lpHolder -> {
return this.applyOptionNode(holder, lpHolder, node, option, value);
});
}
}
public CompletableFuture<PermissionResult> setPermissionValue(GDPermissionHolder holder, String permission, Tristate value, Set<Context> 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<? super Optional<Group>, ? 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<? super User, ? extends PermissionResult>) lpHolder -> {
return this.applyPermissionNode(holder, lpHolder, node, value, save);
});
}
}
public CompletableFuture<PermissionResult> setTransientOption(GDPermissionHolder holder, String permission, String value, Set<Context> 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<? super Optional<Group>, ? 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<? super User, ? extends PermissionResult>) lpHolder -> {
return this.applyTransientOptionNode(holder, lpHolder, permissionNode, value);
});
}
}
public CompletableFuture<PermissionResult> setTransientPermission(GDPermissionHolder holder, String permission, Tristate value, Set<Context> 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<? super Optional<Group>, ? 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<? super User, ? extends PermissionResult>) 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<Context> 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<Context> 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<Context> 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()) {

View File

@ -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<Context> contexts) {
default CompletableFuture<PermissionResult> setOptionValue(GDPermissionHolder holder, String permission, String value, Set<Context> 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<Context> contexts, boolean check);
CompletableFuture<PermissionResult> setOptionValue(GDPermissionHolder holder, String permission, String value, Set<Context> 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<Context> contexts) {
default CompletableFuture<PermissionResult> setPermissionValue(GDPermissionHolder holder, Flag flag, Tristate value, Set<Context> 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<Context> contexts, boolean check, boolean save) {
default CompletableFuture<PermissionResult> setPermissionValue(GDPermissionHolder holder, Flag flag, Tristate value, Set<Context> 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<Context> contexts) {
default CompletableFuture<PermissionResult> setPermissionValue(GDPermissionHolder holder, String permission, Tristate value, Set<Context> 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<Context> contexts, boolean check, boolean save);
CompletableFuture<PermissionResult> setPermissionValue(GDPermissionHolder holder, String permission, Tristate value, Set<Context> 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<Context> contexts);
CompletableFuture<PermissionResult> setTransientOption(GDPermissionHolder holder, String permission, String value, Set<Context> 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<Context> contexts);
CompletableFuture<PermissionResult> setTransientPermission(GDPermissionHolder holder, String permission, Tristate value, Set<Context> contexts);
/**
* Refreshes all cached permission data of holder.

View File

@ -396,18 +396,18 @@ public List<String> getOptionValueList(GDPermissionHolder holder, Option option,
}
@Override
public PermissionResult setOptionValue(GDPermissionHolder holder, String permission, String value, Set<Context> contexts, boolean check) {
return convertResult(holderToPEXSubject(holder).data().update(data -> data.setOption(contextsGDToPEX(contexts), permission, value))).join();
public CompletableFuture<PermissionResult> setOptionValue(GDPermissionHolder holder, String permission, String value, Set<Context> 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<Context> contexts) {
return convertResult(holderToPEXSubject(holder).transientData().update(data -> data.setOption(contextsGDToPEX(contexts), permission, value))).join();
public CompletableFuture<PermissionResult> setTransientOption(GDPermissionHolder holder, String permission, String value, Set<Context> 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<Context> contexts) {
return convertResult(holderToPEXSubject(holder).transientData().update(data -> data.setPermission(contextsGDToPEX(contexts), permission, pValFromBool(value.asBoolean())))).join();
public CompletableFuture<PermissionResult> setTransientPermission(GDPermissionHolder holder, String permission, Tristate value, Set<Context> 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<Context> contexts, boolean check, boolean save) {
return convertResult(holderToPEXSubject(holder).data().update(data -> data.setPermission(contextsGDToPEX(contexts), permission, intFromTristate(value)))).join();
public CompletableFuture<PermissionResult> setPermissionValue(GDPermissionHolder holder, String permission, Tristate value, Set<Context> contexts, boolean check, boolean save) {
return convertResult(holderToPEXSubject(holder).data().update(data -> data.setPermission(contextsGDToPEX(contexts), permission, intFromTristate(value))));
}
@Override

View File

@ -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());

View File

@ -83,7 +83,7 @@ public void initialize() throws Exception {
worldsDataFolder.mkdirs();
}
rootWorldSavePath = new File(".").toPath();
rootWorldSavePath = Bukkit.getWorldContainer().toPath();
super.initialize();
}

View File

@ -196,35 +196,35 @@ public List<String> getOptionValueList(GDPermissionHolder holder, Option option,
return PERMISSION_PROVIDER.getOptionValueList(holder, option, contexts);
}
public PermissionResult setOptionValue(GDPermissionHolder holder, String permission, String value, Set<Context> contexts) {
public CompletableFuture<PermissionResult> setOptionValue(GDPermissionHolder holder, String permission, String value, Set<Context> contexts) {
return PERMISSION_PROVIDER.setOptionValue(holder, permission, value, contexts, true);
}
public PermissionResult setOptionValue(GDPermissionHolder holder, String permission, String value, Set<Context> contexts, boolean check) {
public CompletableFuture<PermissionResult> setOptionValue(GDPermissionHolder holder, String permission, String value, Set<Context> contexts, boolean check) {
return PERMISSION_PROVIDER.setOptionValue(holder, permission, value, contexts, check);
}
public PermissionResult setPermissionValue(GDPermissionHolder holder, Flag flag, Tristate value, Set<Context> contexts) {
public CompletableFuture<PermissionResult> setPermissionValue(GDPermissionHolder holder, Flag flag, Tristate value, Set<Context> contexts) {
return PERMISSION_PROVIDER.setPermissionValue(holder, flag, value, contexts, true, true);
}
public PermissionResult setPermissionValue(GDPermissionHolder holder, String permission, Tristate value, Set<Context> contexts) {
public CompletableFuture<PermissionResult> setPermissionValue(GDPermissionHolder holder, String permission, Tristate value, Set<Context> contexts) {
return PERMISSION_PROVIDER.setPermissionValue(holder, permission, value, contexts, true, true);
}
public PermissionResult setPermissionValue(GDPermissionHolder holder, Flag flag, Tristate value, Set<Context> contexts, boolean check, boolean save) {
public CompletableFuture<PermissionResult> setPermissionValue(GDPermissionHolder holder, Flag flag, Tristate value, Set<Context> 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<Context> contexts, boolean check, boolean save) {
public CompletableFuture<PermissionResult> setPermissionValue(GDPermissionHolder holder, String permission, Tristate value, Set<Context> 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<Context> contexts) {
public CompletableFuture<PermissionResult> setTransientOption(GDPermissionHolder holder, String permission, String value, Set<Context> contexts) {
return PERMISSION_PROVIDER.setTransientOption(holder, permission, value, contexts);
}
public PermissionResult setTransientPermission(GDPermissionHolder holder, String permission, Tristate value, Set<Context> contexts) {
public CompletableFuture<PermissionResult> setTransientPermission(GDPermissionHolder holder, String permission, Tristate value, Set<Context> contexts) {
return PERMISSION_PROVIDER.setTransientPermission(holder, permission, value, contexts);
}

View File

@ -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",

View File

@ -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",

View File

@ -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",

View File

@ -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",

View File

@ -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",

View File

@ -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",

View File

@ -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",

View File

@ -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",

View File

@ -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",

View File

@ -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

View File

@ -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..."
}
}

View File

@ -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."

View File

@ -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."

View File

@ -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."

View File

@ -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."

View File

@ -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. Уменьшите добавляемое количество или попросите администратора выдать игроку нужное количество блоков."

View File

@ -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

View File

@ -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();

View File

@ -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...");

View File

@ -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");

View File

@ -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<CommandSource> createCustomFlagConsumer(GDPermissionUser src, G
} else if (addClaimContext) {
definitionContexts.add(claim.getContext());
}
CompletableFuture<PermissionResult> result = null;
for (FlagData flagData : customFlag.getFlagData()) {
final Set<Context> newContexts = new HashSet<>(definitionContexts);
newContexts.addAll(flagData.getContexts());
@ -1120,13 +1124,15 @@ private Consumer<CommandSource> 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<CommandSource> 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<PermissionResult> 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<PermissionResult> future = PermissionUtil.getInstance().setPermissionValue(this.subject, flag, newValue, newContexts);
future.thenAcceptAsync(r -> {
if (!r.successful()) {
// Try again without server context
newContexts.remove(permServerContext);
CompletableFuture<PermissionResult> 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);
}
});
};
}

View File

@ -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<CommandSource> 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<PermissionResult> 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<PermissionResult> 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<CommandSource> removeOptionValueConsumer(GDPermissionUser src, GDClaim claim, Option option, OptionContextHolder optionHolder, Set<Context> contexts, MenuType displayType) {
return consumer -> {
PermissionUtil.getInstance().setOptionValue(this.subject, option.getPermission(), "undefined", contexts);
showOptionPermissions(src, claim, displayType);
final CompletableFuture<PermissionResult> 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);
});
}
});
};
}

View File

@ -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(" : ")

View File

@ -725,7 +725,9 @@ public static List<Component> generateClaimTextList(List<Component> 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<Component> generateClaimTextList(List<Component> 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)

View File

@ -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);
}
}
}

View File

@ -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";

View File

@ -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<World> 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;

View File

@ -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<World> fromLocation, Location<World> 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<World> 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<World> 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<World> 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<World> 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;

View File

@ -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;

View File

@ -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();
}
}
}

View File

@ -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<World> location = entityItem.getLocation();
Location<World> 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<Wor
if (GriefDefenderPlugin.CLAIM_BLOCK_SYSTEM == ClaimBlockSystem.VOLUME) {
final double claimableChunks = claimBlocksRemaining / 65536.0;
final Map<String, Object> 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<String, Object> 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));
}

View File

@ -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<Context> 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<PermissionResult> 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<PermissionResult> setFlagPermission(Flag flag, Subject
@Override
public CompletableFuture<PermissionResult> setOption(Option option, String value, Set<Context> 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<PermissionResult> setOption(Option option, Subject subject, String value, Set<Context> 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> T getActiveOptionValue(TypeToken<T> type, Option<T> option, Subject s
public CompletableFuture<PermissionResult> setFlagDefinition(Subject subject, FlagDefinition flagDefinition, Tristate value) {
final Set<Context> contexts = new HashSet<>();
contexts.addAll(flagDefinition.getContexts());
PermissionResult result = null;
PermissionResult result = new GDPermissionResult(ResultTypes.SUCCESS, TextComponent.builder().append("SUCCESS").build());
CompletableFuture<PermissionResult> future = new CompletableFuture<>();
for (FlagData flagData : flagDefinition.getFlagData()) {
final Set<Context> 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);

View File

@ -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");

View File

@ -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<Context> s1, Set<Context> s2) {
public LuckPermsProvider() {
final ProviderRegistration<LuckPerms> 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<String> getOptionValueList(GDPermissionHolder holder, Option option,
return list;
}
public PermissionResult setOptionValue(GDPermissionHolder holder, String key, String value, Set<Context> contexts, boolean check) {
DataMutateResult result = null;
public CompletableFuture<PermissionResult> setOptionValue(GDPermissionHolder holder, String key, String value, Set<Context> 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<? super Optional<Group>, ? 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<? super User, ? extends PermissionResult>) lpHolder -> {
return this.applyOptionNode(holder, lpHolder, node, option, value);
});
}
}
public CompletableFuture<PermissionResult> setPermissionValue(GDPermissionHolder holder, String permission, Tristate value, Set<Context> 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<? super Optional<Group>, ? 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<? super User, ? extends PermissionResult>) lpHolder -> {
return this.applyPermissionNode(holder, lpHolder, node, value, save);
});
}
}
public CompletableFuture<PermissionResult> setTransientOption(GDPermissionHolder holder, String permission, String value, Set<Context> 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<? super Optional<Group>, ? 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<? super User, ? extends PermissionResult>) lpHolder -> {
return this.applyTransientOptionNode(holder, lpHolder, permissionNode, value);
});
}
}
public CompletableFuture<PermissionResult> setTransientPermission(GDPermissionHolder holder, String permission, Tristate value, Set<Context> 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<? super Optional<Group>, ? 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<? super User, ? extends PermissionResult>) 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<Context> 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<Context> 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<Context> 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()) {

View File

@ -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<Context> contexts) {
default CompletableFuture<PermissionResult> setOptionValue(GDPermissionHolder holder, String permission, String value, Set<Context> 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<Context> contexts, boolean check);
CompletableFuture<PermissionResult> setOptionValue(GDPermissionHolder holder, String permission, String value, Set<Context> 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<Context> contexts) {
default CompletableFuture<PermissionResult> setPermissionValue(GDPermissionHolder holder, Flag flag, Tristate value, Set<Context> 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<Context> contexts, boolean check, boolean save) {
default CompletableFuture<PermissionResult> setPermissionValue(GDPermissionHolder holder, Flag flag, Tristate value, Set<Context> 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<Context> contexts) {
default CompletableFuture<PermissionResult> setPermissionValue(GDPermissionHolder holder, String permission, Tristate value, Set<Context> 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<Context> contexts, boolean check, boolean save);
CompletableFuture<PermissionResult> setPermissionValue(GDPermissionHolder holder, String permission, Tristate value, Set<Context> 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<Context> contexts);
CompletableFuture<PermissionResult> setTransientOption(GDPermissionHolder holder, String permission, String value, Set<Context> 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<Context> contexts);
CompletableFuture<PermissionResult> setTransientPermission(GDPermissionHolder holder, String permission, Tristate value, Set<Context> contexts);
/**
* Refreshes all cached permission data of holder.

View File

@ -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());

View File

@ -190,35 +190,35 @@ public List<String> getOptionValueList(GDPermissionHolder holder, Option option,
return PERMISSION_PROVIDER.getOptionValueList(holder, option, contexts);
}
public PermissionResult setOptionValue(GDPermissionHolder holder, String permission, String value, Set<Context> contexts) {
public CompletableFuture<PermissionResult> setOptionValue(GDPermissionHolder holder, String permission, String value, Set<Context> contexts) {
return PERMISSION_PROVIDER.setOptionValue(holder, permission, value, contexts, true);
}
public PermissionResult setOptionValue(GDPermissionHolder holder, String permission, String value, Set<Context> contexts, boolean check) {
public CompletableFuture<PermissionResult> setOptionValue(GDPermissionHolder holder, String permission, String value, Set<Context> contexts, boolean check) {
return PERMISSION_PROVIDER.setOptionValue(holder, permission, value, contexts, check);
}
public PermissionResult setPermissionValue(GDPermissionHolder holder, Flag flag, Tristate value, Set<Context> contexts) {
public CompletableFuture<PermissionResult> setPermissionValue(GDPermissionHolder holder, Flag flag, Tristate value, Set<Context> contexts) {
return PERMISSION_PROVIDER.setPermissionValue(holder, flag, value, contexts, true, true);
}
public PermissionResult setPermissionValue(GDPermissionHolder holder, String permission, Tristate value, Set<Context> contexts) {
public CompletableFuture<PermissionResult> setPermissionValue(GDPermissionHolder holder, String permission, Tristate value, Set<Context> contexts) {
return PERMISSION_PROVIDER.setPermissionValue(holder, permission, value, contexts, true, true);
}
public PermissionResult setPermissionValue(GDPermissionHolder holder, Flag flag, Tristate value, Set<Context> contexts, boolean check, boolean save) {
public CompletableFuture<PermissionResult> setPermissionValue(GDPermissionHolder holder, Flag flag, Tristate value, Set<Context> 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<Context> contexts, boolean check, boolean save) {
public CompletableFuture<PermissionResult> setPermissionValue(GDPermissionHolder holder, String permission, Tristate value, Set<Context> 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<Context> contexts) {
public CompletableFuture<PermissionResult> setTransientOption(GDPermissionHolder holder, String permission, String value, Set<Context> contexts) {
return PERMISSION_PROVIDER.setTransientOption(holder, permission, value, contexts);
}
public PermissionResult setTransientPermission(GDPermissionHolder holder, String permission, Tristate value, Set<Context> contexts) {
public CompletableFuture<PermissionResult> setTransientPermission(GDPermissionHolder holder, String permission, Tristate value, Set<Context> contexts) {
return PERMISSION_PROVIDER.setTransientPermission(holder, permission, value, contexts);
}