Finish implementing options for next major release.

* Fixed '/cfg' and '/cog' commands.
* Fixed 'create-mode' not working as intended.
* Fixed 'any' usage with flag commands.
* Fixed 'command-execute' usage.
* Fixed 'command-execute-pvp' usage.
* Fixed option removal/save with LP v5.
* Added context support for controlling user flag command usage.
* Added context support to option GUI.
* Added permission 'griefdefender.user.claim.command.flag.arg' which controls if a user can use flag command with arguments.
* Added permission 'griefdefender.user.claim.command.flag.gui' which controls if a user can use flag GUI.
* Added new group context '#all' which can be used to represent all sources or targets.
* Removed 'max-claim-inspection-distance' from config as it is now controlled by 'radius-inspect' option.
* Removed 'combat-timeout' from config as it is now controlled by 'pvp-combat-timeout' option.
* Implemented the folloing new options
  'player-command-enter' - Handles executing commands when a player enters a claim.
  'player-command-exit' - Handles executing commands when a player exits a claim.
   Note: both command options support the following placeholders : %player%, %owner%, %uuid%, %world%, %server%, %location%

  'player-gamemode' - Used to determine the gamemode of a player when entering a claim.
  'player-deny-godmode' - Used to determine if a player can be in godmode when entering a claim.
  'player-walk-speed' - Controls the player walk speed when entering a claim.
  'player-weather' - Controls player local weather when entering a claim.
  'pvp-combat-command' - Used to determine if a player can use commands during PvP combat.
  'pvp-combat-teleport' - Used to determine if a player can teleport during PvP combat.
  'pvp-combat-timeout' - Used to determine how many seconds PvP combat is considered to continue after the most recent damage.
  'radius-inspect' - Controls the radius in blocks to search within when inspecting for claims.
  'spawn-limit' - Used to control the spawn limit for a specific set of entities in a claim.
* Only save once when toggling flag definitions that include multiple definitions.
This commit is contained in:
bloodshot 2019-12-30 18:25:55 -05:00
parent ff27faa69c
commit 436f053fbe
95 changed files with 2348 additions and 1044 deletions

@ -1 +1 @@
Subproject commit 85fca6156bc71b67199ff1bec1ceb14ee184cb12
Subproject commit 77a0a3f713aece41a2cccfbe4a13c87b4dd2d139

View File

@ -518,45 +518,6 @@ public class GDPlayerData implements PlayerData {
return this.ignoreBasicClaims;
}
public boolean canManageOption(Player player, GDClaim claim, boolean isGroup) {
if (claim.allowEdit(player) != null) {
return false;
}
if (claim.isWilderness()) {
return player.hasPermission(GDPermissions.MANAGE_WILDERNESS);
}
if (isGroup) {
if (claim.isTown() && player.hasPermission(GDPermissions.COMMAND_CLAIM_OPTIONS_GROUP_TOWN)) {
return true;
}
if (claim.isAdminClaim() && player.hasPermission(GDPermissions.COMMAND_CLAIM_OPTIONS_GROUP_ADMIN)) {
return true;
}
if (claim.isBasicClaim() && player.hasPermission(GDPermissions.COMMAND_CLAIM_OPTIONS_GROUP_BASIC)) {
return true;
}
if (claim.isSubdivision() && player.hasPermission(GDPermissions.COMMAND_CLAIM_OPTIONS_GROUP_SUBDIVISION)) {
return true;
}
} else {
if (claim.isTown() && player.hasPermission(GDPermissions.COMMAND_CLAIM_OPTIONS_PLAYER_TOWN)) {
return true;
}
if (claim.isAdminClaim() && player.hasPermission(GDPermissions.COMMAND_CLAIM_OPTIONS_PLAYER_ADMIN)) {
return true;
}
if (claim.isBasicClaim() && player.hasPermission(GDPermissions.COMMAND_CLAIM_OPTIONS_PLAYER_BASIC)) {
return true;
}
if (claim.isSubdivision() && player.hasPermission(GDPermissions.COMMAND_CLAIM_OPTIONS_PLAYER_SUBDIVISION)) {
return true;
}
}
return false;
}
@Override
public int getMaxAccruedClaimBlocks() {
return GDPermissionManager.getInstance().getInternalOptionValue(TypeToken.of(Integer.class), this.getSubject(), Options.MAX_ACCRUED_BLOCKS);
@ -669,13 +630,18 @@ public class GDPlayerData implements PlayerData {
return totalTax;
}
public boolean inPvpCombat(World world) {
if (this.lastPvpTimestamp == null) {
public boolean inPvpCombat() {
final Player player = this.getSubject().getOnlinePlayer();
if (this.lastPvpTimestamp == null || player == null) {
return false;
}
final Instant now = Instant.now();
final int combatTimeout = GriefDefenderPlugin.getActiveConfig(world).getConfig().pvp.combatTimeout;
final int combatTimeout = GDPermissionManager.getInstance().getInternalOptionValue(TypeToken.of(Integer.class), player, Options.PVP_COMBAT_TIMEOUT);
if (combatTimeout <= 0) {
return false;
}
if (this.lastPvpTimestamp.plusSeconds(combatTimeout).isBefore(now)) {
this.lastPvpTimestamp = null;
return false;
@ -684,6 +650,27 @@ public class GDPlayerData implements PlayerData {
return true;
}
public int getPvpCombatTimeRemaining() {
final Player player = this.getSubject().getOnlinePlayer();
if (this.lastPvpTimestamp == null || player == null) {
return 0;
}
final Instant now = Instant.now();
final int combatTimeout = GDPermissionManager.getInstance().getInternalOptionValue(TypeToken.of(Integer.class), player, Options.PVP_COMBAT_TIMEOUT);
if (combatTimeout <= 0) {
return 0;
}
if (this.lastPvpTimestamp.plusSeconds(combatTimeout).isBefore(now)) {
this.lastPvpTimestamp = null;
return 0;
}
final int duration = (int) Duration.between(this.lastPvpTimestamp, now).getSeconds();
return combatTimeout - duration;
}
public void onClaimDelete() {
this.lastShovelLocation = null;
this.eventResultCache = null;

View File

@ -273,7 +273,6 @@ public class GriefDefenderPlugin {
public GDBlockType createVisualBlock;
public GDItemType modificationTool;
public GDItemType investigationTool;
public int maxInspectionDistance = 100;
public static boolean debugLogging = false;
public static boolean debugActive = false;
@ -871,7 +870,6 @@ public class GriefDefenderPlugin {
this.createVisualBlock = BlockTypeRegistryModule.getInstance().getById(BaseStorage.globalConfig.getConfig().visual.claimCreateStartBlock).orElse(defaultCreateVisualBlock);
this.modificationTool = ItemTypeRegistryModule.getInstance().getById(BaseStorage.globalConfig.getConfig().claim.modificationTool).orElse(null);
this.investigationTool = ItemTypeRegistryModule.getInstance().getById(BaseStorage.globalConfig.getConfig().claim.investigationTool).orElse(null);
this.maxInspectionDistance = BaseStorage.globalConfig.getConfig().general.maxClaimInspectionDistance;
if (this.dataStore != null) {
for (World world : Bukkit.getServer().getWorlds()) {
final String dimType = world.getEnvironment().name().toLowerCase();

View File

@ -249,6 +249,7 @@ public class MessageCache {
public Component FLAG_UI_OVERRIDE_NO_PERMISSION;
public Component FLAG_UI_RETURN_FLAGS;
public Component LABEL_ACCESSORS;
public Component LABEL_ALL;
public Component LABEL_AREA;
public Component LABEL_BLOCKS;
public Component LABEL_BUILDERS;
@ -292,6 +293,8 @@ public class MessageCache {
public Component MODE_NATURE;
public Component MODE_SUBDIVISION;
public Component MODE_TOWN;
public Component OPTION_APPLY_PLAYER_DENY_FLIGHT;
public Component OPTION_APPLY_PLAYER_DENY_GODMODE;
public Component OPTION_DESCRIPTION_ABANDON_DELAY;
public Component OPTION_DESCRIPTION_ABANDON_RETURN_RATIO;
public Component OPTION_DESCRIPTION_BLOCKS_ACCRUED_PER_HOUR;
@ -311,7 +314,8 @@ public class MessageCache {
public Component OPTION_DESCRIPTION_MIN_SIZE_X;
public Component OPTION_DESCRIPTION_MIN_SIZE_Y;
public Component OPTION_DESCRIPTION_MIN_SIZE_Z;
public Component OPTION_DESCRIPTION_PLAYER_COMMAND;
public Component OPTION_DESCRIPTION_PLAYER_COMMAND_ENTER;
public Component OPTION_DESCRIPTION_PLAYER_COMMAND_EXIT;
public Component OPTION_DESCRIPTION_PLAYER_DENY_FLIGHT;
public Component OPTION_DESCRIPTION_PLAYER_DENY_GODMODE;
public Component OPTION_DESCRIPTION_PLAYER_DENY_HUNGER;
@ -326,7 +330,7 @@ public class MessageCache {
public Component OPTION_DESCRIPTION_TAX_EXPIRATION;
public Component OPTION_DESCRIPTION_TAX_EXPIRATION_DAYS_KEEP;
public Component OPTION_DESCRIPTION_TAX_RATE;
public Component OPTION_PLAYER_DENY_FLIGHT;
public Component OPTION_UI_CLICK_REMOVE;
public Component OWNER_ADMIN;
public Component PERMISSION_ASSIGN_WITHOUT_HAVING;
public Component PERMISSION_CLAIM_CREATE;
@ -345,6 +349,8 @@ public class MessageCache {
public Component PERMISSION_FIRE_SPREAD;
public Component PERMISSION_FLAG_DEFAULTS;
public Component PERMISSION_FLAG_OVERRIDES;
public Component PERMISSION_FLAG_ARG;
public Component PERMISSION_FLAG_GUI;
public Component PERMISSION_FLAG_USE;
public Component PERMISSION_FLOW_LIQUID;
public Component PERMISSION_GLOBAL_OPTION;
@ -607,6 +613,7 @@ public class MessageCache {
FLAG_UI_OVERRIDE_NO_PERMISSION = MessageStorage.MESSAGE_DATA.getMessage("flag-ui-override-no-permission");
FLAG_UI_RETURN_FLAGS = MessageStorage.MESSAGE_DATA.getMessage("flag-ui-return-flags");
LABEL_ACCESSORS = MessageStorage.MESSAGE_DATA.getMessage("label-accessors");
LABEL_ALL = MessageStorage.MESSAGE_DATA.getMessage("label-all");
LABEL_AREA = MessageStorage.MESSAGE_DATA.getMessage("label-area");
LABEL_BLOCKS = MessageStorage.MESSAGE_DATA.getMessage("label-blocks");
LABEL_BUILDERS = MessageStorage.MESSAGE_DATA.getMessage("label-builders");
@ -669,7 +676,8 @@ public class MessageCache {
OPTION_DESCRIPTION_MIN_SIZE_X = MessageStorage.MESSAGE_DATA.getMessage("option-description-min-size-x");
OPTION_DESCRIPTION_MIN_SIZE_Y = MessageStorage.MESSAGE_DATA.getMessage("option-description-min-size-y");
OPTION_DESCRIPTION_MIN_SIZE_Z = MessageStorage.MESSAGE_DATA.getMessage("option-description-min-size-z");
OPTION_DESCRIPTION_PLAYER_COMMAND = MessageStorage.MESSAGE_DATA.getMessage("option-description-player-command");
OPTION_DESCRIPTION_PLAYER_COMMAND_ENTER = MessageStorage.MESSAGE_DATA.getMessage("option-description-player-command-enter");
OPTION_DESCRIPTION_PLAYER_COMMAND_EXIT = MessageStorage.MESSAGE_DATA.getMessage("option-description-player-command-exit");
OPTION_DESCRIPTION_PLAYER_DENY_FLIGHT = MessageStorage.MESSAGE_DATA.getMessage("option-description-player-deny-flight");
OPTION_DESCRIPTION_PLAYER_DENY_GODMODE = MessageStorage.MESSAGE_DATA.getMessage("option-description-player-deny-godmode");
OPTION_DESCRIPTION_PLAYER_DENY_HUNGER = MessageStorage.MESSAGE_DATA.getMessage("option-description-player-deny-hunger");
@ -684,7 +692,9 @@ public class MessageCache {
OPTION_DESCRIPTION_TAX_EXPIRATION = MessageStorage.MESSAGE_DATA.getMessage("option-description-tax-expiration");
OPTION_DESCRIPTION_TAX_EXPIRATION_DAYS_KEEP = MessageStorage.MESSAGE_DATA.getMessage("option-description-tax-expiration-days-keep");
OPTION_DESCRIPTION_TAX_RATE = MessageStorage.MESSAGE_DATA.getMessage("option-description-tax-rate");
OPTION_PLAYER_DENY_FLIGHT = MessageStorage.MESSAGE_DATA.getMessage("option-player-deny-flight");
OPTION_APPLY_PLAYER_DENY_FLIGHT = MessageStorage.MESSAGE_DATA.getMessage("option-apply-player-deny-flight");
OPTION_APPLY_PLAYER_DENY_GODMODE = MessageStorage.MESSAGE_DATA.getMessage("option-apply-player-deny-godmode");
OPTION_UI_CLICK_REMOVE = MessageStorage.MESSAGE_DATA.getMessage("option-ui-click-remove");
OWNER_ADMIN = MessageStorage.MESSAGE_DATA.getMessage("owner-admin");
PERMISSION_ASSIGN_WITHOUT_HAVING = MessageStorage.MESSAGE_DATA.getMessage("permission-assign-without-having");
PERMISSION_CLAIM_CREATE = MessageStorage.MESSAGE_DATA.getMessage("permission-claim-create");
@ -703,6 +713,8 @@ public class MessageCache {
PERMISSION_FIRE_SPREAD = MessageStorage.MESSAGE_DATA.getMessage("permission-fire-spread");
PERMISSION_FLAG_DEFAULTS = MessageStorage.MESSAGE_DATA.getMessage("permission-flag-defaults");
PERMISSION_FLAG_OVERRIDES = MessageStorage.MESSAGE_DATA.getMessage("permission-flag-overrides");
PERMISSION_FLAG_ARG = MessageStorage.MESSAGE_DATA.getMessage("permission-flag-arg");
PERMISSION_FLAG_GUI = MessageStorage.MESSAGE_DATA.getMessage("permission-flag-gui");
PERMISSION_FLAG_USE = MessageStorage.MESSAGE_DATA.getMessage("permission-flag-use");
PERMISSION_FLOW_LIQUID = MessageStorage.MESSAGE_DATA.getMessage("permission-flow-liquid");
PERMISSION_GLOBAL_OPTION = MessageStorage.MESSAGE_DATA.getMessage("permission-global-option");

View File

@ -92,6 +92,8 @@ import org.bukkit.Chunk;
import org.bukkit.Location;
import org.bukkit.World;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Entity;
import org.bukkit.entity.EntityType;
import org.bukkit.entity.Player;
import org.checkerframework.checker.nullness.qual.Nullable;
@ -2017,6 +2019,19 @@ public class GDClaim implements Claim {
return new GDClaimResult(ClaimResultType.SUCCESS);
}
public int countEntities(EntityType type) {
int count = 0;
for (Chunk chunk : this.getChunks()) {
for (Entity entity : chunk.getEntities()) {
if (entity.getType() == type) {
count++;
}
}
}
return count;
}
@Override
public boolean equals(Object o) {
if (this == o) {

View File

@ -113,6 +113,8 @@ public abstract class ClaimFlagBase extends BaseCommand {
public void execute(Player player, String[] args) throws InvalidCommandArgument {
final GDPermissionUser src = PermissionHolderCache.getInstance().getOrCreateUser(player);
final GDPermissionHolder commandSubject = subject;
final GDPlayerData playerData = src.getInternalPlayerData();
final GDClaim claim = GriefDefenderPlugin.getInstance().dataStore.getClaimAtPlayer(playerData, player.getLocation());
String commandFlag = null;
String target = null;
String value = null;
@ -123,12 +125,21 @@ public abstract class ClaimFlagBase extends BaseCommand {
contexts = arguments.substring(index, arguments.length());
}
if (args.length > 0) {
if (!src.getInternalPlayerData().canIgnoreClaim(claim) && !player.hasPermission(GDPermissions.COMMAND_FLAGS_CLAIM_ARG)) {
TextAdapter.sendComponent(player, MessageCache.getInstance().PERMISSION_FLAG_ARG);
return;
}
if (args.length < 3) {
throw new InvalidCommandArgument();
}
commandFlag = args[0];
target = args[1];
value = args[2];
} else {
if (!src.getInternalPlayerData().canIgnoreClaim(claim) && !player.hasPermission(GDPermissions.COMMAND_FLAGS_CLAIM_GUI)) {
TextAdapter.sendComponent(player, MessageCache.getInstance().PERMISSION_FLAG_GUI);
return;
}
}
final Flag flag = FlagRegistryModule.getInstance().getById(commandFlag).orElse(null);
if (commandFlag != null && flag == null) {
@ -149,9 +160,7 @@ public abstract class ClaimFlagBase extends BaseCommand {
}
}
final GDPlayerData playerData = GriefDefenderPlugin.getInstance().dataStore.getOrCreatePlayerData(player.getWorld(), player.getUniqueId());
GDClaim claim = GriefDefenderPlugin.getInstance().dataStore.getClaimAtPlayer(playerData, player.getLocation());
final Set<Context> contextSet = CauseContextHelper.generateContexts(player, claim, contexts);
final Set<Context> contextSet = CauseContextHelper.generateContexts(flag.getPermission(), player, claim, contexts);
if (contextSet == null) {
return;
}
@ -911,7 +920,6 @@ public abstract class ClaimFlagBase extends BaseCommand {
newValue = Tristate.UNDEFINED;
}
PermissionResult result = null;
final Flag flag = flagData.getFlag();
GDFlagPermissionEvent.Set event = new GDFlagPermissionEvent.Set(this.subject, flagData.getFlag(), newValue, newContexts);
GriefDefender.getEventManager().post(event);
@ -919,8 +927,11 @@ public abstract class ClaimFlagBase extends BaseCommand {
return;
}
result = GriefDefenderPlugin.getInstance().getPermissionProvider().setPermissionValue(GriefDefenderPlugin.DEFAULT_HOLDER, flag, newValue, newContexts);
PermissionResult 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, displayType);
};

View File

@ -91,6 +91,8 @@ import java.util.TreeMap;
import java.util.UUID;
import java.util.concurrent.TimeUnit;
import java.util.function.Consumer;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@SuppressWarnings({ "unchecked", "rawtypes" })
public abstract class ClaimOptionBase extends BaseCommand {
@ -121,17 +123,31 @@ public abstract class ClaimOptionBase extends BaseCommand {
throw new InvalidCommandArgument();
}
commandOption = args[0];
value = args[1];
// Check for quoted string
Pattern pattern = Pattern.compile("\"(.*)\"");
Matcher matcher = pattern.matcher(arguments);
if (matcher.find()) {
value = matcher.group(1);
} else {
value = args[1];
}
}
Option option = null;
Option<?> option = null;
if (commandOption != null) {
option = GriefDefender.getRegistry().getType(Option.class, commandOption).orElse(null);
if (commandOption != null && option == null) {
if (option == null) {
TextAdapter.sendComponent(player, MessageStorage.MESSAGE_DATA.getMessage(MessageStorage.OPTION_NOT_FOUND, ImmutableMap.of(
"option", commandOption)));
return;
}
if (option == Options.PLAYER_COMMAND_ENTER || option == Options.PLAYER_COMMAND_EXIT) {
if (contexts == null) {
TextAdapter.sendComponent(player, MessageStorage.MESSAGE_DATA.getMessage(MessageStorage.OPTION_REQUIRES_CONTEXTS, ImmutableMap.of(
"contexts", "run-as=[player|console] run-for=[public|owner|member]")));
return;
}
}
}
final GDPlayerData playerData = GriefDefenderPlugin.getInstance().dataStore.getOrCreatePlayerData(player.getWorld(), player.getUniqueId());
@ -142,7 +158,7 @@ public abstract class ClaimOptionBase extends BaseCommand {
return;
}
} else if (!claim.isTown() && !playerData.canManageAdminClaims && !playerData.canIgnoreClaim(claim)) {
GriefDefenderPlugin.sendMessage(player, MessageCache.getInstance().PERMISSION_GLOBAL_OPTION);
GriefDefenderPlugin.sendMessage(player, MessageCache.getInstance().PERMISSION_PLAYER_OPTION);
return;
}
if (option != null) {
@ -165,10 +181,32 @@ public abstract class ClaimOptionBase extends BaseCommand {
}
}
final Set<Context> contextSet = CauseContextHelper.generateContexts(player, claim, contexts);
final Set<Context> contextSet = CauseContextHelper.generateContexts(option.getPermission(), player, claim, contexts);
if (contextSet == null) {
return;
}
if (option == Options.PLAYER_COMMAND_ENTER || option == Options.PLAYER_COMMAND_EXIT) {
final Set<String> requiredKeys = (Set<String>) option.getRequiredContextKeys();
for (String key : requiredKeys) {
boolean found = false;
for (Context context : contextSet) {
if (context.getKey().equalsIgnoreCase(key)) {
found = true;
break;
}
}
if (!found) {
TextAdapter.sendComponent(player, MessageStorage.MESSAGE_DATA.getMessage(MessageStorage.OPTION_REQUIRES_CONTEXTS, ImmutableMap.of(
"contexts", key)));
return;
}
}
if (contexts == null) {
TextAdapter.sendComponent(player, MessageStorage.MESSAGE_DATA.getMessage(MessageStorage.OPTION_REQUIRES_CONTEXTS, ImmutableMap.of(
"contexts", "run-as=[player|console] run-for=[public|owner|member]")));
return;
}
}
if (claim != null) {
if (commandOption == null && value == null && player.hasPermission(GDPermissions.COMMAND_LIST_CLAIM_OPTIONS)) {
@ -521,7 +559,11 @@ public abstract class ClaimOptionBase extends BaseCommand {
}
}
final boolean customContexts = UIHelper.containsCustomContext(contexts);
boolean customContexts = UIHelper.containsCustomContext(contexts);
// special case
if (option == Options.PLAYER_COMMAND_ENTER || option == Options.PLAYER_COMMAND_EXIT) {
customContexts = true;
}
Component optionContexts = UIHelper.getFriendlyContextString(claim, contexts);
String currentValue = optionHolder.getValue();
TextColor color = optionHolder.getColor();
@ -549,11 +591,12 @@ public abstract class ClaimOptionBase extends BaseCommand {
}
if (hasEditPermission) {
if (!option.getAllowedType().isAssignableFrom(Integer.class) && !option.getAllowedType().isAssignableFrom(Double.class)) {
this.appendContexts(builder, contexts);
builder.clickEvent(ClickEvent.runCommand(GDCallbackHolder.getInstance().createCallbackRunCommand(newOptionValueConsumer(src, claim, option, optionHolder, contexts, displayType, false))));
} else {
builder.append(TextComponent.builder()
.append(TextComponent.of(" >").decoration(TextDecoration.BOLD, true))
.clickEvent(ClickEvent.runCommand(GDCallbackHolder.getInstance().createCallbackRunCommand(newOptionValueConsumer(src, claim, option, optionHolder, contexts, displayType, false)))));
builder.append(TextComponent.builder().append(TextComponent.of(" >").decoration(TextDecoration.BOLD, true)));
this.appendContexts(builder, contexts);
builder.clickEvent(ClickEvent.runCommand(GDCallbackHolder.getInstance().createCallbackRunCommand(newOptionValueConsumer(src, claim, option, optionHolder, contexts, displayType, false))));
}
if (option.getAllowedType().isAssignableFrom(String.class)) {
@ -568,9 +611,51 @@ public abstract class ClaimOptionBase extends BaseCommand {
"value", TextComponent.of(currentValue).color(TextColor.GOLD)))).build()));
}
if (customContexts) {
builder.append(" ")
.append("[", TextColor.WHITE)
.append(TextComponent.builder()
.append("x", TextColor.RED)
.hoverEvent(HoverEvent.showText(MessageCache.getInstance().FLAG_UI_CLICK_REMOVE))
.clickEvent(ClickEvent.runCommand(GDCallbackHolder.getInstance().createCallbackRunCommand(removeOptionValueConsumer(src, claim, option, optionHolder, contexts, displayType))))
.build())
.append("]", TextColor.WHITE);
}
return builder.build();
}
private void appendContexts(TextComponent.Builder builder, Set<Context> contexts) {
// check source/target
Component source = null;
Component target = null;
final Component whiteOpenBracket = TextComponent.of("[", TextColor.WHITE);
final Component whiteCloseBracket = TextComponent.of("]", TextColor.WHITE);
for (Context context : contexts) {
if (context.getKey().equals(ContextKeys.SOURCE)) {
source = TextComponent.builder()
.append(whiteOpenBracket)
.append("s", TextColor.GREEN)
.append("=", TextColor.WHITE)
.append(context.getValue().replace("minecraft:", ""), TextColor.GOLD)
.append(whiteCloseBracket)
.hoverEvent(HoverEvent.showText(MessageCache.getInstance().LABEL_SOURCE))
.build();
builder.append(" ").append(source);
} else if (context.getKey().equals(ContextKeys.TARGET)) {
target = TextComponent.builder()
.append(whiteOpenBracket)
.append("t", TextColor.GREEN)
.append("=", TextColor.WHITE)
.append(context.getValue().replace("minecraft:", ""), TextColor.GOLD)
.append(whiteCloseBracket)
.hoverEvent(HoverEvent.showText(MessageCache.getInstance().LABEL_TARGET))
.build();
builder.append(" ").append(target);
}
}
}
private boolean containsDefaultContext(Set<Context> contexts) {
for (Context context : contexts) {
if (context.getKey().contains("gd_claim_default")) {
@ -638,7 +723,7 @@ public abstract class ClaimOptionBase extends BaseCommand {
if (value == null || value == WeatherTypes.UNDEFINED) {
newValue = "clear";
} else if (value == WeatherTypes.CLEAR) {
newValue = "rain";
newValue = "downfall";
} else {
newValue = "undefined";
}
@ -722,6 +807,13 @@ public abstract class ClaimOptionBase extends BaseCommand {
};
}
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);
};
}
private Consumer<CommandSender> adjustNumberConsumer(GDPermissionUser src, GDClaim claim, Option option, String currentValue, MenuType menuType, Set<Context> contexts) {
return consumer -> {
String newValue = "";
@ -882,8 +974,8 @@ public abstract class ClaimOptionBase extends BaseCommand {
if (value.equalsIgnoreCase("clear")) {
return (T) WeatherTypes.CLEAR;
}
if (value.equalsIgnoreCase("rain")) {
return (T) WeatherTypes.RAIN;
if (value.equalsIgnoreCase("downfall")) {
return (T) WeatherTypes.DOWNFALL;
}
}
if (type.getRawType().isAssignableFrom(CreateModeType.class)) {

View File

@ -24,7 +24,6 @@
*/
package com.griefdefender.command;
import co.aikar.commands.BaseCommand;
import co.aikar.commands.InvalidCommandArgument;
import co.aikar.commands.annotation.CommandAlias;
import co.aikar.commands.annotation.CommandCompletion;
@ -34,35 +33,10 @@ import co.aikar.commands.annotation.Optional;
import co.aikar.commands.annotation.Subcommand;
import co.aikar.commands.annotation.Syntax;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Lists;
import com.griefdefender.GDPlayerData;
import com.griefdefender.GriefDefenderPlugin;
import com.griefdefender.api.claim.ClaimContexts;
import com.griefdefender.api.permission.Context;
import com.griefdefender.api.permission.option.Option;
import com.griefdefender.cache.MessageCache;
import com.griefdefender.cache.PermissionHolderCache;
import com.griefdefender.claim.GDClaim;
import com.griefdefender.configuration.MessageStorage;
import com.griefdefender.internal.pagination.PaginationList;
import com.griefdefender.permission.GDPermissionHolder;
import com.griefdefender.permission.GDPermissions;
import com.griefdefender.registry.OptionRegistryModule;
import com.griefdefender.util.CauseContextHelper;
import com.griefdefender.util.PermissionUtil;
import net.kyori.text.Component;
import net.kyori.text.TextComponent;
import net.kyori.text.adapter.bukkit.TextAdapter;
import net.kyori.text.format.TextColor;
import net.kyori.text.format.TextDecoration;
import org.bukkit.entity.Player;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
@CommandAlias("%griefdefender")
@CommandPermission(GDPermissions.COMMAND_OPTIONS_CLAIM)
public class CommandClaimOption extends ClaimOptionBase {

View File

@ -32,12 +32,8 @@ import co.aikar.commands.annotation.Description;
import co.aikar.commands.annotation.Optional;
import co.aikar.commands.annotation.Subcommand;
import co.aikar.commands.annotation.Syntax;
import com.griefdefender.GriefDefenderPlugin;
import com.griefdefender.api.Tristate;
import com.griefdefender.cache.MessageCache;
import com.griefdefender.cache.PermissionHolderCache;
import com.griefdefender.permission.GDPermissions;
import com.griefdefender.util.PermissionUtil;
import org.bukkit.OfflinePlayer;
import org.bukkit.entity.Player;

View File

@ -43,7 +43,6 @@ import java.util.regex.Pattern;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.OfflinePlayer;
import org.bukkit.World.Environment;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
@ -121,7 +120,6 @@ public class CommandHelper {
if (source instanceof Player) {
return ((Player) source);
} else {
//throw new CommandException(Text.of("You must be a player to run this command!"));
return null;
}
}
@ -131,15 +129,15 @@ public class CommandHelper {
return true;
}
if (flag.getName().equals("block-break") || flag.getName().equals("block-place") || flag.getName().equals("collide-block")) {
if (flag == Flags.BLOCK_BREAK || flag == Flags.BLOCK_PLACE || flag == Flags.COLLIDE_BLOCK) {
if (validateBlockTarget(target) ||
validateItemTarget(target)) {
return true;
}
return false;
}
if (flag.getName().equals("enter-claim") || flag.getName().equals("exit-claim") || flag.getName().equals("entity-riding") ||
flag.getName().equals("entity-damage") || flag.getName().equals("portal-use")) {
if (flag == Flags.ENTER_CLAIM || flag == Flags.EXIT_CLAIM || flag == Flags.ENTITY_RIDING ||
flag == Flags.ENTITY_DAMAGE || flag == Flags.PORTAL_USE) {
if (validateEntityTarget(target) ||
validateBlockTarget(target) ||
validateItemTarget(target)) {
@ -148,20 +146,20 @@ public class CommandHelper {
return false;
}
if (flag.getName().equals("interact-inventory")) {
if (flag == Flags.INTERACT_INVENTORY) {
// Always return true due to custom inventories
return true;
}
if (flag.getName().equals("liquid-flow") || flag.getName().equals("interact-block-primary")
|| flag.getName().equals("interact-block-secondary")) {
if (flag == Flags.LIQUID_FLOW || flag == Flags.INTERACT_BLOCK_PRIMARY
|| flag == Flags.INTERACT_BLOCK_SECONDARY) {
return validateBlockTarget(target);
}
if (flag.getName().equals("entity-chunk-spawn") || flag.getName().equals("entity-spawn") ||
flag.getName().equals("interact-entity-primary") || flag.getName().equals("interact-entity-secondary")) {
if (flag == Flags.ENTITY_CHUNK_SPAWN || flag == Flags.ENTITY_SPAWN ||
flag == Flags.INTERACT_ENTITY_PRIMARY || flag == Flags.INTERACT_ENTITY_SECONDARY) {
return validateEntityTarget(target);
}
if (flag.getName().equals("item-drop") || flag.getName().equals("item-pickup") ||
flag.getName().equals("item-spawn") || flag.getName().equals("item-use")) {
if (flag == Flags.ITEM_DROP|| flag == Flags.ITEM_PICKUP ||
flag == Flags.ITEM_SPAWN || flag == Flags.ITEM_USE) {
return validateItemTarget(target);
}
@ -200,7 +198,7 @@ public class CommandHelper {
return false;
}
public static PermissionResult addFlagPermission(CommandSender src, GDPermissionHolder subject, Claim claim, Flag claimFlag, String target, Tristate value, Set<Context> contexts) {
public static PermissionResult addFlagPermission(CommandSender src, GDPermissionHolder subject, Claim claim, Flag flag, String target, Tristate value, Set<Context> contexts) {
if (src instanceof Player) {
Component denyReason = ((GDClaim) claim).allowEdit((Player) src);
if (denyReason != null) {
@ -209,11 +207,9 @@ public class CommandHelper {
}
}
final String baseFlag = claimFlag.toString().toLowerCase();
String flagPermission = GDPermissions.FLAG_BASE + "." + baseFlag;
// special handling for commands
target = adjustTargetForTypes(target, claimFlag);
if (baseFlag.equals(Flags.COMMAND_EXECUTE.getName()) || baseFlag.equals(Flags.COMMAND_EXECUTE_PVP.getName())) {
target = adjustTargetForTypes(target, flag);
if (flag == Flags.COMMAND_EXECUTE || flag == Flags.COMMAND_EXECUTE_PVP) {
target = handleCommandFlag(src, target);
if (target == null) {
// failed
@ -227,9 +223,7 @@ public class CommandHelper {
}
String[] parts = target.split(":");
if (parts.length > 1 && parts[1].equalsIgnoreCase("any")) {
target = baseFlag + "." + parts[0];
} else {
if (parts.length <= 1 || !parts[1].equalsIgnoreCase("any")) {
// check for meta
parts = target.split("\\.");
String targetFlag = parts[0];
@ -239,13 +233,13 @@ public class CommandHelper {
} catch (NumberFormatException e) {
final Component message = GriefDefenderPlugin.getInstance().messageData.getMessage(MessageStorage.PERMISSION_CLAIM_MANAGE, ImmutableMap.of(
"meta", parts[1],
"flag", baseFlag));
"flag", flag.getName().toLowerCase()));
GriefDefenderPlugin.sendMessage(src, message);
return new GDPermissionResult(ResultTypes.TARGET_NOT_VALID);
}
}
addFlagContexts(contexts, claimFlag, targetFlag);
if (!targetFlag.startsWith("#") && !CommandHelper.validateFlagTarget(claimFlag, targetFlag)) {
addFlagContexts(contexts, flag, targetFlag);
if (!targetFlag.startsWith("#") && !CommandHelper.validateFlagTarget(flag, targetFlag)) {
//TODO
/*final Text message = GriefDefenderPlugin.getInstance().messageData.permissionClaimManage
.apply(ImmutableMap.of(
@ -260,25 +254,14 @@ public class CommandHelper {
}
}
return applyFlagPermission(src, subject, claim, flagPermission, target, value, contexts, null, false);
return applyFlagPermission(src, subject, claim, flag, target, value, contexts, null, false);
}
public static PermissionResult applyFlagPermission(CommandSender src, GDPermissionHolder subject, Claim claim, String flagPermission, String target, Tristate value, Set<Context> contexts, MenuType flagType) {
return applyFlagPermission(src, subject, claim, flagPermission, target, value, contexts, flagType, false);
public static PermissionResult applyFlagPermission(CommandSender src, GDPermissionHolder subject, Claim claim, Flag flag, String target, Tristate value, Set<Context> contexts, MenuType flagType) {
return applyFlagPermission(src, subject, claim, flag, target, value, contexts, flagType, false);
}
public static PermissionResult applyFlagPermission(CommandSender src, GDPermissionHolder subject, Claim claim, String flagPermission, String target, Tristate value, Set<Context> contexts, MenuType flagType, boolean clicked) {
// Check if player can manage flag
if (src instanceof Player) {
final String basePermission = flagPermission.replace(GDPermissions.FLAG_BASE + ".", "");
Tristate result = Tristate.fromBoolean(src.hasPermission(GDPermissions.USER_CLAIM_FLAGS + "." + basePermission));
if (result != Tristate.TRUE) {
GriefDefenderPlugin.sendMessage(src, MessageCache.getInstance().PERMISSION_FLAG_USE);
return new GDPermissionResult(ResultTypes.NO_PERMISSION);
}
}
public static PermissionResult applyFlagPermission(CommandSender src, GDPermissionHolder subject, Claim claim, Flag flag, String target, Tristate value, Set<Context> contexts, MenuType flagType, boolean clicked) {
boolean hasDefaultContext = false;
boolean hasOverrideContext = false;
Component reason = null;
@ -339,8 +322,18 @@ public class CommandHelper {
}
}
// Check if player can manage flag with contexts
if (src instanceof Player) {
final GDPermissionUser sourceUser = PermissionHolderCache.getInstance().getOrCreateUser(((Player) src));
final Tristate result = PermissionUtil.getInstance().getPermissionValue(sourceUser, GDPermissions.USER_CLAIM_FLAGS + "." + flag.getName().toLowerCase(), contexts);
if (result != Tristate.TRUE) {
GriefDefenderPlugin.sendMessage(src, MessageCache.getInstance().PERMISSION_FLAG_USE);
return new GDPermissionResult(ResultTypes.NO_PERMISSION);
}
}
if (subject == GriefDefenderPlugin.DEFAULT_HOLDER) {
PermissionUtil.getInstance().setPermissionValue(GriefDefenderPlugin.DEFAULT_HOLDER, flagPermission, value, contexts);
PermissionUtil.getInstance().setPermissionValue(GriefDefenderPlugin.DEFAULT_HOLDER, flag, value, contexts);
if (!clicked && src instanceof Player) {
TextAdapter.sendComponent(src, TextComponent.builder("")
.append(TextComponent.builder("\n[").append(MessageCache.getInstance().FLAG_UI_RETURN_FLAGS.color(TextColor.AQUA)).append("]\n")
@ -348,14 +341,14 @@ public class CommandHelper {
.append(MessageStorage.MESSAGE_DATA.getMessage(MessageStorage.FLAG_SET_PERMISSION_TARGET,
ImmutableMap.of(
"type", flagTypeText,
"permission", flagPermission.replace(GDPermissions.FLAG_BASE + ".", ""),
"permission", flag.getPermission(),
"contexts", getFriendlyContextString(claim, contexts),
"value", getClickableText(src, (GDClaim) claim, subject, contexts, flagPermission, value, flagType).color(TextColor.LIGHT_PURPLE),
"value", getClickableText(src, (GDClaim) claim, subject, contexts, flag, value, flagType).color(TextColor.LIGHT_PURPLE),
"target", "ALL")))
.build());
}
} else {
PermissionUtil.getInstance().setPermissionValue(subject, flagPermission, value, contexts);
PermissionUtil.getInstance().setPermissionValue(subject, flag, value, contexts);
if (!clicked && src instanceof Player) {
TextAdapter.sendComponent(src, TextComponent.builder("")
.append(TextComponent.builder("")
@ -366,9 +359,9 @@ public class CommandHelper {
.append(MessageStorage.MESSAGE_DATA.getMessage(MessageStorage.FLAG_SET_PERMISSION_TARGET,
ImmutableMap.of(
"type", flagTypeText,
"permission", flagPermission.replace(GDPermissions.FLAG_BASE + ".", ""),
"permission", flag.getPermission(),
"contexts", getFriendlyContextString(claim, contexts),
"value", getClickableText(src, (GDClaim) claim, subject, contexts, flagPermission, value, flagType).color(TextColor.LIGHT_PURPLE),
"value", getClickableText(src, (GDClaim) claim, subject, contexts, flag, value, flagType).color(TextColor.LIGHT_PURPLE),
"target", subject.getFriendlyName())))
.build());
}
@ -471,7 +464,7 @@ public class CommandHelper {
return color;
}
public static Consumer<CommandSender> createFlagConsumer(CommandSender src, GDClaim claim, Subject subject, Set<Context> contexts, String flagPermission, Tristate flagValue, MenuType flagType) {
public static Consumer<CommandSender> createFlagConsumer(CommandSender src, GDClaim claim, Subject subject, Set<Context> contexts, Flag flag, Tristate flagValue, MenuType flagType) {
return consumer -> {
Tristate newValue = Tristate.UNDEFINED;
if (flagValue == Tristate.TRUE) {
@ -488,16 +481,16 @@ public class CommandHelper {
} else if (flagType == MenuType.CLAIM) {
flagTypeText = TextComponent.of("CLAIM", TextColor.GOLD);
}
String target = flagPermission.replace(GDPermissions.FLAG_BASE + ".", "");
Set<Context> newContexts = new HashSet<>(contexts);
PermissionUtil.getInstance().setPermissionValue(GriefDefenderPlugin.DEFAULT_HOLDER, flagPermission, newValue, newContexts);
PermissionUtil.getInstance().setPermissionValue(GriefDefenderPlugin.DEFAULT_HOLDER, flag, newValue, newContexts);
TextAdapter.sendComponent(src, TextComponent.builder("")
.append("Set ", TextColor.GREEN)
.append(flagTypeText)
.append(" permission ")
.append(target, TextColor.AQUA)
.append(flag.getName().toLowerCase(), TextColor.AQUA)
.append("\n to ", TextColor.GREEN)
.append(getClickableText(src, (GDClaim) claim, subject, newContexts, flagPermission, newValue, flagType).color(TextColor.LIGHT_PURPLE))
.append(getClickableText(src, (GDClaim) claim, subject, newContexts, flag, newValue, flagType).color(TextColor.LIGHT_PURPLE))
.append(" for ", TextColor.GREEN)
.append(subject.getFriendlyName(), TextColor.GOLD).build());
};
@ -568,10 +561,6 @@ public class CommandHelper {
}
}
//PaginationService paginationService = Sponge.getServiceManager().provide(PaginationService.class).get();
//PaginationList.Builder paginationBuilder = paginationService.builder()
// .title(Text.of(TextColors.RED,"Claim list")).padding(Text.of(TextStyles.STRIKETHROUGH, "-")).contents(claimsTextList);
//paginationBuilder.sendTo(src);
PaginationList.Builder builder = PaginationList.builder().title(MessageCache.getInstance().CLAIMLIST_UI_TITLE.color(TextColor.RED)).padding(TextComponent.builder(" ").decoration(TextDecoration.STRIKETHROUGH, true).build()).contents(claimsTextList);
builder.sendTo(src);
}
@ -847,9 +836,9 @@ public class CommandHelper {
};
}
public static Consumer<CommandSender> createFlagConsumer(CommandSender src, GDPermissionHolder subject, String subjectName, Set<Context> contexts, GDClaim claim, String flagPermission, Tristate flagValue, String source) {
public static Consumer<CommandSender> createFlagConsumer(CommandSender src, GDPermissionHolder subject, String subjectName, Set<Context> contexts, GDClaim claim, Flag flag, Tristate flagValue, String source) {
return consumer -> {
String target = flagPermission.replace(GDPermissions.FLAG_BASE + ".", "");
String target = flag.getName().toLowerCase();
if (target.isEmpty()) {
target = "any";
}
@ -860,22 +849,22 @@ public class CommandHelper {
newValue = Tristate.TRUE;
}
CommandHelper.applyFlagPermission(src, subject, claim, flagPermission, target, newValue, null, MenuType.GROUP);
CommandHelper.applyFlagPermission(src, subject, claim, flag, target, newValue, null, MenuType.GROUP);
};
}
public static Component getClickableText(CommandSender src, GDClaim claim, Subject subject, Set<Context> contexts, String flagPermission, Tristate flagValue, MenuType type) {
public static Component getClickableText(CommandSender src, GDClaim claim, Subject subject, Set<Context> contexts, Flag flag, Tristate flagValue, MenuType type) {
TextComponent.Builder textBuilder = TextComponent.builder(flagValue.toString().toLowerCase())
.hoverEvent(HoverEvent.showText(TextComponent.builder("")
.append(MessageStorage.MESSAGE_DATA.getMessage(MessageStorage.CLAIMLIST_UI_CLICK_TOGGLE_VALUE,
ImmutableMap.of("type", type.name().toLowerCase())))
.append("\n")
.append(UIHelper.getPermissionMenuTypeHoverText(type)).build()))
.clickEvent(ClickEvent.runCommand(GDCallbackHolder.getInstance().createCallbackRunCommand(createFlagConsumer(src, claim, subject, contexts, flagPermission, flagValue, type))));
.clickEvent(ClickEvent.runCommand(GDCallbackHolder.getInstance().createCallbackRunCommand(createFlagConsumer(src, claim, subject, contexts, flag, flagValue, type))));
return textBuilder.build();
}
public static Component getClickableText(CommandSender src, GDPermissionHolder subject, String subjectName, Set<Context> contexts, GDClaim claim, String flagPermission, Tristate flagValue, String source, MenuType type) {
public static Component getClickableText(CommandSender src, GDPermissionHolder subject, String subjectName, Set<Context> contexts, GDClaim claim, Flag flag, Tristate flagValue, String source, MenuType type) {
Component onClickText = MessageStorage.MESSAGE_DATA.getMessage(MessageStorage.CLAIMLIST_UI_CLICK_TOGGLE_VALUE,
ImmutableMap.of("type", "flag"));
boolean hasPermission = true;
@ -897,7 +886,7 @@ public class CommandHelper {
.append("\n")
.append(UIHelper.getPermissionMenuTypeHoverText(type)).build()));
if (hasPermission) {
textBuilder.clickEvent(ClickEvent.runCommand(GDCallbackHolder.getInstance().createCallbackRunCommand(createFlagConsumer(src, subject, subjectName, contexts, claim, flagPermission, flagValue, source))));
textBuilder.clickEvent(ClickEvent.runCommand(GDCallbackHolder.getInstance().createCallbackRunCommand(createFlagConsumer(src, subject, subjectName, contexts, claim, flag, flagValue, source))));
}
return textBuilder.build();
}

View File

@ -204,12 +204,17 @@ public class MessageStorage {
public static final String FLAG_UI_CLICK_TOGGLE = "flag-ui-click-toggle";
public static final String FLAG_UI_INHERIT_PARENT = "flag-ui-inherit-parent";
public static final String FLAG_UI_OVERRIDE_PERMISSION = "flag-ui-override-permission";
public static final String OPTION_APPLY_PLAYER_GAMEMODE = "option-apply-player-gamemode";
public static final String OPTION_APPLY_PLAYER_WALK_SPEED = "option-apply-player-walk-speed";
public static final String OPTION_APPLY_PLAYER_WEATHER = "option-apply-player-weather";
public static final String OPTION_APPLY_SPAWN_LIMIT = "option-apply-spawn-limit";
public static final String OPTION_INVALID_CONTEXT = "option-invalid-context";
public static final String OPTION_INVALID_TARGET = "option-invalid-target";
public static final String OPTION_INVALID_VALUE = "option-invalid-value";
public static final String OPTION_NOT_FOUND = "option-not-found";
public static final String OPTION_NOT_SET = "option-not-set";
public static final String OPTION_OVERRIDE_NOT_SUPPORTED = "option-override-not-supported";
public static final String OPTION_REQUIRES_CONTEXTS = "option-requires-contexts";
public static final String OPTION_RESET_SUCCESS = "option-reset-success";
public static final String OPTION_SET_TARGET = "option-set-target";
public static final String OPTION_UI_CLICK_TOGGLE = "option-ui-click-toggle";
@ -263,6 +268,7 @@ public class MessageStorage {
public static final String PLAYERINFO_UI_WORLD = "playerinfo-ui-world";
public static final String PLUGIN_COMMAND_NOT_FOUND = "plugin-command-not-found";
public static final String PLUGIN_NOT_FOUND = "plugin-not-found";
public static final String PVP_IN_COMBAT_NOT_ALLOWED = "pvp-in-combat-not-allowed";
public static final String REGISTRY_BLOCK_NOT_FOUND = "registry-type-not-found";
public static final String REGISTRY_ENTITY_NOT_FOUND = "registry-entity-not-found";
public static final String REGISTRY_ITEM_NOT_FOUND = "registry-item-not-found";

View File

@ -104,6 +104,9 @@ public class DefaultPermissionCategory extends ConfigCategory {
this.defaultUserOptions.put(Options.PLAYER_WALK_SPEED.getName(), "-1");
this.defaultUserOptions.put(Options.PLAYER_WEATHER.getName(), "undefined");
this.defaultUserOptions.put(Options.PVP.getName(), "undefined");
this.defaultUserOptions.put(Options.PVP_COMBAT_COMMAND.getName(), "false");
this.defaultUserOptions.put(Options.PVP_COMBAT_TELEPORT.getName(), "false");
this.defaultUserOptions.put(Options.PVP_COMBAT_TIMEOUT.getName(), "15");
this.defaultBasicOptions.put(Options.MIN_SIZE_X.getName(), "5");
this.defaultBasicOptions.put(Options.MIN_SIZE_Y.getName(), "5");

View File

@ -1,35 +0,0 @@
/*
* This file is part of GriefDefender, licensed under the MIT License (MIT).
*
* Copyright (c) bloodmc
* Copyright (c) contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package com.griefdefender.configuration.category;
import ninja.leaping.configurate.objectmapping.Setting;
import ninja.leaping.configurate.objectmapping.serialize.ConfigSerializable;
@ConfigSerializable
public class GeneralCategory extends ConfigCategory {
@Setting(value = "max-claim-inspection-distance", comment = "The max claim inspection block distance. (Default: 100)")
public int maxClaimInspectionDistance = 100;
}

View File

@ -40,7 +40,7 @@ public class WeatherTypeSerializer implements TypeSerializer<WeatherType> {
case "clear" :
return WeatherTypes.CLEAR;
case "rain" :
return WeatherTypes.RAIN;
return WeatherTypes.DOWNFALL;
default :
return WeatherTypes.UNDEFINED;
}

View File

@ -27,9 +27,7 @@ package com.griefdefender.configuration.type;
import com.griefdefender.configuration.category.BanCategory;
import com.griefdefender.configuration.category.BlacklistCategory;
import com.griefdefender.configuration.category.ClaimCategory;
import com.griefdefender.configuration.category.GeneralCategory;
import com.griefdefender.configuration.category.OptionCategory;
import com.griefdefender.configuration.category.PvpCategory;
import com.griefdefender.configuration.category.TownCategory;
import com.griefdefender.configuration.category.VisualCategory;
@ -57,12 +55,6 @@ public class ConfigBase {
@Setting
public OptionCategory options = new OptionCategory();
@Setting
public GeneralCategory general = new GeneralCategory();
@Setting
public PvpCategory pvp = new PvpCategory();
@Setting
public TownCategory town = new TownCategory();

View File

@ -40,7 +40,6 @@ import com.griefdefender.api.permission.flag.Flags;
import com.griefdefender.api.permission.option.Options;
import com.griefdefender.cache.EventResultCache;
import com.griefdefender.cache.MessageCache;
import com.griefdefender.cache.PermissionHolderCache;
import com.griefdefender.claim.GDClaim;
import com.griefdefender.claim.GDClaimManager;
import com.griefdefender.configuration.GriefDefenderConfig;
@ -192,7 +191,7 @@ public class BlockEventHandler implements Listener {
final Location faceLocation = BlockUtil.getInstance().getBlockRelative(location, face);
final GDClaim targetClaim = this.storage.getClaimAt(faceLocation);
final ItemStack activeItem = user != null && user.getOnlinePlayer() != null ? NMSUtil.getInstance().getActiveItem(user.getOnlinePlayer()) : null;
final Tristate result = GDPermissionManager.getInstance().getFinalPermission(event, location, targetClaim, GDPermissions.INTERACT_BLOCK_SECONDARY, activeItem, event.getBlock(), user, TrustTypes.BUILDER, true);
final Tristate result = GDPermissionManager.getInstance().getFinalPermission(event, location, targetClaim, Flags.INTERACT_BLOCK_SECONDARY, activeItem, event.getBlock(), user, TrustTypes.BUILDER, true);
if (result == Tristate.FALSE) {
event.setCancelled(true);
} else {
@ -215,7 +214,7 @@ public class BlockEventHandler implements Listener {
return;
}
final Tristate result = GDPermissionManager.getInstance().getFinalPermission(event, location, targetClaim, GDPermissions.BLOCK_GROW, null, event.getBlock(), (GDPermissionUser) null, TrustTypes.BUILDER, false);
final Tristate result = GDPermissionManager.getInstance().getFinalPermission(event, location, targetClaim, Flags.BLOCK_GROW, null, event.getBlock(), (GDPermissionUser) null, TrustTypes.BUILDER, false);
if (result == Tristate.FALSE) {
event.setCancelled(true);
return;
@ -237,7 +236,7 @@ public class BlockEventHandler implements Listener {
continue;
}
final Tristate result = GDPermissionManager.getInstance().getFinalPermission(event, location, targetClaim, GDPermissions.BLOCK_GROW, null, blockstate, event.getPlayer(), TrustTypes.BUILDER, true);
final Tristate result = GDPermissionManager.getInstance().getFinalPermission(event, location, targetClaim, Flags.BLOCK_GROW, null, blockstate, event.getPlayer(), TrustTypes.BUILDER, true);
if (result == Tristate.FALSE) {
event.setCancelled(true);
return;
@ -266,7 +265,7 @@ public class BlockEventHandler implements Listener {
}
if (fromBlock.isLiquid()) {
final Tristate result = GDPermissionManager.getInstance().getFinalPermission(event, location, targetClaim, GDPermissions.LIQUID_FLOW, fromBlock, toBlock, user, TrustTypes.BUILDER, true);
final Tristate result = GDPermissionManager.getInstance().getFinalPermission(event, location, targetClaim, Flags.LIQUID_FLOW, fromBlock, toBlock, user, TrustTypes.BUILDER, true);
if (result == Tristate.FALSE) {
event.setCancelled(true);
return;
@ -278,7 +277,7 @@ public class BlockEventHandler implements Listener {
private boolean handleBlockBreak(BlockEvent event, Location location, GDClaim claim, Object source, Object target, GDPermissionUser user, boolean sendDenyMessage) {
// check overrides
final Tristate result = GDPermissionManager.getInstance().getFinalPermission(event, location, claim, GDPermissions.BLOCK_BREAK, source, target, user, TrustTypes.BUILDER, true);
final Tristate result = GDPermissionManager.getInstance().getFinalPermission(event, location, claim, Flags.BLOCK_BREAK, source, target, user, TrustTypes.BUILDER, true);
if (result == Tristate.FALSE) {
if (sendDenyMessage && user != null) {
final Component message = GriefDefenderPlugin.getInstance().messageData.getMessage(MessageStorage.PERMISSION_BUILD,
@ -330,7 +329,7 @@ public class BlockEventHandler implements Listener {
GDClaim targetClaim = this.storage.getClaimAt(location);
// check overrides
final Tristate result = GDPermissionManager.getInstance().getFinalPermission(event, location, targetClaim, GDPermissions.LEAF_DECAY, event.getBlock().getWorld(), event.getBlock(), (GDPermissionUser) null);
final Tristate result = GDPermissionManager.getInstance().getFinalPermission(event, location, targetClaim, Flags.LEAF_DECAY, event.getBlock().getWorld(), event.getBlock(), (GDPermissionUser) null);
if (result == Tristate.FALSE) {
event.setCancelled(true);
}
@ -425,7 +424,7 @@ public class BlockEventHandler implements Listener {
for (Block block : event.blockList()) {
final Location location = block.getLocation();
targetClaim = GriefDefenderPlugin.getInstance().dataStore.getClaimAt(location, targetClaim);
Tristate result = GDPermissionManager.getInstance().getFinalPermission(event, location, targetClaim, GDPermissions.EXPLOSION_BLOCK, source, location.getBlock(), user, true);
Tristate result = GDPermissionManager.getInstance().getFinalPermission(event, location, targetClaim, Flags.EXPLOSION_BLOCK, source, location.getBlock(), user, true);
if (result == Tristate.FALSE) {
// Avoid lagging server from large explosions.
if (event.blockList().size() > 100) {
@ -472,7 +471,7 @@ public class BlockEventHandler implements Listener {
}
// check overrides
final Tristate result = GDPermissionManager.getInstance().getFinalPermission(event, location, targetClaim, GDPermissions.BLOCK_BREAK, player, event.getBlock(), player, TrustTypes.BUILDER, true);
final Tristate result = GDPermissionManager.getInstance().getFinalPermission(event, location, targetClaim, Flags.BLOCK_BREAK, player, event.getBlock(), player, TrustTypes.BUILDER, true);
if (result == Tristate.FALSE) {
if (player != null) {
Component message = GDPermissionManager.getInstance().getEventMessage();
@ -535,7 +534,7 @@ public class BlockEventHandler implements Listener {
if (GDFlags.BLOCK_PLACE) {
// check overrides
final Tristate result = GDPermissionManager.getInstance().getFinalPermission(event, location, targetClaim, GDPermissions.BLOCK_PLACE, player, block, player, TrustTypes.BUILDER, true);
final Tristate result = GDPermissionManager.getInstance().getFinalPermission(event, location, targetClaim, Flags.BLOCK_PLACE, player, block, player, TrustTypes.BUILDER, true);
if (result == Tristate.FALSE) {
event.setCancelled(true);
GDTimings.BLOCK_PLACE_EVENT.stopTiming();

View File

@ -25,24 +25,21 @@
package com.griefdefender.listener;
import com.google.common.collect.ImmutableMap;
import com.google.common.reflect.TypeToken;
import com.griefdefender.GDPlayerData;
import com.griefdefender.GDTimings;
import com.griefdefender.GriefDefenderPlugin;
import com.griefdefender.api.Tristate;
import com.griefdefender.api.claim.TrustTypes;
import com.griefdefender.api.permission.Context;
import com.griefdefender.api.permission.ContextKeys;
import com.griefdefender.api.permission.flag.Flags;
import com.griefdefender.api.permission.option.Options;
import com.griefdefender.claim.GDClaim;
import com.griefdefender.configuration.MessageStorage;
import com.griefdefender.event.GDCauseStackManager;
import com.griefdefender.permission.GDPermissionManager;
import com.griefdefender.permission.GDPermissions;
import com.griefdefender.permission.flag.GDFlags;
import com.griefdefender.storage.BaseStorage;
import com.griefdefender.util.PaginationUtil;
import net.kyori.text.Component;
import net.kyori.text.adapter.bukkit.TextAdapter;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.command.PluginCommand;
@ -127,29 +124,72 @@ public class CommandEventHandler implements Listener {
GDTimings.PLAYER_COMMAND_EVENT.stopTiming();
return;
}
String commandTarget = pluginId + ":" + command;
// first check the args
String argument = "";
for (String arg : args) {
if (arg.isEmpty()) {
continue;
}
commandTarget += "." + arg;
final int combatTimeRemaining = playerData.getPvpCombatTimeRemaining();
final boolean inPvpCombat = combatTimeRemaining > 0;
final boolean pvpCombatCommand = GDPermissionManager.getInstance().getInternalOptionValue(TypeToken.of(Boolean.class), player, Options.PVP_COMBAT_COMMAND);
if (!pvpCombatCommand && inPvpCombat) {
final Component denyMessage = GriefDefenderPlugin.getInstance().messageData.getMessage(MessageStorage.PVP_IN_COMBAT_NOT_ALLOWED,
ImmutableMap.of(
"time-remaining", combatTimeRemaining));
GriefDefenderPlugin.sendMessage(player, denyMessage);
event.setCancelled(true);
GDTimings.PLAYER_COMMAND_EVENT.stopTiming();
return;
}
final Context context = new Context(ContextKeys.TARGET, commandTarget);
if (GDFlags.COMMAND_EXECUTE && !commandExecuteSourceBlacklisted && !GriefDefenderPlugin.isTargetIdBlacklisted(Flags.COMMAND_EXECUTE.getName(), commandTarget, player.getWorld().getUID())) {
final Tristate result = GDPermissionManager.getInstance().getFinalPermission(event, player.getLocation(), claim, GDPermissions.COMMAND_EXECUTE, player, commandTarget, player, TrustTypes.ACCESSOR, true);
String commandBaseTarget = pluginId + ":" + command;
String commandTargetWithArgs = commandBaseTarget;
// first check the args
for (String arg : args) {
if (!arg.isEmpty()) {
commandTargetWithArgs = commandTargetWithArgs + "." + arg;
}
}
boolean commandExecuteTargetBlacklisted = false;
if (GriefDefenderPlugin.isTargetIdBlacklisted(Flags.COMMAND_EXECUTE.getName(), commandBaseTarget, player.getWorld().getUID())) {
commandExecuteTargetBlacklisted = true;
} else if (GriefDefenderPlugin.isTargetIdBlacklisted(Flags.COMMAND_EXECUTE.getName(), commandTargetWithArgs, player.getWorld().getUID())) {
commandExecuteTargetBlacklisted = true;
}
if (GDFlags.COMMAND_EXECUTE && !inPvpCombat && !commandExecuteSourceBlacklisted && !commandExecuteTargetBlacklisted) {
// First check base command
Tristate result = GDPermissionManager.getInstance().getFinalPermission(event, player.getLocation(), claim, Flags.COMMAND_EXECUTE, player, commandBaseTarget, player, true);
if (result != Tristate.FALSE) {
// check with args
result = GDPermissionManager.getInstance().getFinalPermission(event, player.getLocation(), claim, Flags.COMMAND_EXECUTE, player, commandTargetWithArgs, player, true);
}
if (result == Tristate.FALSE) {
final Component denyMessage = GriefDefenderPlugin.getInstance().messageData.getMessage(MessageStorage.COMMAND_BLOCKED,
ImmutableMap.of(
"command", command,
"player", claim.getOwnerName()));
TextAdapter.sendComponent(player, denyMessage);
GriefDefenderPlugin.sendMessage(player, denyMessage);
event.setCancelled(true);
GDTimings.PLAYER_COMMAND_EVENT.stopTiming();
return;
}
GDTimings.PLAYER_COMMAND_EVENT.stopTiming();
return;
}
if (GDFlags.COMMAND_EXECUTE_PVP && inPvpCombat && !commandExecuteSourceBlacklisted && !commandExecuteTargetBlacklisted) {
// First check base command
Tristate result = GDPermissionManager.getInstance().getFinalPermission(event, player.getLocation(), claim, Flags.COMMAND_EXECUTE_PVP, player, commandBaseTarget, player, true);
if (result != Tristate.FALSE) {
// check with args
result = GDPermissionManager.getInstance().getFinalPermission(event, player.getLocation(), claim, Flags.COMMAND_EXECUTE_PVP, player, commandTargetWithArgs, player, true);
}
if (result == Tristate.FALSE) {
final Component denyMessage = GriefDefenderPlugin.getInstance().messageData.getMessage(MessageStorage.COMMAND_BLOCKED,
ImmutableMap.of(
"command", command,
"player", claim.getOwnerName()));
GriefDefenderPlugin.sendMessage(player, denyMessage);
event.setCancelled(true);
}
}
GDTimings.PLAYER_COMMAND_EVENT.stopTiming();
}

View File

@ -36,10 +36,10 @@ import org.bukkit.event.block.BlockBurnEvent;
import com.griefdefender.GriefDefenderPlugin;
import com.griefdefender.api.Tristate;
import com.griefdefender.api.claim.TrustTypes;
import com.griefdefender.api.permission.flag.Flags;
import com.griefdefender.claim.GDClaim;
import com.griefdefender.permission.GDPermissionManager;
import com.griefdefender.permission.GDPermissionUser;
import com.griefdefender.permission.GDPermissions;
import com.griefdefender.permission.flag.GDFlags;
import com.griefdefender.storage.BaseStorage;
import com.griefdefender.util.CauseContextHelper;
@ -78,7 +78,7 @@ public class CommonBlockEventHandler {
Location location = toBlock.getLocation();
GDClaim targetClaim = this.storage.getClaimAt(location);
final Tristate result = GDPermissionManager.getInstance().getFinalPermission(event, location, targetClaim, GDPermissions.BLOCK_SPREAD, fromBlock, toBlock, user, TrustTypes.BUILDER, true);
final Tristate result = GDPermissionManager.getInstance().getFinalPermission(event, location, targetClaim, Flags.BLOCK_SPREAD, fromBlock, toBlock, user, TrustTypes.BUILDER, true);
if (result == Tristate.FALSE) {
((Cancellable) event).setCancelled(true);
}
@ -113,7 +113,7 @@ public class CommonBlockEventHandler {
Location location = toBlock.getLocation();
GDClaim targetClaim = this.storage.getClaimAt(location);
final Tristate result = GDPermissionManager.getInstance().getFinalPermission(event, location, targetClaim, GDPermissions.BLOCK_MODIFY, source, toBlock, user, TrustTypes.BUILDER, true);
final Tristate result = GDPermissionManager.getInstance().getFinalPermission(event, location, targetClaim, Flags.BLOCK_MODIFY, source, toBlock, user, TrustTypes.BUILDER, true);
if (result == Tristate.FALSE) {
((Cancellable) event).setCancelled(true);
}
@ -142,7 +142,7 @@ public class CommonBlockEventHandler {
GDClaim targetClaim = this.storage.getClaimAt(location);
final Tristate result = GDPermissionManager.getInstance().getFinalPermission(event, location, targetClaim, GDPermissions.BLOCK_PLACE, source, block, player, TrustTypes.BUILDER, true);
final Tristate result = GDPermissionManager.getInstance().getFinalPermission(event, location, targetClaim, Flags.BLOCK_PLACE, source, block, player, TrustTypes.BUILDER, true);
if (result == Tristate.FALSE) {
((Cancellable) event).setCancelled(true);
}
@ -170,7 +170,7 @@ public class CommonBlockEventHandler {
GDClaim targetClaim = this.storage.getClaimAt(location);
final Tristate result = GDPermissionManager.getInstance().getFinalPermission(event, location, targetClaim, GDPermissions.BLOCK_BREAK, source, block, player, TrustTypes.BUILDER, true);
final Tristate result = GDPermissionManager.getInstance().getFinalPermission(event, location, targetClaim, Flags.BLOCK_BREAK, source, block, player, TrustTypes.BUILDER, true);
if (result == Tristate.FALSE) {
((Cancellable) event).setCancelled(true);
}

View File

@ -25,7 +25,14 @@
package com.griefdefender.listener;
import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.bukkit.Bukkit;
import org.bukkit.GameMode;
import org.bukkit.Location;
import org.bukkit.Material;
@ -49,21 +56,31 @@ import com.griefdefender.api.ChatTypes;
import com.griefdefender.api.GriefDefender;
import com.griefdefender.api.Tristate;
import com.griefdefender.api.claim.TrustTypes;
import com.griefdefender.api.permission.Context;
import com.griefdefender.api.permission.flag.Flags;
import com.griefdefender.api.permission.option.Options;
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.api.permission.option.type.WeatherTypes;
import com.griefdefender.cache.MessageCache;
import com.griefdefender.cache.PermissionHolderCache;
import com.griefdefender.claim.GDClaim;
import com.griefdefender.command.CommandHelper;
import com.griefdefender.configuration.MessageStorage;
import com.griefdefender.event.GDBorderClaimEvent;
import com.griefdefender.internal.registry.ItemTypeRegistryModule;
import com.griefdefender.internal.util.BlockUtil;
import com.griefdefender.internal.util.NMSUtil;
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.OptionContexts;
import com.griefdefender.storage.BaseStorage;
import com.griefdefender.util.PermissionUtil;
import com.griefdefender.util.PlayerUtil;
import net.kyori.text.Component;
import net.kyori.text.TextComponent;
import net.kyori.text.adapter.bukkit.TextAdapter;
@ -129,7 +146,7 @@ public class CommonEntityEventHandler {
if (GDFlags.ENTER_CLAIM && !enterBlacklisted && user != null && user.getInternalPlayerData().lastClaim != null) {
final GDClaim lastClaim = (GDClaim) user.getInternalPlayerData().lastClaim.get();
if (lastClaim != null && lastClaim != fromClaim) {
if (GDPermissionManager.getInstance().getFinalPermission(event, toLocation, toClaim, GDPermissions.ENTER_CLAIM, targetEntity, targetEntity, player, TrustTypes.ACCESSOR, false) == Tristate.FALSE) {
if (GDPermissionManager.getInstance().getFinalPermission(event, toLocation, toClaim, Flags.ENTER_CLAIM, targetEntity, targetEntity, player, TrustTypes.ACCESSOR, true) == Tristate.FALSE) {
Location claimCorner = new Location(toLocation.getWorld(), toClaim.lesserBoundaryCorner.getX(), targetEntity.getLocation().getBlockY(), toClaim.greaterBoundaryCorner.getZ());
targetEntity.teleport(claimCorner);
}
@ -143,6 +160,7 @@ public class CommonEntityEventHandler {
GDBorderClaimEvent gpEvent = new GDBorderClaimEvent(targetEntity, fromClaim, toClaim);
if (user != null && toClaim.isUserTrusted(user, TrustTypes.ACCESSOR)) {
GriefDefender.getEventManager().post(gpEvent);
final GDPlayerData playerData = user.getInternalPlayerData();
if (gpEvent.cancelled()) {
if (targetEntity instanceof Vehicle) {
final Vehicle vehicle = (Vehicle) targetEntity;
@ -194,9 +212,18 @@ public class CommonEntityEventHandler {
}
if (toClaim.isInTown()) {
user.getInternalPlayerData().inTown = true;
playerData.inTown = true;
} else {
user.getInternalPlayerData().inTown = false;
playerData.inTown = false;
}
if (player != null) {
this.checkPlayerFlight(player, playerData, fromClaim, toClaim);
this.checkPlayerGameMode(player, playerData, fromClaim, toClaim);
this.checkPlayerGodMode(player, playerData, fromClaim, toClaim);
this.checkPlayerWalkSpeed(player, playerData, fromClaim, toClaim);
this.checkPlayerWeather(player, playerData, fromClaim, toClaim);
this.runPlayerCommands(fromClaim, user, false);
this.runPlayerCommands(toClaim, user, true);
}
}
@ -208,13 +235,13 @@ public class CommonEntityEventHandler {
boolean enterCancelled = false;
boolean exitCancelled = false;
// enter
if (GDFlags.ENTER_CLAIM && !enterBlacklisted && GDPermissionManager.getInstance().getFinalPermission(event, toLocation, toClaim, GDPermissions.ENTER_CLAIM, targetEntity, targetEntity, user) == Tristate.FALSE) {
if (GDFlags.ENTER_CLAIM && !enterBlacklisted && 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, GDPermissions.EXIT_CLAIM, targetEntity, targetEntity, user) == Tristate.FALSE) {
if (GDFlags.EXIT_CLAIM && !exitBlacklisted && GDPermissionManager.getInstance().getFinalPermission(event, fromLocation, fromClaim, Flags.EXIT_CLAIM, targetEntity, targetEntity, user, true) == Tristate.FALSE) {
exitCancelled = true;
gpEvent.cancelled(true);
}
@ -250,8 +277,9 @@ public class CommonEntityEventHandler {
}
if (user != null) {
final GDPlayerData playerData = user.getInternalPlayerData();
final boolean showGpPrefix = GriefDefenderPlugin.getGlobalConfig().getConfig().message.enterExitShowGdPrefix;
user.getInternalPlayerData().lastClaim = new WeakReference<>(toClaim);
playerData.lastClaim = new WeakReference<>(toClaim);
Component welcomeMessage = gpEvent.getEnterMessage().orElse(null);
if (welcomeMessage != null && !welcomeMessage.equals(TextComponent.empty())) {
ChatType chatType = gpEvent.getEnterMessageChatType();
@ -285,12 +313,20 @@ public class CommonEntityEventHandler {
}
if (toClaim.isInTown()) {
user.getInternalPlayerData().inTown = true;
playerData.inTown = true;
} else {
user.getInternalPlayerData().inTown = false;
playerData.inTown = false;
}
checkPlayerFlight(player, user.getInternalPlayerData(), fromClaim, toClaim);
if (player != null) {
this.checkPlayerFlight(player, playerData, fromClaim, toClaim);
this.checkPlayerGameMode(player, playerData, fromClaim, toClaim);
this.checkPlayerGodMode(player, playerData, fromClaim, toClaim);
this.checkPlayerWalkSpeed(player, playerData, fromClaim, toClaim);
this.checkPlayerWeather(player, playerData, fromClaim, toClaim);
this.runPlayerCommands(fromClaim, user, false);
this.runPlayerCommands(toClaim, user, true);
}
}
}
@ -298,6 +334,76 @@ public class CommonEntityEventHandler {
return true;
}
final static Pattern pattern = Pattern.compile("([^\\s]+)", Pattern.MULTILINE);
private void runPlayerCommands(GDClaim claim, GDPermissionUser user, boolean enter) {
final Player player = user.getOnlinePlayer();
List<String> rawCommandList = new ArrayList<>();
Set<Context> contexts = new HashSet<>();
if (player.getUniqueId().equals(claim.getOwnerUniqueId())) {
contexts.add(OptionContexts.COMMAND_RUNFOR_OWNER);
} else {
contexts.add(OptionContexts.COMMAND_RUNFOR_MEMBER);
}
contexts.add(OptionContexts.COMMAND_RUNFOR_PUBLIC);
// Check console commands
contexts.add(OptionContexts.COMMAND_RUNAS_CONSOLE);
if (enter) {
rawCommandList = GDPermissionManager.getInstance().getInternalOptionValue(new TypeToken<List<String>>() {}, user, Options.PLAYER_COMMAND_ENTER, claim, contexts);
} else {
rawCommandList = GDPermissionManager.getInstance().getInternalOptionValue(new TypeToken<List<String>>() {}, user, Options.PLAYER_COMMAND_EXIT, claim, contexts);
}
if (rawCommandList != null) {
runCommand(claim, player, rawCommandList, true);
}
// Check player commands
contexts.remove(OptionContexts.COMMAND_RUNAS_CONSOLE);
contexts.add(OptionContexts.COMMAND_RUNAS_PLAYER);
if (enter) {
rawCommandList = GDPermissionManager.getInstance().getInternalOptionValue(new TypeToken<List<String>>() {}, user, Options.PLAYER_COMMAND_ENTER, claim, contexts);
} else {
rawCommandList = GDPermissionManager.getInstance().getInternalOptionValue(new TypeToken<List<String>>() {}, user, Options.PLAYER_COMMAND_EXIT, claim, contexts);
}
if (rawCommandList != null) {
runCommand(claim, player, rawCommandList, false);
}
}
private void runCommand(GDClaim claim, Player player, List<String> rawCommandList, boolean runAsConsole) {
final List<String> commands = new ArrayList<>();
for (String command : rawCommandList) {
commands.add(this.replacePlaceHolders(claim, player, command));
}
for (String command : commands) {
final Matcher matcher = pattern.matcher(command);
if (matcher.find()) {
String baseCommand = matcher.group(0);
String args = command.replace(baseCommand + " ", "");
baseCommand = baseCommand.replace("\\", "").replace("/", "");
args = args.replace("%player%", player.getName());
if (runAsConsole) {
CommandHelper.executeCommand(Bukkit.getConsoleSender(), baseCommand, args);
} else {
CommandHelper.executeCommand(player, baseCommand, args);
}
}
}
}
private String replacePlaceHolders(GDClaim claim, Player player, String command) {
command = command
.replace("%player%", player.getName())
.replace("%owner%", claim.getOwnerFriendlyName())
.replace("%uuid%", player.getUniqueId().toString())
.replace("%world%", claim.getWorld().getName())
.replace("%server%", PermissionUtil.getInstance().getServerName())
.replace("%location%", BlockUtil.getInstance().posToString(player.getLocation()));
return command;
}
private void checkPlayerFlight(Player player, GDPlayerData playerData, GDClaim fromClaim, GDClaim toClaim) {
final GameMode gameMode = player.getGameMode();
if (gameMode == GameMode.CREATIVE || gameMode == GameMode.SPECTATOR) {
@ -305,12 +411,11 @@ public class CommonEntityEventHandler {
}
if (fromClaim == toClaim || !player.isFlying()) {
// only handle player-fly in enter/exit
return;
}
final Boolean noFly = GDPermissionManager.getInstance().getInternalOptionValue(TypeToken.of(Boolean.class), playerData.getSubject(), Options.PLAYER_DENY_FLIGHT, toClaim);
final boolean adminFly = player.hasPermission(GDPermissions.BYPASS_OPTION);
final boolean adminFly = player.hasPermission(GDPermissions.BYPASS_OPTION + "." + Options.PLAYER_DENY_FLIGHT.getName().toLowerCase());
final boolean ownerFly = toClaim.isBasicClaim() ? player.hasPermission(GDPermissions.USER_OPTION_PERK_OWNER_FLY_BASIC) : toClaim.isTown() ? player.hasPermission(GDPermissions.USER_OPTION_PERK_OWNER_FLY_TOWN) : false;
if (player.getUniqueId().equals(toClaim.getOwnerUniqueId()) && ownerFly) {
return;
@ -319,7 +424,93 @@ public class CommonEntityEventHandler {
player.setAllowFlight(false);
player.setFlying(false);
playerData.ignoreFallDamage = true;
GriefDefenderPlugin.sendMessage(player, MessageCache.getInstance().OPTION_PLAYER_DENY_FLIGHT);
GriefDefenderPlugin.sendMessage(player, MessageCache.getInstance().OPTION_APPLY_PLAYER_DENY_FLIGHT);
}
}
private void checkPlayerGodMode(Player player, GDPlayerData playerData, GDClaim fromClaim, GDClaim toClaim) {
final GameMode gameMode = player.getGameMode();
if (gameMode == GameMode.CREATIVE || gameMode == GameMode.SPECTATOR || !player.isInvulnerable()) {
return;
}
if (fromClaim == toClaim) {
return;
}
final Boolean noGodMode = GDPermissionManager.getInstance().getInternalOptionValue(TypeToken.of(Boolean.class), playerData.getSubject(), Options.PLAYER_DENY_GODMODE, toClaim);
final boolean bypassOption = player.hasPermission(GDPermissions.BYPASS_OPTION + "." + Options.PLAYER_DENY_GODMODE.getName().toLowerCase());
if (!bypassOption && noGodMode) {
player.setInvulnerable(false);
GriefDefenderPlugin.sendMessage(player, MessageCache.getInstance().OPTION_APPLY_PLAYER_DENY_GODMODE);
}
}
private void checkPlayerGameMode(Player player, GDPlayerData playerData, GDClaim fromClaim, GDClaim toClaim) {
if (fromClaim == toClaim) {
return;
}
final GameMode currentGameMode = player.getGameMode();
final GameModeType gameModeType = GDPermissionManager.getInstance().getInternalOptionValue(TypeToken.of(GameModeType.class), playerData.getSubject(), Options.PLAYER_GAMEMODE, toClaim);
final boolean bypassOption = player.hasPermission(GDPermissions.BYPASS_OPTION + "." + Options.PLAYER_GAMEMODE.getName().toLowerCase());
if (!bypassOption && gameModeType != null && gameModeType != GameModeTypes.UNDEFINED) {
final GameMode newGameMode = PlayerUtil.GAMEMODE_MAP.get(gameModeType);
if (currentGameMode != newGameMode) {
player.setGameMode(newGameMode);
final Component message = GriefDefenderPlugin.getInstance().messageData.getMessage(MessageStorage.OPTION_APPLY_PLAYER_GAMEMODE,
ImmutableMap.of(
"gamemode", gameModeType.getName()));
GriefDefenderPlugin.sendMessage(player, message);
}
}
}
private void checkPlayerWalkSpeed(Player player, GDPlayerData playerData, GDClaim fromClaim, GDClaim toClaim) {
if (fromClaim == toClaim) {
return;
}
final float currentWalkSpeed = player.getWalkSpeed();
final double walkSpeed = GDPermissionManager.getInstance().getInternalOptionValue(TypeToken.of(Double.class), playerData.getSubject(), Options.PLAYER_WALK_SPEED, toClaim);
final boolean bypassOption = player.hasPermission(GDPermissions.BYPASS_OPTION + "." + Options.PLAYER_WALK_SPEED.getName().toLowerCase());
if (!bypassOption && walkSpeed > 0) {
if (currentWalkSpeed != ((float) walkSpeed)) {
player.setWalkSpeed((float) walkSpeed);
final Component message = GriefDefenderPlugin.getInstance().messageData.getMessage(MessageStorage.OPTION_APPLY_PLAYER_WALK_SPEED,
ImmutableMap.of(
"speed", walkSpeed));
GriefDefenderPlugin.sendMessage(player, message);
}
}
}
private void checkPlayerWeather(Player player, GDPlayerData playerData, GDClaim fromClaim, GDClaim toClaim) {
if (fromClaim == toClaim) {
return;
}
final WeatherType weatherType = GDPermissionManager.getInstance().getInternalOptionValue(TypeToken.of(WeatherType.class), playerData.getSubject(), Options.PLAYER_WEATHER, toClaim);
if (weatherType != null && weatherType != WeatherTypes.UNDEFINED) {
final org.bukkit.WeatherType currentWeather = player.getPlayerWeather();
player.setPlayerWeather(PlayerUtil.WEATHERTYPE_MAP.get(weatherType));
final org.bukkit.WeatherType newWeather = player.getPlayerWeather();
if (currentWeather != newWeather) {
final Component message = GriefDefenderPlugin.getInstance().messageData.getMessage(MessageStorage.OPTION_APPLY_PLAYER_WEATHER,
ImmutableMap.of(
"weather", weatherType.getName()));
GriefDefenderPlugin.sendMessage(player, message);
}
} else {
final org.bukkit.WeatherType currentWeather = player.getPlayerWeather();
player.resetPlayerWeather();
final org.bukkit.WeatherType newWeather = player.getPlayerWeather();
if (currentWeather != newWeather) {
final Component message = GriefDefenderPlugin.getInstance().messageData.getMessage(MessageStorage.OPTION_APPLY_PLAYER_WEATHER,
ImmutableMap.of(
"weather", weatherType.getName()));
GriefDefenderPlugin.sendMessage(player, message);
}
}
}

View File

@ -34,6 +34,7 @@ import com.griefdefender.api.claim.Claim;
import com.griefdefender.api.claim.TrustType;
import com.griefdefender.api.claim.TrustTypes;
import com.griefdefender.api.permission.Context;
import com.griefdefender.api.permission.flag.Flag;
import com.griefdefender.api.permission.flag.Flags;
import com.griefdefender.api.permission.option.Options;
import com.griefdefender.cache.MessageCache;
@ -46,7 +47,6 @@ import com.griefdefender.internal.tracking.entity.GDEntity;
import com.griefdefender.internal.util.NMSUtil;
import com.griefdefender.permission.GDPermissionManager;
import com.griefdefender.permission.GDPermissionUser;
import com.griefdefender.permission.GDPermissions;
import com.griefdefender.permission.flag.GDFlags;
import com.griefdefender.storage.BaseStorage;
import com.griefdefender.util.CauseContextHelper;
@ -157,7 +157,7 @@ public class EntityEventHandler implements Listener {
return;
}
}
final Tristate result = GDPermissionManager.getInstance().getFinalPermission(event, location, targetClaim, GDPermissions.BLOCK_BREAK, event.getEntity(), event.getBlock(), user, TrustTypes.BUILDER, true);
final Tristate result = GDPermissionManager.getInstance().getFinalPermission(event, location, targetClaim, Flags.BLOCK_BREAK, event.getEntity(), event.getBlock(), user, TrustTypes.BUILDER, true);
if (result == Tristate.FALSE) {
event.setCancelled(true);
return;
@ -196,10 +196,10 @@ public class EntityEventHandler implements Listener {
// Use any location for permission check
final Vector3i pos = claim.getLesserBoundaryCorner();
Location targetLocation = new Location(location.getWorld(), pos.getX(), pos.getY(), pos.getZ());
Tristate blockResult = GDPermissionManager.getInstance().getFinalPermission(event, location, claim, GDPermissions.EXPLOSION_BLOCK, event.getEntity(), targetLocation, user, true);
Tristate blockResult = GDPermissionManager.getInstance().getFinalPermission(event, location, claim, Flags.EXPLOSION_BLOCK, event.getEntity(), targetLocation, user, true);
if (blockResult == Tristate.FALSE) {
// Check explosion entity
if (GDPermissionManager.getInstance().getFinalPermission(event, location, claim, GDPermissions.EXPLOSION_ENTITY, event.getEntity(), targetLocation, user, true) == Tristate.FALSE) {
if (GDPermissionManager.getInstance().getFinalPermission(event, location, claim, Flags.EXPLOSION_ENTITY, event.getEntity(), targetLocation, user, true) == Tristate.FALSE) {
event.setCancelled(true);
break;
}
@ -241,7 +241,7 @@ public class EntityEventHandler implements Listener {
for (Block block : event.blockList()) {
final Location location = block.getLocation();
targetClaim = GriefDefenderPlugin.getInstance().dataStore.getClaimAt(location, targetClaim);
final Tristate result = GDPermissionManager.getInstance().getFinalPermission(event, location, targetClaim, GDPermissions.EXPLOSION_BLOCK, source, location.getBlock(), user, true);
final Tristate result = GDPermissionManager.getInstance().getFinalPermission(event, location, targetClaim, Flags.EXPLOSION_BLOCK, source, location.getBlock(), user, true);
if (result == Tristate.FALSE) {
// Avoid lagging server from large explosions.
if (event.blockList().size() > 100) {
@ -382,7 +382,7 @@ public class EntityEventHandler implements Listener {
}
}
String permission = GDPermissions.ENTITY_DAMAGE;
Flag flag = Flags.ENTITY_DAMAGE;
ProjectileSource projectileSource = null;
UUID owner = source instanceof Player ? ((Player) source).getUniqueId() : null;
if (owner == null && source instanceof Tameable) {
@ -392,7 +392,7 @@ public class EntityEventHandler implements Listener {
if (projectileSource != null && projectileSource instanceof OfflinePlayer) {
owner = ((OfflinePlayer) projectileSource).getUniqueId();
}
permission = GDPermissions.PROJECTILE_IMPACT_ENTITY;
flag = Flags.PROJECTILE_IMPACT_ENTITY;
} else if (source instanceof DamageCause) {
if (targetEntity instanceof Player) {
owner = ((Player) targetEntity).getUniqueId();
@ -416,7 +416,7 @@ public class EntityEventHandler implements Listener {
}
if (source instanceof Creeper || source instanceof TNTPrimed || (damageCause != null && damageCause == DamageCause.ENTITY_EXPLOSION)) {
final Tristate result = GDPermissionManager.getInstance().getFinalPermission(event, targetEntity.getLocation(), claim, GDPermissions.EXPLOSION_ENTITY, source, targetEntity, user, true);
final Tristate result = GDPermissionManager.getInstance().getFinalPermission(event, targetEntity.getLocation(), claim, Flags.EXPLOSION_ENTITY, source, targetEntity, user, true);
if (result == Tristate.FALSE) {
return true;
}
@ -448,7 +448,7 @@ public class EntityEventHandler implements Listener {
}
final TrustType trustType = TrustTypes.BUILDER;
if (GDPermissionManager.getInstance().getFinalPermission(event, targetEntity.getLocation(), claim, permission, source, targetEntity, user, trustType, true) == Tristate.FALSE) {
if (GDPermissionManager.getInstance().getFinalPermission(event, targetEntity.getLocation(), claim, flag, source, targetEntity, user, trustType, true) == Tristate.FALSE) {
if (source != null && source instanceof Player) {
final Player player = (Player) source;
CommonEntityEventHandler.getInstance().sendInteractEntityDenyMessage(NMSUtil.getInstance().getActiveItem(player), targetEntity, claim, player);
@ -469,14 +469,14 @@ public class EntityEventHandler implements Listener {
return false;
}
if (GDPermissionManager.getInstance().getFinalPermission(event, targetEntity.getLocation(), claim, permission, source, targetEntity, user, trustType, true) == Tristate.FALSE) {
if (GDPermissionManager.getInstance().getFinalPermission(event, targetEntity.getLocation(), claim, flag, source, targetEntity, user, trustType, true) == Tristate.FALSE) {
return true;
}
return false;
}
if (GDPermissionManager.getInstance().getFinalPermission(event, targetEntity.getLocation(), claim, permission, source, targetEntity, user, trustType, true) == Tristate.FALSE) {
if (GDPermissionManager.getInstance().getFinalPermission(event, targetEntity.getLocation(), claim, flag, source, targetEntity, user, trustType, true) == Tristate.FALSE) {
return true;
}
@ -486,17 +486,31 @@ public class EntityEventHandler implements Listener {
private boolean getPvpProtectResult(Event event, GDClaim claim, GDPermissionUser source, GDPermissionUser target) {
final Player sourcePlayer = source.getOnlinePlayer();
final Player targetPlayer = target.getOnlinePlayer();
final boolean sourceInCombat = source.getInternalPlayerData().inPvpCombat(claim.getWorld());
final boolean targetInCombat = target.getInternalPlayerData().inPvpCombat(claim.getWorld());
if (sourceInCombat && targetInCombat) {
final boolean sourceInCombat = source.getInternalPlayerData().inPvpCombat();
final boolean targetInCombat = target.getInternalPlayerData().inPvpCombat();
// Always check if source or target is in combat and if so allow PvP
// This prevents a player from moving to another claim where PvP is disabled
if (sourceInCombat && targetInCombat && (source.getInternalPlayerData().lastPvpTimestamp == target.getInternalPlayerData().lastPvpTimestamp)) {
source.getInternalPlayerData().lastPvpTimestamp = Instant.now();
target.getInternalPlayerData().lastPvpTimestamp = Instant.now();
return false;
}
// Check target claim
if (!claim.isPvpEnabled()) {
GriefDefenderPlugin.sendMessage(sourcePlayer, MessageCache.getInstance().PVP_CLAIM_NOT_ALLOWED);
return true;
}
// Check source claim
final GDClaim sourceClaim = GriefDefenderPlugin.getInstance().dataStore.getClaimAtPlayer(source.getInternalPlayerData(), sourcePlayer.getLocation());
if (!sourceClaim.isPvpEnabled()) {
GriefDefenderPlugin.sendMessage(sourcePlayer, MessageCache.getInstance().PVP_CLAIM_NOT_ALLOWED);
return true;
}
// Check flags
Tristate sourceResult = GDPermissionManager.getInstance().getFinalPermission(event, targetPlayer.getLocation(), claim, GDPermissions.ENTITY_DAMAGE, sourcePlayer, targetPlayer, sourcePlayer, true);
Tristate targetResult = GDPermissionManager.getInstance().getFinalPermission(event, sourcePlayer.getLocation(), claim, GDPermissions.ENTITY_DAMAGE, targetPlayer, sourcePlayer, targetPlayer, true);
Tristate sourceResult = GDPermissionManager.getInstance().getFinalPermission(event, targetPlayer.getLocation(), claim, Flags.ENTITY_DAMAGE, sourcePlayer, targetPlayer, sourcePlayer, true);
Tristate targetResult = GDPermissionManager.getInstance().getFinalPermission(event, sourcePlayer.getLocation(), claim, Flags.ENTITY_DAMAGE, targetPlayer, sourcePlayer, targetPlayer, true);
if (sourceResult == Tristate.FALSE) {
GriefDefenderPlugin.sendMessage(sourcePlayer, MessageCache.getInstance().PVP_SOURCE_NOT_ALLOWED);
return true;
@ -524,14 +538,10 @@ public class EntityEventHandler implements Listener {
return true;
}
final GDClaim sourceClaim = GriefDefenderPlugin.getInstance().dataStore.getClaimAtPlayer(source.getInternalPlayerData(), sourcePlayer.getLocation());
if (!sourceClaim.isPvpEnabled()) {
GriefDefenderPlugin.sendMessage(sourcePlayer, MessageCache.getInstance().PVP_CLAIM_NOT_ALLOWED);
return true;
}
source.getInternalPlayerData().lastPvpTimestamp = Instant.now();
target.getInternalPlayerData().lastPvpTimestamp = Instant.now();
return !claim.isPvpEnabled();
final Instant now = Instant.now();
source.getInternalPlayerData().lastPvpTimestamp = now;
target.getInternalPlayerData().lastPvpTimestamp = now;
return false;
}
@EventHandler(priority = EventPriority.LOWEST)
@ -617,7 +627,7 @@ public class EntityEventHandler implements Listener {
}
final GDClaim targetClaim = GriefDefenderPlugin.getInstance().dataStore.getClaimAt(entity.getLocation());
String permission = GDPermissions.ENTITY_SPAWN;
Flag flag = Flags.ENTITY_SPAWN;
if (entity instanceof Item) {
if (user == null) {
@ -632,10 +642,10 @@ public class EntityEventHandler implements Listener {
GDTimings.ENTITY_SPAWN_EVENT.stopTiming();
return;
}
permission = GDPermissions.ITEM_SPAWN;
flag = Flags.ITEM_SPAWN;
}
if (GDPermissionManager.getInstance().getFinalPermission(event, entity.getLocation(), targetClaim, permission, source, entity, user, TrustTypes.ACCESSOR, true) == Tristate.FALSE) {
if (GDPermissionManager.getInstance().getFinalPermission(event, entity.getLocation(), targetClaim, flag, source, entity, user, TrustTypes.ACCESSOR, true) == Tristate.FALSE) {
((Cancellable) event).setCancelled(true);
}
@ -668,7 +678,7 @@ public class EntityEventHandler implements Listener {
final Location location = event.getVehicle().getLocation();
final GDClaim targetClaim = GriefDefenderPlugin.getInstance().dataStore.getClaimAt(location);
if (GDPermissionManager.getInstance().getFinalPermission(event, location, targetClaim, GDPermissions.ENTITY_RIDING, source, event.getVehicle(), player, TrustTypes.ACCESSOR, true) == Tristate.FALSE) {
if (GDPermissionManager.getInstance().getFinalPermission(event, location, targetClaim, Flags.ENTITY_RIDING, source, event.getVehicle(), player, TrustTypes.ACCESSOR, true) == Tristate.FALSE) {
if (player != null) {
PlayerUtil.getInstance().sendInteractEntityDenyMessage(targetClaim, player, null, event.getVehicle());
}

View File

@ -30,9 +30,6 @@ import com.google.common.reflect.TypeToken;
import com.griefdefender.GDPlayerData;
import com.griefdefender.GDTimings;
import com.griefdefender.GriefDefenderPlugin;
import com.griefdefender.api.ChatType;
import com.griefdefender.api.ChatTypes;
import com.griefdefender.api.GriefDefender;
import com.griefdefender.api.Tristate;
import com.griefdefender.api.claim.Claim;
import com.griefdefender.api.claim.ClaimBlockSystem;
@ -43,6 +40,7 @@ import com.griefdefender.api.claim.ClaimTypes;
import com.griefdefender.api.claim.ShovelTypes;
import com.griefdefender.api.claim.TrustType;
import com.griefdefender.api.claim.TrustTypes;
import com.griefdefender.api.permission.flag.Flag;
import com.griefdefender.api.permission.flag.Flags;
import com.griefdefender.api.permission.option.Options;
import com.griefdefender.api.permission.option.type.CreateModeTypes;
@ -52,7 +50,6 @@ import com.griefdefender.claim.GDClaim;
import com.griefdefender.claim.GDClaimManager;
import com.griefdefender.command.CommandHelper;
import com.griefdefender.configuration.MessageStorage;
import com.griefdefender.event.GDBorderClaimEvent;
import com.griefdefender.event.GDCauseStackManager;
import com.griefdefender.internal.provider.WorldEditProvider;
import com.griefdefender.internal.provider.WorldGuardProvider;
@ -81,7 +78,6 @@ import net.kyori.text.format.TextColor;
import org.bukkit.Bukkit;
import org.bukkit.Chunk;
import org.bukkit.GameMode;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.World;
@ -121,12 +117,9 @@ import org.bukkit.event.player.PlayerQuitEvent;
import org.bukkit.event.player.PlayerRespawnEvent;
import org.bukkit.event.player.PlayerTeleportEvent;
import org.bukkit.event.player.PlayerTeleportEvent.TeleportCause;
import org.bukkit.inventory.EquipmentSlot;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.InventoryHolder;
import org.bukkit.inventory.ItemStack;
import java.lang.ref.WeakReference;
import java.time.Instant;
import java.util.HashSet;
import java.util.Map;
@ -326,7 +319,7 @@ public class PlayerEventHandler implements Listener {
final Location location = event.getItemDrop().getLocation();
final GDClaim targetClaim = GriefDefenderPlugin.getInstance().dataStore.getClaimAt(location);
if (GDPermissionManager.getInstance().getFinalPermission(event, location, targetClaim, GDPermissions.ITEM_DROP, player, event.getItemDrop(), player, TrustTypes.ACCESSOR, true) == Tristate.FALSE) {
if (GDPermissionManager.getInstance().getFinalPermission(event, location, targetClaim, Flags.ITEM_DROP, player, event.getItemDrop(), player, TrustTypes.ACCESSOR, true) == Tristate.FALSE) {
event.setCancelled(true);
}
}
@ -354,7 +347,7 @@ public class PlayerEventHandler implements Listener {
final Location location = event.getItem().getLocation();
final GDClaim targetClaim = GriefDefenderPlugin.getInstance().dataStore.getClaimAt(location);
if (GDPermissionManager.getInstance().getFinalPermission(event, location, targetClaim, GDPermissions.ITEM_PICKUP, player, event.getItem(), player, TrustTypes.ACCESSOR, true) == Tristate.FALSE) {
if (GDPermissionManager.getInstance().getFinalPermission(event, location, targetClaim, Flags.ITEM_PICKUP, player, event.getItem(), player, TrustTypes.ACCESSOR, true) == Tristate.FALSE) {
event.setCancelled(true);
}
}
@ -382,7 +375,7 @@ public class PlayerEventHandler implements Listener {
GDTimings.PLAYER_INTERACT_INVENTORY_OPEN_EVENT.stopTiming();
return;
}
final Tristate result = GDPermissionManager.getInstance().getFinalPermission(event, location, claim, GDPermissions.INVENTORY_OPEN, player, target, user, TrustTypes.CONTAINER, true);
final Tristate result = GDPermissionManager.getInstance().getFinalPermission(event, location, claim, Flags.INTERACT_INVENTORY, player, target, user, TrustTypes.CONTAINER, true);
if (result == Tristate.FALSE) {
final Component message = GriefDefenderPlugin.getInstance().messageData.getMessage(MessageStorage.PERMISSION_INVENTORY_OPEN,
ImmutableMap.of(
@ -416,7 +409,7 @@ public class PlayerEventHandler implements Listener {
}
final GDPermissionUser user = PermissionHolderCache.getInstance().getOrCreateUser(player.getUniqueId());
final Tristate result = GDPermissionManager.getInstance().getFinalPermission(event, location, claim, GDPermissions.INVENTORY_CLICK, source, target, user, TrustTypes.CONTAINER, true);
final Tristate result = GDPermissionManager.getInstance().getFinalPermission(event, location, claim, Flags.INTERACT_INVENTORY_CLICK, source, target, user, TrustTypes.CONTAINER, true);
if (result == Tristate.FALSE) {
final Component message = GriefDefenderPlugin.getInstance().messageData.getMessage(MessageStorage.PERMISSION_INTERACT_ITEM,
ImmutableMap.of(
@ -445,7 +438,7 @@ public class PlayerEventHandler implements Listener {
GDPlayerData playerData = this.dataStore.getOrCreatePlayerData(location.getWorld(), player.getUniqueId());
GDClaim claim = this.dataStore.getClaimAtPlayer(playerData, location);
final Tristate result = GDPermissionManager.getInstance().getFinalPermission(event, location, claim, GDPermissions.ITEM_USE, player, itemInUse, player, TrustTypes.ACCESSOR, true);
final Tristate result = GDPermissionManager.getInstance().getFinalPermission(event, location, claim, Flags.ITEM_USE, player, itemInUse, player, TrustTypes.ACCESSOR, true);
if (result == Tristate.FALSE) {
final Component message = GriefDefenderPlugin.getInstance().messageData.getMessage(MessageStorage.PERMISSION_ITEM_USE,
ImmutableMap.of("item", ItemTypeRegistryModule.getInstance().getNMSKey(itemInUse)));
@ -488,12 +481,12 @@ public class PlayerEventHandler implements Listener {
final Location location = clickedBlock == null ? event.getPlayer().getLocation() : clickedBlock.getLocation();
final GDClaim claim = this.dataStore.getClaimAt(location);
final String ITEM_PERMISSION = primaryEvent ? GDPermissions.INTERACT_ITEM_PRIMARY : GDPermissions.INTERACT_ITEM_SECONDARY;
if ((itemPrimaryBlacklisted && ITEM_PERMISSION.equals(GDPermissions.INTERACT_ITEM_PRIMARY)) || (itemSecondaryBlacklisted && ITEM_PERMISSION.equals(GDPermissions.INTERACT_ITEM_SECONDARY))) {
final Flag flag = primaryEvent ? Flags.INTERACT_ITEM_PRIMARY : Flags.INTERACT_ITEM_SECONDARY;
if ((itemPrimaryBlacklisted && flag == Flags.INTERACT_ITEM_PRIMARY) || (itemSecondaryBlacklisted && flag == Flags.INTERACT_ITEM_SECONDARY)) {
return;
}
if (GDPermissionManager.getInstance().getFinalPermission(event, location, claim, ITEM_PERMISSION, player, itemInHand, player, TrustTypes.ACCESSOR, true) == Tristate.FALSE) {
if (GDPermissionManager.getInstance().getFinalPermission(event, location, claim, flag, player, itemInHand, player, TrustTypes.ACCESSOR, true) == Tristate.FALSE) {
Component message = GriefDefenderPlugin.getInstance().messageData.getMessage(MessageStorage.PERMISSION_INTERACT_ITEM,
ImmutableMap.of(
"player", claim.getOwnerName(),
@ -547,7 +540,7 @@ public class PlayerEventHandler implements Listener {
}
final GDClaim claim = this.dataStore.getClaimAt(location);
if (GDPermissionManager.getInstance().getFinalPermission(event, location, claim, GDPermissions.INTERACT_ITEM_SECONDARY, player, activeItem, player, TrustTypes.ACCESSOR, true) == Tristate.FALSE) {
if (GDPermissionManager.getInstance().getFinalPermission(event, location, claim, Flags.INTERACT_ITEM_SECONDARY, player, activeItem, player, TrustTypes.ACCESSOR, true) == Tristate.FALSE) {
Component message = GriefDefenderPlugin.getInstance().messageData.getMessage(MessageStorage.PERMISSION_INTERACT_ITEM,
ImmutableMap.of(
"player", claim.getOwnerName(),
@ -568,9 +561,9 @@ public class PlayerEventHandler implements Listener {
GDTimings.PLAYER_INTERACT_ENTITY_SECONDARY_EVENT.startTiming();
final GDClaim claim = this.dataStore.getClaimAt(location);
Tristate result = GDPermissionManager.getInstance().getFinalPermission(event, location, claim, GDPermissions.INTERACT_ENTITY_SECONDARY, source, targetEntity, player, TrustTypes.ACCESSOR, true);
Tristate result = GDPermissionManager.getInstance().getFinalPermission(event, location, claim, Flags.INTERACT_ENTITY_SECONDARY, source, targetEntity, player, TrustTypes.ACCESSOR, true);
if (result == Tristate.TRUE && targetEntity instanceof ArmorStand) {
result = GDPermissionManager.getInstance().getFinalPermission(event, location, claim, GDPermissions.INVENTORY_OPEN, source, targetEntity, player, TrustTypes.CONTAINER, false);
result = GDPermissionManager.getInstance().getFinalPermission(event, location, claim, Flags.INTERACT_INVENTORY, source, targetEntity, player, TrustTypes.CONTAINER, false);
}
if (result == Tristate.FALSE) {
event.setCancelled(true);
@ -606,7 +599,7 @@ public class PlayerEventHandler implements Listener {
final GDClaim claim = this.dataStore.getClaimAt(location);
final TrustType trustType = NMSUtil.getInstance().hasBlockTileEntity(location) ? TrustTypes.CONTAINER : TrustTypes.ACCESSOR;
Tristate result = GDPermissionManager.getInstance().getFinalPermission(event, location, claim, GDPermissions.INTERACT_BLOCK_SECONDARY, source, clickedBlock, player, trustType, true);
Tristate result = GDPermissionManager.getInstance().getFinalPermission(event, location, claim, Flags.INTERACT_BLOCK_SECONDARY, source, clickedBlock, player, trustType, true);
if (result == Tristate.FALSE) {
event.setCancelled(true);
GDTimings.PLAYER_INTERACT_BLOCK_SECONDARY_EVENT.stopTiming();
@ -649,13 +642,13 @@ public class PlayerEventHandler implements Listener {
GDTimings.PLAYER_INTERACT_BLOCK_PRIMARY_EVENT.startTiming();
final GDClaim claim = this.dataStore.getClaimAt(location);
final Tristate result = GDPermissionManager.getInstance().getFinalPermission(event, location, claim, GDPermissions.INTERACT_BLOCK_PRIMARY, source, clickedBlock.getState(), player, TrustTypes.BUILDER, true);
final Tristate result = GDPermissionManager.getInstance().getFinalPermission(event, location, claim, Flags.INTERACT_BLOCK_PRIMARY, source, clickedBlock.getState(), player, TrustTypes.BUILDER, true);
if (result == Tristate.FALSE) {
if (GriefDefenderPlugin.isTargetIdBlacklisted(Flags.BLOCK_BREAK.toString(), clickedBlock.getState(), player.getWorld().getUID())) {
GDTimings.PLAYER_INTERACT_BLOCK_PRIMARY_EVENT.stopTiming();
return;
}
if (GDPermissionManager.getInstance().getFinalPermission(event, location, claim, GDPermissions.BLOCK_BREAK, player, clickedBlock.getState(), player, TrustTypes.BUILDER, true) == Tristate.TRUE) {
if (GDPermissionManager.getInstance().getFinalPermission(event, location, claim, Flags.BLOCK_BREAK, player, clickedBlock.getState(), player, TrustTypes.BUILDER, true) == Tristate.TRUE) {
GDTimings.PLAYER_INTERACT_BLOCK_PRIMARY_EVENT.stopTiming();
return;
}
@ -721,11 +714,11 @@ public class PlayerEventHandler implements Listener {
trustType = TrustTypes.ACCESSOR;
}
if (GDFlags.INTERACT_BLOCK_SECONDARY && playerData != null) {
String permission = GDPermissions.INTERACT_BLOCK_SECONDARY;
Flag flag = Flags.INTERACT_BLOCK_SECONDARY;
if (event.getAction() == Action.PHYSICAL) {
permission = GDPermissions.COLLIDE_BLOCK;
flag = Flags.COLLIDE_BLOCK;
}
Tristate result = GDPermissionManager.getInstance().getFinalPermission(event, location, claim, permission, source, clickedBlock, player, trustType, true);
Tristate result = GDPermissionManager.getInstance().getFinalPermission(event, location, claim, flag, source, clickedBlock, player, trustType, true);
if (result == Tristate.FALSE) {
// if player is holding an item, check if it can be placed
if (GDFlags.BLOCK_PLACE && itemInHand != null && itemInHand.getType().isBlock()) {
@ -733,7 +726,7 @@ public class PlayerEventHandler implements Listener {
GDTimings.PLAYER_INTERACT_BLOCK_SECONDARY_EVENT.stopTiming();
return;
}
if (GDPermissionManager.getInstance().getFinalPermission(event, location, claim, GDPermissions.BLOCK_PLACE, source, itemInHand, player, TrustTypes.BUILDER, true) == Tristate.TRUE) {
if (GDPermissionManager.getInstance().getFinalPermission(event, location, claim, Flags.BLOCK_PLACE, source, itemInHand, player, TrustTypes.BUILDER, true) == Tristate.TRUE) {
GDTimings.PLAYER_INTERACT_BLOCK_SECONDARY_EVENT.stopTiming();
return;
}
@ -789,6 +782,21 @@ public class PlayerEventHandler implements Listener {
final Location destination = event.getTo();
final GDPlayerData playerData = GriefDefenderPlugin.getInstance().dataStore.getOrCreatePlayerData(player.getWorld(), player.getUniqueId());
final GDClaim sourceClaim = this.dataStore.getClaimAtPlayer(playerData, player.getLocation());
// Cancel event if player is unable to teleport during PvP combat
final boolean pvpCombatTeleport = GDPermissionManager.getInstance().getInternalOptionValue(TypeToken.of(Boolean.class), player, Options.PVP_COMBAT_TELEPORT, sourceClaim);
if (!pvpCombatTeleport) {
final int combatTimeRemaining = playerData.getPvpCombatTimeRemaining();
if (combatTimeRemaining > 0) {
final Component denyMessage = GriefDefenderPlugin.getInstance().messageData.getMessage(MessageStorage.PVP_IN_COMBAT_NOT_ALLOWED,
ImmutableMap.of(
"time-remaining", combatTimeRemaining));
GriefDefenderPlugin.sendMessage(player, denyMessage);
event.setCancelled(true);
GDTimings.ENTITY_TELEPORT_EVENT.stopTiming();
return;
}
}
// Handle BorderClaimEvent
if (!CommonEntityEventHandler.getInstance().onEntityMove(event, sourceLocation, destination, player)) {
event.setCancelled(true);
@ -800,7 +808,7 @@ public class PlayerEventHandler implements Listener {
final Component message = GriefDefenderPlugin.getInstance().messageData.getMessage(MessageStorage.PERMISSION_PORTAL_EXIT,
ImmutableMap.of(
"player", sourceClaim.getOwnerName()));
if (GDFlags.ENTITY_TELEPORT_FROM && !teleportFromBlacklisted && GDPermissionManager.getInstance().getFinalPermission(event, sourceLocation, sourceClaim, GDPermissions.ENTITY_TELEPORT_FROM, type, player, player, TrustTypes.ACCESSOR, true) == Tristate.FALSE) {
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);
}
@ -808,7 +816,7 @@ public class PlayerEventHandler implements Listener {
event.setCancelled(true);
GDTimings.ENTITY_TELEPORT_EVENT.stopTiming();
return;
} else if (GDFlags.EXIT_CLAIM && !teleportFromBlacklisted && GDPermissionManager.getInstance().getFinalPermission(event, sourceLocation, sourceClaim, GDPermissions.EXIT_CLAIM, type, player, player, TrustTypes.ACCESSOR, true) == Tristate.FALSE) {
} else if (GDFlags.EXIT_CLAIM && !teleportFromBlacklisted && GDPermissionManager.getInstance().getFinalPermission(event, sourceLocation, sourceClaim, Flags.EXIT_CLAIM, type, player, player, TrustTypes.ACCESSOR, true) == Tristate.FALSE) {
if (player != null) {
GriefDefenderPlugin.sendMessage(player, message);
}
@ -831,7 +839,7 @@ public class PlayerEventHandler implements Listener {
final Component message = GriefDefenderPlugin.getInstance().messageData.getMessage(MessageStorage.PERMISSION_PORTAL_ENTER,
ImmutableMap.of(
"player", toClaim.getOwnerName()));
if (GDFlags.ENTITY_TELEPORT_TO && !teleportToBlacklisted && GDPermissionManager.getInstance().getFinalPermission(event, destination, toClaim, GDPermissions.ENTITY_TELEPORT_TO, type, player, player, TrustTypes.ACCESSOR, true) == Tristate.FALSE) {
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);
}
@ -839,7 +847,7 @@ public class PlayerEventHandler implements Listener {
event.setCancelled(true);
GDTimings.ENTITY_TELEPORT_EVENT.stopTiming();
return;
} else if (GDFlags.ENTER_CLAIM && !teleportToBlacklisted && GDPermissionManager.getInstance().getFinalPermission(event, destination, toClaim, GDPermissions.ENTER_CLAIM, type, player, player, TrustTypes.ACCESSOR, true) == Tristate.FALSE) {
} else if (GDFlags.ENTER_CLAIM && !teleportToBlacklisted && GDPermissionManager.getInstance().getFinalPermission(event, destination, toClaim, Flags.ENTER_CLAIM, type, player, player, TrustTypes.ACCESSOR, true) == Tristate.FALSE) {
if (player != null) {
GriefDefenderPlugin.sendMessage(player, message);
}
@ -1460,7 +1468,8 @@ public class PlayerEventHandler implements Listener {
GDTimings.PLAYER_INVESTIGATE_CLAIM.startTiming();
GDClaim claim = null;
if (event.getAction() == Action.LEFT_CLICK_AIR || event.getAction() == Action.RIGHT_CLICK_AIR) {
claim = this.findNearbyClaim(player);
final int maxDistance = GDPermissionManager.getInstance().getInternalOptionValue(TypeToken.of(Integer.class), player, Options.RADIUS_INSPECT);
claim = this.findNearbyClaim(player, maxDistance);
if (player.isSneaking()) {
if (!playerData.canIgnoreClaim(claim) && !player.hasPermission(GDPermissions.VISUALIZE_CLAIMS_NEARBY)) {
GriefDefenderPlugin.sendMessage(player, MessageCache.getInstance().PERMISSION_VISUAL_CLAIMS_NEARBY);
@ -1469,7 +1478,7 @@ public class PlayerEventHandler implements Listener {
}
Location nearbyLocation = playerData.lastValidInspectLocation != null ? playerData.lastValidInspectLocation : player.getLocation();
Set<Claim> claims = BlockUtil.getInstance().getNearbyClaims(nearbyLocation);
Set<Claim> claims = BlockUtil.getInstance().getNearbyClaims(nearbyLocation, maxDistance);
int height = (int) (playerData.lastValidInspectLocation != null ? playerData.lastValidInspectLocation.getBlockY() : PlayerUtil.getInstance().getEyeHeight(player));
boolean hideBorders = this.worldEditProvider != null &&
@ -1529,8 +1538,7 @@ public class PlayerEventHandler implements Listener {
return true;
}
private GDClaim findNearbyClaim(Player player) {
int maxDistance = GriefDefenderPlugin.getInstance().maxInspectionDistance;
private GDClaim findNearbyClaim(Player player, int maxDistance) {
BlockRay blockRay = BlockRay.from(player).distanceLimit(maxDistance).build();
GDPlayerData playerData = GriefDefenderPlugin.getInstance().dataStore.getOrCreatePlayerData(player.getWorld(), player.getUniqueId());
GDClaim claim = null;

View File

@ -41,6 +41,7 @@ import com.griefdefender.internal.util.BlockUtil;
import com.griefdefender.permission.GDPermissionHolder;
import com.griefdefender.permission.GDPermissionUser;
import com.griefdefender.permission.flag.FlagContexts;
import com.griefdefender.permission.option.OptionContexts;
import com.griefdefender.storage.BaseStorage;
import com.griefdefender.util.PermissionUtil;
@ -229,20 +230,26 @@ public class GriefPreventionMigrator {
case FLAG_ENTER_COMMAND :
contexts.add(new Context(ContextKeys.FLAG, Flags.ENTER_CLAIM.getName()));
contexts.add(FlagContexts.TARGET_PLAYER);
PermissionUtil.getInstance().setOptionValue(DEFAULT_HOLDER, Options.PLAYER_COMMAND.getPermission(), param, contexts);
contexts.add(OptionContexts.COMMAND_RUNAS_CONSOLE);
contexts.add(OptionContexts.COMMAND_RUNFOR_PUBLIC);
PermissionUtil.getInstance().setOptionValue(DEFAULT_HOLDER, Options.PLAYER_COMMAND_ENTER.getPermission(), param, contexts);
break;
case FLAG_ENTER_COMMAND_OWNER :
contexts.add(new Context(ContextKeys.FLAG, Flags.ENTER_CLAIM.getName()));
contexts.add(FlagContexts.TARGET_PLAYER);
contexts.add(OptionContexts.COMMAND_RUNAS_CONSOLE);
contexts.add(OptionContexts.COMMAND_RUNFOR_OWNER);
if (claimOwner == null) {
GriefDefenderPlugin.getInstance().getLogger().info("Could not locate owner legacy claim id '" + bukkitClaimId + "'. Skipping...");
break;
}
PermissionUtil.getInstance().setOptionValue(claimOwner, Options.PLAYER_COMMAND.getPermission(), param, contexts);
PermissionUtil.getInstance().setOptionValue(claimOwner, Options.PLAYER_COMMAND_ENTER.getPermission(), param, contexts);
break;
case FLAG_ENTER_COMMAND_MEMBERS : {
contexts.add(new Context(ContextKeys.FLAG, Flags.ENTER_CLAIM.getName()));
contexts.add(FlagContexts.TARGET_PLAYER);
contexts.add(OptionContexts.COMMAND_RUNAS_CONSOLE);
contexts.add(OptionContexts.COMMAND_RUNFOR_MEMBER);
List<UUID> members = new ArrayList<>();
members.addAll(claimStorage.getConfig().getAccessors());
members.addAll(claimStorage.getConfig().getBuilders());
@ -250,18 +257,22 @@ public class GriefPreventionMigrator {
members.addAll(claimStorage.getConfig().getManagers());
for (UUID memberUniqueId : members) {
final GDPermissionUser user = PermissionHolderCache.getInstance().getOrCreateUser(memberUniqueId);
PermissionUtil.getInstance().setOptionValue(user, Options.PLAYER_COMMAND.getPermission(), param, contexts);
PermissionUtil.getInstance().setOptionValue(user, Options.PLAYER_COMMAND_ENTER.getPermission(), param, contexts);
}
break;
}
case FLAG_ENTER_PLAYER_COMMAND :
contexts.add(new Context(ContextKeys.FLAG, Flags.ENTER_CLAIM.getName()));
contexts.add(FlagContexts.TARGET_PLAYER);
PermissionUtil.getInstance().setOptionValue(DEFAULT_HOLDER, Options.PLAYER_COMMAND.getPermission(), param, contexts);
contexts.add(OptionContexts.COMMAND_RUNAS_PLAYER);
contexts.add(OptionContexts.COMMAND_RUNFOR_PUBLIC);
PermissionUtil.getInstance().setOptionValue(DEFAULT_HOLDER, Options.PLAYER_COMMAND_ENTER.getPermission(), param, contexts);
break;
case FLAG_EXIT_COMMAND_MEMBERS : {
contexts.add(new Context(ContextKeys.FLAG, Flags.EXIT_CLAIM.getName()));
contexts.add(FlagContexts.TARGET_PLAYER);
contexts.add(OptionContexts.COMMAND_RUNAS_PLAYER);
contexts.add(OptionContexts.COMMAND_RUNFOR_MEMBER);
List<UUID> members = new ArrayList<>();
members.addAll(claimStorage.getConfig().getAccessors());
members.addAll(claimStorage.getConfig().getBuilders());
@ -269,24 +280,28 @@ public class GriefPreventionMigrator {
members.addAll(claimStorage.getConfig().getManagers());
for (UUID memberUniqueId : members) {
final GDPermissionUser user = PermissionHolderCache.getInstance().getOrCreateUser(memberUniqueId);
PermissionUtil.getInstance().setOptionValue(user, Options.PLAYER_COMMAND.getPermission(), param, contexts);
PermissionUtil.getInstance().setOptionValue(user, Options.PLAYER_COMMAND_EXIT.getPermission(), param, contexts);
}
break;
}
case FLAG_EXIT_COMMAND_OWNER :
contexts.add(new Context(ContextKeys.FLAG, Flags.EXIT_CLAIM.getName()));
contexts.add(FlagContexts.TARGET_PLAYER);
contexts.add(OptionContexts.COMMAND_RUNAS_CONSOLE);
contexts.add(OptionContexts.COMMAND_RUNFOR_MEMBER);
if (claimOwner == null) {
GriefDefenderPlugin.getInstance().getLogger().info("Could not locate owner legacy claim id '" + bukkitClaimId + "'. Skipping...");
break;
}
PermissionUtil.getInstance().setOptionValue(claimOwner, Options.PLAYER_COMMAND.getPermission(), param, contexts);
PermissionUtil.getInstance().setOptionValue(claimOwner, Options.PLAYER_COMMAND_EXIT.getPermission(), param, contexts);
break;
case FLAG_EXIT_COMMAND :
case FLAG_EXIT_PLAYER_COMMAND :
contexts.add(new Context(ContextKeys.FLAG, Flags.EXIT_CLAIM.getName()));
contexts.add(FlagContexts.TARGET_PLAYER);
PermissionUtil.getInstance().setOptionValue(DEFAULT_HOLDER, Options.PLAYER_COMMAND.getPermission(), param, contexts);
contexts.add(OptionContexts.COMMAND_RUNAS_PLAYER);
contexts.add(OptionContexts.COMMAND_RUNFOR_PUBLIC);
PermissionUtil.getInstance().setOptionValue(DEFAULT_HOLDER, Options.PLAYER_COMMAND_EXIT.getPermission(), param, contexts);
break;
case FLAG_EXIT_MESSAGE :
claimStorage.getConfig().setFarewell(LegacyComponentSerializer.legacy().deserialize(param, '§'));

View File

@ -26,6 +26,7 @@ package com.griefdefender.permission;
public class ContextGroupKeys {
public static final String ALL = "#all";
public static final String AMBIENT = "#ambient";
public static final String ANIMAL = "#animal";
public static final String AQUATIC = "#aquatic";

View File

@ -30,12 +30,14 @@ import com.griefdefender.api.permission.ContextKeys;
public class ContextGroups {
// Entity groups
public static final Context SOURCE_ALL = new Context(ContextKeys.SOURCE, ContextGroupKeys.ALL);
public static final Context SOURCE_AMBIENT = new Context(ContextKeys.SOURCE, ContextGroupKeys.AMBIENT);
public static final Context SOURCE_ANIMAL = new Context(ContextKeys.SOURCE, ContextGroupKeys.ANIMAL);
public static final Context SOURCE_AQUATIC = new Context(ContextKeys.SOURCE, ContextGroupKeys.AQUATIC);
public static final Context SOURCE_MISC = new Context(ContextKeys.SOURCE, ContextGroupKeys.MISC);
public static final Context SOURCE_MONSTER = new Context(ContextKeys.SOURCE, ContextGroupKeys.MONSTER);
public static final Context SOURCE_VEHICLE = new Context(ContextKeys.SOURCE, ContextGroupKeys.VEHICLE);
public static final Context TARGET_ALL = new Context(ContextKeys.TARGET, ContextGroupKeys.ALL);
public static final Context TARGET_AMBIENT = new Context(ContextKeys.TARGET, ContextGroupKeys.AMBIENT);
public static final Context TARGET_ANIMAL = new Context(ContextKeys.TARGET, ContextGroupKeys.ANIMAL);
public static final Context TARGET_AQUATIC = new Context(ContextKeys.TARGET, ContextGroupKeys.AQUATIC);

View File

@ -46,8 +46,11 @@ import com.griefdefender.api.permission.flag.FlagData;
import com.griefdefender.api.permission.flag.FlagDefinition;
import com.griefdefender.api.permission.flag.Flags;
import com.griefdefender.api.permission.option.Option;
import com.griefdefender.api.permission.option.Options;
import com.griefdefender.api.permission.option.type.CreateModeType;
import com.griefdefender.api.permission.option.type.CreateModeTypes;
import com.griefdefender.api.permission.option.type.WeatherType;
import com.griefdefender.api.permission.option.type.WeatherTypes;
import com.griefdefender.cache.EventResultCache;
import com.griefdefender.cache.MessageCache;
import com.griefdefender.cache.PermissionHolderCache;
@ -76,7 +79,6 @@ import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.OfflinePlayer;
import org.bukkit.World;
import org.bukkit.block.Block;
import org.bukkit.block.BlockState;
import org.bukkit.block.CreatureSpawner;
@ -139,37 +141,37 @@ public class GDPermissionManager implements PermissionManager {
@Override
public Tristate getActiveFlagPermissionValue(Claim claim, Subject subject, Flag flag, Object source, Object target, Set<Context> contexts, TrustType type, boolean checkOverride) {
return getFinalPermission(null, null, contexts, claim, flag.getPermission(), source, target, (GDPermissionHolder) subject, null, checkOverride);
return getFinalPermission(null, null, contexts, claim, flag, source, target, (GDPermissionHolder) subject, null, checkOverride);
}
public Tristate getFinalPermission(Event event, Location location, Claim claim, String flagPermission, Object source, Object target, GDPermissionHolder permissionHolder) {
return getFinalPermission(event, location, claim, flagPermission, source, target, permissionHolder, null, false);
public Tristate getFinalPermission(Event event, Location location, Claim claim, Flag flag, Object source, Object target, GDPermissionHolder permissionHolder) {
return getFinalPermission(event, location, claim, flag, source, target, permissionHolder, null, false);
}
public Tristate getFinalPermission(Event event, Location location, Claim claim, String flagPermission, Object source, Object target, Player player) {
public Tristate getFinalPermission(Event event, Location location, Claim claim, Flag flag, Object source, Object target, Player player) {
final GDPermissionHolder permissionHolder = PermissionHolderCache.getInstance().getOrCreateUser(player);
return getFinalPermission(event, location, claim, flagPermission, source, target, permissionHolder, null, false);
return getFinalPermission(event, location, claim, flag, source, target, permissionHolder, null, false);
}
public Tristate getFinalPermission(Event event, Location location, Claim claim, String flagPermission, Object source, Object target, Player player, boolean checkOverride) {
public Tristate getFinalPermission(Event event, Location location, Claim claim, Flag flag, Object source, Object target, Player player, boolean checkOverride) {
final GDPermissionHolder permissionHolder = PermissionHolderCache.getInstance().getOrCreateUser(player);
return getFinalPermission(event, location, claim, flagPermission, source, target, permissionHolder, null, checkOverride);
return getFinalPermission(event, location, claim, flag, source, target, permissionHolder, null, checkOverride);
}
public Tristate getFinalPermission(Event event, Location location, Claim claim, String flagPermission, Object source, Object target, GDPermissionHolder permissionHolder, boolean checkOverride) {
return getFinalPermission(event, location, claim, flagPermission, source, target, permissionHolder, null, checkOverride);
public Tristate getFinalPermission(Event event, Location location, Claim claim, Flag flag, Object source, Object target, GDPermissionHolder permissionHolder, boolean checkOverride) {
return getFinalPermission(event, location, claim, flag, source, target, permissionHolder, null, checkOverride);
}
public Tristate getFinalPermission(Event event, Location location, Claim claim, String flagPermission, Object source, Object target, Player player, TrustType type, boolean checkOverride) {
public Tristate getFinalPermission(Event event, Location location, Claim claim, Flag flag, Object source, Object target, Player player, TrustType type, boolean checkOverride) {
final GDPermissionHolder permissionHolder = PermissionHolderCache.getInstance().getOrCreateUser(player);
return getFinalPermission(event, location, claim, flagPermission, source, target, permissionHolder, type, checkOverride);
return getFinalPermission(event, location, claim, flag, source, target, permissionHolder, type, checkOverride);
}
public Tristate getFinalPermission(Event event, Location location, Claim claim, String flagPermission, Object source, Object target, GDPermissionHolder permissionHolder, TrustType type, boolean checkOverride) {
return getFinalPermission(event, location, new HashSet<>(), claim, flagPermission, source, target, permissionHolder, type, checkOverride);
public Tristate getFinalPermission(Event event, Location location, Claim claim, Flag flag, Object source, Object target, GDPermissionHolder permissionHolder, TrustType type, boolean checkOverride) {
return getFinalPermission(event, location, new HashSet<>(), claim, flag, source, target, permissionHolder, type, checkOverride);
}
public Tristate getFinalPermission(Event event, Location location, Set<Context> contexts, Claim claim, String flagPermission, Object source, Object target, GDPermissionHolder permissionHolder, TrustType type, boolean checkOverride) {
public Tristate getFinalPermission(Event event, Location location, Set<Context> contexts, Claim claim, Flag flag, Object source, Object target, GDPermissionHolder permissionHolder, TrustType type, boolean checkOverride) {
if (claim == null) {
return Tristate.TRUE;
}
@ -218,8 +220,7 @@ public class GDPermissionManager implements PermissionManager {
contexts.add(((GDClaim) claim).getWorldContext());
this.eventContexts = contexts;
this.eventPlayerData = playerData;
String targetPermission = flagPermission;
final String targetPermission = flag.getPermission();
/* if (!targetId.isEmpty()) {
String[] parts = targetId.split(":");
String targetMod = parts[0];
@ -236,11 +237,28 @@ public class GDPermissionManager implements PermissionManager {
// targetPermission += "." + targetId + targetMeta;
}*/
targetPermission = StringUtils.replace(targetPermission, ":", ".");
// If player can ignore admin claims and is currently ignoring , allow
/*if (playerData != null && playerData.ignoreAdminClaims && playerData.canIgnoreClaim(claim)) {
return processResult(claim, targetPermission, "ignore", Tristate.TRUE, user);
}*/
if (flag == Flags.ENTITY_SPAWN) {
// Check spawn limit
final int spawnLimit = GDPermissionManager.getInstance().getInternalOptionValue(TypeToken.of(Integer.class), GriefDefenderPlugin.DEFAULT_HOLDER, Options.SPAWN_LIMIT, claim, contexts);
if (spawnLimit > -1) {
if (target instanceof Entity) {
final Entity entity = (Entity) target;
final int currentEntityCount = ((GDClaim) claim).countEntities(entity .getType());
if (currentEntityCount >= spawnLimit) {
if (user != null && user.getOnlinePlayer() != null && source == SpawnReason.ENDER_PEARL || source == SpawnReason.SPAWNER_EGG || source == SpawnReason.SPAWNER) {
final String name = entity.getType().getName() == null ? entity.getType().name().toLowerCase() : entity.getType().getName();
final GDEntityType entityType = EntityTypeRegistryModule.getInstance().getById(name).orElse(null);
final Component message = GriefDefenderPlugin.getInstance().messageData.getMessage(MessageStorage.OPTION_APPLY_SPAWN_LIMIT,
ImmutableMap.of(
"type", entityType.getName(),
"limit", spawnLimit));
GriefDefenderPlugin.sendMessage(user.getOnlinePlayer(), message);
}
return this.processResult(claim, flag.getPermission(), "spawn-limit", Tristate.FALSE, this.eventSubject);
}
}
}
}
if (user != null && playerData != null && !playerData.debugClaimPermissions && playerData.canIgnoreClaim(claim)) {
return processResult(claim, targetPermission, "ignore", Tristate.TRUE, user);
@ -668,6 +686,11 @@ public class GDPermissionManager implements PermissionManager {
}
public void addCustomEntityTypeContexts(Entity targetEntity, Set<Context> contexts, GDEntityType type, boolean isSource) {
if (isSource) {
contexts.add(ContextGroups.SOURCE_ALL);
} else {
contexts.add(ContextGroups.TARGET_ALL);
}
// check vehicle
if (targetEntity instanceof Vehicle) {
if (isSource) {
@ -827,12 +850,16 @@ public class GDPermissionManager implements PermissionManager {
if (!id.contains(":")) {
id = "minecraft:" + id;
}
final String[] parts = id.split(":");
final String modId = parts[0];
if (isSource) {
this.eventSourceId = id.toLowerCase();
contexts.add(new Context("source", this.eventSourceId));
contexts.add(new Context("source", modId + ":any"));
} else {
this.eventTargetId = id.toLowerCase();
contexts.add(new Context("target", this.eventTargetId));
contexts.add(new Context("target", modId + ":any"));
}
return contexts;
}
@ -845,6 +872,12 @@ public class GDPermissionManager implements PermissionManager {
if (!id.contains(":")) {
id = "minecraft:" + id;
}
String[] parts = id.split(":");
if (parts != null && parts.length == 3) {
if (parts[0].equals(parts[1])) {
id = parts[1] + ":" + parts[2];
}
}
if (isSource) {
this.eventSourceId = id.toLowerCase();
} else {
@ -869,13 +902,14 @@ public class GDPermissionManager implements PermissionManager {
return result;
}
/*for (Map.Entry<Set<Context>, Map<String, Boolean>> mapEntry : subject.getSubjectData().getAllPermissions().entrySet()) {
for (Map.Entry<Set<Context>, Map<String, Boolean>> mapEntry : PermissionUtil.getInstance().getPermanentPermissions((GDPermissionHolder) subject).entrySet()) {
final Set<Context> contextSet = mapEntry.getKey();
if (contextSet.contains(claim.getContext())) {
subject.getSubjectData().clearPermissions(contextSet);
continue;
for (Context context : contextSet) {
if (context.getValue().equals(subject.getIdentifier())) {
PermissionUtil.getInstance().clearPermissions((GDPermissionHolder) subject, context);
}
}
}*/
}
result.complete(new GDPermissionResult(ResultTypes.SUCCESS));
return result;
@ -900,8 +934,7 @@ public class GDPermissionManager implements PermissionManager {
return result;
}
//contexts.add(claim.getWorld().getContext());
//subject.getSubjectData().clearPermissions(contexts);
PermissionUtil.getInstance().clearPermissions((GDPermissionHolder) subject, contexts);
result.complete(new GDPermissionResult(ResultTypes.SUCCESS));
return result;
}
@ -1043,9 +1076,9 @@ public class GDPermissionManager implements PermissionManager {
// check claim
if (claim != null) {
contexts.add(claim.getContext());
String value = PermissionUtil.getInstance().getOptionValue(holder, option, contexts);
final T value = this.getOptionActualValue(type, holder, option, contexts);
if (value != null) {
return this.getOptionTypeValue(type, value);
return value;
}
contexts.remove(claim.getContext());
}
@ -1053,18 +1086,18 @@ public class GDPermissionManager implements PermissionManager {
// check claim type
if (claimType != null) {
contexts.add(claimType.getContext());
String value = PermissionUtil.getInstance().getOptionValue(holder, option, contexts);
final T value = this.getOptionActualValue(type, holder, option, contexts);
if (value != null) {
return this.getOptionTypeValue(type, value);
return value;
}
contexts.remove(claimType.getContext());
}
}
// Check only active contexts
String value = PermissionUtil.getInstance().getOptionValue(holder, option, contexts);
T value = this.getOptionActualValue(type, holder, option, contexts);
if (value != null) {
return this.getOptionTypeValue(type, value);
return value;
}
// Check type/global default context
@ -1072,9 +1105,9 @@ public class GDPermissionManager implements PermissionManager {
contexts.add(claimType.getDefaultContext());
}
contexts.add(ClaimContexts.GLOBAL_DEFAULT_CONTEXT);
value = PermissionUtil.getInstance().getOptionValue(holder, option, contexts);
value = this.getOptionActualValue(type, holder, option, contexts);
if (value != null) {
return this.getOptionTypeValue(type, value);
return value;
}
contexts.remove(ClaimContexts.GLOBAL_DEFAULT_CONTEXT);
if (claimType != null) {
@ -1089,6 +1122,21 @@ public class GDPermissionManager implements PermissionManager {
return option.getDefaultValue();
}
private <T> T getOptionActualValue(TypeToken<T> type, GDPermissionHolder holder, Option option, Set<Context> contexts) {
if (option.multiValued()) {
List<String> values = PermissionUtil.getInstance().getOptionValueList(holder, option, contexts);
if (values != null && !values.isEmpty()) {
return (T) values;
}
}
String value = PermissionUtil.getInstance().getOptionValue(holder, option, contexts);
if (value != null) {
return this.getOptionTypeValue(type, value);
}
return null;
}
private <T> T getOptionTypeValue(TypeToken<T> type, String value) {
if (type.getRawType().isAssignableFrom(Double.class)) {
return (T) Double.valueOf(value);
@ -1130,6 +1178,13 @@ public class GDPermissionManager implements PermissionManager {
if (value.equalsIgnoreCase("undefined")) {
return (T) CreateModeTypes.AREA;
}
if (value.equalsIgnoreCase("volume")) {
return (T) CreateModeTypes.VOLUME;
}
if (value.equalsIgnoreCase("area")) {
return (T) CreateModeTypes.AREA;
}
int permValue = 0;
try {
permValue = Integer.parseInt(value);
@ -1141,6 +1196,16 @@ public class GDPermissionManager implements PermissionManager {
}
return (T) (permValue == 1 ? CreateModeTypes.VOLUME : CreateModeTypes.AREA);
}
if (type.getRawType().isAssignableFrom(WeatherType.class)) {
if (value.equalsIgnoreCase("downfall")) {
return (T) WeatherTypes.DOWNFALL;
}
if (value.equalsIgnoreCase("clear")) {
return (T) WeatherTypes.CLEAR;
}
return (T) WeatherTypes.UNDEFINED;
}
if (type.getRawType().isAssignableFrom(Boolean.class)) {
return (T) Boolean.valueOf(Boolean.parseBoolean(value));
}

View File

@ -97,6 +97,8 @@ public class GDPermissions {
// flags
public static final String USER_CLAIM_FLAGS = "griefdefender.user.claim.flag";
public static final String COMMAND_FLAGS_CLAIM = "griefdefender.user.claim.command.flag.base";
public static final String COMMAND_FLAGS_CLAIM_ARG = "griefdefender.user.claim.command.flag.arg";
public static final String COMMAND_FLAGS_CLAIM_GUI = "griefdefender.user.claim.command.flag.gui";
public static final String COMMAND_FLAGS_DEBUG = "griefdefender.user.claim.command.flag.debug";
public static final String COMMAND_FLAGS_PLAYER = "griefdefender.user.claim.command.flag.player";
public static final String COMMAND_FLAGS_GROUP = "griefdefender.user.claim.command.flag.group";
@ -136,16 +138,6 @@ public class GDPermissions {
public static final String COMMAND_CLAIM_PERMISSION_GROUP = "griefdefender.admin.claim.command.permission-group";
public static final String COMMAND_CLAIM_PERMISSION_PLAYER = "griefdefender.admin.claim.command.permission-player";
public static final String COMMAND_CLAIM_SCHEMATIC = "griefdefender.admin.claim.command.schematic";
public static final String COMMAND_CLAIM_OPTIONS_GROUP_BASE = "griefdefender.admin.claim.command.option.group.base";
public static final String COMMAND_CLAIM_OPTIONS_GROUP_ADMIN = "griefdefender.admin.claim.command.option.group.admin";
public static final String COMMAND_CLAIM_OPTIONS_GROUP_BASIC = "griefdefender.admin.claim.command.option.group.basic";
public static final String COMMAND_CLAIM_OPTIONS_GROUP_SUBDIVISION = "griefdefender.admin.claim.command.option.group.subdivision";
public static final String COMMAND_CLAIM_OPTIONS_GROUP_TOWN = "griefdefender.admin.claim.command.option.group.town";
public static final String COMMAND_CLAIM_OPTIONS_PLAYER_BASE = "griefdefender.admin.claim.command.option.player.base";
public static final String COMMAND_CLAIM_OPTIONS_PLAYER_ADMIN = "griefdefender.admin.claim.command.option.player.admin";
public static final String COMMAND_CLAIM_OPTIONS_PLAYER_BASIC = "griefdefender.admin.claim.command.option.player.basic";
public static final String COMMAND_CLAIM_OPTIONS_PLAYER_SUBDIVISION = "griefdefender.admin.claim.command.option.player.subdivision";
public static final String COMMAND_CLAIM_OPTIONS_PLAYER_TOWN = "griefdefender.admin.claim.command.option.player.town";
public static final String COMMAND_IGNORE_CLAIMS = "griefdefender.admin.claim.command.ignore.base";
public static final String COMMAND_DELETE_CLAIM_BASE = "griefdefender.admin.claim.command.delete.base";
public static final String COMMAND_DELETE_CLAIMS = "griefdefender.admin.claim.command.delete-claims";
@ -195,45 +187,6 @@ public class GDPermissions {
public static final String TRUST_BUILDER = "griefdefender.trust.1.2";
public static final String TRUST_MANAGER = "griefdefender.trust.1";
// Flags
public static final String BLOCK_BREAK = "griefdefender.flag.block-break";
public static final String BLOCK_GROW = "griefdefender.flag.block-grow";
public static final String BLOCK_MODIFY = "griefdefender.flag.block-modify";
public static final String BLOCK_PLACE = "griefdefender.flag.block-place";
public static final String BLOCK_SPREAD = "griefdefender.flag.block-spread";
public static final String COLLIDE_BLOCK = "griefdefender.flag.collide-block";
public static final String COLLIDE_ENTITY = "griefdefender.flag.collide-entity";
public static final String COMMAND_EXECUTE = "griefdefender.flag.command-execute";
public static final String COMMAND_EXECUTE_PVP = "griefdefender.flag.command-execute-pvp";
public static final String ENTER_CLAIM = "griefdefender.flag.enter-claim";
public static final String ENTITY_CHUNK_SPAWN = "griefdefender.flag.entity-chunk-spawn";
public static final String ENTITY_DAMAGE = "griefdefender.flag.entity-damage";
public static final String ENTITY_RIDING = "griefdefender.flag.entity-riding";
public static final String ENTITY_SPAWN = "griefdefender.flag.entity-spawn";
public static final String ENTITY_TELEPORT_FROM = "griefdefender.flag.entity-teleport-from";
public static final String ENTITY_TELEPORT_TO = "griefdefender.flag.entity-teleport-to";
public static final String EXIT_CLAIM = "griefdefender.flag.exit-claim";
public static final String EXPLOSION_BLOCK = "griefdefender.flag.explosion-block";
public static final String EXPLOSION_ENTITY = "griefdefender.flag.explosion-entity";
public static final String FLAG_BASE = "griefdefender.flag";
public static final String INTERACT_BLOCK_PRIMARY = "griefdefender.flag.interact-block-primary";
public static final String INTERACT_BLOCK_SECONDARY = "griefdefender.flag.interact-block-secondary";
public static final String INTERACT_ENTITY_PRIMARY = "griefdefender.flag.interact-entity-primary";
public static final String INTERACT_ENTITY_SECONDARY = "griefdefender.flag.interact-entity-secondary";
public static final String INTERACT_ITEM_PRIMARY = "griefdefender.flag.interact-item-primary";
public static final String INTERACT_ITEM_SECONDARY = "griefdefender.flag.interact-item-secondary";
public static final String INVENTORY_CLICK = "griefdefender.flag.interact-inventory-click";
public static final String INVENTORY_OPEN = "griefdefender.flag.interact-inventory";
public static final String ITEM_DROP = "griefdefender.flag.item-drop";
public static final String ITEM_PICKUP = "griefdefender.flag.item-pickup";
public static final String ITEM_SPAWN = "griefdefender.flag.item-spawn";
public static final String ITEM_USE = "griefdefender.flag.item-use";
public static final String LEAF_DECAY = "griefdefender.flag.leaf-decay";
public static final String LIQUID_FLOW = "griefdefender.flag.liquid-flow";
public static final String PORTAL_USE = "griefdefender.flag.portal-use";
public static final String PROJECTILE_IMPACT_BLOCK = "griefdefender.flag.projectile-impact-block";
public static final String PROJECTILE_IMPACT_ENTITY = "griefdefender.flag.projectile-impact-entity";
public static String getTrustPermission(TrustType type) {
if (type == TrustTypes.ACCESSOR) {
return GDPermissions.TRUST_ACCESSOR;

View File

@ -26,6 +26,7 @@ package com.griefdefender.permission.option;
import com.griefdefender.GriefDefenderPlugin;
import com.griefdefender.api.Tristate;
import com.griefdefender.api.permission.Context;
import com.griefdefender.api.permission.option.Option;
import com.griefdefender.api.permission.option.type.CreateModeType;
import com.griefdefender.api.permission.option.type.CreateModeTypes;
@ -38,7 +39,9 @@ import net.kyori.text.Component;
import net.kyori.text.TextComponent;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import org.checkerframework.checker.nullness.qual.Nullable;
@ -56,18 +59,23 @@ public class GDOption<T> implements Option<T> {
private final String id;
private final String name;
private final Class<T> allowed;
private Set<String> requiredContextKeys = new HashSet<>();
private Component description;
private boolean multiValued;
private Boolean isGlobal;
private Boolean isAdmin;
GDOption(OptionBuilder<T> builder) {
this(builder.id, builder.name, builder.typeClass);
this(builder.id, builder.name, builder.description, builder.multiValued, builder.requiredContextKeys, builder.typeClass);
}
public GDOption(String id, String name, Class<T> allowed) {
public GDOption(String id, String name, Component description, boolean multiValued, Set<String> requiredContexts, Class<T> allowed) {
this.id = id;
this.name = name;
this.allowed = allowed;
this.description = description;
this.multiValued = multiValued;
this.requiredContextKeys = requiredContexts;
this.isAdmin = ADMIN_OPTIONS.contains(name);
this.isGlobal = GLOBAL_OPTIONS.contains(name);
}
@ -93,6 +101,16 @@ public class GDOption<T> implements Option<T> {
return this.isAdmin;
}
@Override
public boolean multiValued() {
return this.multiValued;
}
@Override
public Set<String> getRequiredContextKeys() {
return this.requiredContextKeys;
}
@Override
public Class<T> getAllowedType() {
return this.allowed;
@ -172,6 +190,8 @@ public class GDOption<T> implements Option<T> {
public boolean validateStringValue(String value, boolean log) {
if (value.equalsIgnoreCase("undefined")) {
return false;
} else if (this.allowed == List.class) {
return true;
} else if (this.allowed == Integer.class) {
try {
Integer.parseInt(value);
@ -229,12 +249,12 @@ public class GDOption<T> implements Option<T> {
+ ".\nAcceptable values are : adventure, creative, survival, spectator, or undefined. Skipping...");
}
} else if (this.allowed == WeatherType.class) {
if (value.equalsIgnoreCase("clear") || value.equalsIgnoreCase("rain")) {
if (value.equalsIgnoreCase("clear") || value.equalsIgnoreCase("downfall")) {
return true;
}
if (log) {
GriefDefenderPlugin.getInstance().getLogger().warning("Invalid WeatherType value '" + value + "', entered for option " + this.getName()
+ ".\nAcceptable values are : clear, rain, or undefined. Skipping...");
+ ".\nAcceptable values are : clear, downfall, or undefined. Skipping...");
}
}

View File

@ -27,12 +27,19 @@ package com.griefdefender.permission.option;
import com.griefdefender.api.permission.option.Option;
import com.griefdefender.api.permission.option.Option.Builder;
import com.griefdefender.registry.OptionRegistryModule;
import net.kyori.text.Component;
import java.util.HashSet;
import java.util.Set;
public final class OptionBuilder<T> implements Option.Builder<T> {
Class<T> typeClass;
String id;
String name;
Component description;
boolean multiValued = false;
Set<String> requiredContextKeys = new HashSet<>();
@Override
public Builder<T> type(Class<T> tClass) {
@ -52,6 +59,24 @@ public final class OptionBuilder<T> implements Option.Builder<T> {
return this;
}
@Override
public Builder<T> description(Component description) {
this.description = description;
return this;
}
@Override
public Builder<T> multiValued(boolean value) {
this.multiValued = value;
return this;
}
@Override
public Builder<T> requiredContextKeys(Set<String> keys) {
this.requiredContextKeys = keys;
return this;
}
@Override
public Option<T> build() {
final GDOption<T> key = new GDOption<>(this);
@ -64,6 +89,8 @@ public final class OptionBuilder<T> implements Option.Builder<T> {
this.typeClass = null;
this.id = null;
this.name = null;
this.multiValued = false;
this.requiredContextKeys = new HashSet<>();
return this;
}
}

View File

@ -22,14 +22,16 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package com.griefdefender.configuration.category;
package com.griefdefender.permission.option;
import ninja.leaping.configurate.objectmapping.Setting;
import ninja.leaping.configurate.objectmapping.serialize.ConfigSerializable;
import com.griefdefender.api.permission.Context;
import com.griefdefender.api.permission.ContextKeys;
@ConfigSerializable
public class PvpCategory extends ConfigCategory {
public class OptionContexts {
@Setting(value = "combat-timeout", comment = "How long combat is considered to continue after the most recent damage.")
public int combatTimeout = 15;
public static final Context COMMAND_RUNAS_CONSOLE = new Context(ContextKeys.RUN_AS, "console");
public static final Context COMMAND_RUNAS_PLAYER = new Context(ContextKeys.RUN_AS, "player");
public static final Context COMMAND_RUNFOR_MEMBER = new Context(ContextKeys.RUN_FOR, "member");
public static final Context COMMAND_RUNFOR_OWNER = new Context(ContextKeys.RUN_FOR, "owner");
public static final Context COMMAND_RUNFOR_PUBLIC = new Context(ContextKeys.RUN_FOR, "public");
}

View File

@ -42,7 +42,8 @@ import com.griefdefender.claim.GDClaim;
import com.griefdefender.permission.GDPermissionHolder;
import com.griefdefender.permission.GDPermissionResult;
import com.griefdefender.permission.GDPermissionUser;
import com.griefdefender.registry.OptionRegistryModule;
import net.kyori.text.TextComponent;
import net.luckperms.api.LuckPerms;
import net.luckperms.api.cacheddata.CachedMetaData;
import net.luckperms.api.cacheddata.CachedPermissionData;
@ -76,6 +77,7 @@ import java.util.Set;
import java.util.TreeMap;
import java.util.UUID;
import java.util.Map.Entry;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
@ -105,6 +107,8 @@ public class LuckPermsProvider implements PermissionProvider {
private final LuckPerms luckPermsApi;
private final static DefaultDataQueryOrderFunction DEFAULT_DATA_QUERY_ORDER = new DefaultDataQueryOrderFunction();
private final static PermissionResult RESULT_FAILURE = new GDPermissionResult(ResultTypes.FAILURE);
private final static PermissionResult RESULT_SUCCESS = new GDPermissionResult(ResultTypes.SUCCESS);
public LuckPermsProvider() {
this.luckPermsApi = Bukkit.getServicesManager().getRegistration(LuckPerms.class).getProvider();
@ -114,6 +118,11 @@ public class LuckPermsProvider implements PermissionProvider {
return this.luckPermsApi;
}
@Override
public String getServerName() {
return this.luckPermsApi.getServerName();
}
@Override
public boolean hasGroupSubject(String identifier) {
return this.getGroupSubject(identifier) != null;
@ -373,7 +382,6 @@ public class LuckPermsProvider implements PermissionProvider {
return new HashMap<>();
}
//final @NonNull Collection<Node> nodes = permissionHolder.resolveInheritedNodes(QueryOptions.nonContextual());
final Collection<Node> nodes = permissionHolder.data().toCollection();
Map<Set<Context>, Map<String, Boolean>> permanentPermissionMap = new TreeMap<Set<Context>, Map<String, Boolean>>(CONTEXT_COMPARATOR);
for (Node node : nodes) {
@ -718,44 +726,65 @@ public class LuckPermsProvider implements PermissionProvider {
return metaData.getMetaValue(option.getPermission());
}
public PermissionResult setOptionValue(GDPermissionHolder holder, String permission, String value, Set<Context> contexts) {
@Override
public List<String> getOptionValueList(GDPermissionHolder holder, Option option, Set<Context> contexts) {
ImmutableContextSet set = this.getLPContexts(contexts).immutableCopy();
final PermissionHolder permissionHolder = this.getLuckPermsHolder(holder);
if (permissionHolder == null) {
return null;
}
final QueryOptions query = QueryOptions.builder(QueryMode.CONTEXTUAL).option(DataQueryOrderFunction.KEY, DEFAULT_DATA_QUERY_ORDER).context(set).build();
CachedMetaData metaData = permissionHolder.getCachedData().getMetaData(query);
List<String> list = metaData.getMeta().get(option.getPermission());
if (list == null) {
return new ArrayList<>();
}
return list;
}
public PermissionResult setOptionValue(GDPermissionHolder holder, String key, String value, Set<Context> contexts) {
DataMutateResult result = null;
ImmutableContextSet set = this.getLPContexts(contexts).immutableCopy();
final PermissionHolder permissionHolder = this.getLuckPermsHolder(holder);
if (permissionHolder == null) {
return new GDPermissionResult(ResultTypes.FAILURE);
return RESULT_FAILURE;
}
// Always unset existing meta first
final Node currentNode = this.luckPermsApi.getNodeBuilderRegistry().forMeta().key(permission).context(set).build();
result = permissionHolder.data().remove(currentNode);
final Option option = OptionRegistryModule.getInstance().getById(key).orElse(null);
if (option == null) {
return RESULT_FAILURE;
}
final Node node = this.luckPermsApi.getNodeBuilderRegistry().forMeta().key(permission).value(value).context(set).build();
final Node node = MetaNode.builder().key(key).value(value).context(set).build();
if (!value.equalsIgnoreCase("undefined")) {
if (!option.multiValued()) {
this.clearMeta(permissionHolder, key, set);
}
result = permissionHolder.data().add(node);
}
if (result != null && result.wasSuccessful()) {
} else {
this.clearMeta(permissionHolder, key, set);
this.savePermissionHolder(permissionHolder);
return new GDPermissionResult(ResultTypes.SUCCESS);
return RESULT_SUCCESS;
}
return new GDPermissionResult(ResultTypes.FAILURE);
if (result != null) {
if (result.wasSuccessful()) {
this.savePermissionHolder(permissionHolder);
return new GDPermissionResult(ResultTypes.SUCCESS, TextComponent.builder().append(result.name()).build());
}
return new GDPermissionResult(ResultTypes.FAILURE, TextComponent.builder().append(result.name()).build());
}
return RESULT_FAILURE;
}
public PermissionResult setPermissionValue(GDPermissionHolder holder, Flag flag, Tristate value, Set<Context> contexts) {
final boolean result = setPermissionValue(holder, flag.getPermission(), value, contexts);
if (result) {
return new GDPermissionResult(ResultTypes.SUCCESS);
}
return new GDPermissionResult(ResultTypes.FAILURE);
}
public boolean setPermissionValue(GDPermissionHolder holder, String permission, Tristate value, Set<Context> contexts) {
public PermissionResult setPermissionValue(GDPermissionHolder holder, String permission, Tristate value, Set<Context> contexts, boolean save) {
DataMutateResult result = null;
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 false;
return RESULT_FAILURE;
}
if (value == Tristate.UNDEFINED) {
@ -766,11 +795,6 @@ public class LuckPermsProvider implements PermissionProvider {
if (result.wasSuccessful()) {
if (permissionHolder instanceof Group) {
final Group group = (Group) permissionHolder;
group.getCachedData().invalidate();
for (User user :this.luckPermsApi.getUserManager().getLoadedUsers()) {
user.getCachedData().invalidate();
}
// If a group is changed, we invalidate all cache
PermissionHolderCache.getInstance().invalidateAllPermissionCache();
} else {
@ -778,9 +802,14 @@ public class LuckPermsProvider implements PermissionProvider {
PermissionHolderCache.getInstance().getOrCreatePermissionCache(holder).invalidateAll();
}
this.savePermissionHolder(permissionHolder);
if (save) {
this.savePermissionHolder(permissionHolder);
}
return new GDPermissionResult(ResultTypes.SUCCESS, TextComponent.builder().append(result.name()).build());
}
return result.wasSuccessful();
return new GDPermissionResult(ResultTypes.FAILURE, TextComponent.builder().append(result.name()).build());
}
public void setTransientOption(GDPermissionHolder holder, String permission, String value, Set<Context> contexts) {
@ -801,7 +830,7 @@ public class LuckPermsProvider implements PermissionProvider {
return;
}
final Node node = this.luckPermsApi.getNodeBuilderRegistry().forPermission().permission(permission).value(value).context(contextSet).build();
final PermissionNode node = this.luckPermsApi.getNodeBuilderRegistry().forPermission().permission(permission).value(value).context(contextSet).build();
permissionHolder.transientData().add(node);
}
@ -821,6 +850,20 @@ public class LuckPermsProvider implements PermissionProvider {
permissionHolder.getCachedData().invalidate();
}
@Override
public CompletableFuture<Void> save(GDPermissionHolder holder) {
final PermissionHolder permissionHolder = this.getLuckPermsHolder(holder);
if (permissionHolder == null) {
return new CompletableFuture<>();
}
if (permissionHolder instanceof User) {
return this.luckPermsApi.getUserManager().saveUser((User) permissionHolder);
} else {
return this.luckPermsApi.getGroupManager().saveGroup((Group) permissionHolder);
}
}
public Set<Context> getGDContexts(ContextSet contexts) {
final Set<Context> gdContexts = new HashSet<>();
contexts.forEach(entry -> {
@ -849,6 +892,10 @@ public class LuckPermsProvider implements PermissionProvider {
return Tristate.UNDEFINED;
}
private void clearMeta(PermissionHolder holder, String metaKey, ContextSet set) {
holder.data().clear(set, NodeType.META.predicate(node -> node.getMetaKey().equals(metaKey)));
}
private static class DefaultDataQueryOrderFunction implements DataQueryOrderFunction {
@Override

View File

@ -28,6 +28,7 @@ import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.UUID;
import java.util.concurrent.CompletableFuture;
import org.checkerframework.checker.nullness.qual.Nullable;
@ -49,6 +50,13 @@ import com.griefdefender.permission.GDPermissionHolder;
*/
public interface PermissionProvider {
/**
* Get server name.
*
* @return The server name
*/
String getServerName();
/**
* Checks if the group identifier exists.
*
@ -273,6 +281,18 @@ public interface PermissionProvider {
*/
String getOptionValue(GDPermissionHolder holder, Option option, Set<Context> contexts);
/**
* Gets the current values of an option assigned to a holder.
*
* Note: This is intended to be used for options that support multiple values.
*
* @param holder The holder
* @param permission The permission to check
* @param contexts The contexts
* @return The option value list
*/
List<String> getOptionValueList(GDPermissionHolder holder, Option option, Set<Context> contexts);
/**
* Sets an option and value with contexts to a holder.
*
@ -293,7 +313,23 @@ public interface PermissionProvider {
* @param contexts The contexts
* @return The permission result
*/
PermissionResult setPermissionValue(GDPermissionHolder holder, Flag flag, Tristate value, Set<Context> contexts);
default PermissionResult setPermissionValue(GDPermissionHolder holder, Flag flag, Tristate value, Set<Context> contexts) {
return this.setPermissionValue(holder, flag, value, contexts, true);
}
/**
* Sets a permission and value with contexts to a holder.
*
* @param holder The holder
* @param flag The flag to use for permission
* @param value The value
* @param contexts The contexts
* @param save Whether a save should occur
* @return The permission result
*/
default PermissionResult setPermissionValue(GDPermissionHolder holder, Flag flag, Tristate value, Set<Context> contexts, boolean save) {
return this.setPermissionValue(holder, flag.getPermission(), value, contexts, save);
}
/**
* Sets a permission and value with contexts to a holder.
@ -304,7 +340,21 @@ public interface PermissionProvider {
* @param contexts The contexts
* @return Whether the set permission operation was successful
*/
boolean setPermissionValue(GDPermissionHolder holder, String permission, Tristate value, Set<Context> contexts);
default PermissionResult setPermissionValue(GDPermissionHolder holder, String permission, Tristate value, Set<Context> contexts) {
return this.setPermissionValue(holder, permission, value, contexts, true);
}
/**
* Sets a permission and value with contexts to a holder.
*
* @param holder The holder
* @param permission The permission
* @param value The value
* @param contexts The contexts
* @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 save);
/**
* Sets a transient option and value with contexts to a holder.
@ -334,4 +384,12 @@ public interface PermissionProvider {
* @param holder The holder
*/
void refreshCachedData(GDPermissionHolder holder);
/**
* Saves any pending permission changes to holder.
*
* @param holder The holder
* @return a future which will complete when save is done
*/
CompletableFuture<Void> save(GDPermissionHolder holder);
}

View File

@ -45,6 +45,7 @@ import org.bukkit.entity.Player;
import org.bukkit.plugin.Plugin;
import org.checkerframework.checker.nullness.qual.Nullable;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.LinkedList;
@ -219,6 +220,11 @@ public class PermissionsExProvider implements PermissionProvider {
// - Implement API
@Override
public String getServerName() {
return pex.getConfig().getServerTags().get(0);
}
@Override
public boolean hasGroupSubject(String identifier) {
return pex.getSubjects(PermissionsEx.SUBJECTS_GROUP).isRegistered(identifier).join();
@ -393,22 +399,18 @@ public class PermissionsExProvider implements PermissionProvider {
return holderToPEXSubject(holder).getOption(contextsGDToPEX(contexts), option.getPermission()).orElse(null);
}
@Override
public List<String> getOptionValueList(GDPermissionHolder holder, Option option, Set<Context> contexts) {
final List<String> valueList = new ArrayList<>();
valueList.add(holderToPEXSubject(holder).getOption(contextsGDToPEX(contexts), option.getPermission()).orElse(null));
return valueList;
}
@Override
public PermissionResult setOptionValue(GDPermissionHolder holder, String permission, String value, Set<Context> contexts) {
return convertResult(holderToPEXSubject(holder).data().update(data -> data.setOption(contextsGDToPEX(contexts), permission, value))).join();
}
@Override
public PermissionResult setPermissionValue(GDPermissionHolder holder, Flag flag, Tristate value, Set<Context> contexts) {
return convertResult(holderToPEXSubject(holder).data().update(data -> data.setPermission(contextsGDToPEX(contexts), flag.getPermission(), intFromTristate(value)))).join();
}
@Override
public boolean setPermissionValue(GDPermissionHolder holder, String permission, Tristate value, Set<Context> contexts) {
return holderToPEXSubject(holder).data().update(data -> data.setPermission(contextsGDToPEX(contexts), permission, intFromTristate(value)))
.thenApply(chg -> !chg.getNew().equals(chg.getOld())).join();
}
@Override
public void setTransientOption(GDPermissionHolder holder, String permission, String value, Set<Context> contexts) {
holderToPEXSubject(holder).transientData().update(data -> data.setOption(contextsGDToPEX(contexts), permission, value));
@ -424,5 +426,16 @@ public class PermissionsExProvider implements PermissionProvider {
holderToPEXSubject(holder).data().getCache().invalidate(holder.getIdentifier());
holderToPEXSubject(holder).transientData().getCache().invalidate(holder.getIdentifier());
}
@Override
public PermissionResult setPermissionValue(GDPermissionHolder holder, String permission, Tristate value, Set<Context> contexts, boolean save) {
return convertResult(holderToPEXSubject(holder).data().update(data -> data.setPermission(contextsGDToPEX(contexts), permission, intFromTristate(value)))).join();
}
@Override
public CompletableFuture<Void> save(GDPermissionHolder holder) {
// TODO
return new CompletableFuture<>();
}
}

View File

@ -38,9 +38,12 @@ import com.griefdefender.util.RegistryHelper;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
@SuppressWarnings("rawtypes")
public class OptionRegistryModule implements CatalogRegistryModule<Option> {
@ -111,7 +114,8 @@ public class OptionRegistryModule implements CatalogRegistryModule<Option> {
this.createKey("griefdefender:radius-inspect", "radius-inspect", Integer.class);
this.createKey("griefdefender:raid", "raid", Boolean.class);
this.createKey("griefdefender:spawn-limit", "spawn-limit", Integer.class);
this.createKey("griefdefender:player-command", "player-command", String.class);
this.createKey("griefdefender:player-command-enter", "player-command-enter", true, List.class);
this.createKey("griefdefender:player-command-exit", "player-command-exit", true, List.class);
this.createKey("griefdefender:player-deny-flight", "player-deny-flight", Boolean.class);
this.createKey("griefdefender:player-deny-godmode", "player-deny-godmode", Boolean.class);
this.createKey("griefdefender:player-deny-hunger", "player-deny-hunger", Boolean.class);
@ -120,9 +124,12 @@ public class OptionRegistryModule implements CatalogRegistryModule<Option> {
this.createKey("griefdefender:player-keep-inventory", "player-keep-inventory", Tristate.class);
this.createKey("griefdefender:player-keep-level", "player-keep-level", Tristate.class);
this.createKey("griefdefender:player-teleport-delay", "player-teleport-delay", Integer.class);
this.createKey("griefdefender:player-walk-speed", "player-walk-speed", Integer.class);
this.createKey("griefdefender:player-walk-speed", "player-walk-speed", Double.class);
this.createKey("griefdefender:player-weather", "player-weather", WeatherType.class);
this.createKey("griefdefender:pvp", "pvp", Tristate.class);
this.createKey("griefdefender:pvp-combat-command", "pvp-combat-command", Boolean.class);
this.createKey("griefdefender:pvp-combat-teleport", "pvp-combat-teleport", Boolean.class);
this.createKey("griefdefender:pvp-combat-timeout", "pvp-combat-timeout", Integer.class);
RegistryHelper.mapFields(Options.class, input -> {
final String name = input.replace("_", "-");
@ -131,7 +138,15 @@ public class OptionRegistryModule implements CatalogRegistryModule<Option> {
}
private void createKey(String id, String name, Class<?> clazz) {
this.registryMap.put(id, new GDOption<>(id, name, clazz));
this.createKey(id, name, false, new HashSet<>(), clazz);
}
private void createKey(String id, String name, boolean multiValued, Class<?> clazz) {
this.createKey(id, name, multiValued, new HashSet<>(), clazz);
}
private void createKey(String id, String name, boolean multiValued, Set<String> requiredContextKeys, Class<?> clazz) {
this.registryMap.put(id, new GDOption<>(id, name, null, multiValued, requiredContextKeys, clazz));
}
@Override

View File

@ -31,7 +31,6 @@ import com.google.common.collect.ImmutableSet;
import com.griefdefender.GDPlayerData;
import com.griefdefender.GriefDefenderPlugin;
import com.griefdefender.api.GriefDefender;
import com.griefdefender.api.Tristate;
import com.griefdefender.api.claim.Claim;
import com.griefdefender.api.claim.ClaimContexts;
import com.griefdefender.api.claim.ClaimResult;
@ -54,7 +53,6 @@ import com.griefdefender.event.GDCauseStackManager;
import com.griefdefender.event.GDRemoveClaimEvent;
import com.griefdefender.internal.util.VecHelper;
import com.griefdefender.permission.GDPermissionUser;
import com.griefdefender.permission.GDPermissions;
import com.griefdefender.permission.flag.FlagContexts;
import com.griefdefender.permission.option.GDOption;
import com.griefdefender.registry.FlagRegistryModule;
@ -386,11 +384,11 @@ public abstract class BaseStorage {
if (flag == null) {
continue;
}
PermissionUtil.getInstance().setTransientPermission(GriefDefenderPlugin.DEFAULT_HOLDER, GDPermissions.FLAG_BASE + "." + mapEntry.getKey(), mapEntry.getValue(), contexts);
PermissionUtil.getInstance().setTransientPermission(GriefDefenderPlugin.DEFAULT_HOLDER, flag.getPermission(), mapEntry.getValue(), contexts);
if (flag == Flags.ENTITY_DAMAGE) {
// allow monsters to be attacked by default
contexts.add(FlagContexts.TARGET_TYPE_MONSTER);
PermissionUtil.getInstance().setTransientPermission(GriefDefenderPlugin.DEFAULT_HOLDER, GDPermissions.FLAG_BASE + "." + mapEntry.getKey(), true, contexts);
PermissionUtil.getInstance().setTransientPermission(GriefDefenderPlugin.DEFAULT_HOLDER, flag.getPermission(), true, contexts);
contexts.remove(FlagContexts.TARGET_TYPE_MONSTER);
}
}

View File

@ -28,14 +28,15 @@ import com.griefdefender.GriefDefenderPlugin;
import com.griefdefender.api.claim.Claim;
import com.griefdefender.api.claim.ClaimContexts;
import com.griefdefender.api.permission.Context;
import com.griefdefender.api.permission.option.Options;
import com.griefdefender.cache.MessageCache;
import com.griefdefender.cache.PermissionHolderCache;
import com.griefdefender.claim.GDClaim;
import com.griefdefender.claim.GDClaimManager;
import com.griefdefender.event.GDCauseStackManager;
import com.griefdefender.internal.registry.GDItemType;
import com.griefdefender.internal.registry.ItemTypeRegistryModule;
import com.griefdefender.internal.tracking.chunk.GDChunk;
import com.griefdefender.permission.ContextGroups;
import com.griefdefender.permission.GDPermissionUser;
import com.griefdefender.permission.GDPermissions;
@ -44,7 +45,6 @@ import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.World;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import java.util.Arrays;
import java.util.HashSet;
@ -80,11 +80,11 @@ public class CauseContextHelper {
private static final Pattern CONTEXT_SPLIT = Pattern.compile("^context?\\[ *((?:[\\w.-]+:[\\w.-]+:[\\w\\/.-]+(?: *, *(?!\\]$)|(?= *\\]$)))+) *\\]$");
private static final List<String> VALID_CONTEXTS = Arrays.asList("world", "server", "mode", "player", "group", "source", "used_item", "type");
// final String regex = "^context?\\[ *((?:[\\w.-]+:[\\w.-]+:[\\w\\/.-]+(?: *, *(?!\\]$)|(?= *\\]$)))+) *\\]$";
public static Set<Context> generateContexts(CommandSender src, Claim claim, String context) {
return generateContexts(src, claim, context, false);
public static Set<Context> generateContexts(String permission, CommandSender src, Claim claim, String context) {
return generateContexts(permission, src, claim, context, false);
}
public static Set<Context> generateContexts(CommandSender src, Claim claim, String context, boolean isOption) {
public static Set<Context> generateContexts(String permission, CommandSender src, Claim claim, String context, boolean isOption) {
// verify context is valid
if (context == null) {
return new HashSet<>();
@ -102,6 +102,8 @@ public class CauseContextHelper {
final boolean canManageDefaults = src.hasPermission(GDPermissions.MANAGE_FLAG_DEFAULTS);
final boolean canManageOverrides = src.hasPermission(GDPermissions.MANAGE_FLAG_OVERRIDES);
boolean hasSourceContext = false;
boolean hasTargetContext = false;
final Set<Context> contextSet = new HashSet<>();
final String contexts = matcher.group(1);
String[] split = contexts.split(",");
@ -191,7 +193,12 @@ public class CauseContextHelper {
} else if (contextName.equals("group")) {
contextSet.add(new Context(contextName, arg1));
} else if (contextName.equals("source")) {
contextSet.add(new Context(contextName, id));
hasSourceContext = true;
if (!arg1.contains("#") && !arg1.equalsIgnoreCase("any") && !arg1.equalsIgnoreCase("all")) {
contextSet.add(new Context(contextName, id));
} else {
contextSet.add(new Context(contextName, arg1));
}
} else if (contextName.contentEquals("state")) {
contextSet.add(new Context(contextName, id));
} else if (contextName.equals("used_item")) {
@ -202,7 +209,13 @@ public class CauseContextHelper {
}
contextSet.add(new Context(contextName, type.getId()));
} else {
if (arg2 == null) {
if (contextName.equals("target")) {
hasTargetContext = true;
if (permission.equals(Options.SPAWN_LIMIT.getPermission())
&& !arg1.contains("#") && !arg1.equalsIgnoreCase("any") && !arg1.equalsIgnoreCase("all")) {
contextSet.add(new Context(contextName, id));
}
} else if (arg2 == null) {
contextSet.add(new Context(contextName, arg1));
} else {
contextSet.add(new Context(contextName, id));
@ -210,6 +223,14 @@ public class CauseContextHelper {
}
}
if (permission.equals(Options.SPAWN_LIMIT.getPermission())) {
if (!hasSourceContext) {
contextSet.add(ContextGroups.SOURCE_ALL);
}
if (!hasTargetContext) {
contextSet.add(ContextGroups.TARGET_ALL);
}
}
return contextSet;
}
}

View File

@ -43,6 +43,7 @@ import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.UUID;
import java.util.concurrent.CompletableFuture;
public class PermissionUtil {
@ -62,6 +63,10 @@ public class PermissionUtil {
this.PERMISSION_PROVIDER = GriefDefenderPlugin.getInstance().getPermissionProvider();
}
public String getServerName() {
return PERMISSION_PROVIDER.getServerName();
}
public boolean hasGroupSubject(String identifier) {
return PERMISSION_PROVIDER.hasGroupSubject(identifier);
}
@ -186,16 +191,28 @@ public class PermissionUtil {
return PERMISSION_PROVIDER.getOptionValue(holder, option, contexts);
}
public List<String> getOptionValueList(GDPermissionHolder holder, Option option, Set<Context> contexts) {
return PERMISSION_PROVIDER.getOptionValueList(holder, option, contexts);
}
public PermissionResult setOptionValue(GDPermissionHolder holder, String permission, String value, Set<Context> contexts) {
return PERMISSION_PROVIDER.setOptionValue(holder, permission, value, contexts);
}
public PermissionResult setPermissionValue(GDPermissionHolder holder, Flag flag, Tristate value, Set<Context> contexts) {
return PERMISSION_PROVIDER.setPermissionValue(holder, flag, value, contexts);
return PERMISSION_PROVIDER.setPermissionValue(holder, flag, value, contexts, true);
}
public boolean setPermissionValue(GDPermissionHolder holder, String permission, Tristate value, Set<Context> contexts) {
return PERMISSION_PROVIDER.setPermissionValue(holder, permission, value, contexts);
public PermissionResult setPermissionValue(GDPermissionHolder holder, String permission, Tristate value, Set<Context> contexts) {
return PERMISSION_PROVIDER.setPermissionValue(holder, permission, value, contexts, true);
}
public PermissionResult setPermissionValue(GDPermissionHolder holder, Flag flag, Tristate value, Set<Context> contexts, boolean save) {
return PERMISSION_PROVIDER.setPermissionValue(holder, flag, value, contexts, save);
}
public PermissionResult setPermissionValue(GDPermissionHolder holder, String permission, Tristate value, Set<Context> contexts, boolean save) {
return PERMISSION_PROVIDER.setPermissionValue(holder, permission, value, contexts, save);
}
public void setTransientOption(GDPermissionHolder holder, String permission, String value, Set<Context> contexts) {
@ -210,6 +227,10 @@ public class PermissionUtil {
PERMISSION_PROVIDER.refreshCachedData(holder);
}
public CompletableFuture<Void> save(GDPermissionHolder holder) {
return PERMISSION_PROVIDER.save(holder);
}
public boolean containsKey(Set<Context> contexts, String key) {
for (Context context : contexts) {
if (context.getKey().equalsIgnoreCase(key)) {

View File

@ -36,6 +36,10 @@ import com.griefdefender.api.claim.ShovelTypes;
import com.griefdefender.api.permission.flag.Flags;
import com.griefdefender.api.permission.option.Options;
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.api.permission.option.type.WeatherTypes;
import com.griefdefender.cache.PermissionHolderCache;
import com.griefdefender.claim.GDClaim;
import com.griefdefender.configuration.MessageStorage;
@ -50,6 +54,7 @@ import net.kyori.text.TextComponent;
import net.kyori.text.format.TextColor;
import org.bukkit.Bukkit;
import org.bukkit.GameMode;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.OfflinePlayer;
@ -60,6 +65,7 @@ import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import java.util.HashSet;
import java.util.Map;
import java.util.UUID;
import org.checkerframework.checker.nullness.qual.Nullable;
@ -67,6 +73,16 @@ import org.checkerframework.checker.nullness.qual.Nullable;
public class PlayerUtil {
private static BlockFace[] faces = { BlockFace.NORTH, BlockFace.EAST, BlockFace.SOUTH, BlockFace.WEST};
public static Map<GameModeType, GameMode> GAMEMODE_MAP = ImmutableMap.of(
GameModeTypes.ADVENTURE, GameMode.ADVENTURE,
GameModeTypes.CREATIVE, GameMode.CREATIVE,
GameModeTypes.SPECTATOR, GameMode.SPECTATOR,
GameModeTypes.SURVIVAL, GameMode.SURVIVAL
);
public static Map<WeatherType, org.bukkit.WeatherType> WEATHERTYPE_MAP = ImmutableMap.of(
WeatherTypes.CLEAR, org.bukkit.WeatherType.CLEAR,
WeatherTypes.DOWNFALL, org.bukkit.WeatherType.DOWNFALL
);
private static PlayerUtil instance;

View File

@ -3,15 +3,15 @@
"libraries": [
{
"name": "com.griefdefender:adapter:1.12.2",
"sha1": "c17a212f288203daca365bd2f03253a2af35c751",
"path": "com/griefdefender/adapter/1.12.2-SNAPSHOT/adapter-1.12.2-20191007.192753-20.jar",
"url": "https://repo.glaremasters.me/repository/bloodshot/com/griefdefender/adapter/1.12.2-SNAPSHOT/adapter-1.12.2-20191007.192753-20.jar"
"sha1": "c6d1ac2ce3a205ae687a0493769b8b2dcc51b2cc",
"path": "com/griefdefender/adapter/1.12.2-SNAPSHOT/adapter-1.12.2-20191230.225523-21.jar",
"url": "https://repo.glaremasters.me/repository/bloodshot/com/griefdefender/adapter/1.12.2-SNAPSHOT/adapter-1.12.2-20191230.225523-21.jar"
},
{
"name": "com.griefdefender:api:1.0.0",
"sha1": "fb161e9877869876bbf07131c1a7682d37c6664d",
"path": "com/griefdefender/api/1.0.0-SNAPSHOT/api-1.0.0-20191219.230903-12.jar",
"url": "https://repo.glaremasters.me/repository/bloodshot/com/griefdefender/api/1.0.0-SNAPSHOT/api-1.0.0-20191219.230903-12.jar"
"sha1": "a87c88ecf7f4aaa4cc18decef9f0cbb013a0e602",
"path": "com/griefdefender/api/1.0.0-SNAPSHOT/api-1.0.0-20191230.224219-13.jar",
"url": "https://repo.glaremasters.me/repository/bloodshot/com/griefdefender/api/1.0.0-SNAPSHOT/api-1.0.0-20191230.224219-13.jar"
},
{
"name": "com.griefdefender:reflect-helper:1.0",

View File

@ -3,15 +3,15 @@
"libraries": [
{
"name": "com.griefdefender:adapter:1.13.2",
"sha1": "e29bb897bb2e65650019ba1d457bd2d57253e4ac",
"path": "com/griefdefender/adapter/1.13.2-SNAPSHOT/adapter-1.13.2-20191030.135953-20.jar",
"url": "https://repo.glaremasters.me/repository/bloodshot/com/griefdefender/adapter/1.13.2-SNAPSHOT/adapter-1.13.2-20191030.135953-20.jar"
"sha1": "115d51a291c4b2ac6ca3d2b4f62fa7dd9ee44980",
"path": "com/griefdefender/adapter/1.13.2-SNAPSHOT/adapter-1.13.2-20191230.225353-21.jar",
"url": "https://repo.glaremasters.me/repository/bloodshot/com/griefdefender/adapter/1.13.2-SNAPSHOT/adapter-1.13.2-20191230.225353-21.jar"
},
{
"name": "com.griefdefender:api:1.0.0",
"sha1": "fb161e9877869876bbf07131c1a7682d37c6664d",
"path": "com/griefdefender/api/1.0.0-SNAPSHOT/api-1.0.0-20191219.230903-12.jar",
"url": "https://repo.glaremasters.me/repository/bloodshot/com/griefdefender/api/1.0.0-SNAPSHOT/api-1.0.0-20191219.230903-12.jar"
"sha1": "a87c88ecf7f4aaa4cc18decef9f0cbb013a0e602",
"path": "com/griefdefender/api/1.0.0-SNAPSHOT/api-1.0.0-20191230.224219-13.jar",
"url": "https://repo.glaremasters.me/repository/bloodshot/com/griefdefender/api/1.0.0-SNAPSHOT/api-1.0.0-20191230.224219-13.jar"
},
{
"name": "com.griefdefender:reflect-helper:1.0",

View File

@ -3,15 +3,15 @@
"libraries": [
{
"name": "com.griefdefender:adapter:1.14.2",
"sha1": "a1d0d15ed46106f71f0a87e3033bf4e27d2115bd",
"path": "com/griefdefender/adapter/1.14.2-SNAPSHOT/adapter-1.14.2-20191030.135904-20.jar",
"url": "https://repo.glaremasters.me/repository/bloodshot/com/griefdefender/adapter/1.14.2-SNAPSHOT/adapter-1.14.2-20191030.135904-20.jar"
"sha1": "d12b32993aca93f60800a0ba1d1f0f343dd378cc",
"path": "com/griefdefender/adapter/1.14.2-SNAPSHOT/adapter-1.14.2-20191230.225306-21.jar",
"url": "https://repo.glaremasters.me/repository/bloodshot/com/griefdefender/adapter/1.14.2-SNAPSHOT/adapter-1.14.2-20191230.225306-21.jar"
},
{
"name": "com.griefdefender:api:1.0.0",
"sha1": "fb161e9877869876bbf07131c1a7682d37c6664d",
"path": "com/griefdefender/api/1.0.0-SNAPSHOT/api-1.0.0-20191219.230903-12.jar",
"url": "https://repo.glaremasters.me/repository/bloodshot/com/griefdefender/api/1.0.0-SNAPSHOT/api-1.0.0-20191219.230903-12.jar"
"sha1": "a87c88ecf7f4aaa4cc18decef9f0cbb013a0e602",
"path": "com/griefdefender/api/1.0.0-SNAPSHOT/api-1.0.0-20191230.224219-13.jar",
"url": "https://repo.glaremasters.me/repository/bloodshot/com/griefdefender/api/1.0.0-SNAPSHOT/api-1.0.0-20191230.224219-13.jar"
},
{
"name": "com.griefdefender:reflect-helper:1.0",

View File

@ -3,15 +3,15 @@
"libraries": [
{
"name": "com.griefdefender:adapter:1.14.3",
"sha1": "5861e4469cdfdc25a4c424727d71d15186b92441",
"path": "com/griefdefender/adapter/1.14.3-SNAPSHOT/adapter-1.14.3-20191030.135827-21.jar",
"url": "https://repo.glaremasters.me/repository/bloodshot/com/griefdefender/adapter/1.14.3-SNAPSHOT/adapter-1.14.3-20191030.135827-21.jar"
"sha1": "6811ded786ecddb3424c94b3a9856f3d2c2d000a",
"path": "com/griefdefender/adapter/1.14.3-SNAPSHOT/adapter-1.14.3-20191230.225200-22.jar",
"url": "https://repo.glaremasters.me/repository/bloodshot/com/griefdefender/adapter/1.14.3-SNAPSHOT/adapter-1.14.3-20191230.225200-22.jar"
},
{
"name": "com.griefdefender:api:1.0.0",
"sha1": "fb161e9877869876bbf07131c1a7682d37c6664d",
"path": "com/griefdefender/api/1.0.0-SNAPSHOT/api-1.0.0-20191219.230903-12.jar",
"url": "https://repo.glaremasters.me/repository/bloodshot/com/griefdefender/api/1.0.0-SNAPSHOT/api-1.0.0-20191219.230903-12.jar"
"sha1": "a87c88ecf7f4aaa4cc18decef9f0cbb013a0e602",
"path": "com/griefdefender/api/1.0.0-SNAPSHOT/api-1.0.0-20191230.224219-13.jar",
"url": "https://repo.glaremasters.me/repository/bloodshot/com/griefdefender/api/1.0.0-SNAPSHOT/api-1.0.0-20191230.224219-13.jar"
},
{
"name": "com.griefdefender:reflect-helper:1.0",

View File

@ -3,15 +3,15 @@
"libraries": [
{
"name": "com.griefdefender:adapter:1.14.4",
"sha1": "0e014588faa41ae12d5feb77b47b607578c73ed7",
"path": "com/griefdefender/adapter/1.14.4-SNAPSHOT/adapter-1.14.4-20191030.135735-19.jar",
"url": "https://repo.glaremasters.me/repository/bloodshot/com/griefdefender/adapter/1.14.4-SNAPSHOT/adapter-1.14.4-20191030.135735-19.jar"
"sha1": "79eb86d1c62fe70af428e7ac0cc5279790990ff0",
"path": "com/griefdefender/adapter/1.14.4-SNAPSHOT/adapter-1.14.4-20191230.225107-20.jar",
"url": "https://repo.glaremasters.me/repository/bloodshot/com/griefdefender/adapter/1.14.4-SNAPSHOT/adapter-1.14.4-20191230.225107-20.jar"
},
{
"name": "com.griefdefender:api:1.0.0",
"sha1": "fb161e9877869876bbf07131c1a7682d37c6664d",
"path": "com/griefdefender/api/1.0.0-SNAPSHOT/api-1.0.0-20191219.230903-12.jar",
"url": "https://repo.glaremasters.me/repository/bloodshot/com/griefdefender/api/1.0.0-SNAPSHOT/api-1.0.0-20191219.230903-12.jar"
"sha1": "a87c88ecf7f4aaa4cc18decef9f0cbb013a0e602",
"path": "com/griefdefender/api/1.0.0-SNAPSHOT/api-1.0.0-20191230.224219-13.jar",
"url": "https://repo.glaremasters.me/repository/bloodshot/com/griefdefender/api/1.0.0-SNAPSHOT/api-1.0.0-20191230.224219-13.jar"
},
{
"name": "com.griefdefender:reflect-helper:1.0",

View File

@ -3,15 +3,15 @@
"libraries": [
{
"name": "com.griefdefender:adapter:1.15",
"sha1": "0748b075602fa13448f94cfb2fca0b2db58795b6",
"path": "com/griefdefender/adapter/1.15-SNAPSHOT/adapter-1.15-20191211.164543-1.jar",
"url": "https://repo.glaremasters.me/repository/bloodshot/com/griefdefender/adapter/1.15-SNAPSHOT/adapter-1.15-20191211.164543-1.jar"
"sha1": "d7c5414752ad767508174a7de908d93fd3695492",
"path": "com/griefdefender/adapter/1.15-SNAPSHOT/adapter-1.15-20191230.224935-2.jar",
"url": "https://repo.glaremasters.me/repository/bloodshot/com/griefdefender/adapter/1.15-SNAPSHOT/adapter-1.15-20191230.224935-2.jar"
},
{
"name": "com.griefdefender:api:1.0.0",
"sha1": "fb161e9877869876bbf07131c1a7682d37c6664d",
"path": "com/griefdefender/api/1.0.0-SNAPSHOT/api-1.0.0-20191219.230903-12.jar",
"url": "https://repo.glaremasters.me/repository/bloodshot/com/griefdefender/api/1.0.0-SNAPSHOT/api-1.0.0-20191219.230903-12.jar"
"sha1": "a87c88ecf7f4aaa4cc18decef9f0cbb013a0e602",
"path": "com/griefdefender/api/1.0.0-SNAPSHOT/api-1.0.0-20191230.224219-13.jar",
"url": "https://repo.glaremasters.me/repository/bloodshot/com/griefdefender/api/1.0.0-SNAPSHOT/api-1.0.0-20191230.224219-13.jar"
},
{
"name": "com.griefdefender:reflect-helper:1.0",

View File

@ -3,15 +3,15 @@
"libraries": [
{
"name": "com.griefdefender:adapter:1.8.8",
"sha1": "fb0b9235fb0d18bab3b63fa56207d156c40faf6e",
"path": "com/griefdefender/adapter/1.8.8-SNAPSHOT/adapter-1.8.8-20191007.192948-20.jar",
"url": "https://repo.glaremasters.me/repository/bloodshot/com/griefdefender/adapter/1.8.8-SNAPSHOT/adapter-1.8.8-20191007.192948-20.jar"
"sha1": "78a79391b94339c64ea31cfcc257291e9314822c",
"path": "com/griefdefender/adapter/1.8.8-SNAPSHOT/adapter-1.8.8-20191230.225626-21.jar",
"url": "https://repo.glaremasters.me/repository/bloodshot/com/griefdefender/adapter/1.8.8-SNAPSHOT/adapter-1.8.8-20191230.225626-21.jar"
},
{
"name": "com.griefdefender:api:1.0.0",
"sha1": "fb161e9877869876bbf07131c1a7682d37c6664d",
"path": "com/griefdefender/api/1.0.0-SNAPSHOT/api-1.0.0-20191219.230903-12.jar",
"url": "https://repo.glaremasters.me/repository/bloodshot/com/griefdefender/api/1.0.0-SNAPSHOT/api-1.0.0-20191219.230903-12.jar"
"sha1": "a87c88ecf7f4aaa4cc18decef9f0cbb013a0e602",
"path": "com/griefdefender/api/1.0.0-SNAPSHOT/api-1.0.0-20191230.224219-13.jar",
"url": "https://repo.glaremasters.me/repository/bloodshot/com/griefdefender/api/1.0.0-SNAPSHOT/api-1.0.0-20191230.224219-13.jar"
},
{
"name": "com.griefdefender:reflect-helper:1.0",

View File

@ -424,6 +424,12 @@ GriefDefender {
mode-nature="&aBereit, das Grundstück wiederherzustellen! Rechtsklicke einen Block, um zu beginnen. &f/modebasic&c zum Stoppen."
mode-subdivision="&aUnterteilungsmodus. Unterteile deine existierendes Grundstück. Nutze &f/modebasic&a zum Verlassen."
mode-town="&aStadt-Erstellungsmodus aktiviert."
option-apply-player-deny-flight="&cDu darfst auf diesem Grundstück nicht fliegen und wurdest an einen sicheren Ort auf dem Boden teleportiert."
option-apply-player-deny-godmode="&cDu hast keine Berechtigungen unsterblich zu sein."
option-apply-player-gamemode="&aDein Spielmodus wurde zu &6{gamemode}&a geändert."
option-apply-player-walk-speed="&aDeine Laufgeschwindigkeit wurde auf &6{speed}&a geändert."
option-apply-player-weather="&aDein lokales Wetter wurde geändert zu &6{weather}&a."
option-apply-spawn-limit="&cAuf diesem Grundstück sind bereits die maximale Anzahl &a{type}&c, nämlich &6{limit}&c und es können keine weiteren spawnen."
option-description-abandon-delay="&aDie Anzahl Tage, bevor ein neues Grundstück aufgegeben werden kann."
option-description-abandon-return-ratio="&aDer Anteil Blöcke, welcher ein Spieler beim Aufgeben seines Grundstückes zurückerhält."
option-description-blocks-accrued-per-hour="&aBaublöcke pro Stunde.\n&dHinweis&f: Nutze /playerinfo für mehr Informationen."
@ -443,7 +449,8 @@ GriefDefender {
option-description-min-size-x="&aDie Minimalgröße eines Grundstückes auf der x-Achse."
option-description-min-size-y="&aDie Minimalgröße eines Grundstückes auf der y-Achse."
option-description-min-size-z="&aDie Minimalgröße eines Grundstückes auf der z-Achse."
option-description-player-command="&aBestimmt, ob ein Befehl mit einem bestimmten Kontext ausführbar ist."
option-description-player-command-enter="&aFühre einen bestimmten und anpassbaren Befehl aus, wenn ein Spieler dein Grundstück betritt."
option-description-player-command-exit="&aFühre einen bestimmten und anpassbaren Befehl aus, wenn ein Spieler dein Grundstück verlässt."
option-description-player-deny-flight="&aStellt sicher, dass Spieler auf dem Grundstück nicht fliegen können.\n&dHinweis&f: Gibt Spielern nicht die Fähigkeit zu fliegen, sondern verhindert es nur - dies gewährleistet maximale Kompatibilität mit Plugins."
option-description-player-deny-godmode="&aLegt fest, ob Spieler auf dem Grundstück GodMode haben können.\n&dHinweis&f: Gibt Spielern nicht die Möglichkeit GodMode zu erhalten, sondern schaltet ihn lediglich aus - dies gewährleistet maximale Kompatibilität mit Plugins."
option-description-player-deny-hunger="&aLegt fest, ob Spieler auf dem Grundstück hungern können.\n&dHinweis&f: Regeneriert keinen Hunger für Spieler, sondern verhindert lediglich, dass diese Hunger verlieren - dies gewährleistet maximale Kompatibilität mit Plugins."
@ -451,10 +458,16 @@ GriefDefender {
option-description-player-health-regen="&aBestimmt die Regenerierungsrate eines Spielers auf dem Grundstück.\n&dHinweis&f: Hat der Spieler bereits maximales Leben, hat dies keinen Effekt. \n&dHinweis&f: &6-1&f deaktiviert diese Option."
option-description-player-keep-inventory="&aLegt fest, ob Spieler ihr Inventar nach dem Tod auf dem Grundstück behalten."
option-description-player-keep-level="&aLegt fest, ob Spieler ihr EXP beim Tod auf dem Grundstück verlieren."
option-description-player-teleport-delay="&aDie Verzögerung, bis ein Spieler zum neuen Ort teleportiert wird."
option-description-player-walk-speed="&aBestimmt die Laufgeschwindigkeit von Spielern.\n&dBeweis&f: &6-1&f deaktiviert dies."
option-description-player-weather="&aSetzt das Wetter für Spieler auf dem Grundstück."
option-description-pvp="&aLegt fest, ob Spieler sich gegenseitig angreifen können."
option-description-pvp-combat-command="&aLegt fest, ob Spieler während des PvP Kämpfens Befehle nutzen können."
option-description-pvp-combat-teleport="&aLegt fest, ob sich Spieler während eines PvP Kampfes teleportieren können."
option-description-pvp-combat-timeout="&aLegt fest, wie lange sich Spieler nach dem letzten Schlag noch im PvP Kampfmodus befinden sollen."
option-description-radius-inspect="&aDer Radius (in Blöcken), in welchem beim Inspizieren nach Grundstücken gesucht wird."
option-description-radius-list="&aLegt den Radius (in Blöcken) um den Spieler für Grundstücke fest, welche auf der Grundstücksliste angezeigt werden."
option-description-spawn-limit="&aErmöglicht das Erstellen von Spawnlimits für bestimmte Bedingungen und Entitäten."
option-description-tax-expiration="&aAnzahl Tage ohne Steuern, bis ein Grundstück eingefroren wird.\n&dHinweis&f: Bis die Steuern bezahlt sind kann der Spieler dann weder interagieren noch bauen."
option-description-tax-expiration-days-keep="&aAnzahl Tage, bis ein eingefrorenes Grundstück abläuft.\n&dHinweis&f: Bei Ablauf eines Grundstückes wird dieses entweder zurückgesetzt oder einfach entfernt. Kommt auf die Servereinstellungen an - kontaktiere den Admin."
option-description-tax-rate="&aDie Besteuerung eines Grundstückes.\n&dHinweis&f: Steuern sind abhängig von der Anzahl Grundstücksblöcke."
@ -465,6 +478,7 @@ GriefDefender {
option-not-set="{option}&f ist nicht eingestellt.\n&dHinweis&f: Standardoption {value}&f ist solange aktiv."
option-override-not-supported="&cGrundstücksart {type}&c unterstützt keine überschreibenden Einstellungen."
option-player-deny-flight="&cDu darfst in diesem Grundstück nicht fliegen und wurdest zu einem sicheren Landeplatz teleportiert."
option-requires-contexts="&cDiese Option benötigt zum Einstellen den Kontext '&a{contexts}&c'."
option-reset-success="&aGrundstückseinstellungen erfolgreich zurückgesetzt."
option-set-target="&aSetze {type}&a für Option &b{option}&a auf {value}&a mit dem Kontext &7{contexts}&a für &6{target}&a."
option-ui-click-toggle="Klicke hier, um {option}&f umzuschalten."
@ -497,7 +511,9 @@ GriefDefender {
permission-cuboid="&cDu hast keine Berechtigung den 3D Modus für Grundstücke zu nutzen."
permission-edit-claim="&cDu hast keine Berechtigung dieses Grundstück zu bearbeiten."
permission-fire-spread="&cDu hast keine Berechtigung Feuer zu legen."
permission-flag-arg="&cDu hast keine Berechtigungen den Einstellungsbefehl mit weiterem Kontext zu benutzen."
permission-flag-defaults="&cDu hast keine Berechtigung die Standardeinstellungen zu verwalten."
permission-flag-gui="&cDu hast keine Berechtigungen diese EinstellungsGUI zu benutzen."
permission-flag-overrides="&cDu hast keine Berechtigung überschreibende Einstellungen zu verwalten."
permission-flag-use="&cDu hast keine Berechtigung diese Einstellung zu nutzen."
permission-flow-liquid="&cDu hast keine Berechtigung in diesem Grundstück Flüssigkeiten fließen zu lassen."
@ -554,6 +570,7 @@ GriefDefender {
plugin-not-found="&cKonnte kein Plugin &b{id}&c finden."
plugin-reload="&aGriefDefender neu geladen."
pvp-claim-not-allowed="&aPvP ist auf diesem Grundstück nicht erlaubt."
pvp-in-combat-not-allowed="&aDu kannst das nicht tun, während du in einem PvP Kampf bist. Du bist noch für &6{time-remaining}&a Sekunden im Kampfmodus."
pvp-source-not-allowed="&aPvP ist für dich nicht erlaubt."
pvp-target-not-allowed="&aDu kannst keine Spieler attackieren, die PvP ausgestellt haben."
registry-block-not-found="&cDer Block {id}&c konnte nicht gefunden werden."

View File

@ -424,6 +424,12 @@ GriefDefender {
mode-nature="&aReady to restore claim! Right click on a block to restore, and use &f/modebasic&c to stop."
mode-subdivision="&aSubdivision creation mode enabled. Use &f/modebasic&a to exit."
mode-town="&aTown creation mode enabled."
option-apply-player-deny-flight="&cYou do not have access to fly in this claim and have been teleported to a safe spot on ground."
option-apply-player-deny-godmode="&cYou do not have access to use god mode in this claim."
option-apply-player-gamemode="&aYour gamemode has been changed to &6{gamemode}&a."
option-apply-player-walk-speed="&aYour walk speed has been changed to &6{speed}&a."
option-apply-player-weather="&aYour local weather has been changed to &6{weather}&a."
option-apply-spawn-limit="&cThis claim has reached the &a{type}&c spawn limit of &6{limit}&c and can no longer spawn any more."
option-description-abandon-delay="&aThe amount of days before a newly created claim can be abandoned."
option-description-abandon-return-ratio="&aThe portion of basic claim blocks returned to a player when a claim is abandoned."
option-description-blocks-accrued-per-hour="&aBlocks earned per hour.\n&dNote&f: See /playerinfo for more information."
@ -443,7 +449,8 @@ GriefDefender {
option-description-min-size-x="&aThe min size in blocks that the x-axis can be."
option-description-min-size-y="&aThe min size in blocks that the y-axis can be."
option-description-min-size-z="&aThe min size in blocks that the z-axis can be."
option-description-player-command="&aUsed for executing a command with specific contexts."
option-description-player-command-enter="&aUsed for executing a command with specific contexts when a player enters a claim."
option-description-player-command-exit="&aUsed for executing a command with specific contexts when a player exits a claim."
option-description-player-deny-flight="&aUsed to determine if a player is unable to fly in a claim.\n&dNote&f: This does not give players the ability to fly, it merely removes the ability if set. This provides the greatest compatibility with plugins."
option-description-player-deny-godmode="&aUsed to determine if a player can be in godmode within a claim.\n&dNote&f: This does not give players the ability to be in godmode, it merely removes the ability if set. This provides the greatest compatibility with plugins."
option-description-player-deny-hunger="&aUsed to if a player's hunger is denied in a claim.\n&dNote&f: This does not give players the ability to gain hunger, it merely removes the ability to cause hunger if set. This provides the greatest compatibility with plugins."
@ -451,10 +458,16 @@ GriefDefender {
option-description-player-health-regen="&aUsed to set the health regen amount for a player in a claim.\n&dNote&f: If the player is at max health, this will have no effect. \n&dNote&f: A value of &6-1&f disables this option."
option-description-player-keep-inventory="&aUsed to determine if a player can keep inventory after death in a claim."
option-description-player-keep-level="&aUsed to determine if a player can keep their level after death in a claim."
option-description-player-teleport-delay="&aUsed to determine the delay before teleporting a player to a new location."
option-description-player-walk-speed="&aUsed to set a player's walk speed in a claim.\n&dNote&f: A value of &6-1&f disables this option."
option-description-player-weather="&aUsed to set a player's weather in a claim."
option-description-pvp="&aUsed to determine if players can combat each other."
option-description-pvp-combat-command="&aUsed to determine if a player can use commands during PvP combat."
option-description-pvp-combat-teleport="&aUsed to determine if a player can teleport during PvP combat."
option-description-pvp-combat-timeout="&aUsed to determine how many seconds PvP combat is considered to continue after the most recent damage."
option-description-radius-inspect="&aThe radius in blocks used to search for nearby claims while inspecting."
option-description-radius-list="&aThe radius in blocks used to list nearby claims."
option-description-spawn-limit="&aUsed to determine the spawn limit for a specific set of contexts in a claim."
option-description-tax-expiration="&aNumber of days after not paying taxes before a claim will be frozen.\n&dNote&f: A frozen state means you will have no access to build or interact in claim until taxes are paid."
option-description-tax-expiration-days-keep="&aNumber of days to keep a basic claim after frozen and before expiring.\n&dNote&f: On expiration, a claim may either be restored back to original state or be deleted. This depends on the server configuration. Contact an administrator for more information."
option-description-tax-rate="&aThe tax rate of claim.\n&dNote&f: Tax rate is calculated by the number of claimblocks in the basic claim."
@ -464,7 +477,7 @@ GriefDefender {
option-not-found="&cOption {option}&c not found."
option-not-set="{option}&f is currently not set.\n&dNote&f: The default option value of {value}&f will be active until set."
option-override-not-supported="&cClaim type {type}&c does not support option overrides."
option-player-deny-flight="&cYou do not have access to fly in this claim and have been teleported to a safe spot on ground."
option-requires-contexts="&cThis option requres contexts '&a{contexts}&c' to be set."
option-reset-success="&aClaim options reset to defaults successfully."
option-set-target="&aSet {type}&a option &b{option}&a to {value}&a with contexts &7{contexts}&a on &6{target}&a."
option-ui-click-toggle="Click here to toggle {option}&f value."
@ -497,7 +510,9 @@ GriefDefender {
permission-cuboid="&cYou don't have permission to create/resize basic claims in 3D mode."
permission-edit-claim="&cYou don't have permission to edit this claim."
permission-fire-spread="&cYou don't have permission to spread fire in this claim."
permission-flag-arg="&cYou don't have permission to use the flag command with arguments."
permission-flag-defaults="&cYou don't have permission to manage flag defaults."
permission-flag-gui="&cYou don't have permission to use the flag GUI."
permission-flag-overrides="&cYou don't have permission to manage flag overrides."
permission-flag-use="&cYou don't have permission to use this flag."
permission-flow-liquid="&cYou don't have permission to flow liquid in this claim."
@ -554,6 +569,7 @@ GriefDefender {
plugin-not-found="&cCould not locate plugin with id &b{id}&c."
plugin-reload="&aGriefDefender has been reloaded."
pvp-claim-not-allowed="&aYou are not allowed to PvP in this claim."
pvp-in-combat-not-allowed="&aYou cannot perform this action while in PvP combat. You must stay out of combat for &6{time-remaining}&a more seconds."
pvp-source-not-allowed="&aYou are not allowed to PvP."
pvp-target-not-allowed="&aYou cannot attack players who are not participating in PvP."
registry-block-not-found="&cThe block {id}&c could not be found in registry."

View File

@ -424,6 +424,12 @@ GriefDefender {
mode-nature="&f&l[&b&lCREACION&f&l&f&l-&b&lEN&f&l-&b&lMODO&f&l-&eNATURALEZA&f&l] &b&l➜ &a&lACTIVADO\n\nHaz &6&lCLICK-DERECHO&a en un bloque para restaurar. Usa &6&o'/modebasic' &apara salir de este modo.\n&4&l[NOTA] &c Este modo sirve para resturar terrenos a su forma virgen cuando se generó este mundo por primera vez."
mode-subdivision="&f&l[&b&lCREACION&f&l&f&l-&b&lEN&f&l-&b&lMODO&f&l-&eSUBDIVISION&f&l] &b&l➜ &a&lACTIVADO\n\nUsa &6&o'/modebasic' &apara salir de este modo."
mode-town="&f&l[&b&lCREACION&f&l&f&l-&b&lEN&f&l-&b&lMODO&f&l-&eCIUDAD&f&l] &b&l➜ &a&lACTIVADO\n\nUsa &6&o'/modebasic' &apara salir de este modo."
option-apply-player-deny-flight="&4&l[PERMISO-DENEGADO] &cNo puedes volar en este terreno. Has sido teletransportado a un lugar seguro en el suelo."
option-apply-player-deny-godmode="&4&l[PERMISO-DENEGADO] &cNo puedes usar el modo Dios en este terreno."
option-apply-player-gamemode="&aTu modo de juego ha sido cambiado a &6&o{gamemode}&a."
option-apply-player-walk-speed="&aTu velocidad caminar ha sido cambiada a &6&o{speed}&a."
option-apply-player-weather="&aTu clima ha sido cambiado a &6&o{weather}&a."
option-apply-spawn-limit="&4&l[ATENCION] &cEste terreno ha alcanzado el limite de spawn &6&o{limit} &cde tipo &a&o{type}&c y no pueden spawnear más."
option-description-abandon-delay="&aLa cantidad de días antes de que un Claim recién creado puede ser abandonado."
option-description-abandon-return-ratio="&aLos CB's devueltos cuando un jugador abandona un Claim."
option-description-blocks-accrued-per-hour="&aLos CB's ganados por hora.\n&4&l[NOTA] &aUsa &6&o'/playerinfo'&a para ver más información del jugador."
@ -443,7 +449,8 @@ GriefDefender {
option-description-min-size-x="&aTamaño mínimo en bloques en el &eeje X&7(horizontal)"
option-description-min-size-y="&aTamaño mínimo en bloques en el &eeje Y&7(vertical)"
option-description-min-size-z="&aTamaño mínimo en bloques en el &eeje Z&7(profundidad)"
option-description-player-command="&aSe usa para ejecutar comandos con 'Contextos' específicos."
option-description-player-command-enter="&aSe usa para ejecutar un comando con Contextos específicos cuando un jugador &6&oENTRA&a en un terreno."
option-description-player-command-exit="&aSe usa para ejecutar un comando con Contextos específicos cuando un jugador &6&oSALE&a en un terreno."
option-description-player-deny-flight="&aSe usa para determinar si un jugador es capaz de Volar(fly) dentro del terreno.\n&4&l[NOTA] &fEsto no da a los jugadores la habilidad de volar, simplemente se elimina la habilidad si se establece. Esto provee gran compatibilidad con otros plugins."
option-description-player-deny-godmode="&aSe usa para determinar si un jugador puede estar en Modo Dios(godmode) dentro del terreno.\n&4&l[NOTA] &fEsto no da a los jugadores la habilidad de estar en modo Dios, simplemente se elimina la habilidad si se establece. Esto provee gran compatibilidad con otros plugins."
option-description-player-deny-hunger="&aSe usa para determinar si un jugador puede tener hambre(hunger) dentro del terreno.\n&4&l[NOTA] &fEsto no da a los jugadores la habilidad de NO tener hambre, simplemente elimina la habilidad que causa el hambre si se establece. Esto provee gran compatibilidad con otros plugins."
@ -451,10 +458,16 @@ GriefDefender {
option-description-player-health-regen="&aSe usa para determinar la cantidad de regeneración de vida para un jugador en el terreno.\n&4&l[NOTA] &fSi el jugador tiene la vida al máximo, esto no tendrá efecto. \n&4&l[NOTA]&f El valor de &c-1&f desactiva esta opción."
option-description-player-keep-inventory="&aSe usa para determinar si el jugador puede mantener su inventario después de morir en el terreno."
option-description-player-keep-level="&aSe usa para determinar si el jugador puede mantener su nivel de exp. después de morir en el terreno."
option-description-player-teleport-delay="&aSe usa para &6&ndeterminar un retardo&a &o(delay)&a antes de la teletransportación de un jugador a la nueva localización."
option-description-player-walk-speed="&aSe usa para establecer la velocidad de caminar de los jugadores en el terreno.\n&4&l[NOTA] &fEl valor de &c-1&f desactiva esta opción."
option-description-player-weather="&aSe usa para establecer el clima de los jugadores en el terreno."
option-description-pvp="&aSe usa para determinar &6&nsi hay combates PvP&a entre jugadores."
option-description-pvp-combat-command="&aSe usa para determinar si un jugador puede &6&nusar comandos&a durante un combate PvP."
option-description-pvp-combat-teleport="&aSe usa para determinar si un jugador puede &6&nteletransportarse&a durante un combate PvP."
option-description-pvp-combat-timeout="&aSe usa para determinar cuantos &6&nsegundos de combate PvP&a se consideran para continuar después de un daño reciente."
option-description-radius-inspect="&aEl radio de cercania de bloques que se utiliza para encontrar Claims mientras inspeccionamos."
option-description-radius-list="&aEl radio en bloques utilizados para la Lista de terrenos cercanos."
option-description-spawn-limit="&aSe usa para determinar el limite de spawn para colocar Contextos específicos en un terreno."
option-description-tax-expiration="&aNúmero de dias después de no pagar los impuestos antes de que el terreno sea paralizado.\n&4&l[NOTA] &6&o'Paralizado'&f significa que no tendrás acceso para construir o interactuar con nada hasta que te pongas al día con los pagos atrasados.&7Paga las cuotas, chorizo! =)"
option-description-tax-expiration-days-keep="&aNúmero de días para mantener un Claim Basico &odespués&a de ser Paralizado y &oantes&a de la Expiración.\n&4&l[NOTA]: &fDurante la expiración, un Claim puede ser restaurado a su estado natural inicial o eliminado. Esto depende de la configuración del Servidor. Para más información, contacta con un &4Administrador&a."
option-description-tax-rate="&aEl porcentaje de impuestos del terreno.\n&4&l[NOTA] &fEl porcentaje de impuestos es calculado por el número de CB's en el Claim Básico."
@ -465,6 +478,7 @@ GriefDefender {
option-not-set="&4&l[ERROR] &6&o'{option}'&c no está establecida.\n&4&l[NOTA] &cLa opción con valor de &6&o'{value}'&c estará activa hasta que se establezca."
option-override-not-supported="&4&l[ERROR] &cEl Claim tipo &6&o'{type}'&c no soporta la opción de Sobrescribir."
option-player-deny-flight="&4&l[VOLAR-DESACTIVADO] &cNo tienes acceso a la habilidad de volar en este terreno. Serás teletransportado a un lugar seguro en el suelo."
option-requires-contexts="&4&l[ERROR] &cEsta opción requiere el Contexto &6&o'{contexts}'&c para ser establecido."
option-reset-success="&2&l[OPCIONES-RESETEADAS] &a¡Todas las opciones de Claim han sido reiniciadas al estado original con éxito!"
option-set-target="&aEstablecido ( &e&o{type}&a ) una opción ( &b&o{option} &a)&a en (&6&o {value} &a)&a con el Contexto de (&7&o {contexts} &a)&a en el Objetivo de ( &c&o{target} &a)"
option-ui-click-toggle="&6&lCLICK-AQUI &fpara &aACTIVAR&f/&cDESACTIVAR &fel valor &6&o'{option}'"
@ -497,7 +511,9 @@ GriefDefender {
permission-cuboid="&4&l[PERMISO-DENEGADO] &cNo puedes &ncrear/redimensionar&r &cClaims &eBásicos &cen &b&lMODO &d&l3D&c. "
permission-edit-claim="&4&l[PERMISO-DENEGADO] &cNo puedes &neditar&c este terreno."
permission-fire-spread="&4&l[PERMISO-DENEGADO] &cNo puedes &npropagar&c el fuego en este terreno."
permission-flag-arg="&4&l[PERMISO-DENEGADO] &cNo puedes usar comandos de Flags con argumentos."
permission-flag-defaults="&4&l[PERMISO-DENEGADO] &cNo puedes &nadministrar&c los Flags por defecto de este terreno."
permission-flag-gui="&4&l[PERMISO-DENEGADO] &cNo puedes usar la Interfaz Gráfica de Usuario de Flags &6&o(GUI)"
permission-flag-overrides="&4&l[PERMISO-DENEGADO] &cNo puedes &nadministrar&c los Flags ignorados."
permission-flag-use="&4&l[PERMISO-DENEGADO] &cNo puedes &nusar&c este Flag."
permission-flow-liquid="&4&l[PERMISO-DENEGADO] &cNo puedes &nderramar&c liquidos en este terreno."
@ -554,6 +570,7 @@ GriefDefender {
plugin-not-found="&4&l[ERROR] &cNo es posible localizar el Plugin con ID &b{id}&c."
plugin-reload="&b&l[&3&lGRIEF&b&l-&f&lDEFENDER&b&l] &a&lha sido re-cargado. &aTodas las configuraciones han sido &2&lACTUALIZADAS."
pvp-claim-not-allowed="&4&l[PvP-DESACTIVADO] &cNo tienes permitido el PvP en este terreno."
pvp-in-combat-not-allowed="&4&l[ACCION-DENEGADA] &aNo puedes hacer esto en PvP hasta que estés fuera de combate durante más de &6&o{time-remaining}s&a."
pvp-source-not-allowed="&4&l[PvP-DESACTIVADO] &cNo tienes permitido el PvP."
pvp-target-not-allowed="&4&l[PvP-DESACTIVADO] &cNo puedes atacar a los jugadores que NO estén en participando en PvP."
registry-block-not-found="&4&l[BLOQUE-NO-ENCONTRADO] &cEl bloque con ID &6&o'{id}'&c no figura en el Registro."

View File

@ -424,6 +424,12 @@ GriefDefender {
mode-nature="&aPrêt pour restaurer la protection ! Clique-droit sur un bloc pour restaurer, et utilises &f/modebasic&c pour arrêter."
mode-subdivision="&aMode Sous-divions. Utilises la pelle pour créer une sous-division dans ta protection existante. Utilises &f/modebasic&a pour sortir."
mode-town="&aMode création de Village activé."
option-apply-player-deny-flight="&cYou do not have access to fly in this claim and have been teleported to a safe spot on ground."
option-apply-player-deny-godmode="&cYou do not have access to use god mode in this claim."
option-apply-player-gamemode="&aYour gamemode has been changed to &6{gamemode}&a."
option-apply-player-walk-speed="&aYour walk speed has been changed to &6{speed}&a."
option-apply-player-weather="&aYour local weather has been changed to &6{weather}&a."
option-apply-spawn-limit="&cThis claim has reached the &a{type}&c spawn limit of &6{limit}&c and can no longer spawn any more."
option-description-abandon-delay="&aLe nombre de jours avant qu'une nouvelle protection créée puisse être abandonnée."
option-description-abandon-return-ratio="&aLa portion de bloc de protection basique rendu au joueur quand une protection est abandonnée."
option-description-blocks-accrued-per-hour="&aBlocs gagnés par heure.\n&dNote&f: Regarde /playerinfo pour plus d'informations."
@ -443,7 +449,8 @@ GriefDefender {
option-description-min-size-x="&aLa taille minimum de blocs l'axe x peut être."
option-description-min-size-y="&aLa taille minimum de blocs l'axe y peut être."
option-description-min-size-z="&aLa taille minimum de blocs l'axe z peut être."
option-description-player-command="&aUtilisé pour exécuter une commande avec un contexte spécifique."
option-description-player-command-enter="&aUsed for executing a command with specific contexts when a player enters a claim."
option-description-player-command-exit="&aUsed for executing a command with specific contexts when a player exits a claim."
option-description-player-deny-flight="&aUtilisé pour déterminer si un joueur est incapable de fly dans une protection.\n&dNote&f: Cela ne donne pas l'abilité de fly au joueur, ça supprime juste l'abilité si elle a été donnée. Cela donne la meilleurs compatibilité avec les plugins."
option-description-player-deny-godmode="&aUtilisé pour déterminer si un joueur est incapable de godmode dans une protection.\n&dNote&f: Cela ne donne pas l'abilité de godmode au joueur, ça supprime juste l'abilité si elle a été donnée. Cela donne la meilleurs compatibilité avec les plugins."
option-description-player-deny-hunger="&aUtilisé pour refuser la famine dans une protection.\n&dNote&f: Cela ne donne pas l'abilité de gagner de la famine au joueur, ça supprime l'abilité de cause de la famine si défini. Cela donne la meilleurs compatibilité avec les plugins."
@ -451,10 +458,16 @@ GriefDefender {
option-description-player-health-regen="&aUtilisé pour définir le nombre de vies régénérée pour un joueur dans la protection.\n&dNote&f: Si le joueur a la vie au maximum, cela n'aura pas d'effet. \n&dNote&f: Une valeur de&6-1&f désactive cette option."
option-description-player-keep-inventory="&aUtilisé pour déterminer si un joueur à le droit de garder son inventaire après la mort dans une protection."
option-description-player-keep-level="&aUtilisé pour déterminer si un joueur à le droit de garder son niveau après la mort dans une protection."
option-description-player-teleport-delay="&aUsed to determine the delay before teleporting a player to a new location."
option-description-player-walk-speed="&aUtilisé pour définir la vitesse de marche dans une protection.\n&dNote&f: Une valeur de &6-1&f désactive cette option."
option-description-player-weather="&aUtilisé pour définir la météo d'un joueur dans une protection."
option-description-pvp="&aUsed to determine if players can combat each other."
option-description-pvp-combat-command="&aUsed to determine if a player can use commands during PvP combat."
option-description-pvp-combat-teleport="&aUsed to determine if a player can teleport during PvP combat."
option-description-pvp-combat-timeout="&aUsed to determine how many seconds PvP combat is considered to continue after the most recent damage."
option-description-radius-inspect="&aLe rayon de recherche pour les protections à proximité lors de l'inspection."
option-description-radius-list="&aLe rayon en blocs utilisés pour lister les protections à proximité."
option-description-spawn-limit="&aUsed to determine the spawn limit for a specific set of contexts in a claim."
option-description-tax-expiration="&aNombre de jour après ne pas avoir payé les taxes avant que la protection soi mise en demeure.\n&dNote&f: Une mise en demeure signifie que tu n'auras plus accès à la construction ou l'intération avec la protection jusqu'au paiement des taxes."
option-description-tax-expiration-days-keep="&aNombre de jour pour garder une protection basique mise en demeure et avant expiration.\n&dNote&f: Lors de l'expiration, une protection peut soit être restaurée à son état d'origine ou supprimée. Cela dépend de la configuration du serveur. Contacte un administrateur pour plus d'informations."
option-description-tax-rate="&aLe taux de taxe de la protection.\n&dNote&f: Le taux de taxe est calculé par le nombre de blocs de protection dans les protections basiques."
@ -465,6 +478,7 @@ GriefDefender {
option-not-set="{option}&f est actuellement non définit.\n&dNote&f: La valeur par défaut {value}&f de l'option sera active jusqu'à définition."
option-override-not-supported="&cProtection de type {type}&c ne supporte pas les options outrepassantes."
option-player-deny-flight="&cTu n'as pas accès au fly dans cette protection et a été téléporté dans une zone sécurisée au sol."
option-requires-contexts="&cThis option requres contexts '&a{contexts}&c' to be set."
option-reset-success="&aOption de la protection remises par défaut avec succès."
option-set-target="&aDéfinis {type}&a de l'option &b{option}&a à {value}&a avec le contexte &7{contexts}&a sur la cible &6{target}&a."
option-ui-click-toggle="Clique ici pour changer la valeur de {option}&f."
@ -497,7 +511,9 @@ GriefDefender {
permission-cuboid="&cTu n'as pas la permission pour créer/redimensionner les protections basiques en mode 3D."
permission-edit-claim="&cTu n'as pas la permission pour éditer cette protection."
permission-fire-spread="&cTu n'as pas la permission pour propager le feu dans cette protection."
permission-flag-arg="&cYou don't have permission to use the flag command with arguments."
permission-flag-defaults="&cTu n'as pas la permission pour gérer les flags par défaut."
permission-flag-gui="&cYou don't have permission to use the flag GUI."
permission-flag-overrides="&cTu n'as pas la permission pour gérer les flags outrepassant."
permission-flag-use="&cTu n'as pas la permission pour utiliser ce flag."
permission-flow-liquid="&cTu n'as pas la permission pour faire couler le liquide dans cette protection."
@ -554,6 +570,7 @@ GriefDefender {
plugin-not-found="&cImpossible de localiser le plug-in avec l'id &b{id}&c."
plugin-reload="&aGriefDefender a été rechargé."
pvp-claim-not-allowed="&aTu n'as pas le droit de PvP dans cette protection."
pvp-in-combat-not-allowed="&aYou cannot perform this action while in PvP combat. You must stay out of combat for &6{time-remaining}&a more seconds."
pvp-source-not-allowed="&aTu n'as pas le droit de PvP."
pvp-target-not-allowed="&aTu ne peut pas attaquer les joueurs qui ne participent pas au PvP."
registry-block-not-found="&cLe bloc {id} ne peut pas être trouvé dans le registre."

View File

@ -421,6 +421,12 @@ GriefDefender {
mode-nature="&aГотов восстанавливать природу! ПКМ для начала, &f/modebasic&c - для выхода из режима."
mode-subdivision="&aВключён режим создания суб-регионов. Используйте лопату, чтобы создавать суб-регионы в существующих регионах. Воспользуйтесь &f/modebasic&a, чтобы выйти из этого режима."
mode-town="&aВключён режим создания городов."
option-apply-player-deny-flight="&cУ вас нет разрешения на полёт в этом регионе, вы телепортированы в безопасное место на земле."
option-apply-player-deny-godmode="&cУ вас нет доступа к использованию режима бога в этом регионе."
option-apply-player-gamemode="&aВаш игровой режим изменён на &6{gamemode}&a." # doesn't the vanilla game have this message already?
option-apply-player-walk-speed="&aВаша скорость ходьбы изменена на &6{speed}&a."
option-apply-player-weather="&aВаша погода изменена на &6{weather}&a."
option-apply-spawn-limit="&cЭтот регион достиг лимита по количеству &a{type}&c, равного &6{limit}&c, и не может содержать больше."
option-description-abandon-delay="&aКоличество дней до того, как свежесозданный регион может быть удалён."
option-description-abandon-return-ratio="&aДоля базовых блоков региона, возвращаемых игроку при удалении региона."
option-description-blocks-accrued-per-hour="&aЗарабатываемые блоки в час.\n&dПримечание&f: См. /playerinfo."
@ -440,7 +446,8 @@ GriefDefender {
option-description-min-size-x="&aМинимальный размер региона по оси x."
option-description-min-size-y="&aМинимальный размер региона по оси y."
option-description-min-size-z="&aМинимальный размер региона по оси z."
option-description-player-command="&aИспользуется для выполнения команды в определённом контексте."
option-description-player-command-enter="&aИспользуется для запуска команды с определёнными контекстами при входе игрока в регион."
option-description-player-command-exit="&aИспользуется для запуска команды с определёнными контекстами при выходе игрока из региона."
option-description-player-deny-flight="&aОпределяет, может ли игрок летать в регионе.\n&dПримечание&f: не даёт игрокам возможность летать, только удаляет её при необходимости. Даёт наибольшую совместимость с другими плагинами."
option-description-player-deny-godmode="&aОпределяет, может ли игрок быть в режиме бога в регионе.\n&dПримечание&f: не даёт игрокам возможность входить в режим бога, только удаляет её при необходимости. Даёт наибольшую совместимость с другими плагинами."
option-description-player-deny-hunger="&aОпределяет, может ли игрок терять сытость в регионе.\n&dПримечание&f: не даёт игрокам получать сытость в регионе, только удаляет возможность её терять при необходимости. Даёт наибольшую совместимость с другими плагинами."
@ -448,10 +455,16 @@ GriefDefender {
option-description-player-health-regen="&aОпределяет скорость восстановления здоровья игроков в регионе.\n&dПримечание&f: не имеет эффекта на игроков с полным запасом здоровья. \n&dПримечание&f: значение &6-1&f отключает эту опцию."
option-description-player-keep-inventory="&aОпределяет, сохранит ли игрок содержимое своего инвентаря при смерти в регионе."
option-description-player-keep-level="&aОпределяет, сохранит ли игрок свой уровень при смерти в регионе."
option-description-player-teleport-delay="&aЗадержка перед телепортацией игрока в новое место."
option-description-player-walk-speed="&aОпределяет скорость ходьбы игроков в регионе.\n&dПримечание&f: значение &6-1&f отключает эту опцию."
option-description-player-weather="&aОпределяет погоду для игрока в регионе."
option-description-pvp="&aОпределяет, могут ли игроки драться друг с другом."
option-description-pvp-combat-command="&aОпределяет, может ли игрок использовать команды во время PvP."
option-description-pvp-combat-teleport="&aОпределяет, может ли игрок телепортироваться во время PvP."
option-description-pvp-combat-timeout="&aОпределяет, сколько драка в PvP считается продолжающейся после последнего получения урона."
option-description-radius-inspect="&aРадиус в блоках для поиска регионов поблизости при инспектировании."
option-description-radius-list="&aРадиус в блоках для составления списка регионов поблизости."
option-description-spawn-limit="&aОпределяет предел появления сущностей в регионе для определённых контекстов."
option-description-tax-expiration="&aКоличество дней без оплаты налогов, после которых регион будет заморожен.\n&dПримечание&f: заморозка означает отсутствие доступа к строительству и инвентарям в регионе до совершения оплаты."
option-description-tax-expiration-days-keep="&aКоличество дней после заморозки региона до его удаления.\n&dПримечание&f: по истечении срока регион может быть просто удалён или откачен на состояние при создании. Это зависит от настроек сервера. Свяжитесь с администратором для дополнительной информации."
option-description-tax-rate="&aВеличина налога на регион.\n&dПримечание&f: величина налога вычисляется по размеру региона в блоках."
@ -462,6 +475,7 @@ GriefDefender {
option-not-set="&a{option}&f не установлена.\nПрименяется стандартное значение &a{value}&f."
option-override-not-supported="&cРегионы вида &f{type}&c не поддерживают переопределение опций."
option-player-deny-flight="&cУ вас нет разрешения на полёт в этом регионе. Вы были телепортированы на безопасное место на земле."
option-requires-contexts="&cЭта опция требует следующие контексты: '&a{contexts}&c'."
option-reset-success="&aОпции региона успешно откачены на стандартные значения."
option-set-target="&aОпция &b{option}&a вида &b{type}&a с контекстами &7{contexts}&a установлена в значение {value}&a для &6{target}&a."
option-ui-click-toggle="Нажмите здесь, чтобы переключить опцию &f{option}&r."
@ -494,7 +508,9 @@ GriefDefender {
permission-cuboid="&cУ вас нет разрешения на создание/изменение размера базовых регионов в 3D-режиме."
permission-edit-claim="&cУ вас нет разрешения на изменение этого региона."
permission-fire-spread="&cУ вас нет разрешения на поджигание блоков в этом регионе."
permission-flag-arg="&cУ вас нет разрешения на использование команды flag с аргументами."
permission-flag-defaults="&cУ вас нет разрешения на изменение стандартных значений флагов."
permission-flag-gui="&cУ вас нет разрешения на использование GUI флагов."
permission-flag-overrides="&cУ вас нет разрешения на редактирование переопределённых значений флагов."
permission-flag-use="&cУ вас нет разрешения на использование этого флага."
permission-flow-liquid="&cУ вас нет разрешения на разливание жидкостей в этом регионе."
@ -551,6 +567,7 @@ GriefDefender {
plugin-not-found="&cНе удалось найти плагин с идентификатором &b{id}&c."
plugin-reload="&aGriefDefender перезагружен."
pvp-claim-not-allowed="&aВ этом регионе сражения между игроками запрещены."
pvp-in-combat-not-allowed="&aВы не можете выполнить это действие, находясь в PvP-драке. Вы должны быть в безопасности ещё &6{time-remaining}&a секунд."
pvp-source-not-allowed="&aУ вас нет разрешения на сражение с другим игроком."
pvp-target-not-allowed="&aВы не можете атаковать игроков, которые не могут участвовать в сражениях."
registry-block-not-found="&cБлок {id}&c не найден в реестре."

View File

@ -27,17 +27,16 @@ package com.griefdefender;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import com.google.common.reflect.TypeToken;
import com.griefdefender.api.Tristate;
import com.griefdefender.api.claim.Claim;
import com.griefdefender.api.claim.ClaimType;
import com.griefdefender.api.claim.ShovelType;
import com.griefdefender.api.claim.ShovelTypes;
import com.griefdefender.api.data.PlayerData;
import com.griefdefender.api.permission.Context;
import com.griefdefender.api.permission.flag.Flag;
import com.griefdefender.api.permission.option.Options;
import com.griefdefender.api.permission.option.type.CreateModeType;
import com.griefdefender.api.permission.option.type.CreateModeTypes;
import com.griefdefender.api.permission.option.type.WeatherType;
import com.griefdefender.cache.EventResultCache;
import com.griefdefender.cache.MessageCache;
import com.griefdefender.cache.PermissionHolderCache;
@ -53,9 +52,7 @@ import net.kyori.text.Component;
import org.spongepowered.api.Sponge;
import org.spongepowered.api.block.BlockSnapshot;
import org.spongepowered.api.data.Transaction;
import org.spongepowered.api.data.key.Keys;
import org.spongepowered.api.entity.living.player.Player;
import org.spongepowered.api.entity.living.player.User;
import org.spongepowered.api.scheduler.Task;
import org.spongepowered.api.service.economy.Currency;
import org.spongepowered.api.service.economy.account.Account;
@ -64,6 +61,7 @@ import org.spongepowered.api.world.World;
import java.lang.ref.WeakReference;
import java.math.BigDecimal;
import java.time.Duration;
import java.time.Instant;
import java.util.ArrayList;
import java.util.HashSet;
@ -122,6 +120,7 @@ public class GDPlayerData implements PlayerData {
public Location<World> teleportLocation;
public Instant lastPvpTimestamp;
public WeatherType lastWeatherType;
// cached global option values
public int minClaimLevel;
@ -519,45 +518,6 @@ public class GDPlayerData implements PlayerData {
return this.ignoreBasicClaims;
}
public boolean canManageOption(Player player, GDClaim claim, boolean isGroup) {
if (claim.allowEdit(player) != null) {
return false;
}
if (claim.isWilderness()) {
return player.hasPermission(GDPermissions.MANAGE_WILDERNESS);
}
if (isGroup) {
if (claim.isTown() && player.hasPermission(GDPermissions.COMMAND_CLAIM_OPTIONS_GROUP_TOWN)) {
return true;
}
if (claim.isAdminClaim() && player.hasPermission(GDPermissions.COMMAND_CLAIM_OPTIONS_GROUP_ADMIN)) {
return true;
}
if (claim.isBasicClaim() && player.hasPermission(GDPermissions.COMMAND_CLAIM_OPTIONS_GROUP_BASIC)) {
return true;
}
if (claim.isSubdivision() && player.hasPermission(GDPermissions.COMMAND_CLAIM_OPTIONS_GROUP_SUBDIVISION)) {
return true;
}
} else {
if (claim.isTown() && player.hasPermission(GDPermissions.COMMAND_CLAIM_OPTIONS_PLAYER_TOWN)) {
return true;
}
if (claim.isAdminClaim() && player.hasPermission(GDPermissions.COMMAND_CLAIM_OPTIONS_PLAYER_ADMIN)) {
return true;
}
if (claim.isBasicClaim() && player.hasPermission(GDPermissions.COMMAND_CLAIM_OPTIONS_PLAYER_BASIC)) {
return true;
}
if (claim.isSubdivision() && player.hasPermission(GDPermissions.COMMAND_CLAIM_OPTIONS_PLAYER_SUBDIVISION)) {
return true;
}
}
return false;
}
@Override
public int getMaxAccruedClaimBlocks() {
return GDPermissionManager.getInstance().getInternalOptionValue(TypeToken.of(Integer.class), this.getSubject(), Options.MAX_ACCRUED_BLOCKS);
@ -670,13 +630,18 @@ public class GDPlayerData implements PlayerData {
return totalTax;
}
public boolean inPvpCombat(World world) {
if (this.lastPvpTimestamp == null) {
public boolean inPvpCombat() {
final Player player = this.getSubject().getOnlinePlayer();
if (this.lastPvpTimestamp == null || player == null) {
return false;
}
final Instant now = Instant.now();
final int combatTimeout = GriefDefenderPlugin.getActiveConfig(world.getProperties()).getConfig().pvp.combatTimeout;
final int combatTimeout = GDPermissionManager.getInstance().getInternalOptionValue(TypeToken.of(Integer.class), player, Options.PVP_COMBAT_TIMEOUT);
if (combatTimeout <= 0) {
return false;
}
if (this.lastPvpTimestamp.plusSeconds(combatTimeout).isBefore(now)) {
this.lastPvpTimestamp = null;
return false;
@ -685,6 +650,34 @@ public class GDPlayerData implements PlayerData {
return true;
}
public int getPvpCombatTimeRemaining() {
final Player player = this.getSubject().getOnlinePlayer();
if (this.lastPvpTimestamp == null || player == null) {
return 0;
}
final Instant now = Instant.now();
final int combatTimeout = GDPermissionManager.getInstance().getInternalOptionValue(TypeToken.of(Integer.class), player, Options.PVP_COMBAT_TIMEOUT);
if (combatTimeout <= 0) {
return 0;
}
if (this.lastPvpTimestamp.plusSeconds(combatTimeout).isBefore(now)) {
this.lastPvpTimestamp = null;
return 0;
}
final int duration = (int) Duration.between(this.lastPvpTimestamp, now).getSeconds();
return combatTimeout - duration;
}
public void onClaimDelete() {
this.lastShovelLocation = null;
this.eventResultCache = null;
this.claimResizing = null;
this.claimSubdividing = null;
}
public void onDisconnect() {
this.visualBlocks.clear();
this.claimMode = false;

View File

@ -286,7 +286,6 @@ public class GriefDefenderPlugin {
public GDBlockType createVisualBlock;
public GDItemType modificationTool;
public GDItemType investigationTool;
public int maxInspectionDistance = 100;
public static boolean debugLogging = false;
public static boolean debugActive = false;
@ -942,7 +941,6 @@ public class GriefDefenderPlugin {
this.createVisualBlock = BlockTypeRegistryModule.getInstance().getById(BaseStorage.globalConfig.getConfig().visual.claimCreateStartBlock).orElse(defaultCreateVisualBlock);
this.modificationTool = ItemTypeRegistryModule.getInstance().getById(BaseStorage.globalConfig.getConfig().claim.modificationTool).orElse(defaultModTool);
this.investigationTool = ItemTypeRegistryModule.getInstance().getById(BaseStorage.globalConfig.getConfig().claim.investigationTool).orElse(ItemTypeRegistryModule.getInstance().getById("minecraft:stick").get());
this.maxInspectionDistance = BaseStorage.globalConfig.getConfig().general.maxClaimInspectionDistance;
if (this.dataStore != null) {
for (World world : Sponge.getGame().getServer().getWorlds()) {
DimensionType dimType = world.getProperties().getDimensionType();

View File

@ -249,6 +249,7 @@ public class MessageCache {
public Component FLAG_UI_OVERRIDE_NO_PERMISSION;
public Component FLAG_UI_RETURN_FLAGS;
public Component LABEL_ACCESSORS;
public Component LABEL_ALL;
public Component LABEL_AREA;
public Component LABEL_BLOCKS;
public Component LABEL_BUILDERS;
@ -292,6 +293,8 @@ public class MessageCache {
public Component MODE_NATURE;
public Component MODE_SUBDIVISION;
public Component MODE_TOWN;
public Component OPTION_APPLY_PLAYER_DENY_FLIGHT;
public Component OPTION_APPLY_PLAYER_DENY_GODMODE;
public Component OPTION_DESCRIPTION_ABANDON_DELAY;
public Component OPTION_DESCRIPTION_ABANDON_RETURN_RATIO;
public Component OPTION_DESCRIPTION_BLOCKS_ACCRUED_PER_HOUR;
@ -311,7 +314,8 @@ public class MessageCache {
public Component OPTION_DESCRIPTION_MIN_SIZE_X;
public Component OPTION_DESCRIPTION_MIN_SIZE_Y;
public Component OPTION_DESCRIPTION_MIN_SIZE_Z;
public Component OPTION_DESCRIPTION_PLAYER_COMMAND;
public Component OPTION_DESCRIPTION_PLAYER_COMMAND_ENTER;
public Component OPTION_DESCRIPTION_PLAYER_COMMAND_EXIT;
public Component OPTION_DESCRIPTION_PLAYER_DENY_FLIGHT;
public Component OPTION_DESCRIPTION_PLAYER_DENY_GODMODE;
public Component OPTION_DESCRIPTION_PLAYER_DENY_HUNGER;
@ -326,7 +330,7 @@ public class MessageCache {
public Component OPTION_DESCRIPTION_TAX_EXPIRATION;
public Component OPTION_DESCRIPTION_TAX_EXPIRATION_DAYS_KEEP;
public Component OPTION_DESCRIPTION_TAX_RATE;
public Component OPTION_PLAYER_DENY_FLIGHT;
public Component OPTION_UI_CLICK_REMOVE;
public Component OWNER_ADMIN;
public Component PERMISSION_ASSIGN_WITHOUT_HAVING;
public Component PERMISSION_CLAIM_CREATE;
@ -345,6 +349,8 @@ public class MessageCache {
public Component PERMISSION_FIRE_SPREAD;
public Component PERMISSION_FLAG_DEFAULTS;
public Component PERMISSION_FLAG_OVERRIDES;
public Component PERMISSION_FLAG_ARG;
public Component PERMISSION_FLAG_GUI;
public Component PERMISSION_FLAG_USE;
public Component PERMISSION_FLOW_LIQUID;
public Component PERMISSION_GLOBAL_OPTION;
@ -607,6 +613,7 @@ public class MessageCache {
FLAG_UI_OVERRIDE_NO_PERMISSION = MessageStorage.MESSAGE_DATA.getMessage("flag-ui-override-no-permission");
FLAG_UI_RETURN_FLAGS = MessageStorage.MESSAGE_DATA.getMessage("flag-ui-return-flags");
LABEL_ACCESSORS = MessageStorage.MESSAGE_DATA.getMessage("label-accessors");
LABEL_ALL = MessageStorage.MESSAGE_DATA.getMessage("label-all");
LABEL_AREA = MessageStorage.MESSAGE_DATA.getMessage("label-area");
LABEL_BLOCKS = MessageStorage.MESSAGE_DATA.getMessage("label-blocks");
LABEL_BUILDERS = MessageStorage.MESSAGE_DATA.getMessage("label-builders");
@ -669,7 +676,8 @@ public class MessageCache {
OPTION_DESCRIPTION_MIN_SIZE_X = MessageStorage.MESSAGE_DATA.getMessage("option-description-min-size-x");
OPTION_DESCRIPTION_MIN_SIZE_Y = MessageStorage.MESSAGE_DATA.getMessage("option-description-min-size-y");
OPTION_DESCRIPTION_MIN_SIZE_Z = MessageStorage.MESSAGE_DATA.getMessage("option-description-min-size-z");
OPTION_DESCRIPTION_PLAYER_COMMAND = MessageStorage.MESSAGE_DATA.getMessage("option-description-player-command");
OPTION_DESCRIPTION_PLAYER_COMMAND_ENTER = MessageStorage.MESSAGE_DATA.getMessage("option-description-player-command-enter");
OPTION_DESCRIPTION_PLAYER_COMMAND_EXIT = MessageStorage.MESSAGE_DATA.getMessage("option-description-player-command-exit");
OPTION_DESCRIPTION_PLAYER_DENY_FLIGHT = MessageStorage.MESSAGE_DATA.getMessage("option-description-player-deny-flight");
OPTION_DESCRIPTION_PLAYER_DENY_GODMODE = MessageStorage.MESSAGE_DATA.getMessage("option-description-player-deny-godmode");
OPTION_DESCRIPTION_PLAYER_DENY_HUNGER = MessageStorage.MESSAGE_DATA.getMessage("option-description-player-deny-hunger");
@ -684,7 +692,9 @@ public class MessageCache {
OPTION_DESCRIPTION_TAX_EXPIRATION = MessageStorage.MESSAGE_DATA.getMessage("option-description-tax-expiration");
OPTION_DESCRIPTION_TAX_EXPIRATION_DAYS_KEEP = MessageStorage.MESSAGE_DATA.getMessage("option-description-tax-expiration-days-keep");
OPTION_DESCRIPTION_TAX_RATE = MessageStorage.MESSAGE_DATA.getMessage("option-description-tax-rate");
OPTION_PLAYER_DENY_FLIGHT = MessageStorage.MESSAGE_DATA.getMessage("option-player-deny-flight");
OPTION_APPLY_PLAYER_DENY_FLIGHT = MessageStorage.MESSAGE_DATA.getMessage("option-apply-player-deny-flight");
OPTION_APPLY_PLAYER_DENY_GODMODE = MessageStorage.MESSAGE_DATA.getMessage("option-apply-player-deny-godmode");
OPTION_UI_CLICK_REMOVE = MessageStorage.MESSAGE_DATA.getMessage("option-ui-click-remove");
OWNER_ADMIN = MessageStorage.MESSAGE_DATA.getMessage("owner-admin");
PERMISSION_ASSIGN_WITHOUT_HAVING = MessageStorage.MESSAGE_DATA.getMessage("permission-assign-without-having");
PERMISSION_CLAIM_CREATE = MessageStorage.MESSAGE_DATA.getMessage("permission-claim-create");
@ -703,6 +713,8 @@ public class MessageCache {
PERMISSION_FIRE_SPREAD = MessageStorage.MESSAGE_DATA.getMessage("permission-fire-spread");
PERMISSION_FLAG_DEFAULTS = MessageStorage.MESSAGE_DATA.getMessage("permission-flag-defaults");
PERMISSION_FLAG_OVERRIDES = MessageStorage.MESSAGE_DATA.getMessage("permission-flag-overrides");
PERMISSION_FLAG_ARG = MessageStorage.MESSAGE_DATA.getMessage("permission-flag-arg");
PERMISSION_FLAG_GUI = MessageStorage.MESSAGE_DATA.getMessage("permission-flag-gui");
PERMISSION_FLAG_USE = MessageStorage.MESSAGE_DATA.getMessage("permission-flag-use");
PERMISSION_FLOW_LIQUID = MessageStorage.MESSAGE_DATA.getMessage("permission-flow-liquid");
PERMISSION_GLOBAL_OPTION = MessageStorage.MESSAGE_DATA.getMessage("permission-global-option");

View File

@ -49,7 +49,6 @@ import com.griefdefender.api.claim.ShovelTypes;
import com.griefdefender.api.claim.TrustType;
import com.griefdefender.api.claim.TrustTypes;
import com.griefdefender.api.data.ClaimData;
import com.griefdefender.api.event.EventCause;
import com.griefdefender.api.permission.Context;
import com.griefdefender.api.permission.option.Options;
import com.griefdefender.cache.MessageCache;
@ -57,7 +56,6 @@ import com.griefdefender.cache.PermissionHolderCache;
import com.griefdefender.configuration.ClaimDataConfig;
import com.griefdefender.configuration.ClaimStorageData;
import com.griefdefender.configuration.IClaimData;
import com.griefdefender.configuration.MessageDataConfig;
import com.griefdefender.configuration.MessageStorage;
import com.griefdefender.configuration.TownDataConfig;
import com.griefdefender.configuration.TownStorageData;
@ -77,7 +75,6 @@ import com.griefdefender.permission.GDPermissionUser;
import com.griefdefender.permission.GDPermissions;
import com.griefdefender.registry.TrustTypeRegistryModule;
import com.griefdefender.storage.BaseStorage;
import com.griefdefender.storage.FileStorage;
import com.griefdefender.util.EconomyUtil;
import com.griefdefender.util.PermissionUtil;
import com.griefdefender.util.SpongeContexts;
@ -85,9 +82,12 @@ import com.griefdefender.util.SpongeUtil;
import net.kyori.text.Component;
import net.kyori.text.TextComponent;
import net.kyori.text.format.TextColor;
import net.kyori.text.serializer.plain.PlainComponentSerializer;
import org.checkerframework.checker.nullness.qual.Nullable;
import org.spongepowered.api.Sponge;
import org.spongepowered.api.command.CommandSource;
import org.spongepowered.api.entity.Entity;
import org.spongepowered.api.entity.EntityType;
import org.spongepowered.api.entity.living.player.Player;
import org.spongepowered.api.entity.living.player.User;
import org.spongepowered.api.event.cause.Cause;
@ -378,6 +378,14 @@ public class GDClaim implements Claim {
return this.claimData.getName();
}
public String getFriendlyName() {
final Component claimName = this.claimData.getName().orElse(null);
if (claimName == null) {
return "none";
}
return PlainComponentSerializer.INSTANCE.serialize(claimName);
}
public Component getFriendlyNameType() {
return this.getFriendlyNameType(false);
}
@ -531,6 +539,20 @@ public class GDClaim implements Claim {
return TextComponent.of(this.getOwnerPlayerData().getPlayerName());
}
public String getOwnerFriendlyName() {
if (this.isAdminClaim()) {
return "administrator";
}
if (this.isWilderness()) {
return "wilderness";
}
final GDPlayerData playerData = this.ownerPlayerData;
if (playerData == null) {
return "[unknown]";
}
return playerData.getPlayerName();
}
@Override
public boolean contains(Vector3i pos, boolean excludeChildren) {
return this.contains(pos.getX(), pos.getY(), pos.getZ(), excludeChildren, null, false);
@ -2026,6 +2048,19 @@ public class GDClaim implements Claim {
return new GDClaimResult(ClaimResultType.SUCCESS);
}
public int countEntities(EntityType type) {
int count = 0;
for (Chunk chunk : this.getChunks()) {
for (Entity entity : chunk.getEntities()) {
if (entity.getType().equals(type)) {
count++;
}
}
}
return count;
}
@Override
public boolean equals(Object o) {
if (this == o) {

View File

@ -113,6 +113,8 @@ public abstract class ClaimFlagBase extends BaseCommand {
public void execute(Player player, String[] args) throws InvalidCommandArgument {
final GDPermissionUser src = PermissionHolderCache.getInstance().getOrCreateUser(player);
final GDPermissionHolder commandSubject = subject;
final GDPlayerData playerData = src.getInternalPlayerData();
final GDClaim claim = GriefDefenderPlugin.getInstance().dataStore.getClaimAtPlayer(playerData, player.getLocation());
String commandFlag = null;
String target = null;
String value = null;
@ -123,12 +125,21 @@ public abstract class ClaimFlagBase extends BaseCommand {
contexts = arguments.substring(index, arguments.length());
}
if (args.length > 0) {
if (!src.getInternalPlayerData().canIgnoreClaim(claim) && !player.hasPermission(GDPermissions.COMMAND_FLAGS_CLAIM_ARG)) {
TextAdapter.sendComponent(player, MessageCache.getInstance().PERMISSION_FLAG_ARG);
return;
}
if (args.length < 3) {
throw new InvalidCommandArgument();
}
commandFlag = args[0];
target = args[1];
value = args[2];
} else {
if (!src.getInternalPlayerData().canIgnoreClaim(claim) && !player.hasPermission(GDPermissions.COMMAND_FLAGS_CLAIM_GUI)) {
TextAdapter.sendComponent(player, MessageCache.getInstance().PERMISSION_FLAG_GUI);
return;
}
}
final Flag flag = FlagRegistryModule.getInstance().getById(commandFlag).orElse(null);
if (commandFlag != null && flag == null) {
@ -149,9 +160,7 @@ public abstract class ClaimFlagBase extends BaseCommand {
}
}
final GDPlayerData playerData = GriefDefenderPlugin.getInstance().dataStore.getOrCreatePlayerData(player.getWorld(), player.getUniqueId());
GDClaim claim = GriefDefenderPlugin.getInstance().dataStore.getClaimAtPlayer(playerData, player.getLocation());
final Set<Context> contextSet = CauseContextHelper.generateContexts(player, claim, contexts);
final Set<Context> contextSet = CauseContextHelper.generateContexts(flag.getPermission(), player, claim, contexts);
if (contextSet == null) {
return;
}
@ -911,7 +920,6 @@ public abstract class ClaimFlagBase extends BaseCommand {
newValue = Tristate.UNDEFINED;
}
PermissionResult result = null;
final Flag flag = flagData.getFlag();
GDFlagPermissionEvent.Set event = new GDFlagPermissionEvent.Set(this.subject, flagData.getFlag(), newValue, newContexts);
GriefDefender.getEventManager().post(event);
@ -919,8 +927,11 @@ public abstract class ClaimFlagBase extends BaseCommand {
return;
}
result = GriefDefenderPlugin.getInstance().getPermissionProvider().setPermissionValue(GriefDefenderPlugin.DEFAULT_HOLDER, flag, newValue, newContexts);
PermissionResult 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, displayType);
};

View File

@ -91,6 +91,8 @@ import java.util.TreeMap;
import java.util.UUID;
import java.util.concurrent.TimeUnit;
import java.util.function.Consumer;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@SuppressWarnings({ "unchecked", "rawtypes" })
public abstract class ClaimOptionBase extends BaseCommand {
@ -121,17 +123,31 @@ public abstract class ClaimOptionBase extends BaseCommand {
throw new InvalidCommandArgument();
}
commandOption = args[0];
value = args[1];
// Check for quoted string
Pattern pattern = Pattern.compile("\"(.*)\"");
Matcher matcher = pattern.matcher(arguments);
if (matcher.find()) {
value = matcher.group(1);
} else {
value = args[1];
}
}
Option option = null;
Option<?> option = null;
if (commandOption != null) {
option = GriefDefender.getRegistry().getType(Option.class, commandOption).orElse(null);
if (commandOption != null && option == null) {
if (option == null) {
TextAdapter.sendComponent(player, MessageStorage.MESSAGE_DATA.getMessage(MessageStorage.OPTION_NOT_FOUND, ImmutableMap.of(
"option", commandOption)));
return;
}
if (option == Options.PLAYER_COMMAND_ENTER || option == Options.PLAYER_COMMAND_EXIT) {
if (contexts == null) {
TextAdapter.sendComponent(player, MessageStorage.MESSAGE_DATA.getMessage(MessageStorage.OPTION_REQUIRES_CONTEXTS, ImmutableMap.of(
"contexts", "run-as=[player|console] run-for=[public|owner|member]")));
return;
}
}
}
final GDPlayerData playerData = GriefDefenderPlugin.getInstance().dataStore.getOrCreatePlayerData(player.getWorld(), player.getUniqueId());
@ -142,7 +158,7 @@ public abstract class ClaimOptionBase extends BaseCommand {
return;
}
} else if (!claim.isTown() && !playerData.canManageAdminClaims && !playerData.canIgnoreClaim(claim)) {
GriefDefenderPlugin.sendMessage(player, MessageCache.getInstance().PERMISSION_GLOBAL_OPTION);
GriefDefenderPlugin.sendMessage(player, MessageCache.getInstance().PERMISSION_PLAYER_OPTION);
return;
}
if (option != null) {
@ -165,10 +181,32 @@ public abstract class ClaimOptionBase extends BaseCommand {
}
}
final Set<Context> contextSet = CauseContextHelper.generateContexts(player, claim, contexts);
final Set<Context> contextSet = CauseContextHelper.generateContexts(option.getPermission(), player, claim, contexts);
if (contextSet == null) {
return;
}
if (option == Options.PLAYER_COMMAND_ENTER || option == Options.PLAYER_COMMAND_EXIT) {
final Set<String> requiredKeys = (Set<String>) option.getRequiredContextKeys();
for (String key : requiredKeys) {
boolean found = false;
for (Context context : contextSet) {
if (context.getKey().equalsIgnoreCase(key)) {
found = true;
break;
}
}
if (!found) {
TextAdapter.sendComponent(player, MessageStorage.MESSAGE_DATA.getMessage(MessageStorage.OPTION_REQUIRES_CONTEXTS, ImmutableMap.of(
"contexts", key)));
return;
}
}
if (contexts == null) {
TextAdapter.sendComponent(player, MessageStorage.MESSAGE_DATA.getMessage(MessageStorage.OPTION_REQUIRES_CONTEXTS, ImmutableMap.of(
"contexts", "run-as=[player|console] run-for=[public|owner|member]")));
return;
}
}
if (claim != null) {
if (commandOption == null && value == null && player.hasPermission(GDPermissions.COMMAND_LIST_CLAIM_OPTIONS)) {
@ -521,7 +559,11 @@ public abstract class ClaimOptionBase extends BaseCommand {
}
}
final boolean customContexts = UIHelper.containsCustomContext(contexts);
boolean customContexts = UIHelper.containsCustomContext(contexts);
// special case
if (option == Options.PLAYER_COMMAND_ENTER || option == Options.PLAYER_COMMAND_EXIT) {
customContexts = true;
}
Component optionContexts = UIHelper.getFriendlyContextString(claim, contexts);
String currentValue = optionHolder.getValue();
TextColor color = optionHolder.getColor();
@ -549,11 +591,12 @@ public abstract class ClaimOptionBase extends BaseCommand {
}
if (hasEditPermission) {
if (!option.getAllowedType().isAssignableFrom(Integer.class) && !option.getAllowedType().isAssignableFrom(Double.class)) {
this.appendContexts(builder, contexts);
builder.clickEvent(ClickEvent.runCommand(GDCallbackHolder.getInstance().createCallbackRunCommand(newOptionValueConsumer(src, claim, option, optionHolder, contexts, displayType, false))));
} else {
builder.append(TextComponent.builder()
.append(TextComponent.of(" >").decoration(TextDecoration.BOLD, true))
.clickEvent(ClickEvent.runCommand(GDCallbackHolder.getInstance().createCallbackRunCommand(newOptionValueConsumer(src, claim, option, optionHolder, contexts, displayType, false)))));
builder.append(TextComponent.builder().append(TextComponent.of(" >").decoration(TextDecoration.BOLD, true)));
this.appendContexts(builder, contexts);
builder.clickEvent(ClickEvent.runCommand(GDCallbackHolder.getInstance().createCallbackRunCommand(newOptionValueConsumer(src, claim, option, optionHolder, contexts, displayType, false))));
}
if (option.getAllowedType().isAssignableFrom(String.class)) {
@ -568,9 +611,51 @@ public abstract class ClaimOptionBase extends BaseCommand {
"value", TextComponent.of(currentValue).color(TextColor.GOLD)))).build()));
}
if (customContexts) {
builder.append(" ")
.append("[", TextColor.WHITE)
.append(TextComponent.builder()
.append("x", TextColor.RED)
.hoverEvent(HoverEvent.showText(MessageCache.getInstance().FLAG_UI_CLICK_REMOVE))
.clickEvent(ClickEvent.runCommand(GDCallbackHolder.getInstance().createCallbackRunCommand(removeOptionValueConsumer(src, claim, option, optionHolder, contexts, displayType))))
.build())
.append("]", TextColor.WHITE);
}
return builder.build();
}
private void appendContexts(TextComponent.Builder builder, Set<Context> contexts) {
// check source/target
Component source = null;
Component target = null;
final Component whiteOpenBracket = TextComponent.of("[", TextColor.WHITE);
final Component whiteCloseBracket = TextComponent.of("]", TextColor.WHITE);
for (Context context : contexts) {
if (context.getKey().equals(ContextKeys.SOURCE)) {
source = TextComponent.builder()
.append(whiteOpenBracket)
.append("s", TextColor.GREEN)
.append("=", TextColor.WHITE)
.append(context.getValue().replace("minecraft:", ""), TextColor.GOLD)
.append(whiteCloseBracket)
.hoverEvent(HoverEvent.showText(MessageCache.getInstance().LABEL_SOURCE))
.build();
builder.append(" ").append(source);
} else if (context.getKey().equals(ContextKeys.TARGET)) {
target = TextComponent.builder()
.append(whiteOpenBracket)
.append("t", TextColor.GREEN)
.append("=", TextColor.WHITE)
.append(context.getValue().replace("minecraft:", ""), TextColor.GOLD)
.append(whiteCloseBracket)
.hoverEvent(HoverEvent.showText(MessageCache.getInstance().LABEL_TARGET))
.build();
builder.append(" ").append(target);
}
}
}
private boolean containsDefaultContext(Set<Context> contexts) {
for (Context context : contexts) {
if (context.getKey().contains("gd_claim_default")) {
@ -638,7 +723,7 @@ public abstract class ClaimOptionBase extends BaseCommand {
if (value == null || value == WeatherTypes.UNDEFINED) {
newValue = "clear";
} else if (value == WeatherTypes.CLEAR) {
newValue = "rain";
newValue = "downfall";
} else {
newValue = "undefined";
}
@ -722,6 +807,13 @@ public abstract class ClaimOptionBase extends BaseCommand {
};
}
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);
};
}
private Consumer<CommandSource> adjustNumberConsumer(GDPermissionUser src, GDClaim claim, Option option, String currentValue, MenuType menuType, Set<Context> contexts) {
return consumer -> {
String newValue = "";
@ -882,8 +974,8 @@ public abstract class ClaimOptionBase extends BaseCommand {
if (value.equalsIgnoreCase("clear")) {
return (T) WeatherTypes.CLEAR;
}
if (value.equalsIgnoreCase("rain")) {
return (T) WeatherTypes.RAIN;
if (value.equalsIgnoreCase("downfall")) {
return (T) WeatherTypes.DOWNFALL;
}
}
if (type.getRawType().isAssignableFrom(CreateModeType.class)) {

View File

@ -178,6 +178,7 @@ public class CommandClaimAbandon extends BaseCommand {
return;
}
playerData.onClaimDelete();
// remove all context permissions
PermissionUtil.getInstance().clearPermissions(claim);
playerData.revertActiveVisual(player);

View File

@ -155,6 +155,7 @@ public class CommandClaimAbandonAll extends BaseCommand {
playerData.useRestoreSchematic = event.isRestoring();
GriefDefenderPlugin.getInstance().dataStore.abandonClaimsForPlayer(user, allowedClaims);
playerData.useRestoreSchematic = false;
playerData.onClaimDelete();
if (GriefDefenderPlugin.getInstance().isEconomyModeEnabled()) {
final Account playerAccount = GriefDefenderPlugin.getInstance().economyService.get().getOrCreateAccount(playerData.playerID).orElse(null);

View File

@ -105,6 +105,7 @@ public class CommandClaimDelete extends BaseCommand {
return;
}
playerData.onClaimDelete();
PermissionUtil.getInstance().clearPermissions((GDClaim) claim);
playerData.revertActiveVisual(player);

View File

@ -98,6 +98,7 @@ public class CommandClaimDeleteAll extends BaseCommand {
}
GriefDefenderPlugin.getInstance().dataStore.deleteClaimsForPlayer(otherPlayer.getUniqueId());
playerData.onClaimDelete();
if (src != null) {
final Component message = GriefDefenderPlugin.getInstance().messageData.getMessage(MessageStorage.DELETE_ALL_PLAYER_SUCCESS, ImmutableMap.of(
"player", TextComponent.of(otherPlayer.getName()).color(TextColor.AQUA)));

View File

@ -83,7 +83,8 @@ public class CommandClaimDeleteAllAdmin extends BaseCommand {
GriefDefenderPlugin.sendMessage(player, GriefDefenderPlugin.getInstance().messageData.getMessage(MessageStorage.DELETE_ALL_TYPE_SUCCESS,
ImmutableMap.of("type", TextComponent.of("ADMIN").color(TextColor.RED))));
GDPlayerData playerData = GriefDefenderPlugin.getInstance().dataStore.getOrCreatePlayerData(player.getWorld(), player.getUniqueId());
final GDPlayerData playerData = GriefDefenderPlugin.getInstance().dataStore.getOrCreatePlayerData(player.getWorld(), player.getUniqueId());
playerData.onClaimDelete();
playerData.revertActiveVisual(player);
};
}

View File

@ -55,7 +55,7 @@ public class CommandClaimFlagGroup extends ClaimFlagBase {
@Syntax("<group> <flag> <target> <value> [context[key=value]]")
@Subcommand("flag group")
public void execute(Player player, String group, @Optional String[] args) throws InvalidCommandArgument {
if (args.length < 2 || args.length > 3) {
if (args.length < 2 || args.length > 4) {
throw new InvalidCommandArgument();
}

View File

@ -24,7 +24,6 @@
*/
package com.griefdefender.command;
import co.aikar.commands.BaseCommand;
import co.aikar.commands.InvalidCommandArgument;
import co.aikar.commands.annotation.CommandAlias;
import co.aikar.commands.annotation.CommandCompletion;
@ -33,36 +32,10 @@ import co.aikar.commands.annotation.Description;
import co.aikar.commands.annotation.Optional;
import co.aikar.commands.annotation.Subcommand;
import co.aikar.commands.annotation.Syntax;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Lists;
import com.griefdefender.GDPlayerData;
import com.griefdefender.GriefDefenderPlugin;
import com.griefdefender.api.claim.ClaimContexts;
import com.griefdefender.api.permission.Context;
import com.griefdefender.api.permission.option.Option;
import com.griefdefender.cache.MessageCache;
import com.griefdefender.cache.PermissionHolderCache;
import com.griefdefender.claim.GDClaim;
import com.griefdefender.configuration.MessageStorage;
import com.griefdefender.internal.pagination.PaginationList;
import com.griefdefender.permission.GDPermissionHolder;
import com.griefdefender.permission.GDPermissionManager;
import com.griefdefender.permission.GDPermissions;
import com.griefdefender.registry.OptionRegistryModule;
import com.griefdefender.util.CauseContextHelper;
import com.griefdefender.util.PermissionUtil;
import net.kyori.text.Component;
import net.kyori.text.TextComponent;
import net.kyori.text.adapter.spongeapi.TextAdapter;
import net.kyori.text.format.TextColor;
import net.kyori.text.format.TextDecoration;
import org.spongepowered.api.command.CommandException;
import org.spongepowered.api.entity.living.player.Player;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import com.griefdefender.GriefDefenderPlugin;
import com.griefdefender.permission.GDPermissions;
import org.spongepowered.api.entity.living.player.Player;
@CommandAlias("%griefdefender")
@CommandPermission(GDPermissions.COMMAND_OPTIONS_CLAIM)

View File

@ -55,7 +55,7 @@ public class CommandClaimOptionGroup extends ClaimOptionBase {
@Syntax("<group> <option> <value> [context[key=value]]")
@Subcommand("option group")
public void execute(Player player, String group, @Optional String[] args) throws InvalidCommandArgument {
if (args.length < 2 || args.length > 3) {
if (args.length < 2 || args.length > 4) {
throw new InvalidCommandArgument();
}

View File

@ -25,7 +25,6 @@
package com.griefdefender.command;
import com.flowpowered.math.vector.Vector3i;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.reflect.TypeToken;
import com.google.gson.Gson;
@ -52,11 +51,9 @@ import com.griefdefender.cache.MessageCache;
import com.griefdefender.cache.PermissionHolderCache;
import com.griefdefender.claim.GDClaim;
import com.griefdefender.configuration.GriefDefenderConfig;
import com.griefdefender.configuration.MessageDataConfig;
import com.griefdefender.configuration.MessageStorage;
import com.griefdefender.economy.GDBankTransaction;
import com.griefdefender.internal.pagination.PaginationList;
import com.griefdefender.internal.util.NMSUtil;
import com.griefdefender.internal.util.VecHelper;
import com.griefdefender.internal.visual.ClaimVisual;
import com.griefdefender.permission.GDPermissionHolder;
@ -67,7 +64,6 @@ import com.griefdefender.permission.GDPermissions;
import com.griefdefender.permission.flag.GDFlag;
import com.griefdefender.permission.ui.MenuType;
import com.griefdefender.permission.ui.UIHelper;
import com.griefdefender.registry.FlagRegistryModule;
import com.griefdefender.text.action.GDCallbackHolder;
import com.griefdefender.util.PermissionUtil;
import com.griefdefender.util.TaskUtil;
@ -89,7 +85,6 @@ import org.spongepowered.api.command.CommandSource;
import org.spongepowered.api.data.property.entity.EyeLocationProperty;
import org.spongepowered.api.entity.EntityType;
import org.spongepowered.api.entity.living.player.Player;
import org.spongepowered.api.entity.living.player.User;
import org.spongepowered.api.event.CauseStackManager;
import org.spongepowered.api.item.ItemType;
import org.spongepowered.api.plugin.PluginContainer;
@ -99,7 +94,6 @@ import org.spongepowered.api.service.economy.account.Account;
import org.spongepowered.api.service.economy.account.UniqueAccount;
import org.spongepowered.api.service.economy.transaction.ResultType;
import org.spongepowered.api.service.economy.transaction.TransactionResult;
import org.spongepowered.api.world.DimensionTypes;
import org.spongepowered.api.world.Location;
import org.spongepowered.api.world.World;
@ -139,15 +133,15 @@ public class CommandHelper {
return true;
}
if (flag.getName().equals("block-break") || flag.getName().equals("block-place") || flag.getName().equals("collide-block")) {
if (flag == Flags.BLOCK_BREAK || flag == Flags.BLOCK_PLACE || flag == Flags.COLLIDE_BLOCK) {
if (validateBlockTarget(target) ||
validateItemTarget(target)) {
return true;
}
return false;
}
if (flag.getName().equals("enter-claim") || flag.getName().equals("exit-claim") || flag.getName().equals("entity-riding") ||
flag.getName().equals("entity-damage") || flag.getName().equals("portal-use")) {
if (flag == Flags.ENTER_CLAIM || flag == Flags.EXIT_CLAIM || flag == Flags.ENTITY_RIDING ||
flag == Flags.ENTITY_DAMAGE || flag == Flags.PORTAL_USE) {
if (validateEntityTarget(target) ||
validateBlockTarget(target) ||
validateItemTarget(target)) {
@ -156,23 +150,23 @@ public class CommandHelper {
return false;
}
if (flag.getName().equals("interact-inventory")) {
if (flag == Flags.INTERACT_INVENTORY) {
if (validateEntityTarget(target) || validateBlockTarget(target)) {
return true;
}
return false;
}
if (flag.getName().equals("liquid-flow") || flag.getName().equals("interact-block-primary")
|| flag.getName().equals("interact-block-secondary")) {
if (flag == Flags.LIQUID_FLOW || flag == Flags.INTERACT_BLOCK_PRIMARY
|| flag == Flags.INTERACT_BLOCK_SECONDARY) {
return validateBlockTarget(target);
}
if (flag.getName().equals("entity-chunk-spawn") || flag.getName().equals("entity-spawn") ||
flag.getName().equals("interact-entity-primary") || flag.getName().equals("interact-entity-secondary")) {
if (flag == Flags.ENTITY_CHUNK_SPAWN || flag == Flags.ENTITY_SPAWN ||
flag == Flags.INTERACT_ENTITY_PRIMARY || flag == Flags.INTERACT_ENTITY_SECONDARY) {
return validateEntityTarget(target);
}
if (flag.getName().equals("item-drop") || flag.getName().equals("item-pickup") ||
flag.getName().equals("item-spawn") || flag.getName().equals("item-use")) {
if (flag == Flags.ITEM_DROP|| flag == Flags.ITEM_PICKUP ||
flag == Flags.ITEM_SPAWN || flag == Flags.ITEM_USE) {
return validateItemTarget(target);
}
@ -215,7 +209,7 @@ public class CommandHelper {
return false;
}
public static PermissionResult addFlagPermission(CommandSource src, GDPermissionHolder subject, Claim claim, Flag claimFlag, String target, Tristate value, Set<Context> contexts) {
public static PermissionResult addFlagPermission(CommandSource src, GDPermissionHolder subject, Claim claim, Flag flag, String target, Tristate value, Set<Context> contexts) {
if (src instanceof Player) {
Component denyReason = ((GDClaim) claim).allowEdit((Player) src);
if (denyReason != null) {
@ -224,11 +218,9 @@ public class CommandHelper {
}
}
final String baseFlag = claimFlag.toString().toLowerCase();
String flagPermission = GDPermissions.FLAG_BASE + "." + baseFlag;
// special handling for commands
target = adjustTargetForTypes(target, claimFlag);
if (baseFlag.equals(Flags.COMMAND_EXECUTE.getName()) || baseFlag.equals(Flags.COMMAND_EXECUTE_PVP.getName())) {
target = adjustTargetForTypes(target, flag);
if (flag == Flags.COMMAND_EXECUTE || flag == Flags.COMMAND_EXECUTE_PVP) {
target = handleCommandFlag(src, target);
if (target == null) {
// failed
@ -252,13 +244,13 @@ public class CommandHelper {
} catch (NumberFormatException e) {
final Component message = GriefDefenderPlugin.getInstance().messageData.getMessage(MessageStorage.PERMISSION_CLAIM_MANAGE, ImmutableMap.of(
"meta", parts[1],
"flag", baseFlag));
"flag", flag.getName().toLowerCase()));
GriefDefenderPlugin.sendMessage(src, message);
return new GDPermissionResult(ResultTypes.TARGET_NOT_VALID);
}
}
addFlagContexts(contexts, claimFlag, targetFlag);
if (!targetFlag.startsWith("#") && !CommandHelper.validateFlagTarget(claimFlag, targetFlag)) {
addFlagContexts(contexts, flag, targetFlag);
if (!targetFlag.startsWith("#") && !CommandHelper.validateFlagTarget(flag, targetFlag)) {
//TODO
/*final Text message = GriefDefenderPlugin.getInstance().messageData.permissionClaimManage
.apply(ImmutableMap.of(
@ -273,25 +265,14 @@ public class CommandHelper {
}
}
return applyFlagPermission(src, subject, claim, flagPermission, target, value, contexts, null, false);
return applyFlagPermission(src, subject, claim, flag, target, value, contexts, null, false);
}
public static PermissionResult applyFlagPermission(CommandSource src, GDPermissionHolder subject, Claim claim, String flagPermission, String target, Tristate value, Set<Context> contexts, MenuType flagType) {
return applyFlagPermission(src, subject, claim, flagPermission, target, value, contexts, flagType, false);
public static PermissionResult applyFlagPermission(CommandSource src, GDPermissionHolder subject, Claim claim, Flag flag, String target, Tristate value, Set<Context> contexts, MenuType flagType) {
return applyFlagPermission(src, subject, claim, flag, target, value, contexts, flagType, false);
}
public static PermissionResult applyFlagPermission(CommandSource src, GDPermissionHolder subject, Claim claim, String flagPermission, String target, Tristate value, Set<Context> contexts, MenuType flagType, boolean clicked) {
// Check if player can manage flag
if (src instanceof Player) {
final String basePermission = flagPermission.replace(GDPermissions.FLAG_BASE + ".", "");
Tristate result = Tristate.fromBoolean(src.hasPermission(GDPermissions.USER_CLAIM_FLAGS + "." + basePermission));
if (result != Tristate.TRUE) {
GriefDefenderPlugin.sendMessage(src, MessageCache.getInstance().PERMISSION_FLAG_USE);
return new GDPermissionResult(ResultTypes.NO_PERMISSION);
}
}
public static PermissionResult applyFlagPermission(CommandSource src, GDPermissionHolder subject, Claim claim, Flag flag, String target, Tristate value, Set<Context> contexts, MenuType flagType, boolean clicked) {
boolean hasDefaultContext = false;
boolean hasOverrideContext = false;
Component reason = null;
@ -352,8 +333,18 @@ public class CommandHelper {
}
}
// Check if player can manage flag with contexts
if (src instanceof Player) {
final GDPermissionUser sourceUser = PermissionHolderCache.getInstance().getOrCreateUser(((Player) src));
final Tristate result = PermissionUtil.getInstance().getPermissionValue(sourceUser, GDPermissions.USER_CLAIM_FLAGS + "." + flag.getName().toLowerCase(), contexts);
if (result != Tristate.TRUE) {
GriefDefenderPlugin.sendMessage(src, MessageCache.getInstance().PERMISSION_FLAG_USE);
return new GDPermissionResult(ResultTypes.NO_PERMISSION);
}
}
if (subject == GriefDefenderPlugin.DEFAULT_HOLDER) {
PermissionUtil.getInstance().setPermissionValue(GriefDefenderPlugin.DEFAULT_HOLDER, flagPermission, value, contexts);
PermissionUtil.getInstance().setPermissionValue(GriefDefenderPlugin.DEFAULT_HOLDER, flag, value, contexts);
if (!clicked && src instanceof Player) {
TextAdapter.sendComponent(src, TextComponent.builder("")
.append(TextComponent.builder("\n[").append(MessageCache.getInstance().FLAG_UI_RETURN_FLAGS.color(TextColor.AQUA)).append("]\n")
@ -361,14 +352,14 @@ public class CommandHelper {
.append(MessageStorage.MESSAGE_DATA.getMessage(MessageStorage.FLAG_SET_PERMISSION_TARGET,
ImmutableMap.of(
"type", flagTypeText,
"permission", flagPermission.replace(GDPermissions.FLAG_BASE + ".", ""),
"permission", flag.getPermission(),
"contexts", getFriendlyContextString(claim, contexts),
"value", getClickableText(src, (GDClaim) claim, subject, contexts, flagPermission, value, flagType).color(TextColor.LIGHT_PURPLE),
"value", getClickableText(src, (GDClaim) claim, subject, contexts, flag, value, flagType).color(TextColor.LIGHT_PURPLE),
"target", "ALL")))
.build());
}
} else {
PermissionUtil.getInstance().setPermissionValue(subject, flagPermission, value, contexts);
PermissionUtil.getInstance().setPermissionValue(subject, flag, value, contexts);
if (!clicked && src instanceof Player) {
TextAdapter.sendComponent(src, TextComponent.builder("")
.append(TextComponent.builder("")
@ -379,9 +370,9 @@ public class CommandHelper {
.append(MessageStorage.MESSAGE_DATA.getMessage(MessageStorage.FLAG_SET_PERMISSION_TARGET,
ImmutableMap.of(
"type", flagTypeText,
"permission", flagPermission.replace(GDPermissions.FLAG_BASE + ".", ""),
"permission", flag.getPermission(),
"contexts", getFriendlyContextString(claim, contexts),
"value", getClickableText(src, (GDClaim) claim, subject, contexts, flagPermission, value, flagType).color(TextColor.LIGHT_PURPLE),
"value", getClickableText(src, (GDClaim) claim, subject, contexts, flag, value, flagType).color(TextColor.LIGHT_PURPLE),
"target", subject.getFriendlyName())))
.build());
}
@ -484,7 +475,7 @@ public class CommandHelper {
return color;
}
public static Consumer<CommandSource> createFlagConsumer(CommandSource src, GDClaim claim, Subject subject, Set<Context> contexts, String flagPermission, Tristate flagValue, MenuType flagType) {
public static Consumer<CommandSource> createFlagConsumer(CommandSource src, GDClaim claim, Subject subject, Set<Context> contexts, Flag flag, Tristate flagValue, MenuType flagType) {
return consumer -> {
Tristate newValue = Tristate.UNDEFINED;
if (flagValue == Tristate.TRUE) {
@ -501,16 +492,16 @@ public class CommandHelper {
} else if (flagType == MenuType.CLAIM) {
flagTypeText = TextComponent.of("CLAIM", TextColor.GOLD);
}
String target = flagPermission.replace(GDPermissions.FLAG_BASE + ".", "");
Set<Context> newContexts = new HashSet<>(contexts);
PermissionUtil.getInstance().setPermissionValue(GriefDefenderPlugin.DEFAULT_HOLDER, flagPermission, newValue, newContexts);
PermissionUtil.getInstance().setPermissionValue(GriefDefenderPlugin.DEFAULT_HOLDER, flag, newValue, newContexts);
TextAdapter.sendComponent(src, TextComponent.builder("")
.append("Set ", TextColor.GREEN)
.append(flagTypeText)
.append(" permission ")
.append(target, TextColor.AQUA)
.append(flag.getName().toLowerCase(), TextColor.AQUA)
.append("\n to ", TextColor.GREEN)
.append(getClickableText(src, (GDClaim) claim, subject, newContexts, flagPermission, newValue, flagType).color(TextColor.LIGHT_PURPLE))
.append(getClickableText(src, (GDClaim) claim, subject, newContexts, flag, newValue, flagType).color(TextColor.LIGHT_PURPLE))
.append(" for ", TextColor.GREEN)
.append(subject.getFriendlyName(), TextColor.GOLD).build());
};
@ -784,7 +775,8 @@ public class CommandHelper {
final Component defaultMessage = MessageStorage.MESSAGE_DATA.getMessage(MessageStorage.ECONOMY_CLAIM_BUY_TRANSFER_CANCELLED,
ImmutableMap.of(
"owner", owner.getName(),
"player", player.getName()));
"player", player.getName(),
"result", result.getMessage().orElse(TextComponent.of(result.getResultType().toString()))));
TextAdapter.sendComponent(src, result.getMessage().orElse(defaultMessage));
return;
}
@ -856,9 +848,9 @@ public class CommandHelper {
};
}
public static Consumer<CommandSource> createFlagConsumer(CommandSource src, GDPermissionHolder subject, String subjectName, Set<Context> contexts, GDClaim claim, String flagPermission, Tristate flagValue, String source) {
public static Consumer<CommandSource> createFlagConsumer(CommandSource src, GDPermissionHolder subject, String subjectName, Set<Context> contexts, GDClaim claim, Flag flag, Tristate flagValue, String source) {
return consumer -> {
String target = flagPermission.replace(GDPermissions.FLAG_BASE + ".", "");
String target = flag.getName().toLowerCase();
if (target.isEmpty()) {
target = "any";
}
@ -869,22 +861,22 @@ public class CommandHelper {
newValue = Tristate.TRUE;
}
CommandHelper.applyFlagPermission(src, subject, claim, flagPermission, target, newValue, null, MenuType.GROUP);
CommandHelper.applyFlagPermission(src, subject, claim, flag, target, newValue, null, MenuType.GROUP);
};
}
public static Component getClickableText(CommandSource src, GDClaim claim, Subject subject, Set<Context> contexts, String flagPermission, Tristate flagValue, MenuType type) {
public static Component getClickableText(CommandSource src, GDClaim claim, Subject subject, Set<Context> contexts, Flag flag, Tristate flagValue, MenuType type) {
TextComponent.Builder textBuilder = TextComponent.builder(flagValue.toString().toLowerCase())
.hoverEvent(HoverEvent.showText(TextComponent.builder("")
.append(MessageStorage.MESSAGE_DATA.getMessage(MessageStorage.CLAIMLIST_UI_CLICK_TOGGLE_VALUE,
ImmutableMap.of("type", type.name().toLowerCase())))
.append("\n")
.append(UIHelper.getPermissionMenuTypeHoverText(type)).build()))
.clickEvent(ClickEvent.runCommand(GDCallbackHolder.getInstance().createCallbackRunCommand(createFlagConsumer(src, claim, subject, contexts, flagPermission, flagValue, type))));
.clickEvent(ClickEvent.runCommand(GDCallbackHolder.getInstance().createCallbackRunCommand(createFlagConsumer(src, claim, subject, contexts, flag, flagValue, type))));
return textBuilder.build();
}
public static Component getClickableText(CommandSource src, GDPermissionHolder subject, String subjectName, Set<Context> contexts, GDClaim claim, String flagPermission, Tristate flagValue, String source, MenuType type) {
public static Component getClickableText(CommandSource src, GDPermissionHolder subject, String subjectName, Set<Context> contexts, GDClaim claim, Flag flag, Tristate flagValue, String source, MenuType type) {
Component onClickText = MessageStorage.MESSAGE_DATA.getMessage(MessageStorage.CLAIMLIST_UI_CLICK_TOGGLE_VALUE,
ImmutableMap.of("type", "flag"));
boolean hasPermission = true;
@ -906,7 +898,7 @@ public class CommandHelper {
.append("\n")
.append(UIHelper.getPermissionMenuTypeHoverText(type)).build()));
if (hasPermission) {
textBuilder.clickEvent(ClickEvent.runCommand(GDCallbackHolder.getInstance().createCallbackRunCommand(createFlagConsumer(src, subject, subjectName, contexts, claim, flagPermission, flagValue, source))));
textBuilder.clickEvent(ClickEvent.runCommand(GDCallbackHolder.getInstance().createCallbackRunCommand(createFlagConsumer(src, subject, subjectName, contexts, claim, flag, flagValue, source))));
}
return textBuilder.build();
}
@ -1036,16 +1028,24 @@ public class CommandHelper {
Location<World> safeLocation = Sponge.getGame().getTeleportHelper().getSafeLocation(location, 64, 16).orElse(null);
if (safeLocation == null) {
if (teleportDelay > 0) {
playerData.teleportDelay = teleportDelay + 1;
playerData.teleportLocation = location;
return;
}
TextAdapter.sendComponent(player, TextComponent.builder("")
.append("Location is not safe. ", TextColor.RED)
.append(TextComponent.builder("")
.append("Are you sure you want to teleport here?", TextColor.GREEN)
.clickEvent(ClickEvent.runCommand(GDCallbackHolder.getInstance().createCallbackRunCommand(createForceTeleportConsumer(player, location)))).decoration(TextDecoration.UNDERLINED, true).build()).build());
} else {
if (teleportDelay > 0) {
playerData.teleportDelay = teleportDelay + 1;
playerData.teleportLocation = safeLocation;
return;
}
player.setLocation(safeLocation);
}
// TextAdapter.sendComponent(player, MessageCache.getInstance().TELEPORT_NO_SAFE_LOCATION);
};
}

View File

@ -202,12 +202,17 @@ public class MessageStorage {
public static final String FLAG_UI_CLICK_TOGGLE = "flag-ui-click-toggle";
public static final String FLAG_UI_INHERIT_PARENT = "flag-ui-inherit-parent";
public static final String FLAG_UI_OVERRIDE_PERMISSION = "flag-ui-override-permission";
public static final String OPTION_APPLY_PLAYER_GAMEMODE = "option-apply-player-gamemode";
public static final String OPTION_APPLY_PLAYER_WALK_SPEED = "option-apply-player-walk-speed";
public static final String OPTION_APPLY_PLAYER_WEATHER = "option-apply-player-weather";
public static final String OPTION_APPLY_SPAWN_LIMIT = "option-apply-spawn-limit";
public static final String OPTION_INVALID_CONTEXT = "option-invalid-context";
public static final String OPTION_INVALID_TARGET = "option-invalid-target";
public static final String OPTION_INVALID_VALUE = "option-invalid-value";
public static final String OPTION_NOT_FOUND = "option-not-found";
public static final String OPTION_NOT_SET = "option-not-set";
public static final String OPTION_OVERRIDE_NOT_SUPPORTED = "option-override-not-supported";
public static final String OPTION_REQUIRES_CONTEXTS = "option-requires-contexts";
public static final String OPTION_RESET_SUCCESS = "option-reset-success";
public static final String OPTION_SET_TARGET = "option-set-target";
public static final String OPTION_UI_CLICK_TOGGLE = "option-ui-click-toggle";
@ -261,6 +266,7 @@ public class MessageStorage {
public static final String PLAYERINFO_UI_WORLD = "playerinfo-ui-world";
public static final String PLUGIN_COMMAND_NOT_FOUND = "plugin-command-not-found";
public static final String PLUGIN_NOT_FOUND = "plugin-not-found";
public static final String PVP_IN_COMBAT_NOT_ALLOWED = "pvp-in-combat-not-allowed";
public static final String REGISTRY_BLOCK_NOT_FOUND = "registry-type-not-found";
public static final String REGISTRY_ENTITY_NOT_FOUND = "registry-entity-not-found";
public static final String REGISTRY_ITEM_NOT_FOUND = "registry-item-not-found";

View File

@ -104,6 +104,9 @@ public class DefaultPermissionCategory extends ConfigCategory {
this.defaultUserOptions.put(Options.PLAYER_WALK_SPEED.getName(), "-1");
this.defaultUserOptions.put(Options.PLAYER_WEATHER.getName(), "undefined");
this.defaultUserOptions.put(Options.PVP.getName(), "undefined");
this.defaultUserOptions.put(Options.PVP_COMBAT_COMMAND.getName(), "false");
this.defaultUserOptions.put(Options.PVP_COMBAT_TELEPORT.getName(), "false");
this.defaultUserOptions.put(Options.PVP_COMBAT_TIMEOUT.getName(), "15");
this.defaultBasicOptions.put(Options.MIN_SIZE_X.getName(), "5");
this.defaultBasicOptions.put(Options.MIN_SIZE_Y.getName(), "5");

View File

@ -1,35 +0,0 @@
/*
* This file is part of GriefDefender, licensed under the MIT License (MIT).
*
* Copyright (c) bloodmc
* Copyright (c) contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package com.griefdefender.configuration.category;
import ninja.leaping.configurate.objectmapping.Setting;
import ninja.leaping.configurate.objectmapping.serialize.ConfigSerializable;
@ConfigSerializable
public class GeneralCategory extends ConfigCategory {
@Setting(value = "max-claim-inspection-distance", comment = "The max claim inspection block distance. (Default: 100)")
public int maxClaimInspectionDistance = 100;
}

View File

@ -40,7 +40,7 @@ public class WeatherTypeSerializer implements TypeSerializer<WeatherType> {
case "clear" :
return WeatherTypes.CLEAR;
case "rain" :
return WeatherTypes.RAIN;
return WeatherTypes.DOWNFALL;
default :
return WeatherTypes.UNDEFINED;
}

View File

@ -27,9 +27,7 @@ package com.griefdefender.configuration.type;
import com.griefdefender.configuration.category.BanCategory;
import com.griefdefender.configuration.category.BlacklistCategory;
import com.griefdefender.configuration.category.ClaimCategory;
import com.griefdefender.configuration.category.GeneralCategory;
import com.griefdefender.configuration.category.OptionCategory;
import com.griefdefender.configuration.category.PvpCategory;
import com.griefdefender.configuration.category.TownCategory;
import com.griefdefender.configuration.category.VisualCategory;
@ -57,12 +55,6 @@ public class ConfigBase {
@Setting
public OptionCategory options = new OptionCategory();
@Setting
public GeneralCategory general = new GeneralCategory();
@Setting
public PvpCategory pvp = new PvpCategory();
@Setting
public TownCategory town = new TownCategory();

View File

@ -439,10 +439,6 @@ public class BlockUtil {
return false;
}
public Set<Claim> getNearbyClaims(Location<World> location) {
return getNearbyClaims(location, 50);
}
public Set<Claim> getNearbyClaims(Location<World> location, int blockDistance) {
Set<Claim> claims = new HashSet<>();
GDClaimManager claimWorldManager = GriefDefenderPlugin.getInstance().dataStore.getClaimWorldManager(location.getExtent().getUniqueId());

View File

@ -81,7 +81,6 @@ import org.spongepowered.api.event.cause.EventContext;
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.text.Text;
import org.spongepowered.api.util.Direction;
import org.spongepowered.api.world.LocatableBlock;
import org.spongepowered.api.world.Location;
@ -181,7 +180,7 @@ public class BlockEventHandler {
}
// check overrides
final Tristate result = GDPermissionManager.getInstance().getFinalPermission(event, location, targetClaim, GDPermissions.BLOCK_BREAK, source, location.getBlock(), player, TrustTypes.BUILDER, true);
final Tristate result = GDPermissionManager.getInstance().getFinalPermission(event, location, targetClaim, Flags.BLOCK_BREAK, source, location.getBlock(), player, TrustTypes.BUILDER, true);
if (result != Tristate.TRUE) {
final Component message = GriefDefenderPlugin.getInstance().messageData.getMessage(MessageStorage.PERMISSION_BUILD,
ImmutableMap.of(
@ -228,44 +227,44 @@ public class BlockEventHandler {
// If a player successfully interacted with a block recently such as a pressure plate, ignore check
// This fixes issues such as pistons not being able to extend
if (user != null && !isForgePlayerBreak && playerData != null && playerData.eventResultCache != null && playerData.eventResultCache.checkEventResultCache(targetClaim, "block-pre") == Tristate.TRUE) {
GDPermissionManager.getInstance().addEventLogEntry(event, location, source, blockState, user, GDPermissions.BLOCK_BREAK, playerData.eventResultCache.lastTrust, Tristate.TRUE);
GDPermissionManager.getInstance().addEventLogEntry(event, location, source, blockState, user, Flags.BLOCK_BREAK, playerData.eventResultCache.lastTrust, Tristate.TRUE);
continue;
}
if (user != null && targetClaim.isUserTrusted(user, TrustTypes.BUILDER)) {
GDPermissionManager.getInstance().addEventLogEntry(event, location, source, blockState, user, GDPermissions.BLOCK_BREAK, TrustTypes.BUILDER.getName().toLowerCase(), Tristate.TRUE);
GDPermissionManager.getInstance().addEventLogEntry(event, location, source, blockState, user, Flags.BLOCK_BREAK, TrustTypes.BUILDER.getName().toLowerCase(), Tristate.TRUE);
continue;
}
if (sourceClaim.getOwnerUniqueId().equals(targetClaim.getOwnerUniqueId()) && user == null && sourceEntity == null && !isFireSource && !isLeafDecay) {
GDPermissionManager.getInstance().addEventLogEntry(event, location, source, blockState, user, GDPermissions.BLOCK_BREAK, "owner", Tristate.TRUE);
GDPermissionManager.getInstance().addEventLogEntry(event, location, source, blockState, user, Flags.BLOCK_BREAK, "owner", Tristate.TRUE);
continue;
}
if (user != null && pistonExtend) {
if (targetClaim.isUserTrusted(user, TrustTypes.ACCESSOR)) {
GDPermissionManager.getInstance().addEventLogEntry(event, location, source, blockState, user, GDPermissions.BLOCK_BREAK, TrustTypes.ACCESSOR.getName().toLowerCase(), Tristate.TRUE);
GDPermissionManager.getInstance().addEventLogEntry(event, location, source, blockState, user, Flags.BLOCK_BREAK, TrustTypes.ACCESSOR.getName().toLowerCase(), Tristate.TRUE);
continue;
}
}
if (isLeafDecay) {
if (GDPermissionManager.getInstance().getFinalPermission(event, location, targetClaim, GDPermissions.LEAF_DECAY, source, blockState, user) == Tristate.FALSE) {
if (GDPermissionManager.getInstance().getFinalPermission(event, location, targetClaim, Flags.LEAF_DECAY, source, blockState, user) == Tristate.FALSE) {
event.setCancelled(true);
GDTimings.BLOCK_PRE_EVENT.stopTimingIfSync();
return;
}
} else if (isFireSource) {
if (GDPermissionManager.getInstance().getFinalPermission(event, location, targetClaim, GDPermissions.BLOCK_SPREAD, source, blockState, user) == Tristate.FALSE) {
if (GDPermissionManager.getInstance().getFinalPermission(event, location, targetClaim, Flags.BLOCK_SPREAD, source, blockState, user) == Tristate.FALSE) {
event.setCancelled(true);
GDTimings.BLOCK_PRE_EVENT.stopTimingIfSync();
return;
}
} else if (isLiquidSource) {
if (GDPermissionManager.getInstance().getFinalPermission(event, location, targetClaim, GDPermissions.LIQUID_FLOW, source, blockState, user) == Tristate.FALSE) {
if (GDPermissionManager.getInstance().getFinalPermission(event, location, targetClaim, Flags.LIQUID_FLOW, source, blockState, user) == Tristate.FALSE) {
event.setCancelled(true);
lastBlockPreCancelled = true;
GDTimings.BLOCK_PRE_EVENT.stopTimingIfSync();
return;
}
continue;
} else if (GDPermissionManager.getInstance().getFinalPermission(event, location, targetClaim, GDPermissions.BLOCK_BREAK, source, blockState, user) == Tristate.FALSE) {
} else if (GDPermissionManager.getInstance().getFinalPermission(event, location, targetClaim, Flags.BLOCK_BREAK, source, blockState, user) == Tristate.FALSE) {
// PRE events can be spammy so we need to avoid sending player messages here.
event.setCancelled(true);
lastBlockPreCancelled = true;
@ -290,29 +289,29 @@ public class BlockEventHandler {
// If a player successfully interacted with a block recently such as a pressure plate, ignore check
// This fixes issues such as pistons not being able to extend
if (!isForgePlayerBreak && playerData != null && playerData.eventResultCache != null && playerData.eventResultCache.checkEventResultCache(targetClaim, "block-pre") == Tristate.TRUE) {
GDPermissionManager.getInstance().addEventLogEntry(event, location, source, blockState, user, GDPermissions.BLOCK_BREAK, playerData.eventResultCache.lastTrust, Tristate.TRUE);
GDPermissionManager.getInstance().addEventLogEntry(event, location, source, blockState, user, Flags.BLOCK_BREAK, playerData.eventResultCache.lastTrust, Tristate.TRUE);
continue;
}
if (targetClaim.isUserTrusted(user, TrustTypes.BUILDER)) {
GDPermissionManager.getInstance().addEventLogEntry(event, location, source, blockState, user, GDPermissions.BLOCK_BREAK, TrustTypes.BUILDER.getName().toLowerCase(), Tristate.TRUE);
GDPermissionManager.getInstance().addEventLogEntry(event, location, source, blockState, user, Flags.BLOCK_BREAK, TrustTypes.BUILDER.getName().toLowerCase(), Tristate.TRUE);
continue;
}
if (isFireSource) {
if (GDPermissionManager.getInstance().getFinalPermission(event, location, targetClaim, GDPermissions.BLOCK_SPREAD, source, blockState, user) == Tristate.FALSE) {
if (GDPermissionManager.getInstance().getFinalPermission(event, location, targetClaim, Flags.BLOCK_SPREAD, source, blockState, user) == Tristate.FALSE) {
event.setCancelled(true);
GDTimings.BLOCK_PRE_EVENT.stopTimingIfSync();
return;
}
} else if (isLiquidSource) {
if (GDPermissionManager.getInstance().getFinalPermission(event, location, targetClaim, GDPermissions.LIQUID_FLOW, source, blockState, user) == Tristate.FALSE) {
if (GDPermissionManager.getInstance().getFinalPermission(event, location, targetClaim, Flags.LIQUID_FLOW, source, blockState, user) == Tristate.FALSE) {
event.setCancelled(true);
lastBlockPreCancelled = true;
GDTimings.BLOCK_PRE_EVENT.stopTimingIfSync();
return;
}
continue;
} else if (GDPermissionManager.getInstance().getFinalPermission(event, location, targetClaim, GDPermissions.BLOCK_BREAK, source, blockState, user) == Tristate.FALSE) {
} else if (GDPermissionManager.getInstance().getFinalPermission(event, location, targetClaim, Flags.BLOCK_BREAK, source, blockState, user) == Tristate.FALSE) {
event.setCancelled(true);
lastBlockPreCancelled = true;
GDTimings.BLOCK_PRE_EVENT.stopTimingIfSync();
@ -463,13 +462,13 @@ public class BlockEventHandler {
targetClaim = this.dataStore.getClaimAt(event.getTargetLocation());
}
if (GDPermissionManager.getInstance().getFinalPermission(event, event.getTargetLocation(), targetClaim, GDPermissions.COLLIDE_BLOCK, source, event.getTargetBlock(), user, TrustTypes.ACCESSOR, true) == Tristate.TRUE) {
if (GDPermissionManager.getInstance().getFinalPermission(event, event.getTargetLocation(), targetClaim, Flags.COLLIDE_BLOCK, source, event.getTargetBlock(), user, TrustTypes.ACCESSOR, true) == Tristate.TRUE) {
entityBlockCache.setLastResult(Tristate.TRUE);
GDTimings.BLOCK_COLLIDE_EVENT.stopTimingIfSync();
return;
}
if (GDFlags.PORTAL_USE && event.getTargetBlock().getType() == BlockTypes.PORTAL) {
if (GDPermissionManager.getInstance().getFinalPermission(event, event.getTargetLocation(), targetClaim, GDPermissions.PORTAL_USE, source, event.getTargetBlock(), user, TrustTypes.ACCESSOR, true) == Tristate.TRUE) {
if (GDPermissionManager.getInstance().getFinalPermission(event, event.getTargetLocation(), targetClaim, Flags.PORTAL_USE, source, event.getTargetBlock(), user, TrustTypes.ACCESSOR, true) == Tristate.TRUE) {
GDTimings.BLOCK_COLLIDE_EVENT.stopTimingIfSync();
return;
}
@ -522,7 +521,7 @@ public class BlockEventHandler {
targetClaim = this.dataStore.getClaimAt(impactPoint);
}
Tristate result = GDPermissionManager.getInstance().getFinalPermission(event, impactPoint, targetClaim, GDPermissions.PROJECTILE_IMPACT_BLOCK, source, event.getTargetBlock(), user, TrustTypes.ACCESSOR, true);
Tristate result = GDPermissionManager.getInstance().getFinalPermission(event, impactPoint, targetClaim, Flags.PROJECTILE_IMPACT_BLOCK, source, event.getTargetBlock(), user, TrustTypes.ACCESSOR, true);
if (result == Tristate.FALSE) {
event.setCancelled(true);
GDTimings.PROJECTILE_IMPACT_BLOCK_EVENT.stopTimingIfSync();
@ -566,7 +565,7 @@ public class BlockEventHandler {
for (Claim claim : surroundingClaims) {
// Use any location for permission check
Location<World> targetLocation = new Location<>(location.getExtent(), claim.getLesserBoundaryCorner());
Tristate result = GDPermissionManager.getInstance().getFinalPermission(event, location, claim, GDPermissions.EXPLOSION_BLOCK, source, targetLocation, user, true);
Tristate result = GDPermissionManager.getInstance().getFinalPermission(event, location, claim, Flags.EXPLOSION_BLOCK, source, targetLocation, user, true);
if (result == Tristate.FALSE) {
event.setCancelled(true);
break;
@ -610,7 +609,7 @@ public class BlockEventHandler {
continue;
}*/
Tristate result = GDPermissionManager.getInstance().getFinalPermission(event, location, targetClaim, GDPermissions.EXPLOSION_BLOCK, source, location.getBlock(), user, true);
Tristate result = GDPermissionManager.getInstance().getFinalPermission(event, location, targetClaim, Flags.EXPLOSION_BLOCK, source, location.getBlock(), user, true);
if (result == Tristate.FALSE) {
// Avoid lagging server from large explosions.
@ -696,7 +695,7 @@ public class BlockEventHandler {
}
// check overrides
final Tristate result = GDPermissionManager.getInstance().getFinalPermission(event, location, targetClaim, GDPermissions.BLOCK_BREAK, source, transaction.getOriginal(), user, TrustTypes.BUILDER, true);
final Tristate result = GDPermissionManager.getInstance().getFinalPermission(event, location, targetClaim, Flags.BLOCK_BREAK, source, transaction.getOriginal(), user, TrustTypes.BUILDER, true);
if (result != Tristate.TRUE) {
if (player != null) {
final Component message = GriefDefenderPlugin.getInstance().messageData.getMessage(MessageStorage.PERMISSION_BUILD,
@ -787,7 +786,7 @@ public class BlockEventHandler {
}
// check overrides
final Tristate result = GDPermissionManager.getInstance().getFinalPermission(event, location, targetClaim, GDPermissions.BLOCK_PLACE, source, block, user, TrustTypes.BUILDER, true);
final Tristate result = GDPermissionManager.getInstance().getFinalPermission(event, location, targetClaim, Flags.BLOCK_PLACE, source, block, user, TrustTypes.BUILDER, true);
if (result != Tristate.TRUE) {
// TODO - make sure this doesn't spam
/*if (source instanceof Player) {
@ -909,7 +908,7 @@ public class BlockEventHandler {
Location<World> location = event.getTargetTile().getLocation();
// Prevent users exploiting signs
GDClaim claim = GriefDefenderPlugin.getInstance().dataStore.getClaimAt(location);
if (GDPermissionManager.getInstance().getFinalPermission(event, location, claim, GDPermissions.INTERACT_BLOCK_SECONDARY, user, location.getBlock(), user, TrustTypes.ACCESSOR, true) == Tristate.FALSE) {
if (GDPermissionManager.getInstance().getFinalPermission(event, location, claim, Flags.INTERACT_BLOCK_SECONDARY, user, location.getBlock(), user, TrustTypes.ACCESSOR, true) == Tristate.FALSE) {
if (user instanceof Player) {
event.setCancelled(true);
final Component message = GriefDefenderPlugin.getInstance().messageData.getMessage(MessageStorage.PERMISSION_ACCESS,
@ -973,7 +972,7 @@ public class BlockEventHandler {
}
final GDClaim claim = this.dataStore.getClaimAt(loc, targetClaim);
if (!claim.isWilderness() && !targetClaim.equals(claim)) {
Tristate result = GDPermissionManager.getInstance().getFinalPermission(event, loc, claim, GDPermissions.BLOCK_BREAK, player, loc.getBlock(), player, TrustTypes.BUILDER, true);
Tristate result = GDPermissionManager.getInstance().getFinalPermission(event, loc, claim, Flags.BLOCK_BREAK, player, loc.getBlock(), player, TrustTypes.BUILDER, true);
if (result != Tristate.TRUE) {
final Component message = GriefDefenderPlugin.getInstance().messageData.getMessage(MessageStorage.PERMISSION_BUILD_NEAR_CLAIM,
ImmutableMap.of(

View File

@ -25,6 +25,12 @@
package com.griefdefender.listener;
import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.spongepowered.api.Sponge;
import org.spongepowered.api.data.key.Keys;
@ -37,6 +43,7 @@ import org.spongepowered.api.item.inventory.ItemStack;
import org.spongepowered.api.text.Text;
import org.spongepowered.api.world.Location;
import org.spongepowered.api.world.World;
import org.spongepowered.api.world.weather.Weather;
import com.google.common.collect.ImmutableMap;
import com.google.common.reflect.TypeToken;
import com.griefdefender.GDPlayerData;
@ -46,21 +53,31 @@ import com.griefdefender.api.ChatType;
import com.griefdefender.api.GriefDefender;
import com.griefdefender.api.Tristate;
import com.griefdefender.api.claim.TrustTypes;
import com.griefdefender.api.permission.Context;
import com.griefdefender.api.permission.flag.Flags;
import com.griefdefender.api.permission.option.Options;
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.api.permission.option.type.WeatherTypes;
import com.griefdefender.cache.MessageCache;
import com.griefdefender.cache.PermissionHolderCache;
import com.griefdefender.claim.GDClaim;
import com.griefdefender.command.CommandHelper;
import com.griefdefender.configuration.MessageStorage;
import com.griefdefender.event.GDBorderClaimEvent;
import com.griefdefender.internal.util.BlockUtil;
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.OptionContexts;
import com.griefdefender.provider.MCClansProvider;
import com.griefdefender.storage.BaseStorage;
import com.griefdefender.util.EntityUtils;
import com.griefdefender.util.PermissionUtil;
import com.griefdefender.util.PlayerUtil;
import com.griefdefender.util.SpongeUtil;
import net.kyori.text.Component;
import net.kyori.text.TextComponent;
@ -132,7 +149,7 @@ public class CommonEntityEventHandler {
if (fromClaim != toClaim) {
GDBorderClaimEvent gpEvent = new GDBorderClaimEvent(targetEntity, fromClaim, toClaim);
// enter
if (GDFlags.ENTER_CLAIM && !enterBlacklisted && GDPermissionManager.getInstance().getFinalPermission(event, toLocation, toClaim, GDPermissions.ENTER_CLAIM, targetEntity, targetEntity, user) == Tristate.FALSE) {
if (GDFlags.ENTER_CLAIM && !enterBlacklisted && GDPermissionManager.getInstance().getFinalPermission(event, toLocation, toClaim, Flags.ENTER_CLAIM, targetEntity, targetEntity, user) == Tristate.FALSE) {
gpEvent.cancelled(true);
if (event != null) {
event.setCancelled(true);
@ -140,7 +157,7 @@ public class CommonEntityEventHandler {
}
// exit
if (GDFlags.EXIT_CLAIM && !exitBlacklisted && GDPermissionManager.getInstance().getFinalPermission(event, fromLocation, fromClaim, GDPermissions.EXIT_CLAIM, targetEntity, targetEntity, user) == Tristate.FALSE) {
if (GDFlags.EXIT_CLAIM && !exitBlacklisted && GDPermissionManager.getInstance().getFinalPermission(event, fromLocation, fromClaim, Flags.EXIT_CLAIM, targetEntity, targetEntity, user) == Tristate.FALSE) {
gpEvent.cancelled(true);
if (event != null) {
event.setCancelled(true);
@ -173,7 +190,7 @@ public class CommonEntityEventHandler {
if (player != null && GDFlags.ENTER_CLAIM && !enterBlacklisted && user != null && user.getInternalPlayerData().lastClaim != null) {
final GDClaim lastClaim = (GDClaim) user.getInternalPlayerData().lastClaim.get();
if (lastClaim != null && lastClaim != fromClaim) {
if (GDPermissionManager.getInstance().getFinalPermission(event, toLocation, toClaim, GDPermissions.ENTER_CLAIM, targetEntity, targetEntity, player, TrustTypes.ACCESSOR, false) == Tristate.FALSE) {
if (GDPermissionManager.getInstance().getFinalPermission(event, toLocation, toClaim, Flags.ENTER_CLAIM, targetEntity, targetEntity, player, TrustTypes.ACCESSOR, true) == Tristate.FALSE) {
Location<World> claimCorner = new Location<>(toClaim.getWorld(), toClaim.lesserBoundaryCorner.getX(), player.getLocation().getY(), toClaim.greaterBoundaryCorner.getZ());
Location<World> safeLocation = Sponge.getGame().getTeleportHelper().getSafeLocation(claimCorner, 9, 9).orElse(player.getWorld().getSpawnLocation());
if (event != null) {
@ -208,6 +225,7 @@ public class CommonEntityEventHandler {
GDBorderClaimEvent gpEvent = new GDBorderClaimEvent(targetEntity, fromClaim, toClaim);
if (user != null && toClaim.isUserTrusted(user, TrustTypes.ACCESSOR)) {
final GDPlayerData playerData = user.getInternalPlayerData();
GriefDefender.getEventManager().post(gpEvent);
if (gpEvent.cancelled()) {
event.setCancelled(true);
@ -254,6 +272,15 @@ public class CommonEntityEventHandler {
} else {
user.getInternalPlayerData().inTown = false;
}
if (player != null) {
this.checkPlayerFlight(user, fromClaim, toClaim);
this.checkPlayerGameMode(user, fromClaim, toClaim);
this.checkPlayerGodMode(user, fromClaim, toClaim);
this.checkPlayerWalkSpeed(user, fromClaim, toClaim);
this.checkPlayerWeather(user, fromClaim, toClaim);
this.runPlayerCommands(fromClaim, user, false);
this.runPlayerCommands(toClaim, user, true);
}
}
GDTimings.ENTITY_MOVE_EVENT.stopTimingIfSync();
@ -264,13 +291,13 @@ public class CommonEntityEventHandler {
boolean enterCancelled = false;
boolean exitCancelled = false;
// enter
if (GDFlags.ENTER_CLAIM && !enterBlacklisted && GDPermissionManager.getInstance().getFinalPermission(event, toLocation, toClaim, GDPermissions.ENTER_CLAIM, targetEntity, targetEntity, user) == Tristate.FALSE) {
if (GDFlags.ENTER_CLAIM && !enterBlacklisted && 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, GDPermissions.EXIT_CLAIM, targetEntity, targetEntity, user) == Tristate.FALSE) {
if (GDFlags.EXIT_CLAIM && !exitBlacklisted && GDPermissionManager.getInstance().getFinalPermission(event, fromLocation, fromClaim, Flags.EXIT_CLAIM, targetEntity, targetEntity, user, true) == Tristate.FALSE) {
exitCancelled = true;
gpEvent.cancelled(true);
}
@ -301,8 +328,9 @@ public class CommonEntityEventHandler {
}
if (player != null) {
final GDPlayerData playerData = user.getInternalPlayerData();
final boolean showGpPrefix = GriefDefenderPlugin.getGlobalConfig().getConfig().message.enterExitShowGdPrefix;
user.getInternalPlayerData().lastClaim = new WeakReference<>(toClaim);
playerData.lastClaim = new WeakReference<>(toClaim);
Component welcomeMessage = gpEvent.getEnterMessage().orElse(null);
if (welcomeMessage != null && !welcomeMessage.equals(TextComponent.empty())) {
ChatType chatType = gpEvent.getEnterMessageChatType();
@ -336,7 +364,15 @@ public class CommonEntityEventHandler {
}
if (player != null) {
checkPlayerFlight(player, user.getInternalPlayerData(), fromClaim, toClaim);
if (player != null) {
this.checkPlayerFlight(user, fromClaim, toClaim);
this.checkPlayerGameMode(user, fromClaim, toClaim);
this.checkPlayerGodMode(user, fromClaim, toClaim);
this.checkPlayerWalkSpeed(user, fromClaim, toClaim);
this.checkPlayerWeather(user, fromClaim, toClaim);
this.runPlayerCommands(fromClaim, user, false);
this.runPlayerCommands(toClaim, user, true);
}
}
}
}
@ -345,7 +381,79 @@ public class CommonEntityEventHandler {
return true;
}
private void checkPlayerFlight(Player player, GDPlayerData playerData, GDClaim fromClaim, GDClaim toClaim) {
final static Pattern pattern = Pattern.compile("([^\\s]+)", Pattern.MULTILINE);
private void runPlayerCommands(GDClaim claim, GDPermissionUser user, boolean enter) {
final Player player = user.getOnlinePlayer();
List<String> rawCommandList = new ArrayList<>();
Set<Context> contexts = new HashSet<>();
if (player.getUniqueId().equals(claim.getOwnerUniqueId())) {
contexts.add(OptionContexts.COMMAND_RUNFOR_OWNER);
} else {
contexts.add(OptionContexts.COMMAND_RUNFOR_MEMBER);
}
contexts.add(OptionContexts.COMMAND_RUNFOR_PUBLIC);
// Check console commands
contexts.add(OptionContexts.COMMAND_RUNAS_CONSOLE);
if (enter) {
rawCommandList = GDPermissionManager.getInstance().getInternalOptionValue(new TypeToken<List<String>>() {}, user, Options.PLAYER_COMMAND_ENTER, claim, contexts);
} else {
rawCommandList = GDPermissionManager.getInstance().getInternalOptionValue(new TypeToken<List<String>>() {}, user, Options.PLAYER_COMMAND_EXIT, claim, contexts);
}
if (rawCommandList != null) {
runCommand(claim, player, rawCommandList, true);
}
// Check player commands
contexts.remove(OptionContexts.COMMAND_RUNAS_CONSOLE);
contexts.add(OptionContexts.COMMAND_RUNAS_PLAYER);
if (enter) {
rawCommandList = GDPermissionManager.getInstance().getInternalOptionValue(new TypeToken<List<String>>() {}, user, Options.PLAYER_COMMAND_ENTER, claim, contexts);
} else {
rawCommandList = GDPermissionManager.getInstance().getInternalOptionValue(new TypeToken<List<String>>() {}, user, Options.PLAYER_COMMAND_EXIT, claim, contexts);
}
if (rawCommandList != null) {
runCommand(claim, player, rawCommandList, false);
}
}
private void runCommand(GDClaim claim, Player player, List<String> rawCommandList, boolean runAsConsole) {
final List<String> commands = new ArrayList<>();
for (String command : rawCommandList) {
commands.add(this.replacePlaceHolders(claim, player, command));
}
for (String command : commands) {
final Matcher matcher = pattern.matcher(command);
if (matcher.find()) {
String baseCommand = matcher.group(0);
String args = command.replace(baseCommand + " ", "");
baseCommand = baseCommand.replace("\\", "").replace("/", "");
args = args.replace("%player%", player.getName());
if (runAsConsole) {
CommandHelper.executeCommand(Sponge.getServer().getConsole(), baseCommand, args);
} else {
CommandHelper.executeCommand(player, baseCommand, args);
}
}
}
}
private String replacePlaceHolders(GDClaim claim, Player player, String command) {
command = command
.replace("%player%", player.getName())
.replace("%owner%", claim.getOwnerFriendlyName())
.replace("%uuid%", player.getUniqueId().toString())
.replace("%world%", claim.getWorld().getName())
.replace("%server%", PermissionUtil.getInstance().getServerName())
.replace("%location%", BlockUtil.getInstance().posToString(player.getLocation()));
return command;
}
private void checkPlayerFlight(GDPermissionUser user, GDClaim fromClaim, GDClaim toClaim) {
final Player player = user.getOnlinePlayer();
final GDPlayerData playerData = user.getInternalPlayerData();
final GameMode gameMode = player.get(Keys.GAME_MODE).orElse(null);
if (gameMode == null || gameMode == GameModes.CREATIVE || gameMode == GameModes.SPECTATOR) {
return;
@ -366,7 +474,105 @@ public class CommonEntityEventHandler {
player.offer(Keys.CAN_FLY, false);
player.offer(Keys.IS_FLYING, false);
playerData.ignoreFallDamage = true;
GriefDefenderPlugin.sendMessage(player, MessageCache.getInstance().OPTION_PLAYER_DENY_FLIGHT);
GriefDefenderPlugin.sendMessage(player, MessageCache.getInstance().OPTION_APPLY_PLAYER_DENY_FLIGHT);
}
}
private void checkPlayerGodMode(GDPermissionUser user, GDClaim fromClaim, GDClaim toClaim) {
final Player player = user.getOnlinePlayer();
final GDPlayerData playerData = user.getInternalPlayerData();
final GameMode gameMode = player.get(Keys.GAME_MODE).get();
if (gameMode == GameModes.CREATIVE || gameMode == GameModes.SPECTATOR || !player.get(Keys.INVULNERABLE).get()) {
return;
}
if (fromClaim == toClaim) {
return;
}
final Boolean noGodMode = GDPermissionManager.getInstance().getInternalOptionValue(TypeToken.of(Boolean.class), playerData.getSubject(), Options.PLAYER_DENY_GODMODE, toClaim);
final boolean bypassOption = player.hasPermission(GDPermissions.BYPASS_OPTION + "." + Options.PLAYER_DENY_GODMODE.getName().toLowerCase());
if (!bypassOption && noGodMode) {
player.offer(Keys.INVULNERABLE, false);
GriefDefenderPlugin.sendMessage(player, MessageCache.getInstance().OPTION_APPLY_PLAYER_DENY_GODMODE);
}
}
private void checkPlayerGameMode(GDPermissionUser user, GDClaim fromClaim, GDClaim toClaim) {
if (fromClaim == toClaim) {
return;
}
final Player player = user.getOnlinePlayer();
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);
final boolean bypassOption = player.hasPermission(GDPermissions.BYPASS_OPTION + "." + Options.PLAYER_GAMEMODE.getName().toLowerCase());
if (!bypassOption && gameModeType != null && gameModeType != GameModeTypes.UNDEFINED) {
final GameMode newGameMode = PlayerUtil.GAMEMODE_MAP.get(gameModeType);
if (newGameMode != currentGameMode) {
player.offer(Keys.GAME_MODE, PlayerUtil.GAMEMODE_MAP.get(gameModeType));
final Component message = GriefDefenderPlugin.getInstance().messageData.getMessage(MessageStorage.OPTION_APPLY_PLAYER_GAMEMODE,
ImmutableMap.of(
"gamemode", gameModeType.getName()));
GriefDefenderPlugin.sendMessage(player, message);
}
}
}
private void checkPlayerWalkSpeed(GDPermissionUser user, GDClaim fromClaim, GDClaim toClaim) {
if (fromClaim == toClaim) {
return;
}
final Player player = user.getOnlinePlayer();
final GDPlayerData playerData = user.getInternalPlayerData();
final double currentWalkSpeed = player.get(Keys.WALKING_SPEED).get();
final double walkSpeed = GDPermissionManager.getInstance().getInternalOptionValue(TypeToken.of(Double.class), playerData.getSubject(), Options.PLAYER_WALK_SPEED, toClaim);
final boolean bypassOption = player.hasPermission(GDPermissions.BYPASS_OPTION + "." + Options.PLAYER_WALK_SPEED.getName().toLowerCase());
if (!bypassOption && walkSpeed > 0) {
if (currentWalkSpeed != walkSpeed) {
final Component message = GriefDefenderPlugin.getInstance().messageData.getMessage(MessageStorage.OPTION_APPLY_PLAYER_WALK_SPEED,
ImmutableMap.of(
"speed", walkSpeed));
GriefDefenderPlugin.sendMessage(player, message);
}
}
}
private void checkPlayerWeather(GDPermissionUser user, GDClaim fromClaim, GDClaim toClaim) {
if (fromClaim == toClaim) {
return;
}
final Player player = user.getOnlinePlayer();
final GDPlayerData playerData = user.getInternalPlayerData();
final WeatherType weatherType = GDPermissionManager.getInstance().getInternalOptionValue(TypeToken.of(WeatherType.class), playerData.getSubject(), Options.PLAYER_WEATHER, toClaim);
final boolean bypassOption = player.hasPermission(GDPermissions.BYPASS_OPTION + "." + Options.PLAYER_WEATHER.getName().toLowerCase());
if (false && bypassOption) {
return;
}
if (weatherType != null && weatherType != WeatherTypes.UNDEFINED) {
final Weather currentWeather = player.getWorld().getWeather();
final Weather newWeather = PlayerUtil.WEATHERTYPE_MAP.get(weatherType);
if (currentWeather != newWeather) {
PlayerUtil.getInstance().setPlayerWeather(user, weatherType);
final Component message = GriefDefenderPlugin.getInstance().messageData.getMessage(MessageStorage.OPTION_APPLY_PLAYER_WEATHER,
ImmutableMap.of(
"weather", weatherType.getName().toUpperCase()));
GriefDefenderPlugin.sendMessage(player, message);
}
} else {
final WeatherType currentWeather = playerData.lastWeatherType;
PlayerUtil.getInstance().resetPlayerWeather(user);
final WeatherType newWeather = playerData.lastWeatherType;
if (currentWeather != newWeather) {
final Component message = GriefDefenderPlugin.getInstance().messageData.getMessage(MessageStorage.OPTION_APPLY_PLAYER_WEATHER,
ImmutableMap.of(
"weather", newWeather.getName().toUpperCase()));
GriefDefenderPlugin.sendMessage(player, message);
}
}
}

View File

@ -33,6 +33,7 @@ import com.griefdefender.api.Tristate;
import com.griefdefender.api.claim.Claim;
import com.griefdefender.api.claim.TrustType;
import com.griefdefender.api.claim.TrustTypes;
import com.griefdefender.api.permission.flag.Flag;
import com.griefdefender.api.permission.flag.Flags;
import com.griefdefender.api.permission.option.Options;
import com.griefdefender.cache.MessageCache;
@ -43,7 +44,6 @@ import com.griefdefender.configuration.MessageStorage;
import com.griefdefender.internal.util.NMSUtil;
import com.griefdefender.permission.GDPermissionManager;
import com.griefdefender.permission.GDPermissionUser;
import com.griefdefender.permission.GDPermissions;
import com.griefdefender.permission.flag.GDFlags;
import com.griefdefender.storage.BaseStorage;
import com.griefdefender.util.CauseContextHelper;
@ -142,7 +142,7 @@ public class EntityEventHandler {
return;
}*/
Tristate result = GDPermissionManager.getInstance().getFinalPermission(event, location, claim, GDPermissions.EXPLOSION_ENTITY, source, location.getBlock(), user, true);
Tristate result = GDPermissionManager.getInstance().getFinalPermission(event, location, claim, Flags.EXPLOSION_ENTITY, source, location.getBlock(), user, true);
if(result == Tristate.FALSE) {
event.setCancelled(true);
@ -182,7 +182,7 @@ public class EntityEventHandler {
while (iterator.hasNext()) {
Entity entity = iterator.next();
targetClaim = GriefDefenderPlugin.getInstance().dataStore.getClaimAt(entity.getLocation(), targetClaim);
if (GDPermissionManager.getInstance().getFinalPermission(event, entity.getLocation(), targetClaim, GDPermissions.ENTITY_DAMAGE, source, entity, user) == Tristate.FALSE) {
if (GDPermissionManager.getInstance().getFinalPermission(event, entity.getLocation(), targetClaim, Flags.ENTITY_DAMAGE, source, entity, user) == Tristate.FALSE) {
iterator.remove();
}
}
@ -225,7 +225,7 @@ public class EntityEventHandler {
return;
}
String permission = GDPermissions.ENTITY_SPAWN;
Flag flag = Flags.ENTITY_SPAWN;
if (event.getTargetType() == EntityTypes.ITEM) {
if (user == null) {
GDTimings.ENTITY_SPAWN_PRE_EVENT.stopTimingIfSync();
@ -240,7 +240,7 @@ public class EntityEventHandler {
return;
}
permission = GDPermissions.ITEM_SPAWN;
flag = Flags.ITEM_SPAWN;
if (source instanceof BlockSnapshot) {
final BlockSnapshot block = (BlockSnapshot) source;
final Location<World> blockLocation = block.getLocation().orElse(null);
@ -249,11 +249,11 @@ public class EntityEventHandler {
GDTimings.ENTITY_SPAWN_PRE_EVENT.stopTimingIfSync();
return;
}
final Tristate result = GDPermissionManager.getInstance().getFinalPermission(event, location, targetClaim, GDPermissions.BLOCK_BREAK, source, block, user, true);
final Tristate result = GDPermissionManager.getInstance().getFinalPermission(event, location, targetClaim, Flags.BLOCK_BREAK, source, block, user, true);
if (result != Tristate.UNDEFINED) {
if (result == Tristate.TRUE) {
// Check if item drop is allowed
if (GDPermissionManager.getInstance().getFinalPermission(event, location, targetClaim, permission, source, entityTypeId, user, true) == Tristate.FALSE) {
if (GDPermissionManager.getInstance().getFinalPermission(event, location, targetClaim, flag, source, entityTypeId, user, true) == Tristate.FALSE) {
event.setCancelled(true);
}
GDTimings.ENTITY_SPAWN_PRE_EVENT.stopTimingIfSync();
@ -266,7 +266,7 @@ public class EntityEventHandler {
}
}
}
if (GDPermissionManager.getInstance().getFinalPermission(event, location, targetClaim, permission, source, entityTypeId, user, true) == Tristate.FALSE) {
if (GDPermissionManager.getInstance().getFinalPermission(event, location, targetClaim, flag, source, entityTypeId, user, true) == Tristate.FALSE) {
event.setCancelled(true);
}
GDTimings.ENTITY_SPAWN_PRE_EVENT.stopTimingIfSync();
@ -334,7 +334,7 @@ public class EntityEventHandler {
return true;
}
String permission = GDPermissions.ENTITY_SPAWN;
Flag flag = Flags.ENTITY_SPAWN;
if (isChunkSpawn) {
if (GriefDefenderPlugin.isTargetIdBlacklisted(Flags.ENTITY_CHUNK_SPAWN.getName(), entity, world.getProperties())) {
return true;
@ -343,7 +343,7 @@ public class EntityEventHandler {
if (entity instanceof ItemFrame) {
return true;
}
permission = GDPermissions.ENTITY_CHUNK_SPAWN;
flag = Flags.ENTITY_CHUNK_SPAWN;
}
if (!isChunkSpawn && entity instanceof Item) {
@ -356,7 +356,7 @@ public class EntityEventHandler {
if (GriefDefenderPlugin.isTargetIdBlacklisted(Flags.ITEM_SPAWN.getName(), entity, world.getProperties())) {
return true;
}
permission = GDPermissions.ITEM_SPAWN;
flag = Flags.ITEM_SPAWN;
if (actualSource instanceof BlockSnapshot) {
final BlockSnapshot block = (BlockSnapshot) actualSource;
final Location<World> location = block.getLocation().orElse(null);
@ -364,11 +364,11 @@ public class EntityEventHandler {
if (GriefDefenderPlugin.isTargetIdBlacklisted(Flags.BLOCK_BREAK.getName(), block, world.getProperties())) {
return true;
}
final Tristate result = GDPermissionManager.getInstance().getFinalPermission(event, location, targetClaim, GDPermissions.BLOCK_BREAK, actualSource, block, user, TrustTypes.ACCESSOR, true);
final Tristate result = GDPermissionManager.getInstance().getFinalPermission(event, location, targetClaim, Flags.BLOCK_BREAK, actualSource, block, user, TrustTypes.ACCESSOR, true);
if (result != Tristate.UNDEFINED) {
if (result == Tristate.TRUE) {
// Check if item drop is allowed
if (GDPermissionManager.getInstance().getFinalPermission(event, location, targetClaim, permission, actualSource, entity, user, TrustTypes.ACCESSOR, true) == Tristate.FALSE) {
if (GDPermissionManager.getInstance().getFinalPermission(event, location, targetClaim, flag, actualSource, entity, user, TrustTypes.ACCESSOR, true) == Tristate.FALSE) {
return false;
}
return true;
@ -379,7 +379,7 @@ public class EntityEventHandler {
}
}
if (GDPermissionManager.getInstance().getFinalPermission(event, entity.getLocation(), targetClaim, permission, actualSource, entity, user, TrustTypes.ACCESSOR, true) == Tristate.FALSE) {
if (GDPermissionManager.getInstance().getFinalPermission(event, entity.getLocation(), targetClaim, flag, actualSource, entity, user, TrustTypes.ACCESSOR, true) == Tristate.FALSE) {
return false;
}
@ -467,7 +467,7 @@ public class EntityEventHandler {
}
final TrustType trustType = TrustTypes.BUILDER;
if (GDPermissionManager.getInstance().getFinalPermission(event, targetEntity.getLocation(), claim, GDPermissions.ENTITY_DAMAGE, source, targetEntity, user, trustType, true) == Tristate.FALSE) {
if (GDPermissionManager.getInstance().getFinalPermission(event, targetEntity.getLocation(), claim, Flags.ENTITY_DAMAGE, source, targetEntity, user, trustType, true) == Tristate.FALSE) {
return true;
}
@ -483,7 +483,7 @@ public class EntityEventHandler {
if (!(source instanceof Player) && !(targetEntity instanceof Player)) {
if (source instanceof User) {
User sourceUser = (User) source;
perm = GDPermissionManager.getInstance().getFinalPermission(event, targetEntity.getLocation(), claim, GDPermissions.ENTITY_DAMAGE, source, targetEntity, sourceUser, trustType, true);
perm = GDPermissionManager.getInstance().getFinalPermission(event, targetEntity.getLocation(), claim, Flags.ENTITY_DAMAGE, source, targetEntity, sourceUser, trustType, true);
if (targetEntity instanceof Living && perm == Tristate.TRUE) {
return false;
}
@ -501,7 +501,7 @@ public class EntityEventHandler {
} else {
if (targetEntity instanceof Player) {
if (NMSUtil.getInstance().isEntityMonster((Entity) source)) {
if (GDPermissionManager.getInstance().getFinalPermission(event, targetEntity.getLocation(), claim, GDPermissions.ENTITY_DAMAGE, source, targetEntity, user, trustType, true) != Tristate.TRUE) {
if (GDPermissionManager.getInstance().getFinalPermission(event, targetEntity.getLocation(), claim, Flags.ENTITY_DAMAGE, source, targetEntity, user, trustType, true) != Tristate.TRUE) {
return true;
}
}
@ -532,7 +532,7 @@ public class EntityEventHandler {
}
}
if (GDPermissionManager.getInstance().getFinalPermission(event, targetEntity.getLocation(), claim, GDPermissions.ENTITY_DAMAGE, attacker, targetEntity, user, trustType, true) == Tristate.FALSE) {
if (GDPermissionManager.getInstance().getFinalPermission(event, targetEntity.getLocation(), claim, Flags.ENTITY_DAMAGE, attacker, targetEntity, user, trustType, true) == Tristate.FALSE) {
return true;
}
@ -635,7 +635,7 @@ public class EntityEventHandler {
return true;
}
if (GDPermissionManager.getInstance().getFinalPermission(event, item.getLocation(), targetClaim, GDPermissions.ITEM_DROP, entity, item, user, TrustTypes.ACCESSOR, true) == Tristate.FALSE) {
if (GDPermissionManager.getInstance().getFinalPermission(event, item.getLocation(), targetClaim, Flags.ITEM_DROP, entity, item, user, TrustTypes.ACCESSOR, true) == Tristate.FALSE) {
return false;
}
return true;
@ -674,6 +674,21 @@ public class EntityEventHandler {
if (entity instanceof Player) {
player = (Player) entity;
user = PermissionHolderCache.getInstance().getOrCreateUser(player);
final GDPlayerData playerData = user.getInternalPlayerData();
// Cancel event if player is unable to teleport during PvP combat
final boolean pvpCombatTeleport = GDPermissionManager.getInstance().getInternalOptionValue(TypeToken.of(Boolean.class), player, Options.PVP_COMBAT_TELEPORT);
if (!pvpCombatTeleport) {
final int combatTimeRemaining = playerData.getPvpCombatTimeRemaining();
if (combatTimeRemaining > 0) {
final Component denyMessage = GriefDefenderPlugin.getInstance().messageData.getMessage(MessageStorage.PVP_IN_COMBAT_NOT_ALLOWED,
ImmutableMap.of(
"time-remaining", combatTimeRemaining));
GriefDefenderPlugin.sendMessage(player, denyMessage);
event.setCancelled(true);
GDTimings.ENTITY_TELEPORT_EVENT.stopTimingIfSync();
return;
}
}
} else {
user = PermissionHolderCache.getInstance().getOrCreateUser(entity.getCreator().orElse(null));
}
@ -706,10 +721,10 @@ public class EntityEventHandler {
}
if (sourceClaim != null) {
if (GDFlags.ENTITY_TELEPORT_FROM && !teleportFromBlacklisted && GDPermissionManager.getInstance().getFinalPermission(event, sourceLocation, sourceClaim, GDPermissions.ENTITY_TELEPORT_FROM, type, entity, user, TrustTypes.ACCESSOR, true) == Tristate.FALSE) {
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, GDPermissions.PORTAL_USE, type, entity, user) == Tristate.TRUE) {
if (portalUseBlacklisted || GDPermissionManager.getInstance().getFinalPermission(event, sourceLocation, sourceClaim, Flags.PORTAL_USE, type, entity, user) == Tristate.TRUE) {
cancelled = false;
}
}
@ -736,10 +751,10 @@ public class EntityEventHandler {
final GDClaim toClaim = this.dataStore.getClaimAt(destination);
if (toClaim != null) {
if (GDFlags.ENTITY_TELEPORT_TO && !teleportToBlacklisted && GDPermissionManager.getInstance().getFinalPermission(event, destination, toClaim, GDPermissions.ENTITY_TELEPORT_TO, type, entity, user, TrustTypes.ACCESSOR, true) == Tristate.FALSE) {
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, GDPermissions.PORTAL_USE, type, entity, user, TrustTypes.ACCESSOR, true) == Tristate.TRUE) {
if (portalUseBlacklisted || GDPermissionManager.getInstance().getFinalPermission(event, destination, toClaim, Flags.PORTAL_USE, type, entity, user, TrustTypes.ACCESSOR, true) == Tristate.TRUE) {
cancelled = false;
}
}
@ -851,9 +866,9 @@ public class EntityEventHandler {
return;
}
targetClaim = this.dataStore.getClaimAt(impactPoint, targetClaim);
final Tristate result = GDPermissionManager.getInstance().getFinalPermission(event, impactPoint, targetClaim, GDPermissions.PROJECTILE_IMPACT_ENTITY, source, entity, user, TrustTypes.ACCESSOR, true);
final Tristate result = GDPermissionManager.getInstance().getFinalPermission(event, impactPoint, targetClaim, Flags.PROJECTILE_IMPACT_ENTITY, source, entity, user, TrustTypes.ACCESSOR, true);
if (result == Tristate.FALSE) {
if (GDPermissionManager.getInstance().getFinalPermission(event, impactPoint, targetClaim, GDPermissions.PROJECTILE_IMPACT_ENTITY, source, entity, user) == Tristate.TRUE) {
if (GDPermissionManager.getInstance().getFinalPermission(event, impactPoint, targetClaim, Flags.PROJECTILE_IMPACT_ENTITY, source, entity, user) == Tristate.TRUE) {
GDTimings.PROJECTILE_IMPACT_ENTITY_EVENT.stopTimingIfSync();
return;
}
@ -888,7 +903,7 @@ public class EntityEventHandler {
final Location<World> location = entity.getLocation();
final GDClaim targetClaim = GriefDefenderPlugin.getInstance().dataStore.getClaimAt(location);
if (GDPermissionManager.getInstance().getFinalPermission(event, location, targetClaim, GDPermissions.ENTITY_RIDING, source, entity, player, TrustTypes.ACCESSOR, true) == Tristate.FALSE) {
if (GDPermissionManager.getInstance().getFinalPermission(event, location, targetClaim, Flags.ENTITY_RIDING, source, entity, player, TrustTypes.ACCESSOR, true) == Tristate.FALSE) {
if (player != null) {
//sendInteractEntityDenyMessage(targetClaim, player, null, entity);
}
@ -901,17 +916,31 @@ public class EntityEventHandler {
private boolean getPvpProtectResult(Event event, GDClaim claim, GDPermissionUser source, GDPermissionUser target) {
final Player sourcePlayer = source.getOnlinePlayer();
final Player targetPlayer = target.getOnlinePlayer();
final boolean sourceInCombat = source.getInternalPlayerData().inPvpCombat(claim.getWorld());
final boolean targetInCombat = target.getInternalPlayerData().inPvpCombat(claim.getWorld());
if (sourceInCombat && targetInCombat) {
final boolean sourceInCombat = source.getInternalPlayerData().inPvpCombat();
final boolean targetInCombat = target.getInternalPlayerData().inPvpCombat();
// Always check if source or target is in combat and if so allow PvP
// This prevents a player from moving to another claim where PvP is disabled
if (sourceInCombat && targetInCombat && (source.getInternalPlayerData().lastPvpTimestamp == target.getInternalPlayerData().lastPvpTimestamp)) {
source.getInternalPlayerData().lastPvpTimestamp = Instant.now();
target.getInternalPlayerData().lastPvpTimestamp = Instant.now();
return false;
}
// Check target claim
if (!claim.isPvpEnabled()) {
GriefDefenderPlugin.sendMessage(sourcePlayer, MessageCache.getInstance().PVP_CLAIM_NOT_ALLOWED);
return true;
}
// Check source claim
final GDClaim sourceClaim = GriefDefenderPlugin.getInstance().dataStore.getClaimAtPlayer(source.getInternalPlayerData(), sourcePlayer.getLocation());
if (!sourceClaim.isPvpEnabled()) {
GriefDefenderPlugin.sendMessage(sourcePlayer, MessageCache.getInstance().PVP_CLAIM_NOT_ALLOWED);
return true;
}
// Check flags
Tristate sourceResult = GDPermissionManager.getInstance().getFinalPermission(event, targetPlayer.getLocation(), claim, GDPermissions.ENTITY_DAMAGE, sourcePlayer, targetPlayer, sourcePlayer, true);
Tristate targetResult = GDPermissionManager.getInstance().getFinalPermission(event, sourcePlayer.getLocation(), claim, GDPermissions.ENTITY_DAMAGE, targetPlayer, sourcePlayer, targetPlayer, true);
Tristate sourceResult = GDPermissionManager.getInstance().getFinalPermission(event, targetPlayer.getLocation(), claim, Flags.ENTITY_DAMAGE, sourcePlayer, targetPlayer, sourcePlayer, true);
Tristate targetResult = GDPermissionManager.getInstance().getFinalPermission(event, sourcePlayer.getLocation(), claim, Flags.ENTITY_DAMAGE, targetPlayer, sourcePlayer, targetPlayer, true);
if (sourceResult == Tristate.FALSE) {
GriefDefenderPlugin.sendMessage(sourcePlayer, MessageCache.getInstance().PVP_SOURCE_NOT_ALLOWED);
return true;
@ -939,13 +968,9 @@ public class EntityEventHandler {
return true;
}
final GDClaim sourceClaim = GriefDefenderPlugin.getInstance().dataStore.getClaimAtPlayer(source.getInternalPlayerData(), sourcePlayer.getLocation());
if (!sourceClaim.isPvpEnabled()) {
GriefDefenderPlugin.sendMessage(sourcePlayer, MessageCache.getInstance().PVP_CLAIM_NOT_ALLOWED);
return true;
}
source.getInternalPlayerData().lastPvpTimestamp = Instant.now();
target.getInternalPlayerData().lastPvpTimestamp = Instant.now();
return !claim.isPvpEnabled();
final Instant now = Instant.now();
source.getInternalPlayerData().lastPvpTimestamp = now;
target.getInternalPlayerData().lastPvpTimestamp = now;
return false;
}
}

View File

@ -42,13 +42,13 @@ import com.griefdefender.api.claim.ClaimTypes;
import com.griefdefender.api.claim.ShovelTypes;
import com.griefdefender.api.claim.TrustType;
import com.griefdefender.api.claim.TrustTypes;
import com.griefdefender.api.permission.flag.Flag;
import com.griefdefender.api.permission.flag.Flags;
import com.griefdefender.api.permission.option.Options;
import com.griefdefender.api.permission.option.type.CreateModeTypes;
import com.griefdefender.cache.MessageCache;
import com.griefdefender.claim.GDClaim;
import com.griefdefender.claim.GDClaimManager;
import com.griefdefender.claim.GDClaimResult;
import com.griefdefender.command.CommandHelper;
import com.griefdefender.configuration.GriefDefenderConfig;
import com.griefdefender.configuration.MessageStorage;
@ -79,7 +79,6 @@ import org.spongepowered.api.block.tileentity.TileEntity;
import org.spongepowered.api.command.CommandMapping;
import org.spongepowered.api.command.CommandSource;
import org.spongepowered.api.data.key.Keys;
import org.spongepowered.api.data.property.entity.EyeLocationProperty;
import org.spongepowered.api.data.type.HandType;
import org.spongepowered.api.data.type.HandTypes;
import org.spongepowered.api.entity.Entity;
@ -130,8 +129,6 @@ import org.spongepowered.api.world.Location;
import org.spongepowered.api.world.World;
import org.spongepowered.api.world.storage.WorldProperties;
import org.spongepowered.common.SpongeImpl;
import org.spongepowered.common.SpongeImplHooks;
import org.spongepowered.common.item.inventory.custom.CustomInventory;
import java.math.BigDecimal;
import java.time.Instant;
@ -282,6 +279,19 @@ public class PlayerEventHandler {
return;
}
final int combatTimeRemaining = playerData.getPvpCombatTimeRemaining();
final boolean inPvpCombat = combatTimeRemaining > 0;
final boolean pvpCombatCommand = GDPermissionManager.getInstance().getInternalOptionValue(TypeToken.of(Boolean.class), player, Options.PVP_COMBAT_COMMAND);
if (!pvpCombatCommand && inPvpCombat) {
final Component denyMessage = GriefDefenderPlugin.getInstance().messageData.getMessage(MessageStorage.PVP_IN_COMBAT_NOT_ALLOWED,
ImmutableMap.of(
"time-remaining", combatTimeRemaining));
GriefDefenderPlugin.sendMessage(player, denyMessage);
event.setCancelled(true);
GDTimings.PLAYER_COMMAND_EVENT.stopTimingIfSync();
return;
}
String commandBaseTarget = pluginId + ":" + command;
String commandTargetWithArgs = commandBaseTarget;
// first check the args
@ -298,12 +308,32 @@ public class PlayerEventHandler {
commandExecuteTargetBlacklisted = true;
}
if (GDFlags.COMMAND_EXECUTE && !commandExecuteSourceBlacklisted && !commandExecuteTargetBlacklisted) {
if (GDFlags.COMMAND_EXECUTE && !inPvpCombat && !commandExecuteSourceBlacklisted && !commandExecuteTargetBlacklisted) {
// First check base command
Tristate result = GDPermissionManager.getInstance().getFinalPermission(event, player.getLocation(), claim, GDPermissions.COMMAND_EXECUTE, event.getSource(), commandBaseTarget, player, true);
Tristate result = GDPermissionManager.getInstance().getFinalPermission(event, player.getLocation(), claim, Flags.COMMAND_EXECUTE, event.getSource(), commandBaseTarget, player, true);
if (result != Tristate.FALSE) {
// check with args
result = GDPermissionManager.getInstance().getFinalPermission(event, player.getLocation(), claim, GDPermissions.COMMAND_EXECUTE, event.getSource(), commandTargetWithArgs, player, true);
result = GDPermissionManager.getInstance().getFinalPermission(event, player.getLocation(), claim, Flags.COMMAND_EXECUTE, event.getSource(), commandTargetWithArgs, player, true);
}
if (result == Tristate.FALSE) {
final Component denyMessage = GriefDefenderPlugin.getInstance().messageData.getMessage(MessageStorage.COMMAND_BLOCKED,
ImmutableMap.of(
"command", command,
"player", claim.getOwnerName()));
GriefDefenderPlugin.sendMessage(player, denyMessage);
event.setCancelled(true);
GDTimings.PLAYER_COMMAND_EVENT.stopTimingIfSync();
return;
}
GDTimings.PLAYER_COMMAND_EVENT.stopTimingIfSync();
return;
}
if (GDFlags.COMMAND_EXECUTE_PVP && inPvpCombat && !commandExecuteSourceBlacklisted && !commandExecuteTargetBlacklisted) {
// First check base command
Tristate result = GDPermissionManager.getInstance().getFinalPermission(event, player.getLocation(), claim, Flags.COMMAND_EXECUTE_PVP, event.getSource(), commandBaseTarget, player, true);
if (result != Tristate.FALSE) {
// check with args
result = GDPermissionManager.getInstance().getFinalPermission(event, player.getLocation(), claim, Flags.COMMAND_EXECUTE_PVP, event.getSource(), commandTargetWithArgs, player, true);
}
if (result == Tristate.FALSE) {
final Component denyMessage = GriefDefenderPlugin.getInstance().messageData.getMessage(MessageStorage.COMMAND_BLOCKED,
@ -316,22 +346,6 @@ public class PlayerEventHandler {
return;
}
}
/*if (GDFlags.COMMAND_EXECUTE_PVP && !commandExecutePvpSourceBlacklisted && playerData != null && (playerData.inPvpCombat(player.getWorld())) && !GriefDefenderPlugin.isTargetIdBlacklisted(Flags.COMMAND_EXECUTE_PVP.getName(), commandPermission + argument, player.getWorld().getProperties())) {
final Tristate result = GPPermissionManager.getInstance().getFinalPermission(event, player.getLocation(), claim, GPPermissions.COMMAND_EXECUTE_PVP, event.getSource(), commandPermission + argument, player);
if (result == Tristate.TRUE) {
GDTimings.PLAYER_COMMAND_EVENT.stopTimingIfSync();
return;
}
if (result == Tristate.FALSE) {
final Component denyMessage = GriefDefenderPlugin.getInstance().messageData.pvpCommandBanned
.apply(ImmutableMap.of(
"command", command)).build();
GriefDefenderPlugin.sendMessage(event.getCause().first(Player.class).get(), denyMessage);
event.setCancelled(true);
GDTimings.PLAYER_COMMAND_EVENT.stopTimingIfSync();
return;
}
}*/
GDTimings.PLAYER_COMMAND_EVENT.stopTimingIfSync();
}
@ -461,7 +475,7 @@ public class PlayerEventHandler {
Location<World> location = entityItem.getLocation();
GDClaim claim = this.dataStore.getClaimAtPlayer(playerData, location);
if (claim != null) {
if (GDPermissionManager.getInstance().getFinalPermission(event, location, claim, GDPermissions.ITEM_DROP, user, entityItem, user, TrustTypes.ACCESSOR, true) == Tristate.FALSE) {
if (GDPermissionManager.getInstance().getFinalPermission(event, location, claim, Flags.ITEM_DROP, user, entityItem, user, TrustTypes.ACCESSOR, true) == Tristate.FALSE) {
event.setCancelled(true);
if (spawncause instanceof Player) {
final Component message = GriefDefenderPlugin.getInstance().messageData.getMessage(MessageStorage.PERMISSION_ITEM_DROP,
@ -497,7 +511,7 @@ public class PlayerEventHandler {
GDTimings.PLAYER_INTERACT_INVENTORY_OPEN_EVENT.startTimingIfSync();
final Location<World> location = blockSnapshot.getLocation().get();
final GDClaim claim = this.dataStore.getClaimAt(location);
final Tristate result = GDPermissionManager.getInstance().getFinalPermission(event, location, claim, GDPermissions.INVENTORY_OPEN, player, blockSnapshot, player, TrustTypes.CONTAINER, true);
final Tristate result = GDPermissionManager.getInstance().getFinalPermission(event, location, claim, Flags.INTERACT_INVENTORY, player, blockSnapshot, player, TrustTypes.CONTAINER, true);
if (result == Tristate.FALSE) {
final Component message = GriefDefenderPlugin.getInstance().messageData.getMessage(MessageStorage.PERMISSION_INVENTORY_OPEN,
ImmutableMap.of(
@ -524,7 +538,7 @@ public class PlayerEventHandler {
GDTimings.PLAYER_INTERACT_INVENTORY_CLOSE_EVENT.startTimingIfSync();
final Location<World> location = player.getLocation();
final GDClaim claim = this.dataStore.getClaimAt(location);
if (GDPermissionManager.getInstance().getFinalPermission(event, location, claim, GDPermissions.ITEM_DROP, player, cursor, player, TrustTypes.ACCESSOR, true) == Tristate.FALSE) {
if (GDPermissionManager.getInstance().getFinalPermission(event, location, claim, Flags.ITEM_DROP, player, cursor, player, TrustTypes.ACCESSOR, true) == Tristate.FALSE) {
final Component message = GriefDefenderPlugin.getInstance().messageData.getMessage(MessageStorage.PERMISSION_ITEM_DROP,
ImmutableMap.of(
"player", claim.getOwnerName(),
@ -552,7 +566,7 @@ public class PlayerEventHandler {
final ItemStackSnapshot cursorItem = event.getCursorTransaction().getOriginal();
// check if original cursor item can be dropped
if (isDrop && cursorItem != ItemStackSnapshot.NONE && !GriefDefenderPlugin.isTargetIdBlacklisted(Flags.ITEM_DROP.getName(), cursorItem, player.getWorld().getProperties())) {
if (GDPermissionManager.getInstance().getFinalPermission(event, location, claim, GDPermissions.ITEM_DROP, player, cursorItem, player, TrustTypes.ACCESSOR, true) == Tristate.FALSE) {
if (GDPermissionManager.getInstance().getFinalPermission(event, location, claim, Flags.ITEM_DROP, player, cursorItem, player, TrustTypes.ACCESSOR, true) == Tristate.FALSE) {
final Component message = GriefDefenderPlugin.getInstance().messageData.getMessage(MessageStorage.PERMISSION_ITEM_DROP,
ImmutableMap.of(
"player", claim.getOwnerName(),
@ -572,7 +586,7 @@ public class PlayerEventHandler {
continue;
}
final Tristate result = GDPermissionManager.getInstance().getFinalPermission(event, location, claim, GDPermissions.INVENTORY_CLICK, player, transaction.getOriginal(), player, TrustTypes.CONTAINER, true);
final Tristate result = GDPermissionManager.getInstance().getFinalPermission(event, location, claim, Flags.INTERACT_INVENTORY_CLICK, player, transaction.getOriginal(), player, TrustTypes.CONTAINER, true);
if (result == Tristate.FALSE) {
Component message = GriefDefenderPlugin.getInstance().messageData.getMessage(MessageStorage.PERMISSION_INTERACT_ITEM,
ImmutableMap.of(
@ -589,7 +603,7 @@ public class PlayerEventHandler {
continue;
}
if (GDPermissionManager.getInstance().getFinalPermission(event, location, claim, GDPermissions.ITEM_DROP, player, transaction.getFinal(), player, TrustTypes.ACCESSOR, true) == Tristate.FALSE) {
if (GDPermissionManager.getInstance().getFinalPermission(event, location, claim, Flags.ITEM_DROP, player, transaction.getFinal(), player, TrustTypes.ACCESSOR, true) == Tristate.FALSE) {
final Component message = GriefDefenderPlugin.getInstance().messageData.getMessage(MessageStorage.PERMISSION_ITEM_DROP,
ImmutableMap.of(
"player", claim.getOwnerName(),
@ -630,9 +644,9 @@ public class PlayerEventHandler {
event.setCancelled(false);
}
Tristate result = GDPermissionManager.getInstance().getFinalPermission(event, location, claim, GDPermissions.INTERACT_ENTITY_PRIMARY, source, targetEntity, player, TrustTypes.ACCESSOR, true);
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, GDPermissions.ENTITY_DAMAGE, source, targetEntity, player, TrustTypes.ACCESSOR, true) != Tristate.TRUE) {
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()));
@ -670,9 +684,9 @@ public class PlayerEventHandler {
return;
}
Tristate result = GDPermissionManager.getInstance().getFinalPermission(event, location, claim, GDPermissions.INTERACT_ENTITY_SECONDARY, source, targetEntity, player, TrustTypes.ACCESSOR, true);
Tristate result = GDPermissionManager.getInstance().getFinalPermission(event, location, claim, Flags.INTERACT_ENTITY_SECONDARY, source, targetEntity, player, TrustTypes.ACCESSOR, true);
if (result == Tristate.TRUE && targetEntity instanceof ArmorStand) {
result = GDPermissionManager.getInstance().getFinalPermission(event, location, claim, GDPermissions.INVENTORY_OPEN, source, targetEntity, player, TrustTypes.CONTAINER, false);
result = GDPermissionManager.getInstance().getFinalPermission(event, location, claim, Flags.INTERACT_INVENTORY, source, targetEntity, player, TrustTypes.CONTAINER, false);
}
if (result == Tristate.FALSE) {
event.setCancelled(true);
@ -711,7 +725,7 @@ public class PlayerEventHandler {
GDPlayerData playerData = this.dataStore.getOrCreatePlayerData(world, player.getUniqueId());
Location<World> location = player.getLocation();
GDClaim claim = this.dataStore.getClaimAtPlayer(playerData, location);
if (GDPermissionManager.getInstance().getFinalPermission(event, location, claim, GDPermissions.ITEM_PICKUP, player, event.getTargetEntity(), player, true) == Tristate.FALSE) {
if (GDPermissionManager.getInstance().getFinalPermission(event, location, claim, Flags.ITEM_PICKUP, player, event.getTargetEntity(), player, true) == Tristate.FALSE) {
event.setCancelled(true);
}
@ -788,7 +802,7 @@ public class PlayerEventHandler {
GDPlayerData playerData = this.dataStore.getOrCreatePlayerData(location.getExtent(), player.getUniqueId());
GDClaim claim = this.dataStore.getClaimAtPlayer(playerData, location);
final Tristate result = GDPermissionManager.getInstance().getFinalPermission(event, location, claim, GDPermissions.ITEM_USE, player, event.getItemStackInUse().getType(), player, TrustTypes.ACCESSOR, true);
final Tristate result = GDPermissionManager.getInstance().getFinalPermission(event, location, claim, Flags.ITEM_USE, player, event.getItemStackInUse().getType(), player, TrustTypes.ACCESSOR, true);
if (result == Tristate.FALSE) {
final Component message = GriefDefenderPlugin.getInstance().messageData.getMessage(MessageStorage.PERMISSION_ITEM_USE,
ImmutableMap.of(
@ -846,13 +860,13 @@ public class PlayerEventHandler {
}
final GDClaim claim = this.dataStore.getClaimAt(location);
final Tristate result = GDPermissionManager.getInstance().getFinalPermission(event, location, claim, GDPermissions.INTERACT_BLOCK_PRIMARY, source, clickedBlock.getState(), player, TrustTypes.BUILDER, true);
final Tristate result = GDPermissionManager.getInstance().getFinalPermission(event, location, claim, Flags.INTERACT_BLOCK_PRIMARY, source, clickedBlock.getState(), player, TrustTypes.BUILDER, true);
if (result == Tristate.FALSE) {
if (GriefDefenderPlugin.isTargetIdBlacklisted(Flags.BLOCK_BREAK.getName(), clickedBlock.getState(), player.getWorld().getProperties())) {
GDTimings.PLAYER_INTERACT_BLOCK_PRIMARY_EVENT.stopTimingIfSync();
return;
}
if (GDPermissionManager.getInstance().getFinalPermission(event, location, claim, GDPermissions.BLOCK_BREAK, source, clickedBlock.getState(), player, TrustTypes.BUILDER, true) == Tristate.TRUE) {
if (GDPermissionManager.getInstance().getFinalPermission(event, location, claim, Flags.BLOCK_BREAK, source, clickedBlock.getState(), player, TrustTypes.BUILDER, true) == Tristate.TRUE) {
GDTimings.PLAYER_INTERACT_BLOCK_PRIMARY_EVENT.stopTimingIfSync();
return;
}
@ -899,7 +913,7 @@ public class PlayerEventHandler {
final TileEntity tileEntity = clickedBlock.getLocation().get().getTileEntity().orElse(null);
final TrustType trustType = (tileEntity != null && NMSUtil.getInstance().containsInventory(tileEntity)) ? TrustTypes.CONTAINER : TrustTypes.ACCESSOR;
if (GDFlags.INTERACT_BLOCK_SECONDARY && playerData != null) {
Tristate result = GDPermissionManager.getInstance().getFinalPermission(event, location, claim, GDPermissions.INTERACT_BLOCK_SECONDARY, source, event.getTargetBlock(), player, trustType, true);
Tristate result = GDPermissionManager.getInstance().getFinalPermission(event, location, claim, Flags.INTERACT_BLOCK_SECONDARY, source, event.getTargetBlock(), player, trustType, true);
if (result == Tristate.FALSE) {
// if player is holding an item, check if it can be placed
if (GDFlags.BLOCK_PLACE && !itemInHand.isEmpty() && NMSUtil.getInstance().isItemBlock(itemInHand)) {
@ -907,7 +921,7 @@ public class PlayerEventHandler {
GDTimings.PLAYER_INTERACT_BLOCK_SECONDARY_EVENT.stopTimingIfSync();
return;
}
if (GDPermissionManager.getInstance().getFinalPermission(event, location, claim, GDPermissions.BLOCK_PLACE, source, itemInHand, player, TrustTypes.BUILDER, true) == Tristate.TRUE) {
if (GDPermissionManager.getInstance().getFinalPermission(event, location, claim, Flags.BLOCK_PLACE, source, itemInHand, player, TrustTypes.BUILDER, true) == Tristate.TRUE) {
GDTimings.PLAYER_INTERACT_BLOCK_SECONDARY_EVENT.stopTimingIfSync();
return;
}
@ -961,11 +975,11 @@ public class PlayerEventHandler {
: player.getLocation();
final GDClaim claim = this.dataStore.getClaimAt(location);
final String ITEM_PERMISSION = primaryEvent ? GDPermissions.INTERACT_ITEM_PRIMARY : GDPermissions.INTERACT_ITEM_SECONDARY;
final Flag flag = primaryEvent ? Flags.INTERACT_ITEM_PRIMARY : Flags.INTERACT_ITEM_SECONDARY;
if (playerData.claimMode || (!itemInHand.isEmpty() && (itemInHand.getType().equals(GriefDefenderPlugin.getInstance().modificationTool.getType()) ||
itemInHand.getType().equals(GriefDefenderPlugin.getInstance().investigationTool.getType())))) {
GDPermissionManager.getInstance().addEventLogEntry(event, location, itemInHand, blockSnapshot == null ? entity : blockSnapshot, player, ITEM_PERMISSION, null, Tristate.TRUE);
GDPermissionManager.getInstance().addEventLogEntry(event, location, itemInHand, blockSnapshot == null ? entity : blockSnapshot, player, flag, null, Tristate.TRUE);
event.setCancelled(true);
if (investigateClaim(event, player, blockSnapshot, itemInHand)) {
return event;
@ -983,7 +997,7 @@ public class PlayerEventHandler {
return event;
}
if (GDPermissionManager.getInstance().getFinalPermission(event, location, claim, ITEM_PERMISSION, player, itemType, player, TrustTypes.ACCESSOR, true) == Tristate.FALSE) {
if (GDPermissionManager.getInstance().getFinalPermission(event, location, claim, flag, player, itemType, player, TrustTypes.ACCESSOR, true) == Tristate.FALSE) {
Component message = GriefDefenderPlugin.getInstance().messageData.getMessage(MessageStorage.PERMISSION_INTERACT_ITEM,
ImmutableMap.of(
"player", claim.getOwnerName(),
@ -1582,7 +1596,8 @@ public class PlayerEventHandler {
// if holding shift (sneaking), show all claims in area
GDClaim claim = null;
if (clickedBlock.getState().getType().equals(BlockTypes.AIR)) {
claim = this.findNearbyClaim(player);
final int maxDistance = GDPermissionManager.getInstance().getInternalOptionValue(TypeToken.of(Integer.class), player, Options.RADIUS_INSPECT);
claim = this.findNearbyClaim(player, maxDistance);
// if holding shift (sneaking), show all claims in area
if (player.get(Keys.IS_SNEAKING).get()) {
if (!playerData.canIgnoreClaim(claim) && !player.hasPermission(GDPermissions.VISUALIZE_CLAIMS_NEARBY)) {
@ -1592,7 +1607,7 @@ public class PlayerEventHandler {
}
Location<World> nearbyLocation = playerData.lastValidInspectLocation != null ? playerData.lastValidInspectLocation : player.getLocation();
Set<Claim> claims = BlockUtil.getInstance().getNearbyClaims(nearbyLocation);
Set<Claim> claims = BlockUtil.getInstance().getNearbyClaims(nearbyLocation, maxDistance);
int height = (int) (playerData.lastValidInspectLocation != null ? playerData.lastValidInspectLocation.getBlockY() : PlayerUtil.getInstance().getEyeHeight(player));
boolean hideBorders = this.worldEditProvider != null &&
this.worldEditProvider.hasCUISupport(player) &&
@ -1652,8 +1667,7 @@ public class PlayerEventHandler {
return true;
}
private GDClaim findNearbyClaim(Player player) {
int maxDistance = GriefDefenderPlugin.getInstance().maxInspectionDistance;
private GDClaim findNearbyClaim(Player player, int maxDistance) {
BlockRay<World> blockRay = BlockRay.from(player).distanceLimit(maxDistance).build();
GDPlayerData playerData = GriefDefenderPlugin.getInstance().dataStore.getOrCreatePlayerData(player.getWorld(), player.getUniqueId());
GDClaim claim = null;

View File

@ -40,6 +40,7 @@ import com.griefdefender.configuration.ClaimStorageData;
import com.griefdefender.internal.util.BlockUtil;
import com.griefdefender.permission.GDPermissionHolder;
import com.griefdefender.permission.GDPermissionUser;
import com.griefdefender.permission.option.OptionContexts;
import com.griefdefender.storage.BaseStorage;
import com.griefdefender.util.PermissionUtil;
@ -233,20 +234,26 @@ public class GPBukkitMigrator {
case FLAG_ENTER_COMMAND :
contexts.add(new Context(ContextKeys.FLAG, Flags.ENTER_CLAIM.getName()));
contexts.add(TARGET_PLAYER);
PermissionUtil.getInstance().setOptionValue(DEFAULT_HOLDER, Options.PLAYER_COMMAND.getPermission(), param, contexts);
contexts.add(OptionContexts.COMMAND_RUNAS_CONSOLE);
contexts.add(OptionContexts.COMMAND_RUNFOR_PUBLIC);
PermissionUtil.getInstance().setOptionValue(DEFAULT_HOLDER, Options.PLAYER_COMMAND_ENTER.getPermission(), param, contexts);
break;
case FLAG_ENTER_COMMAND_OWNER :
contexts.add(new Context(ContextKeys.FLAG, Flags.ENTER_CLAIM.getName()));
contexts.add(TARGET_PLAYER);
contexts.add(OptionContexts.COMMAND_RUNAS_CONSOLE);
contexts.add(OptionContexts.COMMAND_RUNFOR_OWNER);
if (claimOwner == null) {
GriefDefenderPlugin.getInstance().getLogger().info("Could not locate owner legacy claim id '" + bukkitClaimId + "'. Skipping...");
break;
}
PermissionUtil.getInstance().setOptionValue(claimOwner, Options.PLAYER_COMMAND.getPermission(), param, contexts);
PermissionUtil.getInstance().setOptionValue(claimOwner, Options.PLAYER_COMMAND_ENTER.getPermission(), param, contexts);
break;
case FLAG_ENTER_COMMAND_MEMBERS : {
contexts.add(new Context(ContextKeys.FLAG, Flags.ENTER_CLAIM.getName()));
contexts.add(TARGET_PLAYER);
contexts.add(OptionContexts.COMMAND_RUNAS_CONSOLE);
contexts.add(OptionContexts.COMMAND_RUNFOR_MEMBER);
List<UUID> members = new ArrayList<>();
members.addAll(claimStorage.getConfig().getAccessors());
members.addAll(claimStorage.getConfig().getBuilders());
@ -254,18 +261,22 @@ public class GPBukkitMigrator {
members.addAll(claimStorage.getConfig().getManagers());
for (UUID memberUniqueId : members) {
final GDPermissionUser user = PermissionHolderCache.getInstance().getOrCreateUser(memberUniqueId);
PermissionUtil.getInstance().setOptionValue(user, Options.PLAYER_COMMAND.getPermission(), param, contexts);
PermissionUtil.getInstance().setOptionValue(user, Options.PLAYER_COMMAND_ENTER.getPermission(), param, contexts);
}
break;
}
case FLAG_ENTER_PLAYER_COMMAND :
contexts.add(new Context(ContextKeys.FLAG, Flags.ENTER_CLAIM.getName()));
contexts.add(new Context(ContextKeys.TARGET, "player"));
PermissionUtil.getInstance().setOptionValue(DEFAULT_HOLDER, Options.PLAYER_COMMAND.getPermission(), param, contexts);
contexts.add(OptionContexts.COMMAND_RUNAS_PLAYER);
contexts.add(OptionContexts.COMMAND_RUNFOR_PUBLIC);
PermissionUtil.getInstance().setOptionValue(DEFAULT_HOLDER, Options.PLAYER_COMMAND_ENTER.getPermission(), param, contexts);
break;
case FLAG_EXIT_COMMAND_MEMBERS : {
contexts.add(new Context(ContextKeys.FLAG, Flags.EXIT_CLAIM.getName()));
contexts.add(TARGET_PLAYER);
contexts.add(OptionContexts.COMMAND_RUNAS_PLAYER);
contexts.add(OptionContexts.COMMAND_RUNFOR_MEMBER);
List<UUID> members = new ArrayList<>();
members.addAll(claimStorage.getConfig().getAccessors());
members.addAll(claimStorage.getConfig().getBuilders());
@ -273,24 +284,28 @@ public class GPBukkitMigrator {
members.addAll(claimStorage.getConfig().getManagers());
for (UUID memberUniqueId : members) {
final GDPermissionUser user = PermissionHolderCache.getInstance().getOrCreateUser(memberUniqueId);
PermissionUtil.getInstance().setOptionValue(user, Options.PLAYER_COMMAND.getPermission(), param, contexts);
PermissionUtil.getInstance().setOptionValue(user, Options.PLAYER_COMMAND_EXIT.getPermission(), param, contexts);
}
break;
}
case FLAG_EXIT_COMMAND_OWNER :
contexts.add(new Context(ContextKeys.FLAG, Flags.EXIT_CLAIM.getName()));
contexts.add(TARGET_PLAYER);
contexts.add(OptionContexts.COMMAND_RUNAS_CONSOLE);
contexts.add(OptionContexts.COMMAND_RUNFOR_MEMBER);
if (claimOwner == null) {
GriefDefenderPlugin.getInstance().getLogger().info("Could not locate owner legacy claim id '" + bukkitClaimId + "'. Skipping...");
break;
}
PermissionUtil.getInstance().setOptionValue(claimOwner, Options.PLAYER_COMMAND.getPermission(), param, contexts);
PermissionUtil.getInstance().setOptionValue(claimOwner, Options.PLAYER_COMMAND_EXIT.getPermission(), param, contexts);
break;
case FLAG_EXIT_COMMAND :
case FLAG_EXIT_PLAYER_COMMAND :
contexts.add(new Context(ContextKeys.FLAG, Flags.EXIT_CLAIM.getName()));
contexts.add(TARGET_PLAYER);
PermissionUtil.getInstance().setOptionValue(DEFAULT_HOLDER, Options.PLAYER_COMMAND.getPermission(), param, contexts);
contexts.add(OptionContexts.COMMAND_RUNAS_PLAYER);
contexts.add(OptionContexts.COMMAND_RUNFOR_PUBLIC);
PermissionUtil.getInstance().setOptionValue(DEFAULT_HOLDER, Options.PLAYER_COMMAND_EXIT.getPermission(), param, contexts);
break;
case FLAG_EXIT_MESSAGE :
claimStorage.getConfig().setFarewell(LegacyComponentSerializer.legacy().deserialize(param, '§'));

View File

@ -26,6 +26,7 @@ package com.griefdefender.permission;
public class ContextGroupKeys {
public static final String ALL = "#all";
public static final String AMBIENT = "#ambient";
public static final String ANIMAL = "#animal";
public static final String AQUATIC = "#aquatic";

View File

@ -30,12 +30,14 @@ import com.griefdefender.api.permission.ContextKeys;
public class ContextGroups {
// Entity groups
public static final Context SOURCE_ALL = new Context(ContextKeys.SOURCE, ContextGroupKeys.ALL);
public static final Context SOURCE_AMBIENT = new Context(ContextKeys.SOURCE, ContextGroupKeys.AMBIENT);
public static final Context SOURCE_ANIMAL = new Context(ContextKeys.SOURCE, ContextGroupKeys.ANIMAL);
public static final Context SOURCE_AQUATIC = new Context(ContextKeys.SOURCE, ContextGroupKeys.AQUATIC);
public static final Context SOURCE_MISC = new Context(ContextKeys.SOURCE, ContextGroupKeys.MISC);
public static final Context SOURCE_MONSTER = new Context(ContextKeys.SOURCE, ContextGroupKeys.MONSTER);
public static final Context SOURCE_VEHICLE = new Context(ContextKeys.SOURCE, ContextGroupKeys.VEHICLE);
public static final Context TARGET_ALL = new Context(ContextKeys.TARGET, ContextGroupKeys.ALL);
public static final Context TARGET_AMBIENT = new Context(ContextKeys.TARGET, ContextGroupKeys.AMBIENT);
public static final Context TARGET_ANIMAL = new Context(ContextKeys.TARGET, ContextGroupKeys.ANIMAL);
public static final Context TARGET_AQUATIC = new Context(ContextKeys.TARGET, ContextGroupKeys.AQUATIC);

View File

@ -48,8 +48,11 @@ import com.griefdefender.api.permission.flag.FlagData;
import com.griefdefender.api.permission.flag.FlagDefinition;
import com.griefdefender.api.permission.flag.Flags;
import com.griefdefender.api.permission.option.Option;
import com.griefdefender.api.permission.option.Options;
import com.griefdefender.api.permission.option.type.CreateModeType;
import com.griefdefender.api.permission.option.type.CreateModeTypes;
import com.griefdefender.api.permission.option.type.WeatherType;
import com.griefdefender.api.permission.option.type.WeatherTypes;
import com.griefdefender.cache.EventResultCache;
import com.griefdefender.cache.MessageCache;
import com.griefdefender.cache.PermissionHolderCache;
@ -159,48 +162,48 @@ public class GDPermissionManager implements PermissionManager {
@Override
public Tristate getActiveFlagPermissionValue(Claim claim, Subject subject, Flag flag, Object source, Object target, Set<Context> contexts, TrustType type, boolean checkOverride) {
return getFinalPermission(null, null, contexts, claim, flag.getPermission(), source, target, (GDPermissionHolder) subject, null, checkOverride);
return getFinalPermission(null, null, contexts, claim, flag, source, target, (GDPermissionHolder) subject, null, checkOverride);
}
public Tristate getFinalPermission(Event event, Location<World> location, Claim claim, String flagPermission, Object source, Object target, GDPermissionHolder permissionHolder) {
return getFinalPermission(event, location, claim, flagPermission, source, target, permissionHolder, null, false);
public Tristate getFinalPermission(Event event, Location<World> location, Claim claim, Flag flag, Object source, Object target, GDPermissionHolder permissionHolder) {
return getFinalPermission(event, location, claim, flag, source, target, permissionHolder, null, false);
}
public Tristate getFinalPermission(Event event, Location<World> location, Claim claim, String flagPermission, Object source, Object target, Player player) {
public Tristate getFinalPermission(Event event, Location<World> location, Claim claim, Flag flag, Object source, Object target, Player player) {
final GDPermissionHolder permissionHolder = PermissionHolderCache.getInstance().getOrCreateUser(player);
return getFinalPermission(event, location, claim, flagPermission, source, target, permissionHolder, null, false);
return getFinalPermission(event, location, claim, flag, source, target, permissionHolder, null, false);
}
public Tristate getFinalPermission(Event event, Location<World> location, Claim claim, String flagPermission, Object source, Object target, Player player, boolean checkOverride) {
public Tristate getFinalPermission(Event event, Location<World> location, Claim claim, Flag flag, Object source, Object target, Player player, boolean checkOverride) {
final GDPermissionHolder permissionHolder = PermissionHolderCache.getInstance().getOrCreateUser(player);
return getFinalPermission(event, location, claim, flagPermission, source, target, permissionHolder, null, checkOverride);
return getFinalPermission(event, location, claim, flag, source, target, permissionHolder, null, checkOverride);
}
public Tristate getFinalPermission(Event event, Location<World> location, Claim claim, String flagPermission, Object source, Object target, GDPermissionHolder permissionHolder, boolean checkOverride) {
return getFinalPermission(event, location, claim, flagPermission, source, target, permissionHolder, null, checkOverride);
public Tristate getFinalPermission(Event event, Location<World> location, Claim claim, Flag flag, Object source, Object target, GDPermissionHolder permissionHolder, boolean checkOverride) {
return getFinalPermission(event, location, claim, flag, source, target, permissionHolder, null, checkOverride);
}
public Tristate getFinalPermission(Event event, Location<World> location, Claim claim, String flagPermission, Object source, Object target, User user) {
public Tristate getFinalPermission(Event event, Location<World> location, Claim claim, Flag flag, Object source, Object target, User user) {
final GDPermissionHolder permissionHolder = PermissionHolderCache.getInstance().getOrCreateUser(user);
return getFinalPermission(event, location, claim, flagPermission, source, target, permissionHolder, null, false);
return getFinalPermission(event, location, claim, flag, source, target, permissionHolder, null, false);
}
public Tristate getFinalPermission(Event event, Location<World> location, Claim claim, String flagPermission, Object source, Object target, User user, boolean checkOverride) {
public Tristate getFinalPermission(Event event, Location<World> location, Claim claim, Flag flag, Object source, Object target, User user, boolean checkOverride) {
final GDPermissionHolder permissionHolder = PermissionHolderCache.getInstance().getOrCreateUser(user);
return getFinalPermission(event, location, claim, flagPermission, source, target, permissionHolder, null, checkOverride);
return getFinalPermission(event, location, claim, flag, source, target, permissionHolder, null, checkOverride);
}
public Tristate getFinalPermission(Event event, Location<World> location, Claim claim, String flagPermission, Object source, Object target, Player player, TrustType type, boolean checkOverride) {
public Tristate getFinalPermission(Event event, Location<World> location, Claim claim, Flag flag, Object source, Object target, Player player, TrustType type, boolean checkOverride) {
final GDPermissionHolder permissionHolder = PermissionHolderCache.getInstance().getOrCreateUser(player);
return getFinalPermission(event, location, claim, flagPermission, source, target, permissionHolder, type, checkOverride);
return getFinalPermission(event, location, claim, flag, source, target, permissionHolder, type, checkOverride);
}
public Tristate getFinalPermission(Event event, Location<World> location, Claim claim, String flagPermission, Object source, Object target, User user, TrustType type, boolean checkOverride) {
public Tristate getFinalPermission(Event event, Location<World> location, Claim claim, Flag flag, Object source, Object target, User user, TrustType type, boolean checkOverride) {
final GDPermissionHolder permissionHolder = PermissionHolderCache.getInstance().getOrCreateUser(user);
return getFinalPermission(event, location, claim, flagPermission, source, target, permissionHolder, type, checkOverride);
return getFinalPermission(event, location, claim, flag, source, target, permissionHolder, type, checkOverride);
}
public Tristate getFinalPermission(Event event, Location<World> location, Claim claim, String flagPermission, Object source, Object target, GDPermissionHolder subject, TrustType type, boolean checkOverride) {
public Tristate getFinalPermission(Event event, Location<World> location, Claim claim, Flag flag, Object source, Object target, GDPermissionHolder subject, TrustType type, boolean checkOverride) {
final Set<Context> contexts = new HashSet<>();
for (Map.Entry<EventContextKey<?>, Object> mapEntry : event.getContext().asMap().entrySet()) {
if (IGNORED_EVENT_CONTEXTS.contains(mapEntry.getKey())) {
@ -218,10 +221,10 @@ public class GDPermissionManager implements PermissionManager {
final Context context = new Context(parts[1], contextId);
contexts.add(context);
}
return getFinalPermission(event, location, contexts, claim, flagPermission, source, target, subject, type, checkOverride);
return getFinalPermission(event, location, contexts, claim, flag, source, target, subject, type, checkOverride);
}
public Tristate getFinalPermission(Event event, Location<World> location, Set<Context> contexts, Claim claim, String flagPermission, Object source, Object target, GDPermissionHolder permissionHolder, TrustType type, boolean checkOverride) {
public Tristate getFinalPermission(Event event, Location<World> location, Set<Context> contexts, Claim claim, Flag flag, Object source, Object target, GDPermissionHolder permissionHolder, TrustType type, boolean checkOverride) {
if (claim == null) {
return Tristate.TRUE;
}
@ -277,24 +280,29 @@ public class GDPermissionManager implements PermissionManager {
contexts.add(((GDClaim) claim).getWorldContext());
this.eventContexts = contexts;
this.eventPlayerData = playerData;
final String targetPermission = flag.getPermission();
String targetPermission = flagPermission;
/*if (!targetId.isEmpty()) {
//String[] parts = targetId.split(":");
//String targetMod = parts[0];
// move target meta to end of permission
Matcher m = PATTERN_META.matcher(targetId);
String targetMeta = "";
if (!flagPermission.contains("command-execute")) {
if (m.find()) {
targetMeta = m.group(0);
targetId = StringUtils.replace(targetId, targetMeta, "");
if (flag == Flags.ENTITY_SPAWN) {
// Check spawn limit
final int spawnLimit = GDPermissionManager.getInstance().getInternalOptionValue(TypeToken.of(Integer.class), GriefDefenderPlugin.DEFAULT_HOLDER, Options.SPAWN_LIMIT, claim, contexts);
if (spawnLimit > -1) {
if (target instanceof Entity) {
final Entity entity = (Entity) target;
final int currentEntityCount = ((GDClaim) claim).countEntities(entity .getType());
if (currentEntityCount >= spawnLimit) {
if (source instanceof Player) {
final Component message = GriefDefenderPlugin.getInstance().messageData.getMessage(MessageStorage.OPTION_APPLY_SPAWN_LIMIT,
ImmutableMap.of(
"type", entity.getType().getId(),
"limit", spawnLimit));
GriefDefenderPlugin.sendMessage((Player) source, message);
}
return this.processResult(claim, flag.getPermission(), "spawn-limit", Tristate.FALSE, this.eventSubject);
}
}
}
targetPermission += "." + targetId + targetMeta;
}*/
}
targetPermission = StringUtils.replace(targetPermission, ":", ".");
// If player can ignore admin claims and is currently ignoring , allow
if (user != null && playerData != null && !playerData.debugClaimPermissions && playerData.canIgnoreClaim(claim)) {
return processResult(claim, targetPermission, "ignore", Tristate.TRUE, user);
@ -494,29 +502,17 @@ public class GDPermissionManager implements PermissionManager {
return permissionValue;
}
public void addEventLogEntry(Event event, Location<World> location, Object source, Object target, User user, String permission, String trust, Tristate result) {
public void addEventLogEntry(Event event, Location<World> location, Object source, Object target, User user, Flag flag, String trust, Tristate result) {
final GDPermissionHolder holder = PermissionHolderCache.getInstance().getOrCreateUser(user);
addEventLogEntry(event, location, source, target, holder, permission, trust, result);
addEventLogEntry(event, location, source, target, holder, flag, trust, result);
}
// Used for situations where events are skipped for perf reasons
public void addEventLogEntry(Event event, Location<World> location, Object source, Object target, GDPermissionHolder permissionSubject, String permission, String trust, Tristate result) {
public void addEventLogEntry(Event event, Location<World> location, Object source, Object target, GDPermissionHolder permissionSubject, Flag flag, String trust, Tristate result) {
if (GriefDefenderPlugin.debugActive) {
String sourceId = getPermissionIdentifier(source, true);
String targetPermission = permission;
String targetPermission = flag.getPermission();
String targetId = getPermissionIdentifier(target);
/*if (!targetId.isEmpty()) {
// move target meta to end of permission
Matcher m = PATTERN_META.matcher(targetId);
String targetMeta = "";
if (!permission.contains("command-execute")) {
if (m.find()) {
targetMeta = m.group(0);
targetId = StringUtils.replace(targetId, targetMeta, "");
}
}
targetPermission += "." + targetId + targetMeta;
}*/
if (permissionSubject == null) {
permissionSubject = GriefDefenderPlugin.DEFAULT_HOLDER;
}
@ -823,6 +819,11 @@ public class GDPermissionManager implements PermissionManager {
}
public void addCustomEntityTypeContexts(Entity targetEntity, Set<Context> contexts, GDEntityType type, boolean isSource) {
if (isSource) {
contexts.add(ContextGroups.SOURCE_ALL);
} else {
contexts.add(ContextGroups.TARGET_ALL);
}
// check vehicle
if (targetEntity instanceof Boat || targetEntity instanceof Minecart) {
if (isSource) {
@ -1214,9 +1215,9 @@ public class GDPermissionManager implements PermissionManager {
// check claim
if (claim != null) {
contexts.add(claim.getContext());
String value = PermissionUtil.getInstance().getOptionValue(holder, option, contexts);
final T value = this.getOptionActualValue(type, holder, option, contexts);
if (value != null) {
return this.getOptionTypeValue(type, value);
return value;
}
contexts.remove(claim.getContext());
}
@ -1224,18 +1225,18 @@ public class GDPermissionManager implements PermissionManager {
// check claim type
if (claimType != null) {
contexts.add(claimType.getContext());
String value = PermissionUtil.getInstance().getOptionValue(holder, option, contexts);
final T value = this.getOptionActualValue(type, holder, option, contexts);
if (value != null) {
return this.getOptionTypeValue(type, value);
return value;
}
contexts.remove(claimType.getContext());
}
}
String value = PermissionUtil.getInstance().getOptionValue(holder, option, contexts);
// Check only active contexts
T value = this.getOptionActualValue(type, holder, option, contexts);
if (value != null) {
return this.getOptionTypeValue(type, value);
return value;
}
// Check type/global default context
@ -1243,9 +1244,9 @@ public class GDPermissionManager implements PermissionManager {
contexts.add(claimType.getDefaultContext());
}
contexts.add(ClaimContexts.GLOBAL_DEFAULT_CONTEXT);
value = PermissionUtil.getInstance().getOptionValue(holder, option, contexts);
value = this.getOptionActualValue(type, holder, option, contexts);
if (value != null) {
return this.getOptionTypeValue(type, value);
return value;
}
contexts.remove(ClaimContexts.GLOBAL_DEFAULT_CONTEXT);
if (claimType != null) {
@ -1260,6 +1261,21 @@ public class GDPermissionManager implements PermissionManager {
return option.getDefaultValue();
}
private <T> T getOptionActualValue(TypeToken<T> type, GDPermissionHolder holder, Option option, Set<Context> contexts) {
if (option.multiValued()) {
List<String> values = PermissionUtil.getInstance().getOptionValueList(holder, option, contexts);
if (values != null && !values.isEmpty()) {
return (T) values;
}
}
String value = PermissionUtil.getInstance().getOptionValue(holder, option, contexts);
if (value != null) {
return this.getOptionTypeValue(type, value);
}
return null;
}
private <T> T getOptionTypeValue(TypeToken<T> type, String value) {
if (type.getRawType().isAssignableFrom(Double.class)) {
return (T) Double.valueOf(value);
@ -1301,6 +1317,13 @@ public class GDPermissionManager implements PermissionManager {
if (value.equalsIgnoreCase("undefined")) {
return (T) CreateModeTypes.AREA;
}
if (value.equalsIgnoreCase("volume")) {
return (T) CreateModeTypes.VOLUME;
}
if (value.equalsIgnoreCase("area")) {
return (T) CreateModeTypes.AREA;
}
int permValue = 0;
try {
permValue = Integer.parseInt(value);
@ -1312,6 +1335,16 @@ public class GDPermissionManager implements PermissionManager {
}
return (T) (permValue == 1 ? CreateModeTypes.VOLUME : CreateModeTypes.AREA);
}
if (type.getRawType().isAssignableFrom(WeatherType.class)) {
if (value.equalsIgnoreCase("downfall")) {
return (T) WeatherTypes.DOWNFALL;
}
if (value.equalsIgnoreCase("clear")) {
return (T) WeatherTypes.CLEAR;
}
return (T) WeatherTypes.UNDEFINED;
}
if (type.getRawType().isAssignableFrom(Boolean.class)) {
return (T) Boolean.valueOf(Boolean.parseBoolean(value));
}
@ -1324,7 +1357,6 @@ public class GDPermissionManager implements PermissionManager {
if (playerData != null) {
playerData.ignoreActiveContexts = true;
}
//contexts.addAll(PermissionUtil.getInstance().getActiveContexts(holder));
PermissionUtil.getInstance().addActiveContexts(contexts, holder, playerData, claim);
}

View File

@ -97,6 +97,8 @@ public class GDPermissions {
// flags
public static final String USER_CLAIM_FLAGS = "griefdefender.user.claim.flag";
public static final String COMMAND_FLAGS_CLAIM = "griefdefender.user.claim.command.flag.base";
public static final String COMMAND_FLAGS_CLAIM_ARG = "griefdefender.user.claim.command.flag.arg";
public static final String COMMAND_FLAGS_CLAIM_GUI = "griefdefender.user.claim.command.flag.gui";
public static final String COMMAND_FLAGS_DEBUG = "griefdefender.user.claim.command.flag.debug";
public static final String COMMAND_FLAGS_PLAYER = "griefdefender.user.claim.command.flag.player";
public static final String COMMAND_FLAGS_GROUP = "griefdefender.user.claim.command.flag.group";
@ -136,16 +138,6 @@ public class GDPermissions {
public static final String COMMAND_CLAIM_PERMISSION_GROUP = "griefdefender.admin.claim.command.permission-group";
public static final String COMMAND_CLAIM_PERMISSION_PLAYER = "griefdefender.admin.claim.command.permission-player";
public static final String COMMAND_CLAIM_SCHEMATIC = "griefdefender.admin.claim.command.schematic";
public static final String COMMAND_CLAIM_OPTIONS_GROUP_BASE = "griefdefender.admin.claim.command.option.group.base";
public static final String COMMAND_CLAIM_OPTIONS_GROUP_ADMIN = "griefdefender.admin.claim.command.option.group.admin";
public static final String COMMAND_CLAIM_OPTIONS_GROUP_BASIC = "griefdefender.admin.claim.command.option.group.basic";
public static final String COMMAND_CLAIM_OPTIONS_GROUP_SUBDIVISION = "griefdefender.admin.claim.command.option.group.subdivision";
public static final String COMMAND_CLAIM_OPTIONS_GROUP_TOWN = "griefdefender.admin.claim.command.option.group.town";
public static final String COMMAND_CLAIM_OPTIONS_PLAYER_BASE = "griefdefender.admin.claim.command.option.player.base";
public static final String COMMAND_CLAIM_OPTIONS_PLAYER_ADMIN = "griefdefender.admin.claim.command.option.player.admin";
public static final String COMMAND_CLAIM_OPTIONS_PLAYER_BASIC = "griefdefender.admin.claim.command.option.player.basic";
public static final String COMMAND_CLAIM_OPTIONS_PLAYER_SUBDIVISION = "griefdefender.admin.claim.command.option.player.subdivision";
public static final String COMMAND_CLAIM_OPTIONS_PLAYER_TOWN = "griefdefender.admin.claim.command.option.player.town";
public static final String COMMAND_IGNORE_CLAIMS = "griefdefender.admin.claim.command.ignore.base";
public static final String COMMAND_DELETE_CLAIM_BASE = "griefdefender.admin.claim.command.delete.base";
public static final String COMMAND_DELETE_CLAIMS = "griefdefender.admin.claim.command.delete-claims";
@ -195,45 +187,6 @@ public class GDPermissions {
public static final String TRUST_BUILDER = "griefdefender.trust.1.2";
public static final String TRUST_MANAGER = "griefdefender.trust.1";
// Flags
public static final String BLOCK_BREAK = "griefdefender.flag.block-break";
public static final String BLOCK_GROW = "griefdefender.flag.block-grow";
public static final String BLOCK_MODIFY = "griefdefender.flag.block-modify";
public static final String BLOCK_PLACE = "griefdefender.flag.block-place";
public static final String BLOCK_SPREAD = "griefdefender.flag.block-spread";
public static final String COLLIDE_BLOCK = "griefdefender.flag.collide-block";
public static final String COLLIDE_ENTITY = "griefdefender.flag.collide-entity";
public static final String COMMAND_EXECUTE = "griefdefender.flag.command-execute";
public static final String COMMAND_EXECUTE_PVP = "griefdefender.flag.command-execute-pvp";
public static final String ENTER_CLAIM = "griefdefender.flag.enter-claim";
public static final String ENTITY_CHUNK_SPAWN = "griefdefender.flag.entity-chunk-spawn";
public static final String ENTITY_DAMAGE = "griefdefender.flag.entity-damage";
public static final String ENTITY_RIDING = "griefdefender.flag.entity-riding";
public static final String ENTITY_SPAWN = "griefdefender.flag.entity-spawn";
public static final String ENTITY_TELEPORT_FROM = "griefdefender.flag.entity-teleport-from";
public static final String ENTITY_TELEPORT_TO = "griefdefender.flag.entity-teleport-to";
public static final String EXIT_CLAIM = "griefdefender.flag.exit-claim";
public static final String EXPLOSION_BLOCK = "griefdefender.flag.explosion-block";
public static final String EXPLOSION_ENTITY = "griefdefender.flag.explosion-entity";
public static final String FLAG_BASE = "griefdefender.flag";
public static final String INTERACT_BLOCK_PRIMARY = "griefdefender.flag.interact-block-primary";
public static final String INTERACT_BLOCK_SECONDARY = "griefdefender.flag.interact-block-secondary";
public static final String INTERACT_ENTITY_PRIMARY = "griefdefender.flag.interact-entity-primary";
public static final String INTERACT_ENTITY_SECONDARY = "griefdefender.flag.interact-entity-secondary";
public static final String INTERACT_ITEM_PRIMARY = "griefdefender.flag.interact-item-primary";
public static final String INTERACT_ITEM_SECONDARY = "griefdefender.flag.interact-item-secondary";
public static final String INVENTORY_CLICK = "griefdefender.flag.interact-inventory-click";
public static final String INVENTORY_OPEN = "griefdefender.flag.interact-inventory";
public static final String ITEM_DROP = "griefdefender.flag.item-drop";
public static final String ITEM_PICKUP = "griefdefender.flag.item-pickup";
public static final String ITEM_SPAWN = "griefdefender.flag.item-spawn";
public static final String ITEM_USE = "griefdefender.flag.item-use";
public static final String LEAF_DECAY = "griefdefender.flag.leaf-decay";
public static final String LIQUID_FLOW = "griefdefender.flag.liquid-flow";
public static final String PORTAL_USE = "griefdefender.flag.portal-use";
public static final String PROJECTILE_IMPACT_BLOCK = "griefdefender.flag.projectile-impact-block";
public static final String PROJECTILE_IMPACT_ENTITY = "griefdefender.flag.projectile-impact-entity";
public static String getTrustPermission(TrustType type) {
if (type == TrustTypes.ACCESSOR) {
return GDPermissions.TRUST_ACCESSOR;

View File

@ -38,7 +38,9 @@ import net.kyori.text.Component;
import net.kyori.text.TextComponent;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import org.checkerframework.checker.nullness.qual.Nullable;
@ -56,18 +58,23 @@ public class GDOption<T> implements Option<T> {
private final String id;
private final String name;
private final Class<T> allowed;
private Set<String> requiredContextKeys = new HashSet<>();
private Component description;
private boolean multiValued;
private Boolean isGlobal;
private Boolean isAdmin;
GDOption(OptionBuilder<T> builder) {
this(builder.id, builder.name, builder.typeClass);
this(builder.id, builder.name, builder.description, builder.multiValued, builder.requiredContextKeys, builder.typeClass);
}
public GDOption(String id, String name, Class<T> allowed) {
public GDOption(String id, String name, Component description, boolean multiValued, Set<String> requiredContexts, Class<T> allowed) {
this.id = id;
this.name = name;
this.allowed = allowed;
this.description = description;
this.multiValued = multiValued;
this.requiredContextKeys = requiredContexts;
this.isAdmin = ADMIN_OPTIONS.contains(name);
this.isGlobal = GLOBAL_OPTIONS.contains(name);
}
@ -93,6 +100,16 @@ public class GDOption<T> implements Option<T> {
return this.isAdmin;
}
@Override
public boolean multiValued() {
return this.multiValued;
}
@Override
public Set<String> getRequiredContextKeys() {
return this.requiredContextKeys;
}
@Override
public Class<T> getAllowedType() {
return this.allowed;
@ -123,6 +140,7 @@ public class GDOption<T> implements Option<T> {
this.description = null;
}
@SuppressWarnings("unchecked")
@Override
public T getDefaultValue() {
if (this.allowed.isAssignableFrom(Tristate.class)) {
@ -172,6 +190,8 @@ public class GDOption<T> implements Option<T> {
public boolean validateStringValue(String value, boolean log) {
if (value.equalsIgnoreCase("undefined")) {
return false;
} else if (this.allowed == List.class) {
return true;
} else if (this.allowed == Integer.class) {
try {
Integer.parseInt(value);
@ -229,12 +249,12 @@ public class GDOption<T> implements Option<T> {
+ ".\nAcceptable values are : adventure, creative, survival, spectator, or undefined. Skipping...");
}
} else if (this.allowed == WeatherType.class) {
if (value.equalsIgnoreCase("clear") || value.equalsIgnoreCase("rain")) {
if (value.equalsIgnoreCase("clear") || value.equalsIgnoreCase("downfall")) {
return true;
}
if (log) {
GriefDefenderPlugin.getInstance().getLogger().warn("Invalid WeatherType value '" + value + "', entered for option " + this.getName()
+ ".\nAcceptable values are : clear, rain, or undefined. Skipping...");
+ ".\nAcceptable values are : clear, downfall, or undefined. Skipping...");
}
}

View File

@ -27,12 +27,19 @@ package com.griefdefender.permission.option;
import com.griefdefender.api.permission.option.Option;
import com.griefdefender.api.permission.option.Option.Builder;
import com.griefdefender.registry.OptionRegistryModule;
import net.kyori.text.Component;
import java.util.HashSet;
import java.util.Set;
public final class OptionBuilder<T> implements Option.Builder<T> {
Class<T> typeClass;
String id;
String name;
Component description;
boolean multiValued = false;
Set<String> requiredContextKeys = new HashSet<>();
@Override
public Builder<T> type(Class<T> tClass) {
@ -52,6 +59,24 @@ public final class OptionBuilder<T> implements Option.Builder<T> {
return this;
}
@Override
public Builder<T> description(Component description) {
this.description = description;
return this;
}
@Override
public Builder<T> multiValued(boolean value) {
this.multiValued = value;
return this;
}
@Override
public Builder<T> requiredContextKeys(Set<String> keys) {
this.requiredContextKeys = keys;
return this;
}
@Override
public Option<T> build() {
final GDOption<T> key = new GDOption<>(this);
@ -64,6 +89,8 @@ public final class OptionBuilder<T> implements Option.Builder<T> {
this.typeClass = null;
this.id = null;
this.name = null;
this.multiValued = false;
this.requiredContextKeys = new HashSet<>();
return this;
}
}

View File

@ -22,14 +22,16 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package com.griefdefender.configuration.category;
package com.griefdefender.permission.option;
import ninja.leaping.configurate.objectmapping.Setting;
import ninja.leaping.configurate.objectmapping.serialize.ConfigSerializable;
import com.griefdefender.api.permission.Context;
import com.griefdefender.api.permission.ContextKeys;
@ConfigSerializable
public class PvpCategory extends ConfigCategory {
public class OptionContexts {
@Setting(value = "combat-timeout", comment = "How long combat is considered to continue after the most recent damage.")
public int combatTimeout = 15;
public static final Context COMMAND_RUNAS_CONSOLE = new Context(ContextKeys.RUN_AS, "console");
public static final Context COMMAND_RUNAS_PLAYER = new Context(ContextKeys.RUN_AS, "player");
public static final Context COMMAND_RUNFOR_MEMBER = new Context(ContextKeys.RUN_FOR, "member");
public static final Context COMMAND_RUNFOR_OWNER = new Context(ContextKeys.RUN_FOR, "owner");
public static final Context COMMAND_RUNFOR_PUBLIC = new Context(ContextKeys.RUN_FOR, "public");
}

View File

@ -36,15 +36,14 @@ import com.griefdefender.api.permission.ContextKeys;
import com.griefdefender.api.permission.PermissionResult;
import com.griefdefender.api.permission.ResultTypes;
import com.griefdefender.api.permission.flag.Flag;
import com.griefdefender.api.permission.flag.Flags;
import com.griefdefender.api.permission.option.Option;
import com.griefdefender.cache.PermissionHolderCache;
import com.griefdefender.claim.GDClaim;
import com.griefdefender.permission.GDPermissionHolder;
import com.griefdefender.permission.GDPermissionManager;
import com.griefdefender.permission.GDPermissionResult;
import com.griefdefender.permission.GDPermissionUser;
import com.griefdefender.registry.OptionRegistryModule;
import net.kyori.text.TextComponent;
import net.luckperms.api.LuckPerms;
import net.luckperms.api.cacheddata.CachedMetaData;
import net.luckperms.api.cacheddata.CachedPermissionData;
@ -78,6 +77,7 @@ import java.util.Set;
import java.util.TreeMap;
import java.util.UUID;
import java.util.Map.Entry;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
@ -107,6 +107,8 @@ public class LuckPermsProvider implements PermissionProvider {
private final LuckPerms luckPermsApi;
private final static DefaultDataQueryOrderFunction DEFAULT_DATA_QUERY_ORDER = new DefaultDataQueryOrderFunction();
private final static PermissionResult RESULT_FAILURE = new GDPermissionResult(ResultTypes.FAILURE);
private final static PermissionResult RESULT_SUCCESS = new GDPermissionResult(ResultTypes.SUCCESS);
public LuckPermsProvider() {
final ProviderRegistration<LuckPerms> service = Sponge.getServiceManager().getRegistration(LuckPerms.class).orElse(null);
@ -117,6 +119,11 @@ public class LuckPermsProvider implements PermissionProvider {
return this.luckPermsApi;
}
@Override
public String getServerName() {
return this.luckPermsApi.getServerName();
}
@Override
public boolean hasGroupSubject(String identifier) {
return this.getGroupSubject(identifier) != null;
@ -715,44 +722,65 @@ public class LuckPermsProvider implements PermissionProvider {
return metaData.getMetaValue(option.getPermission());
}
public PermissionResult setOptionValue(GDPermissionHolder holder, String permission, String value, Set<Context> contexts) {
@Override
public List<String> getOptionValueList(GDPermissionHolder holder, Option option, Set<Context> contexts) {
ImmutableContextSet set = this.getLPContexts(contexts).immutableCopy();
final PermissionHolder permissionHolder = this.getLuckPermsHolder(holder);
if (permissionHolder == null) {
return null;
}
final QueryOptions query = QueryOptions.builder(QueryMode.CONTEXTUAL).option(DataQueryOrderFunction.KEY, DEFAULT_DATA_QUERY_ORDER).context(set).build();
CachedMetaData metaData = permissionHolder.getCachedData().getMetaData(query);
List<String> list = metaData.getMeta().get(option.getPermission());
if (list == null) {
return new ArrayList<>();
}
return list;
}
public PermissionResult setOptionValue(GDPermissionHolder holder, String key, String value, Set<Context> contexts) {
DataMutateResult result = null;
ImmutableContextSet set = this.getLPContexts(contexts).immutableCopy();
final PermissionHolder permissionHolder = this.getLuckPermsHolder(holder);
if (permissionHolder == null) {
return new GDPermissionResult(ResultTypes.FAILURE);
return RESULT_FAILURE;
}
// Always unset existing meta first
final Node currentNode = this.luckPermsApi.getNodeBuilderRegistry().forMeta().key(permission).context(set).build();
result = permissionHolder.data().remove(currentNode);
final Option option = OptionRegistryModule.getInstance().getById(key).orElse(null);
if (option == null) {
return RESULT_FAILURE;
}
final Node node = this.luckPermsApi.getNodeBuilderRegistry().forMeta().key(permission).value(value).context(set).build();
final Node node = MetaNode.builder().key(key).value(value).context(set).build();
if (!value.equalsIgnoreCase("undefined")) {
if (!option.multiValued()) {
this.clearMeta(permissionHolder, key, set);
}
result = permissionHolder.data().add(node);
}
if (result != null && result.wasSuccessful()) {
} else {
this.clearMeta(permissionHolder, key, set);
this.savePermissionHolder(permissionHolder);
return new GDPermissionResult(ResultTypes.SUCCESS);
return RESULT_SUCCESS;
}
return new GDPermissionResult(ResultTypes.FAILURE);
if (result != null) {
if (result.wasSuccessful()) {
this.savePermissionHolder(permissionHolder);
return new GDPermissionResult(ResultTypes.SUCCESS, TextComponent.builder().append(result.name()).build());
}
return new GDPermissionResult(ResultTypes.FAILURE, TextComponent.builder().append(result.name()).build());
}
return RESULT_FAILURE;
}
public PermissionResult setPermissionValue(GDPermissionHolder holder, Flag flag, Tristate value, Set<Context> contexts) {
final boolean result = setPermissionValue(holder, flag.getPermission(), value, contexts);
if (result) {
return new GDPermissionResult(ResultTypes.SUCCESS);
}
return new GDPermissionResult(ResultTypes.FAILURE);
}
public boolean setPermissionValue(GDPermissionHolder holder, String permission, Tristate value, Set<Context> contexts) {
public PermissionResult setPermissionValue(GDPermissionHolder holder, String permission, Tristate value, Set<Context> contexts, boolean save) {
DataMutateResult result = null;
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 false;
return RESULT_FAILURE;
}
if (value == Tristate.UNDEFINED) {
@ -763,11 +791,6 @@ public class LuckPermsProvider implements PermissionProvider {
if (result.wasSuccessful()) {
if (permissionHolder instanceof Group) {
final Group group = (Group) permissionHolder;
group.getCachedData().invalidate();
for (User user :this.luckPermsApi.getUserManager().getLoadedUsers()) {
user.getCachedData().invalidate();
}
// If a group is changed, we invalidate all cache
PermissionHolderCache.getInstance().invalidateAllPermissionCache();
} else {
@ -775,9 +798,14 @@ public class LuckPermsProvider implements PermissionProvider {
PermissionHolderCache.getInstance().getOrCreatePermissionCache(holder).invalidateAll();
}
this.savePermissionHolder(permissionHolder);
if (save) {
this.savePermissionHolder(permissionHolder);
}
return new GDPermissionResult(ResultTypes.SUCCESS, TextComponent.builder().append(result.name()).build());
}
return result.wasSuccessful();
return new GDPermissionResult(ResultTypes.FAILURE, TextComponent.builder().append(result.name()).build());
}
public void setTransientOption(GDPermissionHolder holder, String permission, String value, Set<Context> contexts) {
@ -798,7 +826,7 @@ public class LuckPermsProvider implements PermissionProvider {
return;
}
final Node node = this.luckPermsApi.getNodeBuilderRegistry().forPermission().permission(permission).value(value).context(contextSet).build();
final PermissionNode node = this.luckPermsApi.getNodeBuilderRegistry().forPermission().permission(permission).value(value).context(contextSet).build();
permissionHolder.transientData().add(node);
}
@ -818,6 +846,20 @@ public class LuckPermsProvider implements PermissionProvider {
permissionHolder.getCachedData().invalidate();
}
@Override
public CompletableFuture<Void> save(GDPermissionHolder holder) {
final PermissionHolder permissionHolder = this.getLuckPermsHolder(holder);
if (permissionHolder == null) {
return new CompletableFuture<>();
}
if (permissionHolder instanceof User) {
return this.luckPermsApi.getUserManager().saveUser((User) permissionHolder);
} else {
return this.luckPermsApi.getGroupManager().saveGroup((Group) permissionHolder);
}
}
public Set<Context> getGDContexts(ContextSet contexts) {
final Set<Context> gdContexts = new HashSet<>();
contexts.forEach(entry -> {
@ -846,6 +888,10 @@ public class LuckPermsProvider implements PermissionProvider {
return Tristate.UNDEFINED;
}
private void clearMeta(PermissionHolder holder, String metaKey, ContextSet set) {
holder.data().clear(set, NodeType.META.predicate(node -> node.getMetaKey().equals(metaKey)));
}
private static class DefaultDataQueryOrderFunction implements DataQueryOrderFunction {
@Override

View File

@ -28,6 +28,7 @@ import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.UUID;
import java.util.concurrent.CompletableFuture;
import org.checkerframework.checker.nullness.qual.Nullable;
@ -49,6 +50,13 @@ import com.griefdefender.permission.GDPermissionHolder;
*/
public interface PermissionProvider {
/**
* Get server name.
*
* @return The server name
*/
String getServerName();
/**
* Checks if the group identifier exists.
*
@ -273,6 +281,18 @@ public interface PermissionProvider {
*/
String getOptionValue(GDPermissionHolder holder, Option option, Set<Context> contexts);
/**
* Gets the current values of an option assigned to a holder.
*
* Note: This is intended to be used for options that support multiple values.
*
* @param holder The holder
* @param permission The permission to check
* @param contexts The contexts
* @return The option value list
*/
List<String> getOptionValueList(GDPermissionHolder holder, Option option, Set<Context> contexts);
/**
* Sets an option and value with contexts to a holder.
*
@ -293,7 +313,23 @@ public interface PermissionProvider {
* @param contexts The contexts
* @return The permission result
*/
PermissionResult setPermissionValue(GDPermissionHolder holder, Flag flag, Tristate value, Set<Context> contexts);
default PermissionResult setPermissionValue(GDPermissionHolder holder, Flag flag, Tristate value, Set<Context> contexts) {
return this.setPermissionValue(holder, flag, value, contexts, true);
}
/**
* Sets a permission and value with contexts to a holder.
*
* @param holder The holder
* @param flag The flag to use for permission
* @param value The value
* @param contexts The contexts
* @param save Whether a save should occur
* @return The permission result
*/
default PermissionResult setPermissionValue(GDPermissionHolder holder, Flag flag, Tristate value, Set<Context> contexts, boolean save) {
return this.setPermissionValue(holder, flag.getPermission(), value, contexts, save);
}
/**
* Sets a permission and value with contexts to a holder.
@ -304,7 +340,21 @@ public interface PermissionProvider {
* @param contexts The contexts
* @return Whether the set permission operation was successful
*/
boolean setPermissionValue(GDPermissionHolder holder, String permission, Tristate value, Set<Context> contexts);
default PermissionResult setPermissionValue(GDPermissionHolder holder, String permission, Tristate value, Set<Context> contexts) {
return this.setPermissionValue(holder, permission, value, contexts, true);
}
/**
* Sets a permission and value with contexts to a holder.
*
* @param holder The holder
* @param permission The permission
* @param value The value
* @param contexts The contexts
* @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 save);
/**
* Sets a transient option and value with contexts to a holder.
@ -334,4 +384,12 @@ public interface PermissionProvider {
* @param holder The holder
*/
void refreshCachedData(GDPermissionHolder holder);
/**
* Saves any pending permission changes to holder.
*
* @param holder The holder
* @return a future which will complete when save is done
*/
CompletableFuture<Void> save(GDPermissionHolder holder);
}

View File

@ -38,9 +38,12 @@ import com.griefdefender.util.RegistryHelper;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
@SuppressWarnings("rawtypes")
public class OptionRegistryModule implements CatalogRegistryModule<Option> {
@ -111,7 +114,8 @@ public class OptionRegistryModule implements CatalogRegistryModule<Option> {
this.createKey("griefdefender:radius-inspect", "radius-inspect", Integer.class);
this.createKey("griefdefender:raid", "raid", Boolean.class);
this.createKey("griefdefender:spawn-limit", "spawn-limit", Integer.class);
this.createKey("griefdefender:player-command", "player-command", String.class);
this.createKey("griefdefender:player-command-enter", "player-command-enter", true, List.class);
this.createKey("griefdefender:player-command-exit", "player-command-exit", true, List.class);
this.createKey("griefdefender:player-deny-flight", "player-deny-flight", Boolean.class);
this.createKey("griefdefender:player-deny-godmode", "player-deny-godmode", Boolean.class);
this.createKey("griefdefender:player-deny-hunger", "player-deny-hunger", Boolean.class);
@ -120,9 +124,12 @@ public class OptionRegistryModule implements CatalogRegistryModule<Option> {
this.createKey("griefdefender:player-keep-inventory", "player-keep-inventory", Tristate.class);
this.createKey("griefdefender:player-keep-level", "player-keep-level", Tristate.class);
this.createKey("griefdefender:player-teleport-delay", "player-teleport-delay", Integer.class);
this.createKey("griefdefender:player-walk-speed", "player-walk-speed", Integer.class);
this.createKey("griefdefender:player-walk-speed", "player-walk-speed", Double.class);
this.createKey("griefdefender:player-weather", "player-weather", WeatherType.class);
this.createKey("griefdefender:pvp", "pvp", Tristate.class);
this.createKey("griefdefender:pvp-combat-command", "pvp-combat-command", Boolean.class);
this.createKey("griefdefender:pvp-combat-teleport", "pvp-combat-teleport", Boolean.class);
this.createKey("griefdefender:pvp-combat-timeout", "pvp-combat-timeout", Integer.class);
RegistryHelper.mapFields(Options.class, input -> {
final String name = input.replace("_", "-");
@ -131,7 +138,15 @@ public class OptionRegistryModule implements CatalogRegistryModule<Option> {
}
private void createKey(String id, String name, Class<?> clazz) {
this.registryMap.put(id, new GDOption<>(id, name, clazz));
this.createKey(id, name, false, new HashSet<>(), clazz);
}
private void createKey(String id, String name, boolean multiValued, Class<?> clazz) {
this.createKey(id, name, multiValued, new HashSet<>(), clazz);
}
private void createKey(String id, String name, boolean multiValued, Set<String> requiredContextKeys, Class<?> clazz) {
this.registryMap.put(id, new GDOption<>(id, name, null, multiValued, requiredContextKeys, clazz));
}
@Override

View File

@ -44,7 +44,6 @@ import com.griefdefender.api.permission.option.Option;
import com.griefdefender.claim.GDClaim;
import com.griefdefender.claim.GDClaimManager;
import com.griefdefender.claim.GDClaimResult;
import com.griefdefender.claim.GDClaimType;
import com.griefdefender.configuration.ClaimTemplateStorage;
import com.griefdefender.configuration.GriefDefenderConfig;
import com.griefdefender.configuration.MessageStorage;
@ -53,18 +52,15 @@ import com.griefdefender.configuration.type.GlobalConfig;
import com.griefdefender.event.GDCauseStackManager;
import com.griefdefender.event.GDRemoveClaimEvent;
import com.griefdefender.permission.GDPermissionUser;
import com.griefdefender.permission.GDPermissions;
import com.griefdefender.permission.flag.FlagContexts;
import com.griefdefender.permission.option.GDOption;
import com.griefdefender.registry.FlagRegistryModule;
import com.griefdefender.registry.OptionRegistryModule;
import com.griefdefender.util.PermissionUtil;
import com.griefdefender.util.SpongeContexts;
import net.kyori.text.TextComponent;
import net.kyori.text.format.TextColor;
import org.spongepowered.api.Sponge;
import org.spongepowered.api.command.CommandSource;
import org.spongepowered.api.service.permission.SubjectData;
import org.spongepowered.api.world.Location;
import org.spongepowered.api.world.World;
import org.spongepowered.api.world.storage.WorldProperties;
@ -376,7 +372,6 @@ public abstract class BaseStorage {
this.setDefaultFlags(contexts, globalDefaultFlags);
final Map<String, String> globalDefaultOptions = activeConfig.getConfig().permissionCategory.getUserOptionDefaults();
this.setDefaultOptions(ClaimContexts.GLOBAL_DEFAULT_CONTEXT.getName(), contexts, new HashMap<>(globalDefaultOptions));
// TODO - does not work with LP v5
//GriefDefenderPlugin.getInstance().getPermissionProvider().setTransientPermission(GriefDefenderPlugin.DEFAULT_HOLDER, "griefdefender", false, new HashSet<>());
activeConfig.save();
}
@ -388,11 +383,11 @@ public abstract class BaseStorage {
if (flag == null) {
continue;
}
PermissionUtil.getInstance().setTransientPermission(GriefDefenderPlugin.DEFAULT_HOLDER, GDPermissions.FLAG_BASE + "." + mapEntry.getKey(), mapEntry.getValue(), contexts);
PermissionUtil.getInstance().setTransientPermission(GriefDefenderPlugin.DEFAULT_HOLDER, flag.getPermission(), mapEntry.getValue(), contexts);
if (flag == Flags.ENTITY_DAMAGE) {
// allow monsters to be attacked by default
contexts.add(FlagContexts.TARGET_TYPE_MONSTER);
PermissionUtil.getInstance().setTransientPermission(GriefDefenderPlugin.DEFAULT_HOLDER, GDPermissions.FLAG_BASE + "." + mapEntry.getKey(), true, contexts);
PermissionUtil.getInstance().setTransientPermission(GriefDefenderPlugin.DEFAULT_HOLDER, flag.getPermission(), true, contexts);
contexts.remove(FlagContexts.TARGET_TYPE_MONSTER);
}
}

View File

@ -28,9 +28,12 @@ import com.griefdefender.GriefDefenderPlugin;
import com.griefdefender.api.claim.Claim;
import com.griefdefender.api.claim.ClaimContexts;
import com.griefdefender.api.permission.Context;
import com.griefdefender.api.permission.option.Options;
import com.griefdefender.cache.MessageCache;
import com.griefdefender.claim.GDClaim;
import com.griefdefender.internal.util.NMSUtil;
import com.griefdefender.permission.ContextGroupKeys;
import com.griefdefender.permission.ContextGroups;
import com.griefdefender.permission.GDPermissions;
import net.kyori.text.TextComponent;
import org.spongepowered.api.Sponge;
@ -46,7 +49,6 @@ import org.spongepowered.api.event.cause.EventContextKeys;
import org.spongepowered.api.event.world.ExplosionEvent;
import org.spongepowered.api.item.ItemType;
import org.spongepowered.api.world.storage.WorldProperties;
import org.spongepowered.common.SpongeImplHooks;
import java.util.Arrays;
import java.util.HashSet;
@ -119,11 +121,11 @@ public class CauseContextHelper {
private static final Pattern CONTEXT_SPLIT = Pattern.compile("^context?\\[ *((?:[\\w.-]+:[\\w.-]+:[\\w\\/.-]+(?: *, *(?!\\]$)|(?= *\\]$)))+) *\\]$");
private static final List<String> VALID_CONTEXTS = Arrays.asList("world", "server", "mode", "player", "group", "source", "used_item", "type");
// final String regex = "^context?\\[ *((?:[\\w.-]+:[\\w.-]+:[\\w\\/.-]+(?: *, *(?!\\]$)|(?= *\\]$)))+) *\\]$";
public static Set<Context> generateContexts(CommandSource src, Claim claim, String context) {
return generateContexts(src, claim, context, false);
public static Set<Context> generateContexts(String permission, CommandSource src, Claim claim, String context) {
return generateContexts(permission, src, claim, context, false);
}
public static Set<Context> generateContexts(CommandSource src, Claim claim, String context, boolean isOption) {
public static Set<Context> generateContexts(String permission, CommandSource src, Claim claim, String context, boolean isOption) {
// verify context is valid
if (context == null) {
return new HashSet<>();
@ -141,6 +143,8 @@ public class CauseContextHelper {
final boolean canManageDefaults = src.hasPermission(GDPermissions.MANAGE_FLAG_DEFAULTS);
final boolean canManageOverrides = src.hasPermission(GDPermissions.MANAGE_FLAG_OVERRIDES);
boolean hasSourceContext = false;
boolean hasTargetContext = false;
final Set<Context> contextSet = new HashSet<>();
final String contexts = matcher.group(1);
String[] split = contexts.split(",");
@ -232,7 +236,12 @@ public class CauseContextHelper {
} else if (contextName.equals("meta")) {
contextSet.add(new Context(contextName, arg1));
} else if (contextName.equals("source")) {
contextSet.add(new Context(contextName, id));
hasSourceContext = true;
if (!arg1.contains("#") && !arg1.equalsIgnoreCase("any") && !arg1.equalsIgnoreCase("all")) {
contextSet.add(new Context(contextName, id));
} else {
contextSet.add(new Context(contextName, arg1));
}
} else if (contextName.contentEquals("state")) {
contextSet.add(new Context(contextName, id));
} else if (contextName.equals("used_item")) {
@ -243,7 +252,13 @@ public class CauseContextHelper {
}
contextSet.add(new Context(contextName, type.getId()));
} else {
if (arg2 == null) {
if (contextName.equals("target")) {
hasTargetContext = true;
if (permission.equals(Options.SPAWN_LIMIT.getPermission())
&& !arg1.contains("#") && !arg1.equalsIgnoreCase("any") && !arg1.equalsIgnoreCase("all")) {
contextSet.add(new Context(contextName, id));
}
} else if (arg2 == null) {
contextSet.add(new Context(contextName, arg1));
} else {
contextSet.add(new Context(contextName, id));
@ -251,6 +266,14 @@ public class CauseContextHelper {
}
}
if (permission.equals(Options.SPAWN_LIMIT.getPermission())) {
if (!hasSourceContext) {
contextSet.add(ContextGroups.SOURCE_ALL);
}
if (!hasTargetContext) {
contextSet.add(ContextGroups.TARGET_ALL);
}
}
return contextSet;
}
}

View File

@ -41,6 +41,7 @@ import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.UUID;
import java.util.concurrent.CompletableFuture;
public class PermissionUtil {
@ -60,6 +61,10 @@ public class PermissionUtil {
this.PERMISSION_PROVIDER = GriefDefenderPlugin.getInstance().getPermissionProvider();
}
public String getServerName() {
return PERMISSION_PROVIDER.getServerName();
}
public boolean hasGroupSubject(String identifier) {
return PERMISSION_PROVIDER.hasGroupSubject(identifier);
}
@ -180,16 +185,28 @@ public class PermissionUtil {
return PERMISSION_PROVIDER.getOptionValue(holder, option, contexts);
}
public List<String> getOptionValueList(GDPermissionHolder holder, Option option, Set<Context> contexts) {
return PERMISSION_PROVIDER.getOptionValueList(holder, option, contexts);
}
public PermissionResult setOptionValue(GDPermissionHolder holder, String permission, String value, Set<Context> contexts) {
return PERMISSION_PROVIDER.setOptionValue(holder, permission, value, contexts);
}
public PermissionResult setPermissionValue(GDPermissionHolder holder, Flag flag, Tristate value, Set<Context> contexts) {
return PERMISSION_PROVIDER.setPermissionValue(holder, flag, value, contexts);
return PERMISSION_PROVIDER.setPermissionValue(holder, flag, value, contexts, true);
}
public boolean setPermissionValue(GDPermissionHolder holder, String permission, Tristate value, Set<Context> contexts) {
return PERMISSION_PROVIDER.setPermissionValue(holder, permission, value, contexts);
public PermissionResult setPermissionValue(GDPermissionHolder holder, String permission, Tristate value, Set<Context> contexts) {
return PERMISSION_PROVIDER.setPermissionValue(holder, permission, value, contexts, true);
}
public PermissionResult setPermissionValue(GDPermissionHolder holder, Flag flag, Tristate value, Set<Context> contexts, boolean save) {
return PERMISSION_PROVIDER.setPermissionValue(holder, flag, value, contexts, save);
}
public PermissionResult setPermissionValue(GDPermissionHolder holder, String permission, Tristate value, Set<Context> contexts, boolean save) {
return PERMISSION_PROVIDER.setPermissionValue(holder, permission, value, contexts, save);
}
public void setTransientOption(GDPermissionHolder holder, String permission, String value, Set<Context> contexts) {
@ -204,6 +221,10 @@ public class PermissionUtil {
PERMISSION_PROVIDER.refreshCachedData(holder);
}
public CompletableFuture<Void> save(GDPermissionHolder holder) {
return PERMISSION_PROVIDER.save(holder);
}
public boolean containsKey(Set<Context> contexts, String key) {
for (Context context : contexts) {
if (context.getKey().equalsIgnoreCase(key)) {

View File

@ -24,6 +24,8 @@
*/
package com.griefdefender.util;
import com.google.common.collect.BiMap;
import com.google.common.collect.ImmutableBiMap;
import com.griefdefender.GDPlayerData;
import com.griefdefender.GriefDefenderPlugin;
import com.griefdefender.api.claim.ClaimType;
@ -31,6 +33,10 @@ import com.griefdefender.api.claim.ClaimTypes;
import com.griefdefender.api.claim.ShovelType;
import com.griefdefender.api.claim.ShovelTypes;
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.api.permission.option.type.WeatherTypes;
import com.griefdefender.cache.PermissionHolderCache;
import com.griefdefender.internal.visual.ClaimVisual;
import com.griefdefender.internal.visual.GDClaimVisualType;
@ -38,11 +44,15 @@ import com.griefdefender.permission.GDPermissionUser;
import net.kyori.text.Component;
import net.kyori.text.TextComponent;
import net.kyori.text.format.TextColor;
import net.minecraft.entity.player.EntityPlayerMP;
import net.minecraft.network.play.server.SPacketChangeGameState;
import org.spongepowered.api.Sponge;
import org.spongepowered.api.data.property.entity.EyeLocationProperty;
import org.spongepowered.api.data.type.HandTypes;
import org.spongepowered.api.entity.living.player.Player;
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.item.ItemType;
import org.spongepowered.api.item.inventory.ItemStack;
import org.spongepowered.api.service.user.UserStorageService;
@ -56,6 +66,16 @@ import javax.annotation.Nullable;
public class PlayerUtil {
private static Direction[] faces = { Direction.NORTH, Direction.EAST, Direction.SOUTH, Direction.WEST};
public static BiMap<GameModeType, GameMode> GAMEMODE_MAP = ImmutableBiMap.of(
GameModeTypes.ADVENTURE, GameModes.ADVENTURE,
GameModeTypes.CREATIVE, GameModes.CREATIVE,
GameModeTypes.SPECTATOR, GameModes.SPECTATOR,
GameModeTypes.SURVIVAL, GameModes.SURVIVAL
);
public static BiMap<WeatherType, org.spongepowered.api.world.weather.Weather> WEATHERTYPE_MAP = ImmutableBiMap.of(
WeatherTypes.CLEAR, org.spongepowered.api.world.weather.Weathers.CLEAR,
WeatherTypes.DOWNFALL, org.spongepowered.api.world.weather.Weathers.RAIN
);
private static PlayerUtil instance;
@ -204,4 +224,23 @@ public class PlayerUtil {
}
return 0;
}
public void setPlayerWeather(GDPermissionUser user, WeatherType type) {
final Player player = user.getOnlinePlayer();
if (type == WeatherTypes.DOWNFALL) {
((EntityPlayerMP) player).connection.sendPacket(new SPacketChangeGameState(2, 0));
} else {
((EntityPlayerMP) player).connection.sendPacket(new SPacketChangeGameState(1, 0));
}
user.getInternalPlayerData().lastWeatherType = type;
}
public void resetPlayerWeather(GDPermissionUser user) {
final Player player = user.getOnlinePlayer();
if (player.getWorld().getProperties().isRaining()) {
this.setPlayerWeather(user, WeatherTypes.DOWNFALL);
} else {
this.setPlayerWeather(user, WeatherTypes.CLEAR);
}
}
}

View File

@ -3,9 +3,9 @@
"libraries": [
{
"name": "com.griefdefender:api:1.0.0",
"sha1": "fb161e9877869876bbf07131c1a7682d37c6664d",
"path": "com/griefdefender/api/1.0.0-SNAPSHOT/api-1.0.0-20191219.230903-12.jar",
"url": "https://repo.glaremasters.me/repository/bloodshot/com/griefdefender/api/1.0.0-SNAPSHOT/api-1.0.0-20191219.230903-12.jar"
"sha1": "a87c88ecf7f4aaa4cc18decef9f0cbb013a0e602",
"path": "com/griefdefender/api/1.0.0-SNAPSHOT/api-1.0.0-20191230.224219-13.jar",
"url": "https://repo.glaremasters.me/repository/bloodshot/com/griefdefender/api/1.0.0-SNAPSHOT/api-1.0.0-20191230.224219-13.jar"
},
{
"name": "com.griefdefender:reflect-helper:1.0",

View File

@ -157,9 +157,9 @@ GriefDefender {
claimlist-ui-title=Grundstücksliste
claimlist-ui-title-child-claims=Teilgrundstücke
command-blocked="&cDer Befehl &f{command}&c wurde vom Grundstücksbesitzer &6{player}&c deaktiviert."
command-claimban-success-block="&aErfolgreich folgenden Block &cgeblockt: &a{id}."
command-claimban-success-entity="&aErfolgreich folgendes Objekt &cgeblockt: &a{id}."
command-claimban-success-item="&aErfolgreich folgendes Item &cgeblockt: &a{id}."
command-claimban-success-block="&aErfolgreich folgenden Block &cgeblockt&a: {id}."
command-claimban-success-entity="&aErfolgreich folgendes Objekt &cgeblock&at: {id}."
command-claimban-success-item="&aErfolgreich folgendes Item &cgeblockt&a: {id}."
command-claimbuy-title="&bKäufliche Grundstücke."
command-claimclear-killed="&c&6{amount}&a Objekte vom Typ {type} getötet&f."
command-claimclear-no-entities="&cKonnte keine Objekte vom Typ {type} finden&c."
@ -173,9 +173,9 @@ GriefDefender {
command-claimmode-disabled="Grundstücksmodus: &cAUS"
command-claimmode-enabled="Grundstücksmodus &aAN&f\n&aLinksklick zum Inspizieren.\n&aRechtsklick, um Grundstücke zu erstellen und anzupassen.&b\nTipp&f: &aZum Verlassen des Modus: &f/claim&a."
command-claimspawn-not-found="&aKein Grundstück {name}&a gefunden."
command-claimunban-success-block="&aErfolgreich folgenden Block &centblockt: &a{id}."
command-claimunban-success-entity="&aErfolgreich folgendes Objekt &centblockt: &a{id}."
command-claimunban-success-item="&aErfolgreich folgendes Item &centblockt: &a{id}."
command-claimunban-success-block="&aErfolgreich folgenden Block &centblockt&a: {id}."
command-claimunban-success-entity="&aErfolgreich folgendes Objekt &centblockt&a: {id}."
command-claimunban-success-item="&aErfolgreich folgendes Item &centblockt&a: {id}."
command-cuboid-disabled="&aGrundstücksmodus: 2D (Automatisch von 0 bis maximale Bauhöhe)."
command-cuboid-enabled="&aGrundstücksmodus: 3D."
command-execute-failed="&cKonnte den Befehl '{command} {args}' nicht ausführen."
@ -202,7 +202,7 @@ GriefDefender {
command-worldedit-missing="&cDieser Befehl benötigt installiertes WorldEdit auf dem Server."
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 erstellt."
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."
create-failed-result="&aErstellung fehlgeschlagen: &6{reason}&a."
create-insufficient-blocks-2d="&cDu hast nicht genug Baublöcke, um das Gebiet zu sichern.\nDu brauchst &a{block-amount}&c mehr Blöcke."
create-insufficient-blocks-3d="&cDu hast nicht genug Baublöcke, um das Gebiet zu sichern.\nDu brauchst &a{chunk-amount}&c mehr Chunks. &f({block-amount})"
@ -424,6 +424,12 @@ GriefDefender {
mode-nature="&aBereit, das Grundstück wiederherzustellen! Rechtsklicke einen Block, um zu beginnen. &f/modebasic&c zum Stoppen."
mode-subdivision="&aUnterteilungsmodus. Unterteile deine existierendes Grundstück. Nutze &f/modebasic&a zum Verlassen."
mode-town="&aStadt-Erstellungsmodus aktiviert."
option-apply-player-deny-flight="&cDu darfst auf diesem Grundstück nicht fliegen und wurdest an einen sicheren Ort auf dem Boden teleportiert."
option-apply-player-deny-godmode="&cDu hast keine Berechtigungen unsterblich zu sein."
option-apply-player-gamemode="&aDein Spielmodus wurde zu &6{gamemode}&a geändert."
option-apply-player-walk-speed="&aDeine Laufgeschwindigkeit wurde auf &6{speed}&a geändert."
option-apply-player-weather="&aDein lokales Wetter wurde geändert zu &6{weather}&a."
option-apply-spawn-limit="&cAuf diesem Grundstück sind bereits die maximale Anzahl &a{type}&c, nämlich &6{limit}&c und es können keine weiteren spawnen."
option-description-abandon-delay="&aDie Anzahl Tage, bevor ein neues Grundstück aufgegeben werden kann."
option-description-abandon-return-ratio="&aDer Anteil Blöcke, welcher ein Spieler beim Aufgeben seines Grundstückes zurückerhält."
option-description-blocks-accrued-per-hour="&aBaublöcke pro Stunde.\n&dHinweis&f: Nutze /playerinfo für mehr Informationen."
@ -443,7 +449,8 @@ GriefDefender {
option-description-min-size-x="&aDie Minimalgröße eines Grundstückes auf der x-Achse."
option-description-min-size-y="&aDie Minimalgröße eines Grundstückes auf der y-Achse."
option-description-min-size-z="&aDie Minimalgröße eines Grundstückes auf der z-Achse."
option-description-player-command="&aBestimmt, ob ein Befehl mit einem bestimmten Kontext ausführbar ist."
option-description-player-command-enter="&aFühre einen bestimmten und anpassbaren Befehl aus, wenn ein Spieler dein Grundstück betritt."
option-description-player-command-exit="&aFühre einen bestimmten und anpassbaren Befehl aus, wenn ein Spieler dein Grundstück verlässt."
option-description-player-deny-flight="&aStellt sicher, dass Spieler auf dem Grundstück nicht fliegen können.\n&dHinweis&f: Gibt Spielern nicht die Fähigkeit zu fliegen, sondern verhindert es nur - dies gewährleistet maximale Kompatibilität mit Plugins."
option-description-player-deny-godmode="&aLegt fest, ob Spieler auf dem Grundstück GodMode haben können.\n&dHinweis&f: Gibt Spielern nicht die Möglichkeit GodMode zu erhalten, sondern schaltet ihn lediglich aus - dies gewährleistet maximale Kompatibilität mit Plugins."
option-description-player-deny-hunger="&aLegt fest, ob Spieler auf dem Grundstück hungern können.\n&dHinweis&f: Regeneriert keinen Hunger für Spieler, sondern verhindert lediglich, dass diese Hunger verlieren - dies gewährleistet maximale Kompatibilität mit Plugins."
@ -451,10 +458,16 @@ GriefDefender {
option-description-player-health-regen="&aBestimmt die Regenerierungsrate eines Spielers auf dem Grundstück.\n&dHinweis&f: Hat der Spieler bereits maximales Leben, hat dies keinen Effekt. \n&dHinweis&f: &6-1&f deaktiviert diese Option."
option-description-player-keep-inventory="&aLegt fest, ob Spieler ihr Inventar nach dem Tod auf dem Grundstück behalten."
option-description-player-keep-level="&aLegt fest, ob Spieler ihr EXP beim Tod auf dem Grundstück verlieren."
option-description-player-teleport-delay="&aDie Verzögerung, bis ein Spieler zum neuen Ort teleportiert wird."
option-description-player-walk-speed="&aBestimmt die Laufgeschwindigkeit von Spielern.\n&dBeweis&f: &6-1&f deaktiviert dies."
option-description-player-weather="&aSetzt das Wetter für Spieler auf dem Grundstück."
option-description-pvp="&aLegt fest, ob Spieler sich gegenseitig angreifen können."
option-description-pvp-combat-command="&aLegt fest, ob Spieler während des PvP Kämpfens Befehle nutzen können."
option-description-pvp-combat-teleport="&aLegt fest, ob sich Spieler während eines PvP Kampfes teleportieren können."
option-description-pvp-combat-timeout="&aLegt fest, wie lange sich Spieler nach dem letzten Schlag noch im PvP Kampfmodus befinden sollen."
option-description-radius-inspect="&aDer Radius (in Blöcken), in welchem beim Inspizieren nach Grundstücken gesucht wird."
option-description-radius-list="&aLegt den Radius (in Blöcken) um den Spieler für Grundstücke fest, welche auf der Grundstücksliste angezeigt werden."
option-description-spawn-limit="&aErmöglicht das Erstellen von Spawnlimits für bestimmte Bedingungen und Entitäten."
option-description-tax-expiration="&aAnzahl Tage ohne Steuern, bis ein Grundstück eingefroren wird.\n&dHinweis&f: Bis die Steuern bezahlt sind kann der Spieler dann weder interagieren noch bauen."
option-description-tax-expiration-days-keep="&aAnzahl Tage, bis ein eingefrorenes Grundstück abläuft.\n&dHinweis&f: Bei Ablauf eines Grundstückes wird dieses entweder zurückgesetzt oder einfach entfernt. Kommt auf die Servereinstellungen an - kontaktiere den Admin."
option-description-tax-rate="&aDie Besteuerung eines Grundstückes.\n&dHinweis&f: Steuern sind abhängig von der Anzahl Grundstücksblöcke."
@ -465,6 +478,7 @@ GriefDefender {
option-not-set="{option}&f ist nicht eingestellt.\n&dHinweis&f: Standardoption {value}&f ist solange aktiv."
option-override-not-supported="&cGrundstücksart {type}&c unterstützt keine überschreibenden Einstellungen."
option-player-deny-flight="&cDu darfst in diesem Grundstück nicht fliegen und wurdest zu einem sicheren Landeplatz teleportiert."
option-requires-contexts="&cDiese Option benötigt zum Einstellen den Kontext '&a{contexts}&c'."
option-reset-success="&aGrundstückseinstellungen erfolgreich zurückgesetzt."
option-set-target="&aSetze {type}&a für Option &b{option}&a auf {value}&a mit dem Kontext &7{contexts}&a für &6{target}&a."
option-ui-click-toggle="Klicke hier, um {option}&f umzuschalten."
@ -497,7 +511,9 @@ GriefDefender {
permission-cuboid="&cDu hast keine Berechtigung den 3D Modus für Grundstücke zu nutzen."
permission-edit-claim="&cDu hast keine Berechtigung dieses Grundstück zu bearbeiten."
permission-fire-spread="&cDu hast keine Berechtigung Feuer zu legen."
permission-flag-arg="&cDu hast keine Berechtigungen den Einstellungsbefehl mit weiterem Kontext zu benutzen."
permission-flag-defaults="&cDu hast keine Berechtigung die Standardeinstellungen zu verwalten."
permission-flag-gui="&cDu hast keine Berechtigungen diese EinstellungsGUI zu benutzen."
permission-flag-overrides="&cDu hast keine Berechtigung überschreibende Einstellungen zu verwalten."
permission-flag-use="&cDu hast keine Berechtigung diese Einstellung zu nutzen."
permission-flow-liquid="&cDu hast keine Berechtigung in diesem Grundstück Flüssigkeiten fließen zu lassen."
@ -554,6 +570,7 @@ GriefDefender {
plugin-not-found="&cKonnte kein Plugin &b{id}&c finden."
plugin-reload="&aGriefDefender neu geladen."
pvp-claim-not-allowed="&aPvP ist auf diesem Grundstück nicht erlaubt."
pvp-in-combat-not-allowed="&aDu kannst das nicht tun, während du in einem PvP Kampf bist. Du bist noch für &6{time-remaining}&a Sekunden im Kampfmodus."
pvp-source-not-allowed="&aPvP ist für dich nicht erlaubt."
pvp-target-not-allowed="&aDu kannst keine Spieler attackieren, die PvP ausgestellt haben."
registry-block-not-found="&cDer Block {id}&c konnte nicht gefunden werden."

View File

@ -424,6 +424,12 @@ GriefDefender {
mode-nature="&aReady to restore claim! Right click on a block to restore, and use &f/modebasic&c to stop."
mode-subdivision="&aSubdivision creation mode enabled. Use &f/modebasic&a to exit."
mode-town="&aTown creation mode enabled."
option-apply-player-deny-flight="&cYou do not have access to fly in this claim and have been teleported to a safe spot on ground."
option-apply-player-deny-godmode="&cYou do not have access to use god mode in this claim."
option-apply-player-gamemode="&aYour gamemode has been changed to &6{gamemode}&a."
option-apply-player-walk-speed="&aYour walk speed has been changed to &6{speed}&a."
option-apply-player-weather="&aYour local weather has been changed to &6{weather}&a."
option-apply-spawn-limit="&cThis claim has reached the &a{type}&c spawn limit of &6{limit}&c and can no longer spawn any more."
option-description-abandon-delay="&aThe amount of days before a newly created claim can be abandoned."
option-description-abandon-return-ratio="&aThe portion of basic claim blocks returned to a player when a claim is abandoned."
option-description-blocks-accrued-per-hour="&aBlocks earned per hour.\n&dNote&f: See /playerinfo for more information."
@ -443,7 +449,8 @@ GriefDefender {
option-description-min-size-x="&aThe min size in blocks that the x-axis can be."
option-description-min-size-y="&aThe min size in blocks that the y-axis can be."
option-description-min-size-z="&aThe min size in blocks that the z-axis can be."
option-description-player-command="&aUsed for executing a command with specific contexts."
option-description-player-command-enter="&aUsed for executing a command with specific contexts when a player enters a claim."
option-description-player-command-exit="&aUsed for executing a command with specific contexts when a player exits a claim."
option-description-player-deny-flight="&aUsed to determine if a player is unable to fly in a claim.\n&dNote&f: This does not give players the ability to fly, it merely removes the ability if set. This provides the greatest compatibility with plugins."
option-description-player-deny-godmode="&aUsed to determine if a player can be in godmode within a claim.\n&dNote&f: This does not give players the ability to be in godmode, it merely removes the ability if set. This provides the greatest compatibility with plugins."
option-description-player-deny-hunger="&aUsed to if a player's hunger is denied in a claim.\n&dNote&f: This does not give players the ability to gain hunger, it merely removes the ability to cause hunger if set. This provides the greatest compatibility with plugins."
@ -451,10 +458,16 @@ GriefDefender {
option-description-player-health-regen="&aUsed to set the health regen amount for a player in a claim.\n&dNote&f: If the player is at max health, this will have no effect. \n&dNote&f: A value of &6-1&f disables this option."
option-description-player-keep-inventory="&aUsed to determine if a player can keep inventory after death in a claim."
option-description-player-keep-level="&aUsed to determine if a player can keep their level after death in a claim."
option-description-player-teleport-delay="&aUsed to determine the delay before teleporting a player to a new location."
option-description-player-walk-speed="&aUsed to set a player's walk speed in a claim.\n&dNote&f: A value of &6-1&f disables this option."
option-description-player-weather="&aUsed to set a player's weather in a claim."
option-description-pvp="&aUsed to determine if players can combat each other."
option-description-pvp-combat-command="&aUsed to determine if a player can use commands during PvP combat."
option-description-pvp-combat-teleport="&aUsed to determine if a player can teleport during PvP combat."
option-description-pvp-combat-timeout="&aUsed to determine how many seconds PvP combat is considered to continue after the most recent damage."
option-description-radius-inspect="&aThe radius in blocks used to search for nearby claims while inspecting."
option-description-radius-list="&aThe radius in blocks used to list nearby claims."
option-description-spawn-limit="&aUsed to determine the spawn limit for a specific set of contexts in a claim."
option-description-tax-expiration="&aNumber of days after not paying taxes before a claim will be frozen.\n&dNote&f: A frozen state means you will have no access to build or interact in claim until taxes are paid."
option-description-tax-expiration-days-keep="&aNumber of days to keep a basic claim after frozen and before expiring.\n&dNote&f: On expiration, a claim may either be restored back to original state or be deleted. This depends on the server configuration. Contact an administrator for more information."
option-description-tax-rate="&aThe tax rate of claim.\n&dNote&f: Tax rate is calculated by the number of claimblocks in the basic claim."
@ -464,7 +477,7 @@ GriefDefender {
option-not-found="&cOption {option}&c not found."
option-not-set="{option}&f is currently not set.\n&dNote&f: The default option value of {value}&f will be active until set."
option-override-not-supported="&cClaim type {type}&c does not support option overrides."
option-player-deny-flight="&cYou do not have access to fly in this claim and have been teleported to a safe spot on ground."
option-requires-contexts="&cThis option requres contexts '&a{contexts}&c' to be set."
option-reset-success="&aClaim options reset to defaults successfully."
option-set-target="&aSet {type}&a option &b{option}&a to {value}&a with contexts &7{contexts}&a on &6{target}&a."
option-ui-click-toggle="Click here to toggle {option}&f value."
@ -497,7 +510,9 @@ GriefDefender {
permission-cuboid="&cYou don't have permission to create/resize basic claims in 3D mode."
permission-edit-claim="&cYou don't have permission to edit this claim."
permission-fire-spread="&cYou don't have permission to spread fire in this claim."
permission-flag-arg="&cYou don't have permission to use the flag command with arguments."
permission-flag-defaults="&cYou don't have permission to manage flag defaults."
permission-flag-gui="&cYou don't have permission to use the flag GUI."
permission-flag-overrides="&cYou don't have permission to manage flag overrides."
permission-flag-use="&cYou don't have permission to use this flag."
permission-flow-liquid="&cYou don't have permission to flow liquid in this claim."
@ -554,6 +569,7 @@ GriefDefender {
plugin-not-found="&cCould not locate plugin with id &b{id}&c."
plugin-reload="&aGriefDefender has been reloaded."
pvp-claim-not-allowed="&aYou are not allowed to PvP in this claim."
pvp-in-combat-not-allowed="&aYou cannot perform this action while in PvP combat. You must stay out of combat for &6{time-remaining}&a more seconds."
pvp-source-not-allowed="&aYou are not allowed to PvP."
pvp-target-not-allowed="&aYou cannot attack players who are not participating in PvP."
registry-block-not-found="&cThe block {id}&c could not be found in registry."

View File

@ -424,6 +424,12 @@ GriefDefender {
mode-nature="&f&l[&b&lCREACION&f&l&f&l-&b&lEN&f&l-&b&lMODO&f&l-&eNATURALEZA&f&l] &b&l➜ &a&lACTIVADO\n\nHaz &6&lCLICK-DERECHO&a en un bloque para restaurar. Usa &6&o'/modebasic' &apara salir de este modo.\n&4&l[NOTA] &c Este modo sirve para resturar terrenos a su forma virgen cuando se generó este mundo por primera vez."
mode-subdivision="&f&l[&b&lCREACION&f&l&f&l-&b&lEN&f&l-&b&lMODO&f&l-&eSUBDIVISION&f&l] &b&l➜ &a&lACTIVADO\n\nUsa &6&o'/modebasic' &apara salir de este modo."
mode-town="&f&l[&b&lCREACION&f&l&f&l-&b&lEN&f&l-&b&lMODO&f&l-&eCIUDAD&f&l] &b&l➜ &a&lACTIVADO\n\nUsa &6&o'/modebasic' &apara salir de este modo."
option-apply-player-deny-flight="&4&l[PERMISO-DENEGADO] &cNo puedes volar en este terreno. Has sido teletransportado a un lugar seguro en el suelo."
option-apply-player-deny-godmode="&4&l[PERMISO-DENEGADO] &cNo puedes usar el modo Dios en este terreno."
option-apply-player-gamemode="&aTu modo de juego ha sido cambiado a &6&o{gamemode}&a."
option-apply-player-walk-speed="&aTu velocidad caminar ha sido cambiada a &6&o{speed}&a."
option-apply-player-weather="&aTu clima ha sido cambiado a &6&o{weather}&a."
option-apply-spawn-limit="&4&l[ATENCION] &cEste terreno ha alcanzado el limite de spawn &6&o{limit} &cde tipo &a&o{type}&c y no pueden spawnear más."
option-description-abandon-delay="&aLa cantidad de días antes de que un Claim recién creado puede ser abandonado."
option-description-abandon-return-ratio="&aLos CB's devueltos cuando un jugador abandona un Claim."
option-description-blocks-accrued-per-hour="&aLos CB's ganados por hora.\n&4&l[NOTA] &aUsa &6&o'/playerinfo'&a para ver más información del jugador."
@ -443,7 +449,8 @@ GriefDefender {
option-description-min-size-x="&aTamaño mínimo en bloques en el &eeje X&7(horizontal)"
option-description-min-size-y="&aTamaño mínimo en bloques en el &eeje Y&7(vertical)"
option-description-min-size-z="&aTamaño mínimo en bloques en el &eeje Z&7(profundidad)"
option-description-player-command="&aSe usa para ejecutar comandos con 'Contextos' específicos."
option-description-player-command-enter="&aSe usa para ejecutar un comando con Contextos específicos cuando un jugador &6&oENTRA&a en un terreno."
option-description-player-command-exit="&aSe usa para ejecutar un comando con Contextos específicos cuando un jugador &6&oSALE&a en un terreno."
option-description-player-deny-flight="&aSe usa para determinar si un jugador es capaz de Volar(fly) dentro del terreno.\n&4&l[NOTA] &fEsto no da a los jugadores la habilidad de volar, simplemente se elimina la habilidad si se establece. Esto provee gran compatibilidad con otros plugins."
option-description-player-deny-godmode="&aSe usa para determinar si un jugador puede estar en Modo Dios(godmode) dentro del terreno.\n&4&l[NOTA] &fEsto no da a los jugadores la habilidad de estar en modo Dios, simplemente se elimina la habilidad si se establece. Esto provee gran compatibilidad con otros plugins."
option-description-player-deny-hunger="&aSe usa para determinar si un jugador puede tener hambre(hunger) dentro del terreno.\n&4&l[NOTA] &fEsto no da a los jugadores la habilidad de NO tener hambre, simplemente elimina la habilidad que causa el hambre si se establece. Esto provee gran compatibilidad con otros plugins."
@ -451,10 +458,16 @@ GriefDefender {
option-description-player-health-regen="&aSe usa para determinar la cantidad de regeneración de vida para un jugador en el terreno.\n&4&l[NOTA] &fSi el jugador tiene la vida al máximo, esto no tendrá efecto. \n&4&l[NOTA]&f El valor de &c-1&f desactiva esta opción."
option-description-player-keep-inventory="&aSe usa para determinar si el jugador puede mantener su inventario después de morir en el terreno."
option-description-player-keep-level="&aSe usa para determinar si el jugador puede mantener su nivel de exp. después de morir en el terreno."
option-description-player-teleport-delay="&aSe usa para &6&ndeterminar un retardo&a &o(delay)&a antes de la teletransportación de un jugador a la nueva localización."
option-description-player-walk-speed="&aSe usa para establecer la velocidad de caminar de los jugadores en el terreno.\n&4&l[NOTA] &fEl valor de &c-1&f desactiva esta opción."
option-description-player-weather="&aSe usa para establecer el clima de los jugadores en el terreno."
option-description-pvp="&aSe usa para determinar &6&nsi hay combates PvP&a entre jugadores."
option-description-pvp-combat-command="&aSe usa para determinar si un jugador puede &6&nusar comandos&a durante un combate PvP."
option-description-pvp-combat-teleport="&aSe usa para determinar si un jugador puede &6&nteletransportarse&a durante un combate PvP."
option-description-pvp-combat-timeout="&aSe usa para determinar cuantos &6&nsegundos de combate PvP&a se consideran para continuar después de un daño reciente."
option-description-radius-inspect="&aEl radio de cercania de bloques que se utiliza para encontrar Claims mientras inspeccionamos."
option-description-radius-list="&aEl radio en bloques utilizados para la Lista de terrenos cercanos."
option-description-spawn-limit="&aSe usa para determinar el limite de spawn para colocar Contextos específicos en un terreno."
option-description-tax-expiration="&aNúmero de dias después de no pagar los impuestos antes de que el terreno sea paralizado.\n&4&l[NOTA] &6&o'Paralizado'&f significa que no tendrás acceso para construir o interactuar con nada hasta que te pongas al día con los pagos atrasados.&7Paga las cuotas, chorizo! =)"
option-description-tax-expiration-days-keep="&aNúmero de días para mantener un Claim Basico &odespués&a de ser Paralizado y &oantes&a de la Expiración.\n&4&l[NOTA]: &fDurante la expiración, un Claim puede ser restaurado a su estado natural inicial o eliminado. Esto depende de la configuración del Servidor. Para más información, contacta con un &4Administrador&a."
option-description-tax-rate="&aEl porcentaje de impuestos del terreno.\n&4&l[NOTA] &fEl porcentaje de impuestos es calculado por el número de CB's en el Claim Básico."
@ -465,6 +478,7 @@ GriefDefender {
option-not-set="&4&l[ERROR] &6&o'{option}'&c no está establecida.\n&4&l[NOTA] &cLa opción con valor de &6&o'{value}'&c estará activa hasta que se establezca."
option-override-not-supported="&4&l[ERROR] &cEl Claim tipo &6&o'{type}'&c no soporta la opción de Sobrescribir."
option-player-deny-flight="&4&l[VOLAR-DESACTIVADO] &cNo tienes acceso a la habilidad de volar en este terreno. Serás teletransportado a un lugar seguro en el suelo."
option-requires-contexts="&4&l[ERROR] &cEsta opción requiere el Contexto &6&o'{contexts}'&c para ser establecido."
option-reset-success="&2&l[OPCIONES-RESETEADAS] &a¡Todas las opciones de Claim han sido reiniciadas al estado original con éxito!"
option-set-target="&aEstablecido ( &e&o{type}&a ) una opción ( &b&o{option} &a)&a en (&6&o {value} &a)&a con el Contexto de (&7&o {contexts} &a)&a en el Objetivo de ( &c&o{target} &a)"
option-ui-click-toggle="&6&lCLICK-AQUI &fpara &aACTIVAR&f/&cDESACTIVAR &fel valor &6&o'{option}'"
@ -497,7 +511,9 @@ GriefDefender {
permission-cuboid="&4&l[PERMISO-DENEGADO] &cNo puedes &ncrear/redimensionar&r &cClaims &eBásicos &cen &b&lMODO &d&l3D&c. "
permission-edit-claim="&4&l[PERMISO-DENEGADO] &cNo puedes &neditar&c este terreno."
permission-fire-spread="&4&l[PERMISO-DENEGADO] &cNo puedes &npropagar&c el fuego en este terreno."
permission-flag-arg="&4&l[PERMISO-DENEGADO] &cNo puedes usar comandos de Flags con argumentos."
permission-flag-defaults="&4&l[PERMISO-DENEGADO] &cNo puedes &nadministrar&c los Flags por defecto de este terreno."
permission-flag-gui="&4&l[PERMISO-DENEGADO] &cNo puedes usar la Interfaz Gráfica de Usuario de Flags &6&o(GUI)"
permission-flag-overrides="&4&l[PERMISO-DENEGADO] &cNo puedes &nadministrar&c los Flags ignorados."
permission-flag-use="&4&l[PERMISO-DENEGADO] &cNo puedes &nusar&c este Flag."
permission-flow-liquid="&4&l[PERMISO-DENEGADO] &cNo puedes &nderramar&c liquidos en este terreno."
@ -554,6 +570,7 @@ GriefDefender {
plugin-not-found="&4&l[ERROR] &cNo es posible localizar el Plugin con ID &b{id}&c."
plugin-reload="&b&l[&3&lGRIEF&b&l-&f&lDEFENDER&b&l] &a&lha sido re-cargado. &aTodas las configuraciones han sido &2&lACTUALIZADAS."
pvp-claim-not-allowed="&4&l[PvP-DESACTIVADO] &cNo tienes permitido el PvP en este terreno."
pvp-in-combat-not-allowed="&4&l[ACCION-DENEGADA] &aNo puedes hacer esto en PvP hasta que estés fuera de combate durante más de &6&o{time-remaining}s&a."
pvp-source-not-allowed="&4&l[PvP-DESACTIVADO] &cNo tienes permitido el PvP."
pvp-target-not-allowed="&4&l[PvP-DESACTIVADO] &cNo puedes atacar a los jugadores que NO estén en participando en PvP."
registry-block-not-found="&4&l[BLOQUE-NO-ENCONTRADO] &cEl bloque con ID &6&o'{id}'&c no figura en el Registro."

View File

@ -424,6 +424,12 @@ GriefDefender {
mode-nature="&aPrêt pour restaurer la protection ! Clique-droit sur un bloc pour restaurer, et utilises &f/modebasic&c pour arrêter."
mode-subdivision="&aMode Sous-divions. Utilises la pelle pour créer une sous-division dans ta protection existante. Utilises &f/modebasic&a pour sortir."
mode-town="&aMode création de Village activé."
option-apply-player-deny-flight="&cYou do not have access to fly in this claim and have been teleported to a safe spot on ground."
option-apply-player-deny-godmode="&cYou do not have access to use god mode in this claim."
option-apply-player-gamemode="&aYour gamemode has been changed to &6{gamemode}&a."
option-apply-player-walk-speed="&aYour walk speed has been changed to &6{speed}&a."
option-apply-player-weather="&aYour local weather has been changed to &6{weather}&a."
option-apply-spawn-limit="&cThis claim has reached the &a{type}&c spawn limit of &6{limit}&c and can no longer spawn any more."
option-description-abandon-delay="&aLe nombre de jours avant qu'une nouvelle protection créée puisse être abandonnée."
option-description-abandon-return-ratio="&aLa portion de bloc de protection basique rendu au joueur quand une protection est abandonnée."
option-description-blocks-accrued-per-hour="&aBlocs gagnés par heure.\n&dNote&f: Regarde /playerinfo pour plus d'informations."
@ -443,7 +449,8 @@ GriefDefender {
option-description-min-size-x="&aLa taille minimum de blocs l'axe x peut être."
option-description-min-size-y="&aLa taille minimum de blocs l'axe y peut être."
option-description-min-size-z="&aLa taille minimum de blocs l'axe z peut être."
option-description-player-command="&aUtilisé pour exécuter une commande avec un contexte spécifique."
option-description-player-command-enter="&aUsed for executing a command with specific contexts when a player enters a claim."
option-description-player-command-exit="&aUsed for executing a command with specific contexts when a player exits a claim."
option-description-player-deny-flight="&aUtilisé pour déterminer si un joueur est incapable de fly dans une protection.\n&dNote&f: Cela ne donne pas l'abilité de fly au joueur, ça supprime juste l'abilité si elle a été donnée. Cela donne la meilleurs compatibilité avec les plugins."
option-description-player-deny-godmode="&aUtilisé pour déterminer si un joueur est incapable de godmode dans une protection.\n&dNote&f: Cela ne donne pas l'abilité de godmode au joueur, ça supprime juste l'abilité si elle a été donnée. Cela donne la meilleurs compatibilité avec les plugins."
option-description-player-deny-hunger="&aUtilisé pour refuser la famine dans une protection.\n&dNote&f: Cela ne donne pas l'abilité de gagner de la famine au joueur, ça supprime l'abilité de cause de la famine si défini. Cela donne la meilleurs compatibilité avec les plugins."
@ -451,10 +458,16 @@ GriefDefender {
option-description-player-health-regen="&aUtilisé pour définir le nombre de vies régénérée pour un joueur dans la protection.\n&dNote&f: Si le joueur a la vie au maximum, cela n'aura pas d'effet. \n&dNote&f: Une valeur de&6-1&f désactive cette option."
option-description-player-keep-inventory="&aUtilisé pour déterminer si un joueur à le droit de garder son inventaire après la mort dans une protection."
option-description-player-keep-level="&aUtilisé pour déterminer si un joueur à le droit de garder son niveau après la mort dans une protection."
option-description-player-teleport-delay="&aUsed to determine the delay before teleporting a player to a new location."
option-description-player-walk-speed="&aUtilisé pour définir la vitesse de marche dans une protection.\n&dNote&f: Une valeur de &6-1&f désactive cette option."
option-description-player-weather="&aUtilisé pour définir la météo d'un joueur dans une protection."
option-description-pvp="&aUsed to determine if players can combat each other."
option-description-pvp-combat-command="&aUsed to determine if a player can use commands during PvP combat."
option-description-pvp-combat-teleport="&aUsed to determine if a player can teleport during PvP combat."
option-description-pvp-combat-timeout="&aUsed to determine how many seconds PvP combat is considered to continue after the most recent damage."
option-description-radius-inspect="&aLe rayon de recherche pour les protections à proximité lors de l'inspection."
option-description-radius-list="&aLe rayon en blocs utilisés pour lister les protections à proximité."
option-description-spawn-limit="&aUsed to determine the spawn limit for a specific set of contexts in a claim."
option-description-tax-expiration="&aNombre de jour après ne pas avoir payé les taxes avant que la protection soi mise en demeure.\n&dNote&f: Une mise en demeure signifie que tu n'auras plus accès à la construction ou l'intération avec la protection jusqu'au paiement des taxes."
option-description-tax-expiration-days-keep="&aNombre de jour pour garder une protection basique mise en demeure et avant expiration.\n&dNote&f: Lors de l'expiration, une protection peut soit être restaurée à son état d'origine ou supprimée. Cela dépend de la configuration du serveur. Contacte un administrateur pour plus d'informations."
option-description-tax-rate="&aLe taux de taxe de la protection.\n&dNote&f: Le taux de taxe est calculé par le nombre de blocs de protection dans les protections basiques."
@ -465,6 +478,7 @@ GriefDefender {
option-not-set="{option}&f est actuellement non définit.\n&dNote&f: La valeur par défaut {value}&f de l'option sera active jusqu'à définition."
option-override-not-supported="&cProtection de type {type}&c ne supporte pas les options outrepassantes."
option-player-deny-flight="&cTu n'as pas accès au fly dans cette protection et a été téléporté dans une zone sécurisée au sol."
option-requires-contexts="&cThis option requres contexts '&a{contexts}&c' to be set."
option-reset-success="&aOption de la protection remises par défaut avec succès."
option-set-target="&aDéfinis {type}&a de l'option &b{option}&a à {value}&a avec le contexte &7{contexts}&a sur la cible &6{target}&a."
option-ui-click-toggle="Clique ici pour changer la valeur de {option}&f."
@ -497,7 +511,9 @@ GriefDefender {
permission-cuboid="&cTu n'as pas la permission pour créer/redimensionner les protections basiques en mode 3D."
permission-edit-claim="&cTu n'as pas la permission pour éditer cette protection."
permission-fire-spread="&cTu n'as pas la permission pour propager le feu dans cette protection."
permission-flag-arg="&cYou don't have permission to use the flag command with arguments."
permission-flag-defaults="&cTu n'as pas la permission pour gérer les flags par défaut."
permission-flag-gui="&cYou don't have permission to use the flag GUI."
permission-flag-overrides="&cTu n'as pas la permission pour gérer les flags outrepassant."
permission-flag-use="&cTu n'as pas la permission pour utiliser ce flag."
permission-flow-liquid="&cTu n'as pas la permission pour faire couler le liquide dans cette protection."
@ -554,6 +570,7 @@ GriefDefender {
plugin-not-found="&cImpossible de localiser le plug-in avec l'id &b{id}&c."
plugin-reload="&aGriefDefender a été rechargé."
pvp-claim-not-allowed="&aTu n'as pas le droit de PvP dans cette protection."
pvp-in-combat-not-allowed="&aYou cannot perform this action while in PvP combat. You must stay out of combat for &6{time-remaining}&a more seconds."
pvp-source-not-allowed="&aTu n'as pas le droit de PvP."
pvp-target-not-allowed="&aTu ne peut pas attaquer les joueurs qui ne participent pas au PvP."
registry-block-not-found="&cLe bloc {id} ne peut pas être trouvé dans le registre."

View File

@ -421,6 +421,12 @@ GriefDefender {
mode-nature="&aГотов восстанавливать природу! ПКМ для начала, &f/modebasic&c - для выхода из режима."
mode-subdivision="&aВключён режим создания суб-регионов. Используйте лопату, чтобы создавать суб-регионы в существующих регионах. Воспользуйтесь &f/modebasic&a, чтобы выйти из этого режима."
mode-town="&aВключён режим создания городов."
option-apply-player-deny-flight="&cУ вас нет разрешения на полёт в этом регионе, вы телепортированы в безопасное место на земле."
option-apply-player-deny-godmode="&cУ вас нет доступа к использованию режима бога в этом регионе."
option-apply-player-gamemode="&aВаш игровой режим изменён на &6{gamemode}&a." # doesn't the vanilla game have this message already?
option-apply-player-walk-speed="&aВаша скорость ходьбы изменена на &6{speed}&a."
option-apply-player-weather="&aВаша погода изменена на &6{weather}&a."
option-apply-spawn-limit="&cЭтот регион достиг лимита по количеству &a{type}&c, равного &6{limit}&c, и не может содержать больше."
option-description-abandon-delay="&aКоличество дней до того, как свежесозданный регион может быть удалён."
option-description-abandon-return-ratio="&aДоля базовых блоков региона, возвращаемых игроку при удалении региона."
option-description-blocks-accrued-per-hour="&aЗарабатываемые блоки в час.\n&dПримечание&f: См. /playerinfo."
@ -440,7 +446,8 @@ GriefDefender {
option-description-min-size-x="&aМинимальный размер региона по оси x."
option-description-min-size-y="&aМинимальный размер региона по оси y."
option-description-min-size-z="&aМинимальный размер региона по оси z."
option-description-player-command="&aИспользуется для выполнения команды в определённом контексте."
option-description-player-command-enter="&aИспользуется для запуска команды с определёнными контекстами при входе игрока в регион."
option-description-player-command-exit="&aИспользуется для запуска команды с определёнными контекстами при выходе игрока из региона."
option-description-player-deny-flight="&aОпределяет, может ли игрок летать в регионе.\n&dПримечание&f: не даёт игрокам возможность летать, только удаляет её при необходимости. Даёт наибольшую совместимость с другими плагинами."
option-description-player-deny-godmode="&aОпределяет, может ли игрок быть в режиме бога в регионе.\n&dПримечание&f: не даёт игрокам возможность входить в режим бога, только удаляет её при необходимости. Даёт наибольшую совместимость с другими плагинами."
option-description-player-deny-hunger="&aОпределяет, может ли игрок терять сытость в регионе.\n&dПримечание&f: не даёт игрокам получать сытость в регионе, только удаляет возможность её терять при необходимости. Даёт наибольшую совместимость с другими плагинами."
@ -448,10 +455,16 @@ GriefDefender {
option-description-player-health-regen="&aОпределяет скорость восстановления здоровья игроков в регионе.\n&dПримечание&f: не имеет эффекта на игроков с полным запасом здоровья. \n&dПримечание&f: значение &6-1&f отключает эту опцию."
option-description-player-keep-inventory="&aОпределяет, сохранит ли игрок содержимое своего инвентаря при смерти в регионе."
option-description-player-keep-level="&aОпределяет, сохранит ли игрок свой уровень при смерти в регионе."
option-description-player-teleport-delay="&aЗадержка перед телепортацией игрока в новое место."
option-description-player-walk-speed="&aОпределяет скорость ходьбы игроков в регионе.\n&dПримечание&f: значение &6-1&f отключает эту опцию."
option-description-player-weather="&aОпределяет погоду для игрока в регионе."
option-description-pvp="&aОпределяет, могут ли игроки драться друг с другом."
option-description-pvp-combat-command="&aОпределяет, может ли игрок использовать команды во время PvP."
option-description-pvp-combat-teleport="&aОпределяет, может ли игрок телепортироваться во время PvP."
option-description-pvp-combat-timeout="&aОпределяет, сколько драка в PvP считается продолжающейся после последнего получения урона."
option-description-radius-inspect="&aРадиус в блоках для поиска регионов поблизости при инспектировании."
option-description-radius-list="&aРадиус в блоках для составления списка регионов поблизости."
option-description-spawn-limit="&aОпределяет предел появления сущностей в регионе для определённых контекстов."
option-description-tax-expiration="&aКоличество дней без оплаты налогов, после которых регион будет заморожен.\n&dПримечание&f: заморозка означает отсутствие доступа к строительству и инвентарям в регионе до совершения оплаты."
option-description-tax-expiration-days-keep="&aКоличество дней после заморозки региона до его удаления.\n&dПримечание&f: по истечении срока регион может быть просто удалён или откачен на состояние при создании. Это зависит от настроек сервера. Свяжитесь с администратором для дополнительной информации."
option-description-tax-rate="&aВеличина налога на регион.\n&dПримечание&f: величина налога вычисляется по размеру региона в блоках."
@ -462,6 +475,7 @@ GriefDefender {
option-not-set="&a{option}&f не установлена.\nПрименяется стандартное значение &a{value}&f."
option-override-not-supported="&cРегионы вида &f{type}&c не поддерживают переопределение опций."
option-player-deny-flight="&cУ вас нет разрешения на полёт в этом регионе. Вы были телепортированы на безопасное место на земле."
option-requires-contexts="&cЭта опция требует следующие контексты: '&a{contexts}&c'."
option-reset-success="&aОпции региона успешно откачены на стандартные значения."
option-set-target="&aОпция &b{option}&a вида &b{type}&a с контекстами &7{contexts}&a установлена в значение {value}&a для &6{target}&a."
option-ui-click-toggle="Нажмите здесь, чтобы переключить опцию &f{option}&r."
@ -494,7 +508,9 @@ GriefDefender {
permission-cuboid="&cУ вас нет разрешения на создание/изменение размера базовых регионов в 3D-режиме."
permission-edit-claim="&cУ вас нет разрешения на изменение этого региона."
permission-fire-spread="&cУ вас нет разрешения на поджигание блоков в этом регионе."
permission-flag-arg="&cУ вас нет разрешения на использование команды flag с аргументами."
permission-flag-defaults="&cУ вас нет разрешения на изменение стандартных значений флагов."
permission-flag-gui="&cУ вас нет разрешения на использование GUI флагов."
permission-flag-overrides="&cУ вас нет разрешения на редактирование переопределённых значений флагов."
permission-flag-use="&cУ вас нет разрешения на использование этого флага."
permission-flow-liquid="&cУ вас нет разрешения на разливание жидкостей в этом регионе."
@ -551,6 +567,7 @@ GriefDefender {
plugin-not-found="&cНе удалось найти плагин с идентификатором &b{id}&c."
plugin-reload="&aGriefDefender перезагружен."
pvp-claim-not-allowed="&aВ этом регионе сражения между игроками запрещены."
pvp-in-combat-not-allowed="&aВы не можете выполнить это действие, находясь в PvP-драке. Вы должны быть в безопасности ещё &6{time-remaining}&a секунд."
pvp-source-not-allowed="&aУ вас нет разрешения на сражение с другим игроком."
pvp-target-not-allowed="&aВы не можете атаковать игроков, которые не могут участвовать в сражениях."
registry-block-not-found="&cБлок {id}&c не найден в реестре."