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 boolean canIgnoreClaim(Claim claim) {
return this.ignoreBasicClaims; 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 @Override
public int getMaxAccruedClaimBlocks() { public int getMaxAccruedClaimBlocks() {
return GDPermissionManager.getInstance().getInternalOptionValue(TypeToken.of(Integer.class), this.getSubject(), Options.MAX_ACCRUED_BLOCKS); return GDPermissionManager.getInstance().getInternalOptionValue(TypeToken.of(Integer.class), this.getSubject(), Options.MAX_ACCRUED_BLOCKS);
@ -669,13 +630,18 @@ public double getTotalTax() {
return totalTax; return totalTax;
} }
public boolean inPvpCombat(World world) { public boolean inPvpCombat() {
if (this.lastPvpTimestamp == null) { final Player player = this.getSubject().getOnlinePlayer();
if (this.lastPvpTimestamp == null || player == null) {
return false; return false;
} }
final Instant now = Instant.now(); 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)) { if (this.lastPvpTimestamp.plusSeconds(combatTimeout).isBefore(now)) {
this.lastPvpTimestamp = null; this.lastPvpTimestamp = null;
return false; return false;
@ -684,6 +650,27 @@ public boolean inPvpCombat(World world) {
return true; 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() { public void onClaimDelete() {
this.lastShovelLocation = null; this.lastShovelLocation = null;
this.eventResultCache = null; this.eventResultCache = null;

View File

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

View File

@ -249,6 +249,7 @@ public static MessageCache getInstance() {
public Component FLAG_UI_OVERRIDE_NO_PERMISSION; public Component FLAG_UI_OVERRIDE_NO_PERMISSION;
public Component FLAG_UI_RETURN_FLAGS; public Component FLAG_UI_RETURN_FLAGS;
public Component LABEL_ACCESSORS; public Component LABEL_ACCESSORS;
public Component LABEL_ALL;
public Component LABEL_AREA; public Component LABEL_AREA;
public Component LABEL_BLOCKS; public Component LABEL_BLOCKS;
public Component LABEL_BUILDERS; public Component LABEL_BUILDERS;
@ -292,6 +293,8 @@ public static MessageCache getInstance() {
public Component MODE_NATURE; public Component MODE_NATURE;
public Component MODE_SUBDIVISION; public Component MODE_SUBDIVISION;
public Component MODE_TOWN; 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_DELAY;
public Component OPTION_DESCRIPTION_ABANDON_RETURN_RATIO; public Component OPTION_DESCRIPTION_ABANDON_RETURN_RATIO;
public Component OPTION_DESCRIPTION_BLOCKS_ACCRUED_PER_HOUR; public Component OPTION_DESCRIPTION_BLOCKS_ACCRUED_PER_HOUR;
@ -311,7 +314,8 @@ public static MessageCache getInstance() {
public Component OPTION_DESCRIPTION_MIN_SIZE_X; public Component OPTION_DESCRIPTION_MIN_SIZE_X;
public Component OPTION_DESCRIPTION_MIN_SIZE_Y; public Component OPTION_DESCRIPTION_MIN_SIZE_Y;
public Component OPTION_DESCRIPTION_MIN_SIZE_Z; 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_FLIGHT;
public Component OPTION_DESCRIPTION_PLAYER_DENY_GODMODE; public Component OPTION_DESCRIPTION_PLAYER_DENY_GODMODE;
public Component OPTION_DESCRIPTION_PLAYER_DENY_HUNGER; public Component OPTION_DESCRIPTION_PLAYER_DENY_HUNGER;
@ -326,7 +330,7 @@ public static MessageCache getInstance() {
public Component OPTION_DESCRIPTION_TAX_EXPIRATION; public Component OPTION_DESCRIPTION_TAX_EXPIRATION;
public Component OPTION_DESCRIPTION_TAX_EXPIRATION_DAYS_KEEP; public Component OPTION_DESCRIPTION_TAX_EXPIRATION_DAYS_KEEP;
public Component OPTION_DESCRIPTION_TAX_RATE; public Component OPTION_DESCRIPTION_TAX_RATE;
public Component OPTION_PLAYER_DENY_FLIGHT; public Component OPTION_UI_CLICK_REMOVE;
public Component OWNER_ADMIN; public Component OWNER_ADMIN;
public Component PERMISSION_ASSIGN_WITHOUT_HAVING; public Component PERMISSION_ASSIGN_WITHOUT_HAVING;
public Component PERMISSION_CLAIM_CREATE; public Component PERMISSION_CLAIM_CREATE;
@ -345,6 +349,8 @@ public static MessageCache getInstance() {
public Component PERMISSION_FIRE_SPREAD; public Component PERMISSION_FIRE_SPREAD;
public Component PERMISSION_FLAG_DEFAULTS; public Component PERMISSION_FLAG_DEFAULTS;
public Component PERMISSION_FLAG_OVERRIDES; public Component PERMISSION_FLAG_OVERRIDES;
public Component PERMISSION_FLAG_ARG;
public Component PERMISSION_FLAG_GUI;
public Component PERMISSION_FLAG_USE; public Component PERMISSION_FLAG_USE;
public Component PERMISSION_FLOW_LIQUID; public Component PERMISSION_FLOW_LIQUID;
public Component PERMISSION_GLOBAL_OPTION; public Component PERMISSION_GLOBAL_OPTION;
@ -607,6 +613,7 @@ public void loadCache() {
FLAG_UI_OVERRIDE_NO_PERMISSION = MessageStorage.MESSAGE_DATA.getMessage("flag-ui-override-no-permission"); 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"); FLAG_UI_RETURN_FLAGS = MessageStorage.MESSAGE_DATA.getMessage("flag-ui-return-flags");
LABEL_ACCESSORS = MessageStorage.MESSAGE_DATA.getMessage("label-accessors"); 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_AREA = MessageStorage.MESSAGE_DATA.getMessage("label-area");
LABEL_BLOCKS = MessageStorage.MESSAGE_DATA.getMessage("label-blocks"); LABEL_BLOCKS = MessageStorage.MESSAGE_DATA.getMessage("label-blocks");
LABEL_BUILDERS = MessageStorage.MESSAGE_DATA.getMessage("label-builders"); LABEL_BUILDERS = MessageStorage.MESSAGE_DATA.getMessage("label-builders");
@ -669,7 +676,8 @@ public void loadCache() {
OPTION_DESCRIPTION_MIN_SIZE_X = MessageStorage.MESSAGE_DATA.getMessage("option-description-min-size-x"); 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_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_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_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_GODMODE = MessageStorage.MESSAGE_DATA.getMessage("option-description-player-deny-godmode");
OPTION_DESCRIPTION_PLAYER_DENY_HUNGER = MessageStorage.MESSAGE_DATA.getMessage("option-description-player-deny-hunger"); OPTION_DESCRIPTION_PLAYER_DENY_HUNGER = MessageStorage.MESSAGE_DATA.getMessage("option-description-player-deny-hunger");
@ -684,7 +692,9 @@ public void loadCache() {
OPTION_DESCRIPTION_TAX_EXPIRATION = MessageStorage.MESSAGE_DATA.getMessage("option-description-tax-expiration"); 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_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_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"); OWNER_ADMIN = MessageStorage.MESSAGE_DATA.getMessage("owner-admin");
PERMISSION_ASSIGN_WITHOUT_HAVING = MessageStorage.MESSAGE_DATA.getMessage("permission-assign-without-having"); PERMISSION_ASSIGN_WITHOUT_HAVING = MessageStorage.MESSAGE_DATA.getMessage("permission-assign-without-having");
PERMISSION_CLAIM_CREATE = MessageStorage.MESSAGE_DATA.getMessage("permission-claim-create"); PERMISSION_CLAIM_CREATE = MessageStorage.MESSAGE_DATA.getMessage("permission-claim-create");
@ -703,6 +713,8 @@ public void loadCache() {
PERMISSION_FIRE_SPREAD = MessageStorage.MESSAGE_DATA.getMessage("permission-fire-spread"); PERMISSION_FIRE_SPREAD = MessageStorage.MESSAGE_DATA.getMessage("permission-fire-spread");
PERMISSION_FLAG_DEFAULTS = MessageStorage.MESSAGE_DATA.getMessage("permission-flag-defaults"); PERMISSION_FLAG_DEFAULTS = MessageStorage.MESSAGE_DATA.getMessage("permission-flag-defaults");
PERMISSION_FLAG_OVERRIDES = MessageStorage.MESSAGE_DATA.getMessage("permission-flag-overrides"); 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_FLAG_USE = MessageStorage.MESSAGE_DATA.getMessage("permission-flag-use");
PERMISSION_FLOW_LIQUID = MessageStorage.MESSAGE_DATA.getMessage("permission-flow-liquid"); PERMISSION_FLOW_LIQUID = MessageStorage.MESSAGE_DATA.getMessage("permission-flow-liquid");
PERMISSION_GLOBAL_OPTION = MessageStorage.MESSAGE_DATA.getMessage("permission-global-option"); PERMISSION_GLOBAL_OPTION = MessageStorage.MESSAGE_DATA.getMessage("permission-global-option");

View File

@ -92,6 +92,8 @@
import org.bukkit.Location; import org.bukkit.Location;
import org.bukkit.World; import org.bukkit.World;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;
import org.bukkit.entity.Entity;
import org.bukkit.entity.EntityType;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.checkerframework.checker.nullness.qual.Nullable; import org.checkerframework.checker.nullness.qual.Nullable;
@ -2017,6 +2019,19 @@ public ClaimResult validateClaimType(ClaimType type, UUID newOwnerUUID, GDPlayer
return new GDClaimResult(ClaimResultType.SUCCESS); 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 @Override
public boolean equals(Object o) { public boolean equals(Object o) {
if (this == o) { if (this == o) {

View File

@ -113,6 +113,8 @@ protected ClaimFlagBase(ClaimSubjectType type) {
public void execute(Player player, String[] args) throws InvalidCommandArgument { public void execute(Player player, String[] args) throws InvalidCommandArgument {
final GDPermissionUser src = PermissionHolderCache.getInstance().getOrCreateUser(player); final GDPermissionUser src = PermissionHolderCache.getInstance().getOrCreateUser(player);
final GDPermissionHolder commandSubject = subject; final GDPermissionHolder commandSubject = subject;
final GDPlayerData playerData = src.getInternalPlayerData();
final GDClaim claim = GriefDefenderPlugin.getInstance().dataStore.getClaimAtPlayer(playerData, player.getLocation());
String commandFlag = null; String commandFlag = null;
String target = null; String target = null;
String value = null; String value = null;
@ -123,12 +125,21 @@ public void execute(Player player, String[] args) throws InvalidCommandArgument
contexts = arguments.substring(index, arguments.length()); contexts = arguments.substring(index, arguments.length());
} }
if (args.length > 0) { 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) { if (args.length < 3) {
throw new InvalidCommandArgument(); throw new InvalidCommandArgument();
} }
commandFlag = args[0]; commandFlag = args[0];
target = args[1]; target = args[1];
value = args[2]; 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); final Flag flag = FlagRegistryModule.getInstance().getById(commandFlag).orElse(null);
if (commandFlag != null && flag == null) { if (commandFlag != null && flag == null) {
@ -149,9 +160,7 @@ public void execute(Player player, String[] args) throws InvalidCommandArgument
} }
} }
final GDPlayerData playerData = GriefDefenderPlugin.getInstance().dataStore.getOrCreatePlayerData(player.getWorld(), player.getUniqueId()); final Set<Context> contextSet = CauseContextHelper.generateContexts(flag.getPermission(), player, claim, contexts);
GDClaim claim = GriefDefenderPlugin.getInstance().dataStore.getClaimAtPlayer(playerData, player.getLocation());
final Set<Context> contextSet = CauseContextHelper.generateContexts(player, claim, contexts);
if (contextSet == null) { if (contextSet == null) {
return; return;
} }
@ -911,7 +920,6 @@ private Consumer<CommandSender> createCustomFlagConsumer(GDPermissionUser src, G
newValue = Tristate.UNDEFINED; newValue = Tristate.UNDEFINED;
} }
PermissionResult result = null;
final Flag flag = flagData.getFlag(); final Flag flag = flagData.getFlag();
GDFlagPermissionEvent.Set event = new GDFlagPermissionEvent.Set(this.subject, flagData.getFlag(), newValue, newContexts); GDFlagPermissionEvent.Set event = new GDFlagPermissionEvent.Set(this.subject, flagData.getFlag(), newValue, newContexts);
GriefDefender.getEventManager().post(event); GriefDefender.getEventManager().post(event);
@ -919,8 +927,11 @@ private Consumer<CommandSender> createCustomFlagConsumer(GDPermissionUser src, G
return; 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(); GDCauseStackManager.getInstance().popCause();
showCustomFlags(src, claim, displayType); showCustomFlags(src, claim, displayType);
}; };

View File

@ -91,6 +91,8 @@
import java.util.UUID; import java.util.UUID;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import java.util.function.Consumer; import java.util.function.Consumer;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@SuppressWarnings({ "unchecked", "rawtypes" }) @SuppressWarnings({ "unchecked", "rawtypes" })
public abstract class ClaimOptionBase extends BaseCommand { public abstract class ClaimOptionBase extends BaseCommand {
@ -121,17 +123,31 @@ public void execute(Player player, String[] args) throws InvalidCommandArgument
throw new InvalidCommandArgument(); throw new InvalidCommandArgument();
} }
commandOption = args[0]; commandOption = args[0];
// Check for quoted string
Pattern pattern = Pattern.compile("\"(.*)\"");
Matcher matcher = pattern.matcher(arguments);
if (matcher.find()) {
value = matcher.group(1);
} else {
value = args[1]; value = args[1];
} }
}
Option option = null; Option<?> option = null;
if (commandOption != null) { if (commandOption != null) {
option = GriefDefender.getRegistry().getType(Option.class, commandOption).orElse(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( TextAdapter.sendComponent(player, MessageStorage.MESSAGE_DATA.getMessage(MessageStorage.OPTION_NOT_FOUND, ImmutableMap.of(
"option", commandOption))); "option", commandOption)));
return; 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()); final GDPlayerData playerData = GriefDefenderPlugin.getInstance().dataStore.getOrCreatePlayerData(player.getWorld(), player.getUniqueId());
@ -142,7 +158,7 @@ public void execute(Player player, String[] args) throws InvalidCommandArgument
return; return;
} }
} else if (!claim.isTown() && !playerData.canManageAdminClaims && !playerData.canIgnoreClaim(claim)) { } 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; return;
} }
if (option != null) { if (option != null) {
@ -165,10 +181,32 @@ public void execute(Player player, String[] args) throws InvalidCommandArgument
} }
} }
final Set<Context> contextSet = CauseContextHelper.generateContexts(player, claim, contexts); final Set<Context> contextSet = CauseContextHelper.generateContexts(option.getPermission(), player, claim, contexts);
if (contextSet == null) { if (contextSet == null) {
return; 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 (claim != null) {
if (commandOption == null && value == null && player.hasPermission(GDPermissions.COMMAND_LIST_CLAIM_OPTIONS)) { if (commandOption == null && value == null && player.hasPermission(GDPermissions.COMMAND_LIST_CLAIM_OPTIONS)) {
@ -521,7 +559,11 @@ private Component getClickableOptionComponent(GDPermissionUser src, GDClaim clai
} }
} }
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); Component optionContexts = UIHelper.getFriendlyContextString(claim, contexts);
String currentValue = optionHolder.getValue(); String currentValue = optionHolder.getValue();
TextColor color = optionHolder.getColor(); TextColor color = optionHolder.getColor();
@ -549,11 +591,12 @@ private Component getClickableOptionComponent(GDPermissionUser src, GDClaim clai
} }
if (hasEditPermission) { if (hasEditPermission) {
if (!option.getAllowedType().isAssignableFrom(Integer.class) && !option.getAllowedType().isAssignableFrom(Double.class)) { 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)))); builder.clickEvent(ClickEvent.runCommand(GDCallbackHolder.getInstance().createCallbackRunCommand(newOptionValueConsumer(src, claim, option, optionHolder, contexts, displayType, false))));
} else { } else {
builder.append(TextComponent.builder() builder.append(TextComponent.builder().append(TextComponent.of(" >").decoration(TextDecoration.BOLD, true)));
.append(TextComponent.of(" >").decoration(TextDecoration.BOLD, true)) this.appendContexts(builder, contexts);
.clickEvent(ClickEvent.runCommand(GDCallbackHolder.getInstance().createCallbackRunCommand(newOptionValueConsumer(src, claim, option, optionHolder, contexts, displayType, false))))); builder.clickEvent(ClickEvent.runCommand(GDCallbackHolder.getInstance().createCallbackRunCommand(newOptionValueConsumer(src, claim, option, optionHolder, contexts, displayType, false))));
} }
if (option.getAllowedType().isAssignableFrom(String.class)) { if (option.getAllowedType().isAssignableFrom(String.class)) {
@ -568,9 +611,51 @@ private Component getClickableOptionComponent(GDPermissionUser src, GDClaim clai
"value", TextComponent.of(currentValue).color(TextColor.GOLD)))).build())); "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(); 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) { private boolean containsDefaultContext(Set<Context> contexts) {
for (Context context : contexts) { for (Context context : contexts) {
if (context.getKey().contains("gd_claim_default")) { if (context.getKey().contains("gd_claim_default")) {
@ -638,7 +723,7 @@ private Consumer<CommandSender> newOptionValueConsumer(GDPermissionUser src, GDC
if (value == null || value == WeatherTypes.UNDEFINED) { if (value == null || value == WeatherTypes.UNDEFINED) {
newValue = "clear"; newValue = "clear";
} else if (value == WeatherTypes.CLEAR) { } else if (value == WeatherTypes.CLEAR) {
newValue = "rain"; newValue = "downfall";
} else { } else {
newValue = "undefined"; newValue = "undefined";
} }
@ -722,6 +807,13 @@ private Consumer<CommandSender> newOptionValueConsumer(GDPermissionUser src, GDC
}; };
} }
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) { private Consumer<CommandSender> adjustNumberConsumer(GDPermissionUser src, GDClaim claim, Option option, String currentValue, MenuType menuType, Set<Context> contexts) {
return consumer -> { return consumer -> {
String newValue = ""; String newValue = "";
@ -882,8 +974,8 @@ private static <T> T getMenuTypeValue(TypeToken<T> type, String value) {
if (value.equalsIgnoreCase("clear")) { if (value.equalsIgnoreCase("clear")) {
return (T) WeatherTypes.CLEAR; return (T) WeatherTypes.CLEAR;
} }
if (value.equalsIgnoreCase("rain")) { if (value.equalsIgnoreCase("downfall")) {
return (T) WeatherTypes.RAIN; return (T) WeatherTypes.DOWNFALL;
} }
} }
if (type.getRawType().isAssignableFrom(CreateModeType.class)) { if (type.getRawType().isAssignableFrom(CreateModeType.class)) {

View File

@ -24,7 +24,6 @@
*/ */
package com.griefdefender.command; package com.griefdefender.command;
import co.aikar.commands.BaseCommand;
import co.aikar.commands.InvalidCommandArgument; import co.aikar.commands.InvalidCommandArgument;
import co.aikar.commands.annotation.CommandAlias; import co.aikar.commands.annotation.CommandAlias;
import co.aikar.commands.annotation.CommandCompletion; import co.aikar.commands.annotation.CommandCompletion;
@ -34,35 +33,10 @@
import co.aikar.commands.annotation.Subcommand; import co.aikar.commands.annotation.Subcommand;
import co.aikar.commands.annotation.Syntax; 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.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.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 org.bukkit.entity.Player;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
@CommandAlias("%griefdefender") @CommandAlias("%griefdefender")
@CommandPermission(GDPermissions.COMMAND_OPTIONS_CLAIM) @CommandPermission(GDPermissions.COMMAND_OPTIONS_CLAIM)
public class CommandClaimOption extends ClaimOptionBase { public class CommandClaimOption extends ClaimOptionBase {

View File

@ -32,12 +32,8 @@
import co.aikar.commands.annotation.Optional; import co.aikar.commands.annotation.Optional;
import co.aikar.commands.annotation.Subcommand; import co.aikar.commands.annotation.Subcommand;
import co.aikar.commands.annotation.Syntax; 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.cache.PermissionHolderCache;
import com.griefdefender.permission.GDPermissions; import com.griefdefender.permission.GDPermissions;
import com.griefdefender.util.PermissionUtil;
import org.bukkit.OfflinePlayer; import org.bukkit.OfflinePlayer;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;

View File

@ -43,7 +43,6 @@
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.Location; import org.bukkit.Location;
import org.bukkit.OfflinePlayer;
import org.bukkit.World.Environment; import org.bukkit.World.Environment;
import org.bukkit.command.Command; import org.bukkit.command.Command;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;
@ -121,7 +120,6 @@ public static Player checkPlayer(CommandSender source) {
if (source instanceof Player) { if (source instanceof Player) {
return ((Player) source); return ((Player) source);
} else { } else {
//throw new CommandException(Text.of("You must be a player to run this command!"));
return null; return null;
} }
} }
@ -131,15 +129,15 @@ public static boolean validateFlagTarget(Flag flag, String target) {
return true; 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) || if (validateBlockTarget(target) ||
validateItemTarget(target)) { validateItemTarget(target)) {
return true; return true;
} }
return false; return false;
} }
if (flag.getName().equals("enter-claim") || flag.getName().equals("exit-claim") || flag.getName().equals("entity-riding") || if (flag == Flags.ENTER_CLAIM || flag == Flags.EXIT_CLAIM || flag == Flags.ENTITY_RIDING ||
flag.getName().equals("entity-damage") || flag.getName().equals("portal-use")) { flag == Flags.ENTITY_DAMAGE || flag == Flags.PORTAL_USE) {
if (validateEntityTarget(target) || if (validateEntityTarget(target) ||
validateBlockTarget(target) || validateBlockTarget(target) ||
validateItemTarget(target)) { validateItemTarget(target)) {
@ -148,20 +146,20 @@ public static boolean validateFlagTarget(Flag flag, String target) {
return false; return false;
} }
if (flag.getName().equals("interact-inventory")) { if (flag == Flags.INTERACT_INVENTORY) {
// Always return true due to custom inventories // Always return true due to custom inventories
return true; return true;
} }
if (flag.getName().equals("liquid-flow") || flag.getName().equals("interact-block-primary") if (flag == Flags.LIQUID_FLOW || flag == Flags.INTERACT_BLOCK_PRIMARY
|| flag.getName().equals("interact-block-secondary")) { || flag == Flags.INTERACT_BLOCK_SECONDARY) {
return validateBlockTarget(target); return validateBlockTarget(target);
} }
if (flag.getName().equals("entity-chunk-spawn") || flag.getName().equals("entity-spawn") || if (flag == Flags.ENTITY_CHUNK_SPAWN || flag == Flags.ENTITY_SPAWN ||
flag.getName().equals("interact-entity-primary") || flag.getName().equals("interact-entity-secondary")) { flag == Flags.INTERACT_ENTITY_PRIMARY || flag == Flags.INTERACT_ENTITY_SECONDARY) {
return validateEntityTarget(target); return validateEntityTarget(target);
} }
if (flag.getName().equals("item-drop") || flag.getName().equals("item-pickup") || if (flag == Flags.ITEM_DROP|| flag == Flags.ITEM_PICKUP ||
flag.getName().equals("item-spawn") || flag.getName().equals("item-use")) { flag == Flags.ITEM_SPAWN || flag == Flags.ITEM_USE) {
return validateItemTarget(target); return validateItemTarget(target);
} }
@ -200,7 +198,7 @@ private static boolean validateBlockTarget(String target) {
return false; 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) { if (src instanceof Player) {
Component denyReason = ((GDClaim) claim).allowEdit((Player) src); Component denyReason = ((GDClaim) claim).allowEdit((Player) src);
if (denyReason != null) { if (denyReason != null) {
@ -209,11 +207,9 @@ public static PermissionResult addFlagPermission(CommandSender src, GDPermission
} }
} }
final String baseFlag = claimFlag.toString().toLowerCase();
String flagPermission = GDPermissions.FLAG_BASE + "." + baseFlag;
// special handling for commands // special handling for commands
target = adjustTargetForTypes(target, claimFlag); target = adjustTargetForTypes(target, flag);
if (baseFlag.equals(Flags.COMMAND_EXECUTE.getName()) || baseFlag.equals(Flags.COMMAND_EXECUTE_PVP.getName())) { if (flag == Flags.COMMAND_EXECUTE || flag == Flags.COMMAND_EXECUTE_PVP) {
target = handleCommandFlag(src, target); target = handleCommandFlag(src, target);
if (target == null) { if (target == null) {
// failed // failed
@ -227,9 +223,7 @@ public static PermissionResult addFlagPermission(CommandSender src, GDPermission
} }
String[] parts = target.split(":"); String[] parts = target.split(":");
if (parts.length > 1 && parts[1].equalsIgnoreCase("any")) { if (parts.length <= 1 || !parts[1].equalsIgnoreCase("any")) {
target = baseFlag + "." + parts[0];
} else {
// check for meta // check for meta
parts = target.split("\\."); parts = target.split("\\.");
String targetFlag = parts[0]; String targetFlag = parts[0];
@ -239,13 +233,13 @@ public static PermissionResult addFlagPermission(CommandSender src, GDPermission
} catch (NumberFormatException e) { } catch (NumberFormatException e) {
final Component message = GriefDefenderPlugin.getInstance().messageData.getMessage(MessageStorage.PERMISSION_CLAIM_MANAGE, ImmutableMap.of( final Component message = GriefDefenderPlugin.getInstance().messageData.getMessage(MessageStorage.PERMISSION_CLAIM_MANAGE, ImmutableMap.of(
"meta", parts[1], "meta", parts[1],
"flag", baseFlag)); "flag", flag.getName().toLowerCase()));
GriefDefenderPlugin.sendMessage(src, message); GriefDefenderPlugin.sendMessage(src, message);
return new GDPermissionResult(ResultTypes.TARGET_NOT_VALID); return new GDPermissionResult(ResultTypes.TARGET_NOT_VALID);
} }
} }
addFlagContexts(contexts, claimFlag, targetFlag); addFlagContexts(contexts, flag, targetFlag);
if (!targetFlag.startsWith("#") && !CommandHelper.validateFlagTarget(claimFlag, targetFlag)) { if (!targetFlag.startsWith("#") && !CommandHelper.validateFlagTarget(flag, targetFlag)) {
//TODO //TODO
/*final Text message = GriefDefenderPlugin.getInstance().messageData.permissionClaimManage /*final Text message = GriefDefenderPlugin.getInstance().messageData.permissionClaimManage
.apply(ImmutableMap.of( .apply(ImmutableMap.of(
@ -260,25 +254,14 @@ public static PermissionResult addFlagPermission(CommandSender src, GDPermission
} }
} }
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) { 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, flagPermission, target, value, contexts, flagType, false); 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 hasDefaultContext = false;
boolean hasOverrideContext = false; boolean hasOverrideContext = false;
Component reason = null; Component reason = null;
@ -339,8 +322,18 @@ public static PermissionResult applyFlagPermission(CommandSender src, GDPermissi
} }
} }
// 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) { 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) { if (!clicked && src instanceof Player) {
TextAdapter.sendComponent(src, TextComponent.builder("") TextAdapter.sendComponent(src, TextComponent.builder("")
.append(TextComponent.builder("\n[").append(MessageCache.getInstance().FLAG_UI_RETURN_FLAGS.color(TextColor.AQUA)).append("]\n") .append(TextComponent.builder("\n[").append(MessageCache.getInstance().FLAG_UI_RETURN_FLAGS.color(TextColor.AQUA)).append("]\n")
@ -348,14 +341,14 @@ public static PermissionResult applyFlagPermission(CommandSender src, GDPermissi
.append(MessageStorage.MESSAGE_DATA.getMessage(MessageStorage.FLAG_SET_PERMISSION_TARGET, .append(MessageStorage.MESSAGE_DATA.getMessage(MessageStorage.FLAG_SET_PERMISSION_TARGET,
ImmutableMap.of( ImmutableMap.of(
"type", flagTypeText, "type", flagTypeText,
"permission", flagPermission.replace(GDPermissions.FLAG_BASE + ".", ""), "permission", flag.getPermission(),
"contexts", getFriendlyContextString(claim, contexts), "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"))) "target", "ALL")))
.build()); .build());
} }
} else { } else {
PermissionUtil.getInstance().setPermissionValue(subject, flagPermission, value, contexts); PermissionUtil.getInstance().setPermissionValue(subject, flag, value, contexts);
if (!clicked && src instanceof Player) { if (!clicked && src instanceof Player) {
TextAdapter.sendComponent(src, TextComponent.builder("") TextAdapter.sendComponent(src, TextComponent.builder("")
.append(TextComponent.builder("") .append(TextComponent.builder("")
@ -366,9 +359,9 @@ public static PermissionResult applyFlagPermission(CommandSender src, GDPermissi
.append(MessageStorage.MESSAGE_DATA.getMessage(MessageStorage.FLAG_SET_PERMISSION_TARGET, .append(MessageStorage.MESSAGE_DATA.getMessage(MessageStorage.FLAG_SET_PERMISSION_TARGET,
ImmutableMap.of( ImmutableMap.of(
"type", flagTypeText, "type", flagTypeText,
"permission", flagPermission.replace(GDPermissions.FLAG_BASE + ".", ""), "permission", flag.getPermission(),
"contexts", getFriendlyContextString(claim, contexts), "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()))) "target", subject.getFriendlyName())))
.build()); .build());
} }
@ -471,7 +464,7 @@ public static TextColor getPermissionMenuTypeColor(MenuType type) {
return color; 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 -> { return consumer -> {
Tristate newValue = Tristate.UNDEFINED; Tristate newValue = Tristate.UNDEFINED;
if (flagValue == Tristate.TRUE) { if (flagValue == Tristate.TRUE) {
@ -488,16 +481,16 @@ public static Consumer<CommandSender> createFlagConsumer(CommandSender src, GDCl
} else if (flagType == MenuType.CLAIM) { } else if (flagType == MenuType.CLAIM) {
flagTypeText = TextComponent.of("CLAIM", TextColor.GOLD); flagTypeText = TextComponent.of("CLAIM", TextColor.GOLD);
} }
String target = flagPermission.replace(GDPermissions.FLAG_BASE + ".", "");
Set<Context> newContexts = new HashSet<>(contexts); 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("") TextAdapter.sendComponent(src, TextComponent.builder("")
.append("Set ", TextColor.GREEN) .append("Set ", TextColor.GREEN)
.append(flagTypeText) .append(flagTypeText)
.append(" permission ") .append(" permission ")
.append(target, TextColor.AQUA) .append(flag.getName().toLowerCase(), TextColor.AQUA)
.append("\n to ", TextColor.GREEN) .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(" for ", TextColor.GREEN)
.append(subject.getFriendlyName(), TextColor.GOLD).build()); .append(subject.getFriendlyName(), TextColor.GOLD).build());
}; };
@ -568,10 +561,6 @@ public static void showClaims(CommandSender src, Set<Claim> claims, int height,
} }
} }
//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); 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); builder.sendTo(src);
} }
@ -847,9 +836,9 @@ public static Consumer<CommandSender> createReturnClaimListConsumer(CommandSende
}; };
} }
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 -> { return consumer -> {
String target = flagPermission.replace(GDPermissions.FLAG_BASE + ".", ""); String target = flag.getName().toLowerCase();
if (target.isEmpty()) { if (target.isEmpty()) {
target = "any"; target = "any";
} }
@ -860,22 +849,22 @@ public static Consumer<CommandSender> createFlagConsumer(CommandSender src, GDPe
newValue = Tristate.TRUE; 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()) TextComponent.Builder textBuilder = TextComponent.builder(flagValue.toString().toLowerCase())
.hoverEvent(HoverEvent.showText(TextComponent.builder("") .hoverEvent(HoverEvent.showText(TextComponent.builder("")
.append(MessageStorage.MESSAGE_DATA.getMessage(MessageStorage.CLAIMLIST_UI_CLICK_TOGGLE_VALUE, .append(MessageStorage.MESSAGE_DATA.getMessage(MessageStorage.CLAIMLIST_UI_CLICK_TOGGLE_VALUE,
ImmutableMap.of("type", type.name().toLowerCase()))) ImmutableMap.of("type", type.name().toLowerCase())))
.append("\n") .append("\n")
.append(UIHelper.getPermissionMenuTypeHoverText(type)).build())) .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(); 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, Component onClickText = MessageStorage.MESSAGE_DATA.getMessage(MessageStorage.CLAIMLIST_UI_CLICK_TOGGLE_VALUE,
ImmutableMap.of("type", "flag")); ImmutableMap.of("type", "flag"));
boolean hasPermission = true; boolean hasPermission = true;
@ -897,7 +886,7 @@ public static Component getClickableText(CommandSender src, GDPermissionHolder s
.append("\n") .append("\n")
.append(UIHelper.getPermissionMenuTypeHoverText(type)).build())); .append(UIHelper.getPermissionMenuTypeHoverText(type)).build()));
if (hasPermission) { 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(); 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_CLICK_TOGGLE = "flag-ui-click-toggle";
public static final String FLAG_UI_INHERIT_PARENT = "flag-ui-inherit-parent"; 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 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_CONTEXT = "option-invalid-context";
public static final String OPTION_INVALID_TARGET = "option-invalid-target"; 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_INVALID_VALUE = "option-invalid-value";
public static final String OPTION_NOT_FOUND = "option-not-found"; 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_NOT_SET = "option-not-set";
public static final String OPTION_OVERRIDE_NOT_SUPPORTED = "option-override-not-supported"; 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_RESET_SUCCESS = "option-reset-success";
public static final String OPTION_SET_TARGET = "option-set-target"; public static final String OPTION_SET_TARGET = "option-set-target";
public static final String OPTION_UI_CLICK_TOGGLE = "option-ui-click-toggle"; 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 PLAYERINFO_UI_WORLD = "playerinfo-ui-world";
public static final String PLUGIN_COMMAND_NOT_FOUND = "plugin-command-not-found"; 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 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_BLOCK_NOT_FOUND = "registry-type-not-found";
public static final String REGISTRY_ENTITY_NOT_FOUND = "registry-entity-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"; public static final String REGISTRY_ITEM_NOT_FOUND = "registry-item-not-found";

View File

@ -104,6 +104,9 @@ public DefaultPermissionCategory() {
this.defaultUserOptions.put(Options.PLAYER_WALK_SPEED.getName(), "-1"); this.defaultUserOptions.put(Options.PLAYER_WALK_SPEED.getName(), "-1");
this.defaultUserOptions.put(Options.PLAYER_WEATHER.getName(), "undefined"); this.defaultUserOptions.put(Options.PLAYER_WEATHER.getName(), "undefined");
this.defaultUserOptions.put(Options.PVP.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_X.getName(), "5");
this.defaultBasicOptions.put(Options.MIN_SIZE_Y.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 WeatherType deserialize(TypeToken<?> type, ConfigurationNode node) throws
case "clear" : case "clear" :
return WeatherTypes.CLEAR; return WeatherTypes.CLEAR;
case "rain" : case "rain" :
return WeatherTypes.RAIN; return WeatherTypes.DOWNFALL;
default : default :
return WeatherTypes.UNDEFINED; return WeatherTypes.UNDEFINED;
} }

View File

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

View File

@ -40,7 +40,6 @@
import com.griefdefender.api.permission.option.Options; import com.griefdefender.api.permission.option.Options;
import com.griefdefender.cache.EventResultCache; import com.griefdefender.cache.EventResultCache;
import com.griefdefender.cache.MessageCache; import com.griefdefender.cache.MessageCache;
import com.griefdefender.cache.PermissionHolderCache;
import com.griefdefender.claim.GDClaim; import com.griefdefender.claim.GDClaim;
import com.griefdefender.claim.GDClaimManager; import com.griefdefender.claim.GDClaimManager;
import com.griefdefender.configuration.GriefDefenderConfig; import com.griefdefender.configuration.GriefDefenderConfig;
@ -192,7 +191,7 @@ public void onBlockDispense(BlockDispenseEvent event) {
final Location faceLocation = BlockUtil.getInstance().getBlockRelative(location, face); final Location faceLocation = BlockUtil.getInstance().getBlockRelative(location, face);
final GDClaim targetClaim = this.storage.getClaimAt(faceLocation); final GDClaim targetClaim = this.storage.getClaimAt(faceLocation);
final ItemStack activeItem = user != null && user.getOnlinePlayer() != null ? NMSUtil.getInstance().getActiveItem(user.getOnlinePlayer()) : null; 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) { if (result == Tristate.FALSE) {
event.setCancelled(true); event.setCancelled(true);
} else { } else {
@ -215,7 +214,7 @@ public void onBlockGrow(BlockGrowEvent event) {
return; 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) { if (result == Tristate.FALSE) {
event.setCancelled(true); event.setCancelled(true);
return; return;
@ -237,7 +236,7 @@ public void onStructureGrow(StructureGrowEvent event) {
continue; 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) { if (result == Tristate.FALSE) {
event.setCancelled(true); event.setCancelled(true);
return; return;
@ -266,7 +265,7 @@ public void onBlockFromTo(BlockFromToEvent event) {
} }
if (fromBlock.isLiquid()) { 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) { if (result == Tristate.FALSE) {
event.setCancelled(true); event.setCancelled(true);
return; return;
@ -278,7 +277,7 @@ public void onBlockFromTo(BlockFromToEvent event) {
private boolean handleBlockBreak(BlockEvent event, Location location, GDClaim claim, Object source, Object target, GDPermissionUser user, boolean sendDenyMessage) { private boolean handleBlockBreak(BlockEvent event, Location location, GDClaim claim, Object source, Object target, GDPermissionUser user, boolean sendDenyMessage) {
// check overrides // 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 (result == Tristate.FALSE) {
if (sendDenyMessage && user != null) { if (sendDenyMessage && user != null) {
final Component message = GriefDefenderPlugin.getInstance().messageData.getMessage(MessageStorage.PERMISSION_BUILD, final Component message = GriefDefenderPlugin.getInstance().messageData.getMessage(MessageStorage.PERMISSION_BUILD,
@ -330,7 +329,7 @@ public void onBlockDecay(LeavesDecayEvent event) {
GDClaim targetClaim = this.storage.getClaimAt(location); GDClaim targetClaim = this.storage.getClaimAt(location);
// check overrides // 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) { if (result == Tristate.FALSE) {
event.setCancelled(true); event.setCancelled(true);
} }
@ -425,7 +424,7 @@ public void onExplosionEvent(BlockExplodeEvent event) {
for (Block block : event.blockList()) { for (Block block : event.blockList()) {
final Location location = block.getLocation(); final Location location = block.getLocation();
targetClaim = GriefDefenderPlugin.getInstance().dataStore.getClaimAt(location, targetClaim); 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) { if (result == Tristate.FALSE) {
// Avoid lagging server from large explosions. // Avoid lagging server from large explosions.
if (event.blockList().size() > 100) { if (event.blockList().size() > 100) {
@ -472,7 +471,7 @@ public void onBlockBreak(BlockBreakEvent event) {
} }
// check overrides // 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 (result == Tristate.FALSE) {
if (player != null) { if (player != null) {
Component message = GDPermissionManager.getInstance().getEventMessage(); Component message = GDPermissionManager.getInstance().getEventMessage();
@ -535,7 +534,7 @@ public void onBlockPlace(BlockPlaceEvent event) {
if (GDFlags.BLOCK_PLACE) { if (GDFlags.BLOCK_PLACE) {
// check overrides // 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) { if (result == Tristate.FALSE) {
event.setCancelled(true); event.setCancelled(true);
GDTimings.BLOCK_PLACE_EVENT.stopTiming(); GDTimings.BLOCK_PLACE_EVENT.stopTiming();

View File

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

View File

@ -36,10 +36,10 @@
import com.griefdefender.GriefDefenderPlugin; import com.griefdefender.GriefDefenderPlugin;
import com.griefdefender.api.Tristate; import com.griefdefender.api.Tristate;
import com.griefdefender.api.claim.TrustTypes; import com.griefdefender.api.claim.TrustTypes;
import com.griefdefender.api.permission.flag.Flags;
import com.griefdefender.claim.GDClaim; import com.griefdefender.claim.GDClaim;
import com.griefdefender.permission.GDPermissionManager; import com.griefdefender.permission.GDPermissionManager;
import com.griefdefender.permission.GDPermissionUser; import com.griefdefender.permission.GDPermissionUser;
import com.griefdefender.permission.GDPermissions;
import com.griefdefender.permission.flag.GDFlags; import com.griefdefender.permission.flag.GDFlags;
import com.griefdefender.storage.BaseStorage; import com.griefdefender.storage.BaseStorage;
import com.griefdefender.util.CauseContextHelper; import com.griefdefender.util.CauseContextHelper;
@ -78,7 +78,7 @@ public void handleBlockSpread(Event event, Block fromBlock, Block toBlock) {
Location location = toBlock.getLocation(); Location location = toBlock.getLocation();
GDClaim targetClaim = this.storage.getClaimAt(location); 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) { if (result == Tristate.FALSE) {
((Cancellable) event).setCancelled(true); ((Cancellable) event).setCancelled(true);
} }
@ -113,7 +113,7 @@ public void handleBlockModify(Event event, Object source, Block toBlock) {
Location location = toBlock.getLocation(); Location location = toBlock.getLocation();
GDClaim targetClaim = this.storage.getClaimAt(location); 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) { if (result == Tristate.FALSE) {
((Cancellable) event).setCancelled(true); ((Cancellable) event).setCancelled(true);
} }
@ -142,7 +142,7 @@ public void handleBlockPlace(Event event, Object source, Block block) {
GDClaim targetClaim = this.storage.getClaimAt(location); 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) { if (result == Tristate.FALSE) {
((Cancellable) event).setCancelled(true); ((Cancellable) event).setCancelled(true);
} }
@ -170,7 +170,7 @@ public void handleBlockBreak(Event event, Object source, Block block) {
GDClaim targetClaim = this.storage.getClaimAt(location); 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) { if (result == Tristate.FALSE) {
((Cancellable) event).setCancelled(true); ((Cancellable) event).setCancelled(true);
} }

View File

@ -25,7 +25,14 @@
package com.griefdefender.listener; package com.griefdefender.listener;
import java.lang.ref.WeakReference; 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.GameMode;
import org.bukkit.Location; import org.bukkit.Location;
import org.bukkit.Material; import org.bukkit.Material;
@ -49,21 +56,31 @@
import com.griefdefender.api.GriefDefender; import com.griefdefender.api.GriefDefender;
import com.griefdefender.api.Tristate; import com.griefdefender.api.Tristate;
import com.griefdefender.api.claim.TrustTypes; import com.griefdefender.api.claim.TrustTypes;
import com.griefdefender.api.permission.Context;
import com.griefdefender.api.permission.flag.Flags; import com.griefdefender.api.permission.flag.Flags;
import com.griefdefender.api.permission.option.Options; 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.MessageCache;
import com.griefdefender.cache.PermissionHolderCache; import com.griefdefender.cache.PermissionHolderCache;
import com.griefdefender.claim.GDClaim; import com.griefdefender.claim.GDClaim;
import com.griefdefender.command.CommandHelper;
import com.griefdefender.configuration.MessageStorage; import com.griefdefender.configuration.MessageStorage;
import com.griefdefender.event.GDBorderClaimEvent; import com.griefdefender.event.GDBorderClaimEvent;
import com.griefdefender.internal.registry.ItemTypeRegistryModule; 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.internal.util.VecHelper;
import com.griefdefender.permission.GDPermissionManager; import com.griefdefender.permission.GDPermissionManager;
import com.griefdefender.permission.GDPermissionUser; import com.griefdefender.permission.GDPermissionUser;
import com.griefdefender.permission.GDPermissions; import com.griefdefender.permission.GDPermissions;
import com.griefdefender.permission.flag.GDFlags; import com.griefdefender.permission.flag.GDFlags;
import com.griefdefender.permission.option.OptionContexts;
import com.griefdefender.storage.BaseStorage; import com.griefdefender.storage.BaseStorage;
import com.griefdefender.util.PermissionUtil;
import com.griefdefender.util.PlayerUtil;
import net.kyori.text.Component; import net.kyori.text.Component;
import net.kyori.text.TextComponent; import net.kyori.text.TextComponent;
import net.kyori.text.adapter.bukkit.TextAdapter; import net.kyori.text.adapter.bukkit.TextAdapter;
@ -129,7 +146,7 @@ public boolean onEntityMove(Event event, Location fromLocation, Location toLocat
if (GDFlags.ENTER_CLAIM && !enterBlacklisted && user != null && user.getInternalPlayerData().lastClaim != null) { if (GDFlags.ENTER_CLAIM && !enterBlacklisted && user != null && user.getInternalPlayerData().lastClaim != null) {
final GDClaim lastClaim = (GDClaim) user.getInternalPlayerData().lastClaim.get(); final GDClaim lastClaim = (GDClaim) user.getInternalPlayerData().lastClaim.get();
if (lastClaim != null && lastClaim != fromClaim) { 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()); Location claimCorner = new Location(toLocation.getWorld(), toClaim.lesserBoundaryCorner.getX(), targetEntity.getLocation().getBlockY(), toClaim.greaterBoundaryCorner.getZ());
targetEntity.teleport(claimCorner); targetEntity.teleport(claimCorner);
} }
@ -143,6 +160,7 @@ public boolean onEntityMove(Event event, Location fromLocation, Location toLocat
GDBorderClaimEvent gpEvent = new GDBorderClaimEvent(targetEntity, fromClaim, toClaim); GDBorderClaimEvent gpEvent = new GDBorderClaimEvent(targetEntity, fromClaim, toClaim);
if (user != null && toClaim.isUserTrusted(user, TrustTypes.ACCESSOR)) { if (user != null && toClaim.isUserTrusted(user, TrustTypes.ACCESSOR)) {
GriefDefender.getEventManager().post(gpEvent); GriefDefender.getEventManager().post(gpEvent);
final GDPlayerData playerData = user.getInternalPlayerData();
if (gpEvent.cancelled()) { if (gpEvent.cancelled()) {
if (targetEntity instanceof Vehicle) { if (targetEntity instanceof Vehicle) {
final Vehicle vehicle = (Vehicle) targetEntity; final Vehicle vehicle = (Vehicle) targetEntity;
@ -194,9 +212,18 @@ public boolean onEntityMove(Event event, Location fromLocation, Location toLocat
} }
if (toClaim.isInTown()) { if (toClaim.isInTown()) {
user.getInternalPlayerData().inTown = true; playerData.inTown = true;
} else { } 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 boolean onEntityMove(Event event, Location fromLocation, Location toLocat
boolean enterCancelled = false; boolean enterCancelled = false;
boolean exitCancelled = false; boolean exitCancelled = false;
// enter // 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; enterCancelled = true;
gpEvent.cancelled(true); gpEvent.cancelled(true);
} }
// exit // 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; exitCancelled = true;
gpEvent.cancelled(true); gpEvent.cancelled(true);
} }
@ -250,8 +277,9 @@ public boolean onEntityMove(Event event, Location fromLocation, Location toLocat
} }
if (user != null) { if (user != null) {
final GDPlayerData playerData = user.getInternalPlayerData();
final boolean showGpPrefix = GriefDefenderPlugin.getGlobalConfig().getConfig().message.enterExitShowGdPrefix; 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); Component welcomeMessage = gpEvent.getEnterMessage().orElse(null);
if (welcomeMessage != null && !welcomeMessage.equals(TextComponent.empty())) { if (welcomeMessage != null && !welcomeMessage.equals(TextComponent.empty())) {
ChatType chatType = gpEvent.getEnterMessageChatType(); ChatType chatType = gpEvent.getEnterMessageChatType();
@ -285,12 +313,20 @@ public boolean onEntityMove(Event event, Location fromLocation, Location toLocat
} }
if (toClaim.isInTown()) { if (toClaim.isInTown()) {
user.getInternalPlayerData().inTown = true; playerData.inTown = true;
} else { } 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 boolean onEntityMove(Event event, Location fromLocation, Location toLocat
return true; 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) { private void checkPlayerFlight(Player player, GDPlayerData playerData, GDClaim fromClaim, GDClaim toClaim) {
final GameMode gameMode = player.getGameMode(); final GameMode gameMode = player.getGameMode();
if (gameMode == GameMode.CREATIVE || gameMode == GameMode.SPECTATOR) { if (gameMode == GameMode.CREATIVE || gameMode == GameMode.SPECTATOR) {
@ -305,12 +411,11 @@ private void checkPlayerFlight(Player player, GDPlayerData playerData, GDClaim f
} }
if (fromClaim == toClaim || !player.isFlying()) { if (fromClaim == toClaim || !player.isFlying()) {
// only handle player-fly in enter/exit
return; return;
} }
final Boolean noFly = GDPermissionManager.getInstance().getInternalOptionValue(TypeToken.of(Boolean.class), playerData.getSubject(), Options.PLAYER_DENY_FLIGHT, toClaim); 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; 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) { if (player.getUniqueId().equals(toClaim.getOwnerUniqueId()) && ownerFly) {
return; return;
@ -319,7 +424,93 @@ private void checkPlayerFlight(Player player, GDPlayerData playerData, GDClaim f
player.setAllowFlight(false); player.setAllowFlight(false);
player.setFlying(false); player.setFlying(false);
playerData.ignoreFallDamage = true; 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.TrustType; import com.griefdefender.api.claim.TrustType;
import com.griefdefender.api.claim.TrustTypes; import com.griefdefender.api.claim.TrustTypes;
import com.griefdefender.api.permission.Context; 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.flag.Flags;
import com.griefdefender.api.permission.option.Options; import com.griefdefender.api.permission.option.Options;
import com.griefdefender.cache.MessageCache; import com.griefdefender.cache.MessageCache;
@ -46,7 +47,6 @@
import com.griefdefender.internal.util.NMSUtil; import com.griefdefender.internal.util.NMSUtil;
import com.griefdefender.permission.GDPermissionManager; import com.griefdefender.permission.GDPermissionManager;
import com.griefdefender.permission.GDPermissionUser; import com.griefdefender.permission.GDPermissionUser;
import com.griefdefender.permission.GDPermissions;
import com.griefdefender.permission.flag.GDFlags; import com.griefdefender.permission.flag.GDFlags;
import com.griefdefender.storage.BaseStorage; import com.griefdefender.storage.BaseStorage;
import com.griefdefender.util.CauseContextHelper; import com.griefdefender.util.CauseContextHelper;
@ -157,7 +157,7 @@ public void onEntityChangeBlockEvent(EntityChangeBlockEvent event) {
return; 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) { if (result == Tristate.FALSE) {
event.setCancelled(true); event.setCancelled(true);
return; return;
@ -196,10 +196,10 @@ public void onExplosionPrimeEvent(ExplosionPrimeEvent event) {
// Use any location for permission check // Use any location for permission check
final Vector3i pos = claim.getLesserBoundaryCorner(); final Vector3i pos = claim.getLesserBoundaryCorner();
Location targetLocation = new Location(location.getWorld(), pos.getX(), pos.getY(), pos.getZ()); 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) { if (blockResult == Tristate.FALSE) {
// Check explosion entity // 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); event.setCancelled(true);
break; break;
} }
@ -241,7 +241,7 @@ public void onEntityExplodeEvent(EntityExplodeEvent event) {
for (Block block : event.blockList()) { for (Block block : event.blockList()) {
final Location location = block.getLocation(); final Location location = block.getLocation();
targetClaim = GriefDefenderPlugin.getInstance().dataStore.getClaimAt(location, targetClaim); 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) { if (result == Tristate.FALSE) {
// Avoid lagging server from large explosions. // Avoid lagging server from large explosions.
if (event.blockList().size() > 100) { if (event.blockList().size() > 100) {
@ -382,7 +382,7 @@ public boolean protectEntity(Event event, Object source, Entity targetEntity) {
} }
} }
String permission = GDPermissions.ENTITY_DAMAGE; Flag flag = Flags.ENTITY_DAMAGE;
ProjectileSource projectileSource = null; ProjectileSource projectileSource = null;
UUID owner = source instanceof Player ? ((Player) source).getUniqueId() : null; UUID owner = source instanceof Player ? ((Player) source).getUniqueId() : null;
if (owner == null && source instanceof Tameable) { if (owner == null && source instanceof Tameable) {
@ -392,7 +392,7 @@ public boolean protectEntity(Event event, Object source, Entity targetEntity) {
if (projectileSource != null && projectileSource instanceof OfflinePlayer) { if (projectileSource != null && projectileSource instanceof OfflinePlayer) {
owner = ((OfflinePlayer) projectileSource).getUniqueId(); owner = ((OfflinePlayer) projectileSource).getUniqueId();
} }
permission = GDPermissions.PROJECTILE_IMPACT_ENTITY; flag = Flags.PROJECTILE_IMPACT_ENTITY;
} else if (source instanceof DamageCause) { } else if (source instanceof DamageCause) {
if (targetEntity instanceof Player) { if (targetEntity instanceof Player) {
owner = ((Player) targetEntity).getUniqueId(); owner = ((Player) targetEntity).getUniqueId();
@ -416,7 +416,7 @@ public boolean protectEntity(Event event, Object source, Entity targetEntity) {
} }
if (source instanceof Creeper || source instanceof TNTPrimed || (damageCause != null && damageCause == DamageCause.ENTITY_EXPLOSION)) { 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) { if (result == Tristate.FALSE) {
return true; return true;
} }
@ -448,7 +448,7 @@ public boolean protectEntity(Event event, Object source, Entity targetEntity) {
} }
final TrustType trustType = TrustTypes.BUILDER; 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) { if (source != null && source instanceof Player) {
final Player player = (Player) source; final Player player = (Player) source;
CommonEntityEventHandler.getInstance().sendInteractEntityDenyMessage(NMSUtil.getInstance().getActiveItem(player), targetEntity, claim, player); CommonEntityEventHandler.getInstance().sendInteractEntityDenyMessage(NMSUtil.getInstance().getActiveItem(player), targetEntity, claim, player);
@ -469,14 +469,14 @@ public boolean protectEntity(Event event, Object source, Entity targetEntity) {
return false; 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 true;
} }
return false; 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 true;
} }
@ -486,17 +486,31 @@ public boolean protectEntity(Event event, Object source, Entity targetEntity) {
private boolean getPvpProtectResult(Event event, GDClaim claim, GDPermissionUser source, GDPermissionUser target) { private boolean getPvpProtectResult(Event event, GDClaim claim, GDPermissionUser source, GDPermissionUser target) {
final Player sourcePlayer = source.getOnlinePlayer(); final Player sourcePlayer = source.getOnlinePlayer();
final Player targetPlayer = target.getOnlinePlayer(); final Player targetPlayer = target.getOnlinePlayer();
final boolean sourceInCombat = source.getInternalPlayerData().inPvpCombat(claim.getWorld()); final boolean sourceInCombat = source.getInternalPlayerData().inPvpCombat();
final boolean targetInCombat = target.getInternalPlayerData().inPvpCombat(claim.getWorld()); final boolean targetInCombat = target.getInternalPlayerData().inPvpCombat();
if (sourceInCombat && targetInCombat) { // 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(); source.getInternalPlayerData().lastPvpTimestamp = Instant.now();
target.getInternalPlayerData().lastPvpTimestamp = Instant.now(); target.getInternalPlayerData().lastPvpTimestamp = Instant.now();
return false; 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 // Check flags
Tristate sourceResult = GDPermissionManager.getInstance().getFinalPermission(event, targetPlayer.getLocation(), claim, GDPermissions.ENTITY_DAMAGE, sourcePlayer, targetPlayer, sourcePlayer, 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, GDPermissions.ENTITY_DAMAGE, targetPlayer, sourcePlayer, targetPlayer, true); Tristate targetResult = GDPermissionManager.getInstance().getFinalPermission(event, sourcePlayer.getLocation(), claim, Flags.ENTITY_DAMAGE, targetPlayer, sourcePlayer, targetPlayer, true);
if (sourceResult == Tristate.FALSE) { if (sourceResult == Tristate.FALSE) {
GriefDefenderPlugin.sendMessage(sourcePlayer, MessageCache.getInstance().PVP_SOURCE_NOT_ALLOWED); GriefDefenderPlugin.sendMessage(sourcePlayer, MessageCache.getInstance().PVP_SOURCE_NOT_ALLOWED);
return true; return true;
@ -524,14 +538,10 @@ private boolean getPvpProtectResult(Event event, GDClaim claim, GDPermissionUser
return true; return true;
} }
final GDClaim sourceClaim = GriefDefenderPlugin.getInstance().dataStore.getClaimAtPlayer(source.getInternalPlayerData(), sourcePlayer.getLocation()); final Instant now = Instant.now();
if (!sourceClaim.isPvpEnabled()) { source.getInternalPlayerData().lastPvpTimestamp = now;
GriefDefenderPlugin.sendMessage(sourcePlayer, MessageCache.getInstance().PVP_CLAIM_NOT_ALLOWED); target.getInternalPlayerData().lastPvpTimestamp = now;
return true; return false;
}
source.getInternalPlayerData().lastPvpTimestamp = Instant.now();
target.getInternalPlayerData().lastPvpTimestamp = Instant.now();
return !claim.isPvpEnabled();
} }
@EventHandler(priority = EventPriority.LOWEST) @EventHandler(priority = EventPriority.LOWEST)
@ -617,7 +627,7 @@ public void handleEntitySpawn(Event event, Object source, Entity entity) {
} }
final GDClaim targetClaim = GriefDefenderPlugin.getInstance().dataStore.getClaimAt(entity.getLocation()); final GDClaim targetClaim = GriefDefenderPlugin.getInstance().dataStore.getClaimAt(entity.getLocation());
String permission = GDPermissions.ENTITY_SPAWN; Flag flag = Flags.ENTITY_SPAWN;
if (entity instanceof Item) { if (entity instanceof Item) {
if (user == null) { if (user == null) {
@ -632,10 +642,10 @@ public void handleEntitySpawn(Event event, Object source, Entity entity) {
GDTimings.ENTITY_SPAWN_EVENT.stopTiming(); GDTimings.ENTITY_SPAWN_EVENT.stopTiming();
return; 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); ((Cancellable) event).setCancelled(true);
} }
@ -668,7 +678,7 @@ public void onEntityMount(VehicleEnterEvent event) {
final Location location = event.getVehicle().getLocation(); final Location location = event.getVehicle().getLocation();
final GDClaim targetClaim = GriefDefenderPlugin.getInstance().dataStore.getClaimAt(location); 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) { if (player != null) {
PlayerUtil.getInstance().sendInteractEntityDenyMessage(targetClaim, player, null, event.getVehicle()); PlayerUtil.getInstance().sendInteractEntityDenyMessage(targetClaim, player, null, event.getVehicle());
} }

View File

@ -30,9 +30,6 @@
import com.griefdefender.GDPlayerData; import com.griefdefender.GDPlayerData;
import com.griefdefender.GDTimings; import com.griefdefender.GDTimings;
import com.griefdefender.GriefDefenderPlugin; 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.Tristate;
import com.griefdefender.api.claim.Claim; import com.griefdefender.api.claim.Claim;
import com.griefdefender.api.claim.ClaimBlockSystem; import com.griefdefender.api.claim.ClaimBlockSystem;
@ -43,6 +40,7 @@
import com.griefdefender.api.claim.ShovelTypes; import com.griefdefender.api.claim.ShovelTypes;
import com.griefdefender.api.claim.TrustType; import com.griefdefender.api.claim.TrustType;
import com.griefdefender.api.claim.TrustTypes; 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.flag.Flags;
import com.griefdefender.api.permission.option.Options; import com.griefdefender.api.permission.option.Options;
import com.griefdefender.api.permission.option.type.CreateModeTypes; import com.griefdefender.api.permission.option.type.CreateModeTypes;
@ -52,7 +50,6 @@
import com.griefdefender.claim.GDClaimManager; import com.griefdefender.claim.GDClaimManager;
import com.griefdefender.command.CommandHelper; import com.griefdefender.command.CommandHelper;
import com.griefdefender.configuration.MessageStorage; import com.griefdefender.configuration.MessageStorage;
import com.griefdefender.event.GDBorderClaimEvent;
import com.griefdefender.event.GDCauseStackManager; import com.griefdefender.event.GDCauseStackManager;
import com.griefdefender.internal.provider.WorldEditProvider; import com.griefdefender.internal.provider.WorldEditProvider;
import com.griefdefender.internal.provider.WorldGuardProvider; import com.griefdefender.internal.provider.WorldGuardProvider;
@ -81,7 +78,6 @@
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.Chunk; import org.bukkit.Chunk;
import org.bukkit.GameMode;
import org.bukkit.Location; import org.bukkit.Location;
import org.bukkit.Material; import org.bukkit.Material;
import org.bukkit.World; import org.bukkit.World;
@ -121,12 +117,9 @@
import org.bukkit.event.player.PlayerRespawnEvent; import org.bukkit.event.player.PlayerRespawnEvent;
import org.bukkit.event.player.PlayerTeleportEvent; import org.bukkit.event.player.PlayerTeleportEvent;
import org.bukkit.event.player.PlayerTeleportEvent.TeleportCause; import org.bukkit.event.player.PlayerTeleportEvent.TeleportCause;
import org.bukkit.inventory.EquipmentSlot;
import org.bukkit.inventory.Inventory; import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.InventoryHolder;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;
import java.lang.ref.WeakReference;
import java.time.Instant; import java.time.Instant;
import java.util.HashSet; import java.util.HashSet;
import java.util.Map; import java.util.Map;
@ -326,7 +319,7 @@ public void onPlayerDropItem(PlayerDropItemEvent event) {
final Location location = event.getItemDrop().getLocation(); final Location location = event.getItemDrop().getLocation();
final GDClaim targetClaim = GriefDefenderPlugin.getInstance().dataStore.getClaimAt(location); 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); event.setCancelled(true);
} }
} }
@ -354,7 +347,7 @@ public void onPlayerPickupItem(PlayerPickupItemEvent event) {
final Location location = event.getItem().getLocation(); final Location location = event.getItem().getLocation();
final GDClaim targetClaim = GriefDefenderPlugin.getInstance().dataStore.getClaimAt(location); 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); event.setCancelled(true);
} }
} }
@ -382,7 +375,7 @@ private void onInventoryOpen(Event event, Location location, Object target, Huma
GDTimings.PLAYER_INTERACT_INVENTORY_OPEN_EVENT.stopTiming(); GDTimings.PLAYER_INTERACT_INVENTORY_OPEN_EVENT.stopTiming();
return; 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) { if (result == Tristate.FALSE) {
final Component message = GriefDefenderPlugin.getInstance().messageData.getMessage(MessageStorage.PERMISSION_INVENTORY_OPEN, final Component message = GriefDefenderPlugin.getInstance().messageData.getMessage(MessageStorage.PERMISSION_INVENTORY_OPEN,
ImmutableMap.of( ImmutableMap.of(
@ -416,7 +409,7 @@ public void onPlayerInteractInventoryClick(InventoryClickEvent event) {
} }
final GDPermissionUser user = PermissionHolderCache.getInstance().getOrCreateUser(player.getUniqueId()); 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) { if (result == Tristate.FALSE) {
final Component message = GriefDefenderPlugin.getInstance().messageData.getMessage(MessageStorage.PERMISSION_INTERACT_ITEM, final Component message = GriefDefenderPlugin.getInstance().messageData.getMessage(MessageStorage.PERMISSION_INTERACT_ITEM,
ImmutableMap.of( ImmutableMap.of(
@ -445,7 +438,7 @@ public void onPlayerConsumeItem(PlayerItemConsumeEvent event) {
GDPlayerData playerData = this.dataStore.getOrCreatePlayerData(location.getWorld(), player.getUniqueId()); GDPlayerData playerData = this.dataStore.getOrCreatePlayerData(location.getWorld(), player.getUniqueId());
GDClaim claim = this.dataStore.getClaimAtPlayer(playerData, location); 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) { if (result == Tristate.FALSE) {
final Component message = GriefDefenderPlugin.getInstance().messageData.getMessage(MessageStorage.PERMISSION_ITEM_USE, final Component message = GriefDefenderPlugin.getInstance().messageData.getMessage(MessageStorage.PERMISSION_ITEM_USE,
ImmutableMap.of("item", ItemTypeRegistryModule.getInstance().getNMSKey(itemInUse))); ImmutableMap.of("item", ItemTypeRegistryModule.getInstance().getNMSKey(itemInUse)));
@ -488,12 +481,12 @@ public void onPlayerInteractItem(PlayerInteractEvent event) {
final Location location = clickedBlock == null ? event.getPlayer().getLocation() : clickedBlock.getLocation(); final Location location = clickedBlock == null ? event.getPlayer().getLocation() : clickedBlock.getLocation();
final GDClaim claim = this.dataStore.getClaimAt(location); 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 ((itemPrimaryBlacklisted && ITEM_PERMISSION.equals(GDPermissions.INTERACT_ITEM_PRIMARY)) || (itemSecondaryBlacklisted && ITEM_PERMISSION.equals(GDPermissions.INTERACT_ITEM_SECONDARY))) { if ((itemPrimaryBlacklisted && flag == Flags.INTERACT_ITEM_PRIMARY) || (itemSecondaryBlacklisted && flag == Flags.INTERACT_ITEM_SECONDARY)) {
return; 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, Component message = GriefDefenderPlugin.getInstance().messageData.getMessage(MessageStorage.PERMISSION_INTERACT_ITEM,
ImmutableMap.of( ImmutableMap.of(
"player", claim.getOwnerName(), "player", claim.getOwnerName(),
@ -547,7 +540,7 @@ public void onPlayerInteractEntity(PlayerInteractEntityEvent event) {
} }
final GDClaim claim = this.dataStore.getClaimAt(location); 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, Component message = GriefDefenderPlugin.getInstance().messageData.getMessage(MessageStorage.PERMISSION_INTERACT_ITEM,
ImmutableMap.of( ImmutableMap.of(
"player", claim.getOwnerName(), "player", claim.getOwnerName(),
@ -568,9 +561,9 @@ public void onPlayerInteractEntity(PlayerInteractEntityEvent event) {
GDTimings.PLAYER_INTERACT_ENTITY_SECONDARY_EVENT.startTiming(); GDTimings.PLAYER_INTERACT_ENTITY_SECONDARY_EVENT.startTiming();
final GDClaim claim = this.dataStore.getClaimAt(location); 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) { 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) { if (result == Tristate.FALSE) {
event.setCancelled(true); event.setCancelled(true);
@ -606,7 +599,7 @@ public void onPlayerBucketEvent(PlayerBucketEvent event) {
final GDClaim claim = this.dataStore.getClaimAt(location); final GDClaim claim = this.dataStore.getClaimAt(location);
final TrustType trustType = NMSUtil.getInstance().hasBlockTileEntity(location) ? TrustTypes.CONTAINER : TrustTypes.ACCESSOR; 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) { if (result == Tristate.FALSE) {
event.setCancelled(true); event.setCancelled(true);
GDTimings.PLAYER_INTERACT_BLOCK_SECONDARY_EVENT.stopTiming(); GDTimings.PLAYER_INTERACT_BLOCK_SECONDARY_EVENT.stopTiming();
@ -649,13 +642,13 @@ public void onPlayerInteractBlockPrimary(PlayerInteractEvent event, Player playe
GDTimings.PLAYER_INTERACT_BLOCK_PRIMARY_EVENT.startTiming(); GDTimings.PLAYER_INTERACT_BLOCK_PRIMARY_EVENT.startTiming();
final GDClaim claim = this.dataStore.getClaimAt(location); 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 (result == Tristate.FALSE) {
if (GriefDefenderPlugin.isTargetIdBlacklisted(Flags.BLOCK_BREAK.toString(), clickedBlock.getState(), player.getWorld().getUID())) { if (GriefDefenderPlugin.isTargetIdBlacklisted(Flags.BLOCK_BREAK.toString(), clickedBlock.getState(), player.getWorld().getUID())) {
GDTimings.PLAYER_INTERACT_BLOCK_PRIMARY_EVENT.stopTiming(); GDTimings.PLAYER_INTERACT_BLOCK_PRIMARY_EVENT.stopTiming();
return; 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(); GDTimings.PLAYER_INTERACT_BLOCK_PRIMARY_EVENT.stopTiming();
return; return;
} }
@ -721,11 +714,11 @@ public void onPlayerInteractBlockSecondary(PlayerInteractEvent event) {
trustType = TrustTypes.ACCESSOR; trustType = TrustTypes.ACCESSOR;
} }
if (GDFlags.INTERACT_BLOCK_SECONDARY && playerData != null) { if (GDFlags.INTERACT_BLOCK_SECONDARY && playerData != null) {
String permission = GDPermissions.INTERACT_BLOCK_SECONDARY; Flag flag = Flags.INTERACT_BLOCK_SECONDARY;
if (event.getAction() == Action.PHYSICAL) { 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 (result == Tristate.FALSE) {
// if player is holding an item, check if it can be placed // if player is holding an item, check if it can be placed
if (GDFlags.BLOCK_PLACE && itemInHand != null && itemInHand.getType().isBlock()) { if (GDFlags.BLOCK_PLACE && itemInHand != null && itemInHand.getType().isBlock()) {
@ -733,7 +726,7 @@ public void onPlayerInteractBlockSecondary(PlayerInteractEvent event) {
GDTimings.PLAYER_INTERACT_BLOCK_SECONDARY_EVENT.stopTiming(); GDTimings.PLAYER_INTERACT_BLOCK_SECONDARY_EVENT.stopTiming();
return; 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(); GDTimings.PLAYER_INTERACT_BLOCK_SECONDARY_EVENT.stopTiming();
return; return;
} }
@ -789,6 +782,21 @@ public void onPlayerTeleport(PlayerTeleportEvent event) {
final Location destination = event.getTo(); final Location destination = event.getTo();
final GDPlayerData playerData = GriefDefenderPlugin.getInstance().dataStore.getOrCreatePlayerData(player.getWorld(), player.getUniqueId()); final GDPlayerData playerData = GriefDefenderPlugin.getInstance().dataStore.getOrCreatePlayerData(player.getWorld(), player.getUniqueId());
final GDClaim sourceClaim = this.dataStore.getClaimAtPlayer(playerData, player.getLocation()); 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 // Handle BorderClaimEvent
if (!CommonEntityEventHandler.getInstance().onEntityMove(event, sourceLocation, destination, player)) { if (!CommonEntityEventHandler.getInstance().onEntityMove(event, sourceLocation, destination, player)) {
event.setCancelled(true); event.setCancelled(true);
@ -800,7 +808,7 @@ public void onPlayerTeleport(PlayerTeleportEvent event) {
final Component message = GriefDefenderPlugin.getInstance().messageData.getMessage(MessageStorage.PERMISSION_PORTAL_EXIT, final Component message = GriefDefenderPlugin.getInstance().messageData.getMessage(MessageStorage.PERMISSION_PORTAL_EXIT,
ImmutableMap.of( ImmutableMap.of(
"player", sourceClaim.getOwnerName())); "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) { if (player != null) {
GriefDefenderPlugin.sendMessage(player, message); GriefDefenderPlugin.sendMessage(player, message);
} }
@ -808,7 +816,7 @@ public void onPlayerTeleport(PlayerTeleportEvent event) {
event.setCancelled(true); event.setCancelled(true);
GDTimings.ENTITY_TELEPORT_EVENT.stopTiming(); GDTimings.ENTITY_TELEPORT_EVENT.stopTiming();
return; 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) { if (player != null) {
GriefDefenderPlugin.sendMessage(player, message); GriefDefenderPlugin.sendMessage(player, message);
} }
@ -831,7 +839,7 @@ public void onPlayerTeleport(PlayerTeleportEvent event) {
final Component message = GriefDefenderPlugin.getInstance().messageData.getMessage(MessageStorage.PERMISSION_PORTAL_ENTER, final Component message = GriefDefenderPlugin.getInstance().messageData.getMessage(MessageStorage.PERMISSION_PORTAL_ENTER,
ImmutableMap.of( ImmutableMap.of(
"player", toClaim.getOwnerName())); "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) { if (player != null) {
GriefDefenderPlugin.sendMessage(player, message); GriefDefenderPlugin.sendMessage(player, message);
} }
@ -839,7 +847,7 @@ public void onPlayerTeleport(PlayerTeleportEvent event) {
event.setCancelled(true); event.setCancelled(true);
GDTimings.ENTITY_TELEPORT_EVENT.stopTiming(); GDTimings.ENTITY_TELEPORT_EVENT.stopTiming();
return; 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) { if (player != null) {
GriefDefenderPlugin.sendMessage(player, message); GriefDefenderPlugin.sendMessage(player, message);
} }
@ -1460,7 +1468,8 @@ private boolean investigateClaim(PlayerInteractEvent event, Player player, Block
GDTimings.PLAYER_INVESTIGATE_CLAIM.startTiming(); GDTimings.PLAYER_INVESTIGATE_CLAIM.startTiming();
GDClaim claim = null; GDClaim claim = null;
if (event.getAction() == Action.LEFT_CLICK_AIR || event.getAction() == Action.RIGHT_CLICK_AIR) { 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 (player.isSneaking()) {
if (!playerData.canIgnoreClaim(claim) && !player.hasPermission(GDPermissions.VISUALIZE_CLAIMS_NEARBY)) { if (!playerData.canIgnoreClaim(claim) && !player.hasPermission(GDPermissions.VISUALIZE_CLAIMS_NEARBY)) {
GriefDefenderPlugin.sendMessage(player, MessageCache.getInstance().PERMISSION_VISUAL_CLAIMS_NEARBY); GriefDefenderPlugin.sendMessage(player, MessageCache.getInstance().PERMISSION_VISUAL_CLAIMS_NEARBY);
@ -1469,7 +1478,7 @@ private boolean investigateClaim(PlayerInteractEvent event, Player player, Block
} }
Location nearbyLocation = playerData.lastValidInspectLocation != null ? playerData.lastValidInspectLocation : player.getLocation(); 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)); int height = (int) (playerData.lastValidInspectLocation != null ? playerData.lastValidInspectLocation.getBlockY() : PlayerUtil.getInstance().getEyeHeight(player));
boolean hideBorders = this.worldEditProvider != null && boolean hideBorders = this.worldEditProvider != null &&
@ -1529,8 +1538,7 @@ private boolean investigateClaim(PlayerInteractEvent event, Player player, Block
return true; return true;
} }
private GDClaim findNearbyClaim(Player player) { private GDClaim findNearbyClaim(Player player, int maxDistance) {
int maxDistance = GriefDefenderPlugin.getInstance().maxInspectionDistance;
BlockRay blockRay = BlockRay.from(player).distanceLimit(maxDistance).build(); BlockRay blockRay = BlockRay.from(player).distanceLimit(maxDistance).build();
GDPlayerData playerData = GriefDefenderPlugin.getInstance().dataStore.getOrCreatePlayerData(player.getWorld(), player.getUniqueId()); GDPlayerData playerData = GriefDefenderPlugin.getInstance().dataStore.getOrCreatePlayerData(player.getWorld(), player.getUniqueId());
GDClaim claim = null; GDClaim claim = null;

View File

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

View File

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

View File

@ -30,12 +30,14 @@
public class ContextGroups { public class ContextGroups {
// Entity groups // 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_AMBIENT = new Context(ContextKeys.SOURCE, ContextGroupKeys.AMBIENT);
public static final Context SOURCE_ANIMAL = new Context(ContextKeys.SOURCE, ContextGroupKeys.ANIMAL); 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_AQUATIC = new Context(ContextKeys.SOURCE, ContextGroupKeys.AQUATIC);
public static final Context SOURCE_MISC = new Context(ContextKeys.SOURCE, ContextGroupKeys.MISC); 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_MONSTER = new Context(ContextKeys.SOURCE, ContextGroupKeys.MONSTER);
public static final Context SOURCE_VEHICLE = new Context(ContextKeys.SOURCE, ContextGroupKeys.VEHICLE); 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_AMBIENT = new Context(ContextKeys.TARGET, ContextGroupKeys.AMBIENT);
public static final Context TARGET_ANIMAL = new Context(ContextKeys.TARGET, ContextGroupKeys.ANIMAL); public static final Context TARGET_ANIMAL = new Context(ContextKeys.TARGET, ContextGroupKeys.ANIMAL);
public static final Context TARGET_AQUATIC = new Context(ContextKeys.TARGET, ContextGroupKeys.AQUATIC); public static final Context TARGET_AQUATIC = new Context(ContextKeys.TARGET, ContextGroupKeys.AQUATIC);

View File

@ -46,8 +46,11 @@
import com.griefdefender.api.permission.flag.FlagDefinition; import com.griefdefender.api.permission.flag.FlagDefinition;
import com.griefdefender.api.permission.flag.Flags; import com.griefdefender.api.permission.flag.Flags;
import com.griefdefender.api.permission.option.Option; 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.CreateModeType;
import com.griefdefender.api.permission.option.type.CreateModeTypes; 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.EventResultCache;
import com.griefdefender.cache.MessageCache; import com.griefdefender.cache.MessageCache;
import com.griefdefender.cache.PermissionHolderCache; import com.griefdefender.cache.PermissionHolderCache;
@ -76,7 +79,6 @@
import org.bukkit.Location; import org.bukkit.Location;
import org.bukkit.Material; import org.bukkit.Material;
import org.bukkit.OfflinePlayer; import org.bukkit.OfflinePlayer;
import org.bukkit.World;
import org.bukkit.block.Block; import org.bukkit.block.Block;
import org.bukkit.block.BlockState; import org.bukkit.block.BlockState;
import org.bukkit.block.CreatureSpawner; import org.bukkit.block.CreatureSpawner;
@ -139,37 +141,37 @@ public GDPermissionHolder getDefaultHolder() {
@Override @Override
public Tristate getActiveFlagPermissionValue(Claim claim, Subject subject, Flag flag, Object source, Object target, Set<Context> contexts, TrustType type, boolean checkOverride) { 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) { public Tristate getFinalPermission(Event event, Location location, Claim claim, Flag flag, Object source, Object target, GDPermissionHolder permissionHolder) {
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) { public Tristate getFinalPermission(Event event, Location location, Claim claim, Flag flag, Object source, Object target, Player player) {
final GDPermissionHolder permissionHolder = PermissionHolderCache.getInstance().getOrCreateUser(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); 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) { public Tristate getFinalPermission(Event event, Location location, Claim claim, Flag flag, Object source, Object target, GDPermissionHolder permissionHolder, boolean checkOverride) {
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, 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); 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) { 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, flagPermission, source, target, permissionHolder, type, 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) { if (claim == null) {
return Tristate.TRUE; return Tristate.TRUE;
} }
@ -218,8 +220,7 @@ public Tristate getFinalPermission(Event event, Location location, Set<Context>
contexts.add(((GDClaim) claim).getWorldContext()); contexts.add(((GDClaim) claim).getWorldContext());
this.eventContexts = contexts; this.eventContexts = contexts;
this.eventPlayerData = playerData; this.eventPlayerData = playerData;
final String targetPermission = flag.getPermission();
String targetPermission = flagPermission;
/* if (!targetId.isEmpty()) { /* if (!targetId.isEmpty()) {
String[] parts = targetId.split(":"); String[] parts = targetId.split(":");
String targetMod = parts[0]; String targetMod = parts[0];
@ -236,11 +237,28 @@ public Tristate getFinalPermission(Event event, Location location, Set<Context>
// targetPermission += "." + targetId + targetMeta; // targetPermission += "." + targetId + targetMeta;
}*/ }*/
targetPermission = StringUtils.replace(targetPermission, ":", "."); if (flag == Flags.ENTITY_SPAWN) {
// If player can ignore admin claims and is currently ignoring , allow // Check spawn limit
/*if (playerData != null && playerData.ignoreAdminClaims && playerData.canIgnoreClaim(claim)) { final int spawnLimit = GDPermissionManager.getInstance().getInternalOptionValue(TypeToken.of(Integer.class), GriefDefenderPlugin.DEFAULT_HOLDER, Options.SPAWN_LIMIT, claim, contexts);
return processResult(claim, targetPermission, "ignore", Tristate.TRUE, user); 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)) { if (user != null && playerData != null && !playerData.debugClaimPermissions && playerData.canIgnoreClaim(claim)) {
return processResult(claim, targetPermission, "ignore", Tristate.TRUE, user); return processResult(claim, targetPermission, "ignore", Tristate.TRUE, user);
@ -668,6 +686,11 @@ public boolean isObjectIdBanned(GDClaim claim, String id, BanType type) {
} }
public void addCustomEntityTypeContexts(Entity targetEntity, Set<Context> contexts, GDEntityType type, boolean isSource) { 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 // check vehicle
if (targetEntity instanceof Vehicle) { if (targetEntity instanceof Vehicle) {
if (isSource) { if (isSource) {
@ -827,12 +850,16 @@ private Set<Context> populateEventSourceTargetContext(Set<Context> contexts, Str
if (!id.contains(":")) { if (!id.contains(":")) {
id = "minecraft:" + id; id = "minecraft:" + id;
} }
final String[] parts = id.split(":");
final String modId = parts[0];
if (isSource) { if (isSource) {
this.eventSourceId = id.toLowerCase(); this.eventSourceId = id.toLowerCase();
contexts.add(new Context("source", this.eventSourceId)); contexts.add(new Context("source", this.eventSourceId));
contexts.add(new Context("source", modId + ":any"));
} else { } else {
this.eventTargetId = id.toLowerCase(); this.eventTargetId = id.toLowerCase();
contexts.add(new Context("target", this.eventTargetId)); contexts.add(new Context("target", this.eventTargetId));
contexts.add(new Context("target", modId + ":any"));
} }
return contexts; return contexts;
} }
@ -845,6 +872,12 @@ private String populateEventSourceTarget(String id, boolean isSource) {
if (!id.contains(":")) { if (!id.contains(":")) {
id = "minecraft:" + id; 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) { if (isSource) {
this.eventSourceId = id.toLowerCase(); this.eventSourceId = id.toLowerCase();
} else { } else {
@ -869,13 +902,14 @@ public CompletableFuture<PermissionResult> clearAllFlagPermissions(Subject subje
return result; 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(); final Set<Context> contextSet = mapEntry.getKey();
if (contextSet.contains(claim.getContext())) { for (Context context : contextSet) {
subject.getSubjectData().clearPermissions(contextSet); if (context.getValue().equals(subject.getIdentifier())) {
continue; PermissionUtil.getInstance().clearPermissions((GDPermissionHolder) subject, context);
}
}
} }
}*/
result.complete(new GDPermissionResult(ResultTypes.SUCCESS)); result.complete(new GDPermissionResult(ResultTypes.SUCCESS));
return result; return result;
@ -900,8 +934,7 @@ public CompletableFuture<PermissionResult> clearFlagPermissions(Subject subject,
return result; return result;
} }
//contexts.add(claim.getWorld().getContext()); PermissionUtil.getInstance().clearPermissions((GDPermissionHolder) subject, contexts);
//subject.getSubjectData().clearPermissions(contexts);
result.complete(new GDPermissionResult(ResultTypes.SUCCESS)); result.complete(new GDPermissionResult(ResultTypes.SUCCESS));
return result; return result;
} }
@ -1043,9 +1076,9 @@ public <T> T getInternalOptionValue(TypeToken<T> type, GDPermissionHolder holder
// check claim // check claim
if (claim != null) { if (claim != null) {
contexts.add(claim.getContext()); contexts.add(claim.getContext());
String value = PermissionUtil.getInstance().getOptionValue(holder, option, contexts); final T value = this.getOptionActualValue(type, holder, option, contexts);
if (value != null) { if (value != null) {
return this.getOptionTypeValue(type, value); return value;
} }
contexts.remove(claim.getContext()); contexts.remove(claim.getContext());
} }
@ -1053,18 +1086,18 @@ public <T> T getInternalOptionValue(TypeToken<T> type, GDPermissionHolder holder
// check claim type // check claim type
if (claimType != null) { if (claimType != null) {
contexts.add(claimType.getContext()); contexts.add(claimType.getContext());
String value = PermissionUtil.getInstance().getOptionValue(holder, option, contexts); final T value = this.getOptionActualValue(type, holder, option, contexts);
if (value != null) { if (value != null) {
return this.getOptionTypeValue(type, value); return value;
} }
contexts.remove(claimType.getContext()); contexts.remove(claimType.getContext());
} }
} }
// Check only active contexts // Check only active contexts
String value = PermissionUtil.getInstance().getOptionValue(holder, option, contexts); T value = this.getOptionActualValue(type, holder, option, contexts);
if (value != null) { if (value != null) {
return this.getOptionTypeValue(type, value); return value;
} }
// Check type/global default context // Check type/global default context
@ -1072,9 +1105,9 @@ public <T> T getInternalOptionValue(TypeToken<T> type, GDPermissionHolder holder
contexts.add(claimType.getDefaultContext()); contexts.add(claimType.getDefaultContext());
} }
contexts.add(ClaimContexts.GLOBAL_DEFAULT_CONTEXT); contexts.add(ClaimContexts.GLOBAL_DEFAULT_CONTEXT);
value = PermissionUtil.getInstance().getOptionValue(holder, option, contexts); value = this.getOptionActualValue(type, holder, option, contexts);
if (value != null) { if (value != null) {
return this.getOptionTypeValue(type, value); return value;
} }
contexts.remove(ClaimContexts.GLOBAL_DEFAULT_CONTEXT); contexts.remove(ClaimContexts.GLOBAL_DEFAULT_CONTEXT);
if (claimType != null) { if (claimType != null) {
@ -1089,6 +1122,21 @@ public <T> T getInternalOptionValue(TypeToken<T> type, GDPermissionHolder holder
return option.getDefaultValue(); 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) { private <T> T getOptionTypeValue(TypeToken<T> type, String value) {
if (type.getRawType().isAssignableFrom(Double.class)) { if (type.getRawType().isAssignableFrom(Double.class)) {
return (T) Double.valueOf(value); return (T) Double.valueOf(value);
@ -1130,6 +1178,13 @@ private <T> T getOptionTypeValue(TypeToken<T> type, String value) {
if (value.equalsIgnoreCase("undefined")) { if (value.equalsIgnoreCase("undefined")) {
return (T) CreateModeTypes.AREA; return (T) CreateModeTypes.AREA;
} }
if (value.equalsIgnoreCase("volume")) {
return (T) CreateModeTypes.VOLUME;
}
if (value.equalsIgnoreCase("area")) {
return (T) CreateModeTypes.AREA;
}
int permValue = 0; int permValue = 0;
try { try {
permValue = Integer.parseInt(value); permValue = Integer.parseInt(value);
@ -1141,6 +1196,16 @@ private <T> T getOptionTypeValue(TypeToken<T> type, String value) {
} }
return (T) (permValue == 1 ? CreateModeTypes.VOLUME : CreateModeTypes.AREA); 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)) { if (type.getRawType().isAssignableFrom(Boolean.class)) {
return (T) Boolean.valueOf(Boolean.parseBoolean(value)); return (T) Boolean.valueOf(Boolean.parseBoolean(value));
} }

View File

@ -97,6 +97,8 @@ public class GDPermissions {
// flags // flags
public static final String USER_CLAIM_FLAGS = "griefdefender.user.claim.flag"; 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 = "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_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_PLAYER = "griefdefender.user.claim.command.flag.player";
public static final String COMMAND_FLAGS_GROUP = "griefdefender.user.claim.command.flag.group"; 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_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_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_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_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_CLAIM_BASE = "griefdefender.admin.claim.command.delete.base";
public static final String COMMAND_DELETE_CLAIMS = "griefdefender.admin.claim.command.delete-claims"; 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_BUILDER = "griefdefender.trust.1.2";
public static final String TRUST_MANAGER = "griefdefender.trust.1"; 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) { public static String getTrustPermission(TrustType type) {
if (type == TrustTypes.ACCESSOR) { if (type == TrustTypes.ACCESSOR) {
return GDPermissions.TRUST_ACCESSOR; return GDPermissions.TRUST_ACCESSOR;

View File

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

View File

@ -22,14 +22,16 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE. * THE SOFTWARE.
*/ */
package com.griefdefender.configuration.category; package com.griefdefender.permission.option;
import ninja.leaping.configurate.objectmapping.Setting; import com.griefdefender.api.permission.Context;
import ninja.leaping.configurate.objectmapping.serialize.ConfigSerializable; import com.griefdefender.api.permission.ContextKeys;
@ConfigSerializable public class OptionContexts {
public class PvpCategory extends ConfigCategory {
@Setting(value = "combat-timeout", comment = "How long combat is considered to continue after the most recent damage.") public static final Context COMMAND_RUNAS_CONSOLE = new Context(ContextKeys.RUN_AS, "console");
public int combatTimeout = 15; 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.permission.GDPermissionHolder; import com.griefdefender.permission.GDPermissionHolder;
import com.griefdefender.permission.GDPermissionResult; import com.griefdefender.permission.GDPermissionResult;
import com.griefdefender.permission.GDPermissionUser; import com.griefdefender.permission.GDPermissionUser;
import com.griefdefender.registry.OptionRegistryModule;
import net.kyori.text.TextComponent;
import net.luckperms.api.LuckPerms; import net.luckperms.api.LuckPerms;
import net.luckperms.api.cacheddata.CachedMetaData; import net.luckperms.api.cacheddata.CachedMetaData;
import net.luckperms.api.cacheddata.CachedPermissionData; import net.luckperms.api.cacheddata.CachedPermissionData;
@ -76,6 +77,7 @@
import java.util.TreeMap; import java.util.TreeMap;
import java.util.UUID; import java.util.UUID;
import java.util.Map.Entry; import java.util.Map.Entry;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
@ -105,6 +107,8 @@ public int compare(Set<Context> s1, Set<Context> s2) {
private final LuckPerms luckPermsApi; private final LuckPerms luckPermsApi;
private final static DefaultDataQueryOrderFunction DEFAULT_DATA_QUERY_ORDER = new DefaultDataQueryOrderFunction(); 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() { public LuckPermsProvider() {
this.luckPermsApi = Bukkit.getServicesManager().getRegistration(LuckPerms.class).getProvider(); this.luckPermsApi = Bukkit.getServicesManager().getRegistration(LuckPerms.class).getProvider();
@ -114,6 +118,11 @@ public LuckPerms getApi() {
return this.luckPermsApi; return this.luckPermsApi;
} }
@Override
public String getServerName() {
return this.luckPermsApi.getServerName();
}
@Override @Override
public boolean hasGroupSubject(String identifier) { public boolean hasGroupSubject(String identifier) {
return this.getGroupSubject(identifier) != null; return this.getGroupSubject(identifier) != null;
@ -373,7 +382,6 @@ public Map<Set<Context>, Map<String, Boolean>> getPermanentPermissions(GDPermiss
return new HashMap<>(); return new HashMap<>();
} }
//final @NonNull Collection<Node> nodes = permissionHolder.resolveInheritedNodes(QueryOptions.nonContextual());
final Collection<Node> nodes = permissionHolder.data().toCollection(); final Collection<Node> nodes = permissionHolder.data().toCollection();
Map<Set<Context>, Map<String, Boolean>> permanentPermissionMap = new TreeMap<Set<Context>, Map<String, Boolean>>(CONTEXT_COMPARATOR); Map<Set<Context>, Map<String, Boolean>> permanentPermissionMap = new TreeMap<Set<Context>, Map<String, Boolean>>(CONTEXT_COMPARATOR);
for (Node node : nodes) { for (Node node : nodes) {
@ -718,44 +726,65 @@ public String getOptionValue(GDPermissionHolder holder, Option option, Set<Conte
return metaData.getMetaValue(option.getPermission()); 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; DataMutateResult result = null;
ImmutableContextSet set = this.getLPContexts(contexts).immutableCopy(); ImmutableContextSet set = this.getLPContexts(contexts).immutableCopy();
final PermissionHolder permissionHolder = this.getLuckPermsHolder(holder); final PermissionHolder permissionHolder = this.getLuckPermsHolder(holder);
if (permissionHolder == null) { if (permissionHolder == null) {
return new GDPermissionResult(ResultTypes.FAILURE); return RESULT_FAILURE;
} }
// Always unset existing meta first final Option option = OptionRegistryModule.getInstance().getById(key).orElse(null);
final Node currentNode = this.luckPermsApi.getNodeBuilderRegistry().forMeta().key(permission).context(set).build(); if (option == null) {
result = permissionHolder.data().remove(currentNode); 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 (!value.equalsIgnoreCase("undefined")) {
if (!option.multiValued()) {
this.clearMeta(permissionHolder, key, set);
}
result = permissionHolder.data().add(node); result = permissionHolder.data().add(node);
} } else {
if (result != null && result.wasSuccessful()) { this.clearMeta(permissionHolder, key, set);
this.savePermissionHolder(permissionHolder); 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());
} }
public PermissionResult setPermissionValue(GDPermissionHolder holder, Flag flag, Tristate value, Set<Context> contexts) { return RESULT_FAILURE;
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; DataMutateResult result = null;
ImmutableContextSet set = this.getLPContexts(contexts).immutableCopy(); ImmutableContextSet set = this.getLPContexts(contexts).immutableCopy();
final Node node = this.luckPermsApi.getNodeBuilderRegistry().forPermission().permission(permission).value(value.asBoolean()).context(set).build(); final Node node = this.luckPermsApi.getNodeBuilderRegistry().forPermission().permission(permission).value(value.asBoolean()).context(set).build();
final PermissionHolder permissionHolder = this.getLuckPermsHolder(holder); final PermissionHolder permissionHolder = this.getLuckPermsHolder(holder);
if (permissionHolder == null) { if (permissionHolder == null) {
return false; return RESULT_FAILURE;
} }
if (value == Tristate.UNDEFINED) { if (value == Tristate.UNDEFINED) {
@ -766,11 +795,6 @@ public boolean setPermissionValue(GDPermissionHolder holder, String permission,
if (result.wasSuccessful()) { if (result.wasSuccessful()) {
if (permissionHolder instanceof Group) { 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 // If a group is changed, we invalidate all cache
PermissionHolderCache.getInstance().invalidateAllPermissionCache(); PermissionHolderCache.getInstance().invalidateAllPermissionCache();
} else { } else {
@ -778,9 +802,14 @@ public boolean setPermissionValue(GDPermissionHolder holder, String permission,
PermissionHolderCache.getInstance().getOrCreatePermissionCache(holder).invalidateAll(); PermissionHolderCache.getInstance().getOrCreatePermissionCache(holder).invalidateAll();
} }
if (save) {
this.savePermissionHolder(permissionHolder); this.savePermissionHolder(permissionHolder);
} }
return result.wasSuccessful();
return new GDPermissionResult(ResultTypes.SUCCESS, TextComponent.builder().append(result.name()).build());
}
return new GDPermissionResult(ResultTypes.FAILURE, TextComponent.builder().append(result.name()).build());
} }
public void setTransientOption(GDPermissionHolder holder, String permission, String value, Set<Context> contexts) { public void setTransientOption(GDPermissionHolder holder, String permission, String value, Set<Context> contexts) {
@ -801,7 +830,7 @@ public void setTransientPermission(GDPermissionHolder holder, String permission,
return; 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); permissionHolder.transientData().add(node);
} }
@ -821,6 +850,20 @@ public void refreshCachedData(GDPermissionHolder holder) {
permissionHolder.getCachedData().invalidate(); 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) { public Set<Context> getGDContexts(ContextSet contexts) {
final Set<Context> gdContexts = new HashSet<>(); final Set<Context> gdContexts = new HashSet<>();
contexts.forEach(entry -> { contexts.forEach(entry -> {
@ -849,6 +892,10 @@ public Tristate getGDTristate(net.luckperms.api.util.Tristate state) {
return Tristate.UNDEFINED; 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 { private static class DefaultDataQueryOrderFunction implements DataQueryOrderFunction {
@Override @Override

View File

@ -28,6 +28,7 @@
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
import java.util.UUID; import java.util.UUID;
import java.util.concurrent.CompletableFuture;
import org.checkerframework.checker.nullness.qual.Nullable; import org.checkerframework.checker.nullness.qual.Nullable;
@ -49,6 +50,13 @@
*/ */
public interface PermissionProvider { public interface PermissionProvider {
/**
* Get server name.
*
* @return The server name
*/
String getServerName();
/** /**
* Checks if the group identifier exists. * Checks if the group identifier exists.
* *
@ -273,6 +281,18 @@ public interface PermissionProvider {
*/ */
String getOptionValue(GDPermissionHolder holder, Option option, Set<Context> contexts); 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. * Sets an option and value with contexts to a holder.
* *
@ -293,7 +313,23 @@ public interface PermissionProvider {
* @param contexts The contexts * @param contexts The contexts
* @return The permission result * @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. * Sets a permission and value with contexts to a holder.
@ -304,7 +340,21 @@ public interface PermissionProvider {
* @param contexts The contexts * @param contexts The contexts
* @return Whether the set permission operation was successful * @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. * Sets a transient option and value with contexts to a holder.
@ -334,4 +384,12 @@ public interface PermissionProvider {
* @param holder The holder * @param holder The holder
*/ */
void refreshCachedData(GDPermissionHolder 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.plugin.Plugin; import org.bukkit.plugin.Plugin;
import org.checkerframework.checker.nullness.qual.Nullable; import org.checkerframework.checker.nullness.qual.Nullable;
import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
import java.util.HashMap; import java.util.HashMap;
import java.util.LinkedList; import java.util.LinkedList;
@ -219,6 +220,11 @@ private boolean pValIntegerToBool(@Nullable Integer value) {
// - Implement API // - Implement API
@Override
public String getServerName() {
return pex.getConfig().getServerTags().get(0);
}
@Override @Override
public boolean hasGroupSubject(String identifier) { public boolean hasGroupSubject(String identifier) {
return pex.getSubjects(PermissionsEx.SUBJECTS_GROUP).isRegistered(identifier).join(); return pex.getSubjects(PermissionsEx.SUBJECTS_GROUP).isRegistered(identifier).join();
@ -393,22 +399,18 @@ public String getOptionValue(GDPermissionHolder holder, Option option, Set<Conte
return holderToPEXSubject(holder).getOption(contextsGDToPEX(contexts), option.getPermission()).orElse(null); 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 @Override
public PermissionResult setOptionValue(GDPermissionHolder holder, String permission, String value, Set<Context> contexts) { 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(); 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 @Override
public void setTransientOption(GDPermissionHolder holder, String permission, String value, Set<Context> contexts) { public void setTransientOption(GDPermissionHolder holder, String permission, String value, Set<Context> contexts) {
holderToPEXSubject(holder).transientData().update(data -> data.setOption(contextsGDToPEX(contexts), permission, value)); holderToPEXSubject(holder).transientData().update(data -> data.setOption(contextsGDToPEX(contexts), permission, value));
@ -424,5 +426,16 @@ public void refreshCachedData(GDPermissionHolder holder) {
holderToPEXSubject(holder).data().getCache().invalidate(holder.getIdentifier()); holderToPEXSubject(holder).data().getCache().invalidate(holder.getIdentifier());
holderToPEXSubject(holder).transientData().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 java.util.Collection; import java.util.Collection;
import java.util.HashMap; import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Locale; import java.util.Locale;
import java.util.Map; import java.util.Map;
import java.util.Optional; import java.util.Optional;
import java.util.Set;
@SuppressWarnings("rawtypes") @SuppressWarnings("rawtypes")
public class OptionRegistryModule implements CatalogRegistryModule<Option> { public class OptionRegistryModule implements CatalogRegistryModule<Option> {
@ -111,7 +114,8 @@ public void registerDefaults() {
this.createKey("griefdefender:radius-inspect", "radius-inspect", Integer.class); this.createKey("griefdefender:radius-inspect", "radius-inspect", Integer.class);
this.createKey("griefdefender:raid", "raid", Boolean.class); this.createKey("griefdefender:raid", "raid", Boolean.class);
this.createKey("griefdefender:spawn-limit", "spawn-limit", Integer.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-flight", "player-deny-flight", Boolean.class);
this.createKey("griefdefender:player-deny-godmode", "player-deny-godmode", Boolean.class); this.createKey("griefdefender:player-deny-godmode", "player-deny-godmode", Boolean.class);
this.createKey("griefdefender:player-deny-hunger", "player-deny-hunger", Boolean.class); this.createKey("griefdefender:player-deny-hunger", "player-deny-hunger", Boolean.class);
@ -120,9 +124,12 @@ public void registerDefaults() {
this.createKey("griefdefender:player-keep-inventory", "player-keep-inventory", Tristate.class); 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-keep-level", "player-keep-level", Tristate.class);
this.createKey("griefdefender:player-teleport-delay", "player-teleport-delay", Integer.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:player-weather", "player-weather", WeatherType.class);
this.createKey("griefdefender:pvp", "pvp", Tristate.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 -> { RegistryHelper.mapFields(Options.class, input -> {
final String name = input.replace("_", "-"); final String name = input.replace("_", "-");
@ -131,7 +138,15 @@ public void registerDefaults() {
} }
private void createKey(String id, String name, Class<?> clazz) { 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 @Override

View File

@ -31,7 +31,6 @@
import com.griefdefender.GDPlayerData; import com.griefdefender.GDPlayerData;
import com.griefdefender.GriefDefenderPlugin; import com.griefdefender.GriefDefenderPlugin;
import com.griefdefender.api.GriefDefender; import com.griefdefender.api.GriefDefender;
import com.griefdefender.api.Tristate;
import com.griefdefender.api.claim.Claim; import com.griefdefender.api.claim.Claim;
import com.griefdefender.api.claim.ClaimContexts; import com.griefdefender.api.claim.ClaimContexts;
import com.griefdefender.api.claim.ClaimResult; import com.griefdefender.api.claim.ClaimResult;
@ -54,7 +53,6 @@
import com.griefdefender.event.GDRemoveClaimEvent; import com.griefdefender.event.GDRemoveClaimEvent;
import com.griefdefender.internal.util.VecHelper; import com.griefdefender.internal.util.VecHelper;
import com.griefdefender.permission.GDPermissionUser; import com.griefdefender.permission.GDPermissionUser;
import com.griefdefender.permission.GDPermissions;
import com.griefdefender.permission.flag.FlagContexts; import com.griefdefender.permission.flag.FlagContexts;
import com.griefdefender.permission.option.GDOption; import com.griefdefender.permission.option.GDOption;
import com.griefdefender.registry.FlagRegistryModule; import com.griefdefender.registry.FlagRegistryModule;
@ -386,11 +384,11 @@ private void setDefaultFlags(Set<Context> contexts, Map<String, Boolean> default
if (flag == null) { if (flag == null) {
continue; 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) { if (flag == Flags.ENTITY_DAMAGE) {
// allow monsters to be attacked by default // allow monsters to be attacked by default
contexts.add(FlagContexts.TARGET_TYPE_MONSTER); 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); contexts.remove(FlagContexts.TARGET_TYPE_MONSTER);
} }
} }

View File

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

View File

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

View File

@ -36,6 +36,10 @@
import com.griefdefender.api.permission.flag.Flags; import com.griefdefender.api.permission.flag.Flags;
import com.griefdefender.api.permission.option.Options; import com.griefdefender.api.permission.option.Options;
import com.griefdefender.api.permission.option.type.CreateModeTypes; 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.cache.PermissionHolderCache;
import com.griefdefender.claim.GDClaim; import com.griefdefender.claim.GDClaim;
import com.griefdefender.configuration.MessageStorage; import com.griefdefender.configuration.MessageStorage;
@ -50,6 +54,7 @@
import net.kyori.text.format.TextColor; import net.kyori.text.format.TextColor;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.GameMode;
import org.bukkit.Location; import org.bukkit.Location;
import org.bukkit.Material; import org.bukkit.Material;
import org.bukkit.OfflinePlayer; import org.bukkit.OfflinePlayer;
@ -60,6 +65,7 @@
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;
import java.util.HashSet; import java.util.HashSet;
import java.util.Map;
import java.util.UUID; import java.util.UUID;
import org.checkerframework.checker.nullness.qual.Nullable; import org.checkerframework.checker.nullness.qual.Nullable;
@ -67,6 +73,16 @@
public class PlayerUtil { public class PlayerUtil {
private static BlockFace[] faces = { BlockFace.NORTH, BlockFace.EAST, BlockFace.SOUTH, BlockFace.WEST}; 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; private static PlayerUtil instance;

View File

@ -3,15 +3,15 @@
"libraries": [ "libraries": [
{ {
"name": "com.griefdefender:adapter:1.12.2", "name": "com.griefdefender:adapter:1.12.2",
"sha1": "c17a212f288203daca365bd2f03253a2af35c751", "sha1": "c6d1ac2ce3a205ae687a0493769b8b2dcc51b2cc",
"path": "com/griefdefender/adapter/1.12.2-SNAPSHOT/adapter-1.12.2-20191007.192753-20.jar", "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-20191007.192753-20.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", "name": "com.griefdefender:api:1.0.0",
"sha1": "fb161e9877869876bbf07131c1a7682d37c6664d", "sha1": "a87c88ecf7f4aaa4cc18decef9f0cbb013a0e602",
"path": "com/griefdefender/api/1.0.0-SNAPSHOT/api-1.0.0-20191219.230903-12.jar", "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-20191219.230903-12.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", "name": "com.griefdefender:reflect-helper:1.0",

View File

@ -3,15 +3,15 @@
"libraries": [ "libraries": [
{ {
"name": "com.griefdefender:adapter:1.13.2", "name": "com.griefdefender:adapter:1.13.2",
"sha1": "e29bb897bb2e65650019ba1d457bd2d57253e4ac", "sha1": "115d51a291c4b2ac6ca3d2b4f62fa7dd9ee44980",
"path": "com/griefdefender/adapter/1.13.2-SNAPSHOT/adapter-1.13.2-20191030.135953-20.jar", "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-20191030.135953-20.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", "name": "com.griefdefender:api:1.0.0",
"sha1": "fb161e9877869876bbf07131c1a7682d37c6664d", "sha1": "a87c88ecf7f4aaa4cc18decef9f0cbb013a0e602",
"path": "com/griefdefender/api/1.0.0-SNAPSHOT/api-1.0.0-20191219.230903-12.jar", "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-20191219.230903-12.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", "name": "com.griefdefender:reflect-helper:1.0",

View File

@ -3,15 +3,15 @@
"libraries": [ "libraries": [
{ {
"name": "com.griefdefender:adapter:1.14.2", "name": "com.griefdefender:adapter:1.14.2",
"sha1": "a1d0d15ed46106f71f0a87e3033bf4e27d2115bd", "sha1": "d12b32993aca93f60800a0ba1d1f0f343dd378cc",
"path": "com/griefdefender/adapter/1.14.2-SNAPSHOT/adapter-1.14.2-20191030.135904-20.jar", "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-20191030.135904-20.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", "name": "com.griefdefender:api:1.0.0",
"sha1": "fb161e9877869876bbf07131c1a7682d37c6664d", "sha1": "a87c88ecf7f4aaa4cc18decef9f0cbb013a0e602",
"path": "com/griefdefender/api/1.0.0-SNAPSHOT/api-1.0.0-20191219.230903-12.jar", "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-20191219.230903-12.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", "name": "com.griefdefender:reflect-helper:1.0",

View File

@ -3,15 +3,15 @@
"libraries": [ "libraries": [
{ {
"name": "com.griefdefender:adapter:1.14.3", "name": "com.griefdefender:adapter:1.14.3",
"sha1": "5861e4469cdfdc25a4c424727d71d15186b92441", "sha1": "6811ded786ecddb3424c94b3a9856f3d2c2d000a",
"path": "com/griefdefender/adapter/1.14.3-SNAPSHOT/adapter-1.14.3-20191030.135827-21.jar", "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-20191030.135827-21.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", "name": "com.griefdefender:api:1.0.0",
"sha1": "fb161e9877869876bbf07131c1a7682d37c6664d", "sha1": "a87c88ecf7f4aaa4cc18decef9f0cbb013a0e602",
"path": "com/griefdefender/api/1.0.0-SNAPSHOT/api-1.0.0-20191219.230903-12.jar", "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-20191219.230903-12.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", "name": "com.griefdefender:reflect-helper:1.0",

View File

@ -3,15 +3,15 @@
"libraries": [ "libraries": [
{ {
"name": "com.griefdefender:adapter:1.14.4", "name": "com.griefdefender:adapter:1.14.4",
"sha1": "0e014588faa41ae12d5feb77b47b607578c73ed7", "sha1": "79eb86d1c62fe70af428e7ac0cc5279790990ff0",
"path": "com/griefdefender/adapter/1.14.4-SNAPSHOT/adapter-1.14.4-20191030.135735-19.jar", "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-20191030.135735-19.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", "name": "com.griefdefender:api:1.0.0",
"sha1": "fb161e9877869876bbf07131c1a7682d37c6664d", "sha1": "a87c88ecf7f4aaa4cc18decef9f0cbb013a0e602",
"path": "com/griefdefender/api/1.0.0-SNAPSHOT/api-1.0.0-20191219.230903-12.jar", "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-20191219.230903-12.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", "name": "com.griefdefender:reflect-helper:1.0",

View File

@ -3,15 +3,15 @@
"libraries": [ "libraries": [
{ {
"name": "com.griefdefender:adapter:1.15", "name": "com.griefdefender:adapter:1.15",
"sha1": "0748b075602fa13448f94cfb2fca0b2db58795b6", "sha1": "d7c5414752ad767508174a7de908d93fd3695492",
"path": "com/griefdefender/adapter/1.15-SNAPSHOT/adapter-1.15-20191211.164543-1.jar", "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-20191211.164543-1.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", "name": "com.griefdefender:api:1.0.0",
"sha1": "fb161e9877869876bbf07131c1a7682d37c6664d", "sha1": "a87c88ecf7f4aaa4cc18decef9f0cbb013a0e602",
"path": "com/griefdefender/api/1.0.0-SNAPSHOT/api-1.0.0-20191219.230903-12.jar", "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-20191219.230903-12.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", "name": "com.griefdefender:reflect-helper:1.0",

View File

@ -3,15 +3,15 @@
"libraries": [ "libraries": [
{ {
"name": "com.griefdefender:adapter:1.8.8", "name": "com.griefdefender:adapter:1.8.8",
"sha1": "fb0b9235fb0d18bab3b63fa56207d156c40faf6e", "sha1": "78a79391b94339c64ea31cfcc257291e9314822c",
"path": "com/griefdefender/adapter/1.8.8-SNAPSHOT/adapter-1.8.8-20191007.192948-20.jar", "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-20191007.192948-20.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", "name": "com.griefdefender:api:1.0.0",
"sha1": "fb161e9877869876bbf07131c1a7682d37c6664d", "sha1": "a87c88ecf7f4aaa4cc18decef9f0cbb013a0e602",
"path": "com/griefdefender/api/1.0.0-SNAPSHOT/api-1.0.0-20191219.230903-12.jar", "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-20191219.230903-12.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", "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-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-subdivision="&aUnterteilungsmodus. Unterteile deine existierendes Grundstück. Nutze &f/modebasic&a zum Verlassen."
mode-town="&aStadt-Erstellungsmodus aktiviert." 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-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-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." 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-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-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-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-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-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." 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-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-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-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-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-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-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-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="&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-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." 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-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-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-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-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-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." 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-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-edit-claim="&cDu hast keine Berechtigung dieses Grundstück zu bearbeiten."
permission-fire-spread="&cDu hast keine Berechtigung Feuer zu legen." 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-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-overrides="&cDu hast keine Berechtigung überschreibende Einstellungen zu verwalten."
permission-flag-use="&cDu hast keine Berechtigung diese Einstellung zu nutzen." 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." 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-not-found="&cKonnte kein Plugin &b{id}&c finden."
plugin-reload="&aGriefDefender neu geladen." plugin-reload="&aGriefDefender neu geladen."
pvp-claim-not-allowed="&aPvP ist auf diesem Grundstück nicht erlaubt." 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-source-not-allowed="&aPvP ist für dich nicht erlaubt."
pvp-target-not-allowed="&aDu kannst keine Spieler attackieren, die PvP ausgestellt haben." 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." 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-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-subdivision="&aSubdivision creation mode enabled. Use &f/modebasic&a to exit."
mode-town="&aTown creation mode enabled." 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-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-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." 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-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-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-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-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-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." 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-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-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-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-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-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-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-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="&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-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." 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-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-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-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-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-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." 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-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-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-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-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-overrides="&cYou don't have permission to manage flag overrides."
permission-flag-use="&cYou don't have permission to use this flag." 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." 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-not-found="&cCould not locate plugin with id &b{id}&c."
plugin-reload="&aGriefDefender has been reloaded." plugin-reload="&aGriefDefender has been reloaded."
pvp-claim-not-allowed="&aYou are not allowed to PvP in this claim." 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-source-not-allowed="&aYou are not allowed to PvP."
pvp-target-not-allowed="&aYou cannot attack players who are not participating in 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." 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-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-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." 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-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-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." 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-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-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-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-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-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." 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-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-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-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-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-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-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-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="&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-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." 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-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-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-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-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-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}'" 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-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-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-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-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-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-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." 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-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." 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-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-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." 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." 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-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-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é." 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-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-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." 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-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-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-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-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-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." 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-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-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-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-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-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-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-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="&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-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." 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-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-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-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-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-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." 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-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-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-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-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-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-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." 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-not-found="&cImpossible de localiser le plug-in avec l'id &b{id}&c."
plugin-reload="&aGriefDefender a été rechargé." plugin-reload="&aGriefDefender a été rechargé."
pvp-claim-not-allowed="&aTu n'as pas le droit de PvP dans cette protection." 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-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." 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." 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-nature="&aГотов восстанавливать природу! ПКМ для начала, &f/modebasic&c - для выхода из режима."
mode-subdivision="&aВключён режим создания суб-регионов. Используйте лопату, чтобы создавать суб-регионы в существующих регионах. Воспользуйтесь &f/modebasic&a, чтобы выйти из этого режима." mode-subdivision="&aВключён режим создания суб-регионов. Используйте лопату, чтобы создавать суб-регионы в существующих регионах. Воспользуйтесь &f/modebasic&a, чтобы выйти из этого режима."
mode-town="&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-delay="&aКоличество дней до того, как свежесозданный регион может быть удалён."
option-description-abandon-return-ratio="&aДоля базовых блоков региона, возвращаемых игроку при удалении региона." option-description-abandon-return-ratio="&aДоля базовых блоков региона, возвращаемых игроку при удалении региона."
option-description-blocks-accrued-per-hour="&aЗарабатываемые блоки в час.\n&dПримечание&f: См. /playerinfo." 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-x="&aМинимальный размер региона по оси x."
option-description-min-size-y="&aМинимальный размер региона по оси y." option-description-min-size-y="&aМинимальный размер региона по оси y."
option-description-min-size-z="&aМинимальный размер региона по оси z." 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-flight="&aОпределяет, может ли игрок летать в регионе.\n&dПримечание&f: не даёт игрокам возможность летать, только удаляет её при необходимости. Даёт наибольшую совместимость с другими плагинами."
option-description-player-deny-godmode="&aОпределяет, может ли игрок быть в режиме бога в регионе.\n&dПримечание&f: не даёт игрокам возможность входить в режим бога, только удаляет её при необходимости. Даёт наибольшую совместимость с другими плагинами." option-description-player-deny-godmode="&aОпределяет, может ли игрок быть в режиме бога в регионе.\n&dПримечание&f: не даёт игрокам возможность входить в режим бога, только удаляет её при необходимости. Даёт наибольшую совместимость с другими плагинами."
option-description-player-deny-hunger="&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-health-regen="&aОпределяет скорость восстановления здоровья игроков в регионе.\n&dПримечание&f: не имеет эффекта на игроков с полным запасом здоровья. \n&dПримечание&f: значение &6-1&f отключает эту опцию."
option-description-player-keep-inventory="&aОпределяет, сохранит ли игрок содержимое своего инвентаря при смерти в регионе." option-description-player-keep-inventory="&aОпределяет, сохранит ли игрок содержимое своего инвентаря при смерти в регионе."
option-description-player-keep-level="&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-walk-speed="&aОпределяет скорость ходьбы игроков в регионе.\n&dПримечание&f: значение &6-1&f отключает эту опцию."
option-description-player-weather="&aОпределяет погоду для игрока в регионе." 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-inspect="&aРадиус в блоках для поиска регионов поблизости при инспектировании."
option-description-radius-list="&aРадиус в блоках для составления списка регионов поблизости." option-description-radius-list="&aРадиус в блоках для составления списка регионов поблизости."
option-description-spawn-limit="&aОпределяет предел появления сущностей в регионе для определённых контекстов."
option-description-tax-expiration="&aКоличество дней без оплаты налогов, после которых регион будет заморожен.\n&dПримечание&f: заморозка означает отсутствие доступа к строительству и инвентарям в регионе до совершения оплаты." option-description-tax-expiration="&aКоличество дней без оплаты налогов, после которых регион будет заморожен.\n&dПримечание&f: заморозка означает отсутствие доступа к строительству и инвентарям в регионе до совершения оплаты."
option-description-tax-expiration-days-keep="&aКоличество дней после заморозки региона до его удаления.\n&dПримечание&f: по истечении срока регион может быть просто удалён или откачен на состояние при создании. Это зависит от настроек сервера. Свяжитесь с администратором для дополнительной информации." option-description-tax-expiration-days-keep="&aКоличество дней после заморозки региона до его удаления.\n&dПримечание&f: по истечении срока регион может быть просто удалён или откачен на состояние при создании. Это зависит от настроек сервера. Свяжитесь с администратором для дополнительной информации."
option-description-tax-rate="&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-not-set="&a{option}&f не установлена.\nПрименяется стандартное значение &a{value}&f."
option-override-not-supported="&cРегионы вида &f{type}&c не поддерживают переопределение опций." option-override-not-supported="&cРегионы вида &f{type}&c не поддерживают переопределение опций."
option-player-deny-flight="&cУ вас нет разрешения на полёт в этом регионе. Вы были телепортированы на безопасное место на земле." option-player-deny-flight="&cУ вас нет разрешения на полёт в этом регионе. Вы были телепортированы на безопасное место на земле."
option-requires-contexts="&cЭта опция требует следующие контексты: '&a{contexts}&c'."
option-reset-success="&aОпции региона успешно откачены на стандартные значения." option-reset-success="&aОпции региона успешно откачены на стандартные значения."
option-set-target="&aОпция &b{option}&a вида &b{type}&a с контекстами &7{contexts}&a установлена в значение {value}&a для &6{target}&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." option-ui-click-toggle="Нажмите здесь, чтобы переключить опцию &f{option}&r."
@ -494,7 +508,9 @@ GriefDefender {
permission-cuboid="&cУ вас нет разрешения на создание/изменение размера базовых регионов в 3D-режиме." permission-cuboid="&cУ вас нет разрешения на создание/изменение размера базовых регионов в 3D-режиме."
permission-edit-claim="&cУ вас нет разрешения на изменение этого региона." permission-edit-claim="&cУ вас нет разрешения на изменение этого региона."
permission-fire-spread="&cУ вас нет разрешения на поджигание блоков в этом регионе." permission-fire-spread="&cУ вас нет разрешения на поджигание блоков в этом регионе."
permission-flag-arg="&cУ вас нет разрешения на использование команды flag с аргументами."
permission-flag-defaults="&cУ вас нет разрешения на изменение стандартных значений флагов." permission-flag-defaults="&cУ вас нет разрешения на изменение стандартных значений флагов."
permission-flag-gui="&cУ вас нет разрешения на использование GUI флагов."
permission-flag-overrides="&cУ вас нет разрешения на редактирование переопределённых значений флагов." permission-flag-overrides="&cУ вас нет разрешения на редактирование переопределённых значений флагов."
permission-flag-use="&cУ вас нет разрешения на использование этого флага." permission-flag-use="&cУ вас нет разрешения на использование этого флага."
permission-flow-liquid="&cУ вас нет разрешения на разливание жидкостей в этом регионе." permission-flow-liquid="&cУ вас нет разрешения на разливание жидкостей в этом регионе."
@ -551,6 +567,7 @@ GriefDefender {
plugin-not-found="&cНе удалось найти плагин с идентификатором &b{id}&c." plugin-not-found="&cНе удалось найти плагин с идентификатором &b{id}&c."
plugin-reload="&aGriefDefender перезагружен." plugin-reload="&aGriefDefender перезагружен."
pvp-claim-not-allowed="&aВ этом регионе сражения между игроками запрещены." pvp-claim-not-allowed="&aВ этом регионе сражения между игроками запрещены."
pvp-in-combat-not-allowed="&aВы не можете выполнить это действие, находясь в PvP-драке. Вы должны быть в безопасности ещё &6{time-remaining}&a секунд."
pvp-source-not-allowed="&aУ вас нет разрешения на сражение с другим игроком." pvp-source-not-allowed="&aУ вас нет разрешения на сражение с другим игроком."
pvp-target-not-allowed="&aВы не можете атаковать игроков, которые не могут участвовать в сражениях." pvp-target-not-allowed="&aВы не можете атаковать игроков, которые не могут участвовать в сражениях."
registry-block-not-found="&cБлок {id}&c не найден в реестре." registry-block-not-found="&cБлок {id}&c не найден в реестре."

View File

@ -27,17 +27,16 @@
import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet; import com.google.common.collect.ImmutableSet;
import com.google.common.reflect.TypeToken; import com.google.common.reflect.TypeToken;
import com.griefdefender.api.Tristate;
import com.griefdefender.api.claim.Claim; import com.griefdefender.api.claim.Claim;
import com.griefdefender.api.claim.ClaimType; import com.griefdefender.api.claim.ClaimType;
import com.griefdefender.api.claim.ShovelType; import com.griefdefender.api.claim.ShovelType;
import com.griefdefender.api.claim.ShovelTypes; import com.griefdefender.api.claim.ShovelTypes;
import com.griefdefender.api.data.PlayerData; import com.griefdefender.api.data.PlayerData;
import com.griefdefender.api.permission.Context; 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.Options;
import com.griefdefender.api.permission.option.type.CreateModeType; import com.griefdefender.api.permission.option.type.CreateModeType;
import com.griefdefender.api.permission.option.type.CreateModeTypes; 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.EventResultCache;
import com.griefdefender.cache.MessageCache; import com.griefdefender.cache.MessageCache;
import com.griefdefender.cache.PermissionHolderCache; import com.griefdefender.cache.PermissionHolderCache;
@ -53,9 +52,7 @@
import org.spongepowered.api.Sponge; import org.spongepowered.api.Sponge;
import org.spongepowered.api.block.BlockSnapshot; import org.spongepowered.api.block.BlockSnapshot;
import org.spongepowered.api.data.Transaction; 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.Player;
import org.spongepowered.api.entity.living.player.User;
import org.spongepowered.api.scheduler.Task; import org.spongepowered.api.scheduler.Task;
import org.spongepowered.api.service.economy.Currency; import org.spongepowered.api.service.economy.Currency;
import org.spongepowered.api.service.economy.account.Account; import org.spongepowered.api.service.economy.account.Account;
@ -64,6 +61,7 @@
import java.lang.ref.WeakReference; import java.lang.ref.WeakReference;
import java.math.BigDecimal; import java.math.BigDecimal;
import java.time.Duration;
import java.time.Instant; import java.time.Instant;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashSet; import java.util.HashSet;
@ -122,6 +120,7 @@ public class GDPlayerData implements PlayerData {
public Location<World> teleportLocation; public Location<World> teleportLocation;
public Instant lastPvpTimestamp; public Instant lastPvpTimestamp;
public WeatherType lastWeatherType;
// cached global option values // cached global option values
public int minClaimLevel; public int minClaimLevel;
@ -519,45 +518,6 @@ public boolean canIgnoreClaim(Claim claim) {
return this.ignoreBasicClaims; 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 @Override
public int getMaxAccruedClaimBlocks() { public int getMaxAccruedClaimBlocks() {
return GDPermissionManager.getInstance().getInternalOptionValue(TypeToken.of(Integer.class), this.getSubject(), Options.MAX_ACCRUED_BLOCKS); return GDPermissionManager.getInstance().getInternalOptionValue(TypeToken.of(Integer.class), this.getSubject(), Options.MAX_ACCRUED_BLOCKS);
@ -670,13 +630,18 @@ public double getTotalTax() {
return totalTax; return totalTax;
} }
public boolean inPvpCombat(World world) { public boolean inPvpCombat() {
if (this.lastPvpTimestamp == null) { final Player player = this.getSubject().getOnlinePlayer();
if (this.lastPvpTimestamp == null || player == null) {
return false; return false;
} }
final Instant now = Instant.now(); 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)) { if (this.lastPvpTimestamp.plusSeconds(combatTimeout).isBefore(now)) {
this.lastPvpTimestamp = null; this.lastPvpTimestamp = null;
return false; return false;
@ -685,6 +650,34 @@ public boolean inPvpCombat(World world) {
return true; 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() { public void onDisconnect() {
this.visualBlocks.clear(); this.visualBlocks.clear();
this.claimMode = false; this.claimMode = false;

View File

@ -286,7 +286,6 @@ public class GriefDefenderPlugin {
public GDBlockType createVisualBlock; public GDBlockType createVisualBlock;
public GDItemType modificationTool; public GDItemType modificationTool;
public GDItemType investigationTool; public GDItemType investigationTool;
public int maxInspectionDistance = 100;
public static boolean debugLogging = false; public static boolean debugLogging = false;
public static boolean debugActive = false; public static boolean debugActive = false;
@ -942,7 +941,6 @@ public void loadConfig() {
this.createVisualBlock = BlockTypeRegistryModule.getInstance().getById(BaseStorage.globalConfig.getConfig().visual.claimCreateStartBlock).orElse(defaultCreateVisualBlock); 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.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.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) { if (this.dataStore != null) {
for (World world : Sponge.getGame().getServer().getWorlds()) { for (World world : Sponge.getGame().getServer().getWorlds()) {
DimensionType dimType = world.getProperties().getDimensionType(); DimensionType dimType = world.getProperties().getDimensionType();

View File

@ -249,6 +249,7 @@ public static MessageCache getInstance() {
public Component FLAG_UI_OVERRIDE_NO_PERMISSION; public Component FLAG_UI_OVERRIDE_NO_PERMISSION;
public Component FLAG_UI_RETURN_FLAGS; public Component FLAG_UI_RETURN_FLAGS;
public Component LABEL_ACCESSORS; public Component LABEL_ACCESSORS;
public Component LABEL_ALL;
public Component LABEL_AREA; public Component LABEL_AREA;
public Component LABEL_BLOCKS; public Component LABEL_BLOCKS;
public Component LABEL_BUILDERS; public Component LABEL_BUILDERS;
@ -292,6 +293,8 @@ public static MessageCache getInstance() {
public Component MODE_NATURE; public Component MODE_NATURE;
public Component MODE_SUBDIVISION; public Component MODE_SUBDIVISION;
public Component MODE_TOWN; 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_DELAY;
public Component OPTION_DESCRIPTION_ABANDON_RETURN_RATIO; public Component OPTION_DESCRIPTION_ABANDON_RETURN_RATIO;
public Component OPTION_DESCRIPTION_BLOCKS_ACCRUED_PER_HOUR; public Component OPTION_DESCRIPTION_BLOCKS_ACCRUED_PER_HOUR;
@ -311,7 +314,8 @@ public static MessageCache getInstance() {
public Component OPTION_DESCRIPTION_MIN_SIZE_X; public Component OPTION_DESCRIPTION_MIN_SIZE_X;
public Component OPTION_DESCRIPTION_MIN_SIZE_Y; public Component OPTION_DESCRIPTION_MIN_SIZE_Y;
public Component OPTION_DESCRIPTION_MIN_SIZE_Z; 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_FLIGHT;
public Component OPTION_DESCRIPTION_PLAYER_DENY_GODMODE; public Component OPTION_DESCRIPTION_PLAYER_DENY_GODMODE;
public Component OPTION_DESCRIPTION_PLAYER_DENY_HUNGER; public Component OPTION_DESCRIPTION_PLAYER_DENY_HUNGER;
@ -326,7 +330,7 @@ public static MessageCache getInstance() {
public Component OPTION_DESCRIPTION_TAX_EXPIRATION; public Component OPTION_DESCRIPTION_TAX_EXPIRATION;
public Component OPTION_DESCRIPTION_TAX_EXPIRATION_DAYS_KEEP; public Component OPTION_DESCRIPTION_TAX_EXPIRATION_DAYS_KEEP;
public Component OPTION_DESCRIPTION_TAX_RATE; public Component OPTION_DESCRIPTION_TAX_RATE;
public Component OPTION_PLAYER_DENY_FLIGHT; public Component OPTION_UI_CLICK_REMOVE;
public Component OWNER_ADMIN; public Component OWNER_ADMIN;
public Component PERMISSION_ASSIGN_WITHOUT_HAVING; public Component PERMISSION_ASSIGN_WITHOUT_HAVING;
public Component PERMISSION_CLAIM_CREATE; public Component PERMISSION_CLAIM_CREATE;
@ -345,6 +349,8 @@ public static MessageCache getInstance() {
public Component PERMISSION_FIRE_SPREAD; public Component PERMISSION_FIRE_SPREAD;
public Component PERMISSION_FLAG_DEFAULTS; public Component PERMISSION_FLAG_DEFAULTS;
public Component PERMISSION_FLAG_OVERRIDES; public Component PERMISSION_FLAG_OVERRIDES;
public Component PERMISSION_FLAG_ARG;
public Component PERMISSION_FLAG_GUI;
public Component PERMISSION_FLAG_USE; public Component PERMISSION_FLAG_USE;
public Component PERMISSION_FLOW_LIQUID; public Component PERMISSION_FLOW_LIQUID;
public Component PERMISSION_GLOBAL_OPTION; public Component PERMISSION_GLOBAL_OPTION;
@ -607,6 +613,7 @@ public void loadCache() {
FLAG_UI_OVERRIDE_NO_PERMISSION = MessageStorage.MESSAGE_DATA.getMessage("flag-ui-override-no-permission"); 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"); FLAG_UI_RETURN_FLAGS = MessageStorage.MESSAGE_DATA.getMessage("flag-ui-return-flags");
LABEL_ACCESSORS = MessageStorage.MESSAGE_DATA.getMessage("label-accessors"); 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_AREA = MessageStorage.MESSAGE_DATA.getMessage("label-area");
LABEL_BLOCKS = MessageStorage.MESSAGE_DATA.getMessage("label-blocks"); LABEL_BLOCKS = MessageStorage.MESSAGE_DATA.getMessage("label-blocks");
LABEL_BUILDERS = MessageStorage.MESSAGE_DATA.getMessage("label-builders"); LABEL_BUILDERS = MessageStorage.MESSAGE_DATA.getMessage("label-builders");
@ -669,7 +676,8 @@ public void loadCache() {
OPTION_DESCRIPTION_MIN_SIZE_X = MessageStorage.MESSAGE_DATA.getMessage("option-description-min-size-x"); 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_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_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_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_GODMODE = MessageStorage.MESSAGE_DATA.getMessage("option-description-player-deny-godmode");
OPTION_DESCRIPTION_PLAYER_DENY_HUNGER = MessageStorage.MESSAGE_DATA.getMessage("option-description-player-deny-hunger"); OPTION_DESCRIPTION_PLAYER_DENY_HUNGER = MessageStorage.MESSAGE_DATA.getMessage("option-description-player-deny-hunger");
@ -684,7 +692,9 @@ public void loadCache() {
OPTION_DESCRIPTION_TAX_EXPIRATION = MessageStorage.MESSAGE_DATA.getMessage("option-description-tax-expiration"); 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_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_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"); OWNER_ADMIN = MessageStorage.MESSAGE_DATA.getMessage("owner-admin");
PERMISSION_ASSIGN_WITHOUT_HAVING = MessageStorage.MESSAGE_DATA.getMessage("permission-assign-without-having"); PERMISSION_ASSIGN_WITHOUT_HAVING = MessageStorage.MESSAGE_DATA.getMessage("permission-assign-without-having");
PERMISSION_CLAIM_CREATE = MessageStorage.MESSAGE_DATA.getMessage("permission-claim-create"); PERMISSION_CLAIM_CREATE = MessageStorage.MESSAGE_DATA.getMessage("permission-claim-create");
@ -703,6 +713,8 @@ public void loadCache() {
PERMISSION_FIRE_SPREAD = MessageStorage.MESSAGE_DATA.getMessage("permission-fire-spread"); PERMISSION_FIRE_SPREAD = MessageStorage.MESSAGE_DATA.getMessage("permission-fire-spread");
PERMISSION_FLAG_DEFAULTS = MessageStorage.MESSAGE_DATA.getMessage("permission-flag-defaults"); PERMISSION_FLAG_DEFAULTS = MessageStorage.MESSAGE_DATA.getMessage("permission-flag-defaults");
PERMISSION_FLAG_OVERRIDES = MessageStorage.MESSAGE_DATA.getMessage("permission-flag-overrides"); 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_FLAG_USE = MessageStorage.MESSAGE_DATA.getMessage("permission-flag-use");
PERMISSION_FLOW_LIQUID = MessageStorage.MESSAGE_DATA.getMessage("permission-flow-liquid"); PERMISSION_FLOW_LIQUID = MessageStorage.MESSAGE_DATA.getMessage("permission-flow-liquid");
PERMISSION_GLOBAL_OPTION = MessageStorage.MESSAGE_DATA.getMessage("permission-global-option"); PERMISSION_GLOBAL_OPTION = MessageStorage.MESSAGE_DATA.getMessage("permission-global-option");

View File

@ -49,7 +49,6 @@
import com.griefdefender.api.claim.TrustType; import com.griefdefender.api.claim.TrustType;
import com.griefdefender.api.claim.TrustTypes; import com.griefdefender.api.claim.TrustTypes;
import com.griefdefender.api.data.ClaimData; import com.griefdefender.api.data.ClaimData;
import com.griefdefender.api.event.EventCause;
import com.griefdefender.api.permission.Context; import com.griefdefender.api.permission.Context;
import com.griefdefender.api.permission.option.Options; import com.griefdefender.api.permission.option.Options;
import com.griefdefender.cache.MessageCache; import com.griefdefender.cache.MessageCache;
@ -57,7 +56,6 @@
import com.griefdefender.configuration.ClaimDataConfig; import com.griefdefender.configuration.ClaimDataConfig;
import com.griefdefender.configuration.ClaimStorageData; import com.griefdefender.configuration.ClaimStorageData;
import com.griefdefender.configuration.IClaimData; import com.griefdefender.configuration.IClaimData;
import com.griefdefender.configuration.MessageDataConfig;
import com.griefdefender.configuration.MessageStorage; import com.griefdefender.configuration.MessageStorage;
import com.griefdefender.configuration.TownDataConfig; import com.griefdefender.configuration.TownDataConfig;
import com.griefdefender.configuration.TownStorageData; import com.griefdefender.configuration.TownStorageData;
@ -77,7 +75,6 @@
import com.griefdefender.permission.GDPermissions; import com.griefdefender.permission.GDPermissions;
import com.griefdefender.registry.TrustTypeRegistryModule; import com.griefdefender.registry.TrustTypeRegistryModule;
import com.griefdefender.storage.BaseStorage; import com.griefdefender.storage.BaseStorage;
import com.griefdefender.storage.FileStorage;
import com.griefdefender.util.EconomyUtil; import com.griefdefender.util.EconomyUtil;
import com.griefdefender.util.PermissionUtil; import com.griefdefender.util.PermissionUtil;
import com.griefdefender.util.SpongeContexts; import com.griefdefender.util.SpongeContexts;
@ -85,9 +82,12 @@
import net.kyori.text.Component; import net.kyori.text.Component;
import net.kyori.text.TextComponent; import net.kyori.text.TextComponent;
import net.kyori.text.format.TextColor; import net.kyori.text.format.TextColor;
import net.kyori.text.serializer.plain.PlainComponentSerializer;
import org.checkerframework.checker.nullness.qual.Nullable; import org.checkerframework.checker.nullness.qual.Nullable;
import org.spongepowered.api.Sponge; import org.spongepowered.api.Sponge;
import org.spongepowered.api.command.CommandSource; 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.Player;
import org.spongepowered.api.entity.living.player.User; import org.spongepowered.api.entity.living.player.User;
import org.spongepowered.api.event.cause.Cause; import org.spongepowered.api.event.cause.Cause;
@ -378,6 +378,14 @@ public Optional<Component> getName() {
return this.claimData.getName(); 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() { public Component getFriendlyNameType() {
return this.getFriendlyNameType(false); return this.getFriendlyNameType(false);
} }
@ -531,6 +539,20 @@ public Component getOwnerName() {
return TextComponent.of(this.getOwnerPlayerData().getPlayerName()); 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 @Override
public boolean contains(Vector3i pos, boolean excludeChildren) { public boolean contains(Vector3i pos, boolean excludeChildren) {
return this.contains(pos.getX(), pos.getY(), pos.getZ(), excludeChildren, null, false); return this.contains(pos.getX(), pos.getY(), pos.getZ(), excludeChildren, null, false);
@ -2026,6 +2048,19 @@ public ClaimResult validateClaimType(ClaimType type, UUID newOwnerUUID, GDPlayer
return new GDClaimResult(ClaimResultType.SUCCESS); 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 @Override
public boolean equals(Object o) { public boolean equals(Object o) {
if (this == o) { if (this == o) {

View File

@ -113,6 +113,8 @@ protected ClaimFlagBase(ClaimSubjectType type) {
public void execute(Player player, String[] args) throws InvalidCommandArgument { public void execute(Player player, String[] args) throws InvalidCommandArgument {
final GDPermissionUser src = PermissionHolderCache.getInstance().getOrCreateUser(player); final GDPermissionUser src = PermissionHolderCache.getInstance().getOrCreateUser(player);
final GDPermissionHolder commandSubject = subject; final GDPermissionHolder commandSubject = subject;
final GDPlayerData playerData = src.getInternalPlayerData();
final GDClaim claim = GriefDefenderPlugin.getInstance().dataStore.getClaimAtPlayer(playerData, player.getLocation());
String commandFlag = null; String commandFlag = null;
String target = null; String target = null;
String value = null; String value = null;
@ -123,12 +125,21 @@ public void execute(Player player, String[] args) throws InvalidCommandArgument
contexts = arguments.substring(index, arguments.length()); contexts = arguments.substring(index, arguments.length());
} }
if (args.length > 0) { 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) { if (args.length < 3) {
throw new InvalidCommandArgument(); throw new InvalidCommandArgument();
} }
commandFlag = args[0]; commandFlag = args[0];
target = args[1]; target = args[1];
value = args[2]; 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); final Flag flag = FlagRegistryModule.getInstance().getById(commandFlag).orElse(null);
if (commandFlag != null && flag == null) { if (commandFlag != null && flag == null) {
@ -149,9 +160,7 @@ public void execute(Player player, String[] args) throws InvalidCommandArgument
} }
} }
final GDPlayerData playerData = GriefDefenderPlugin.getInstance().dataStore.getOrCreatePlayerData(player.getWorld(), player.getUniqueId()); final Set<Context> contextSet = CauseContextHelper.generateContexts(flag.getPermission(), player, claim, contexts);
GDClaim claim = GriefDefenderPlugin.getInstance().dataStore.getClaimAtPlayer(playerData, player.getLocation());
final Set<Context> contextSet = CauseContextHelper.generateContexts(player, claim, contexts);
if (contextSet == null) { if (contextSet == null) {
return; return;
} }
@ -911,7 +920,6 @@ private Consumer<CommandSource> createCustomFlagConsumer(GDPermissionUser src, G
newValue = Tristate.UNDEFINED; newValue = Tristate.UNDEFINED;
} }
PermissionResult result = null;
final Flag flag = flagData.getFlag(); final Flag flag = flagData.getFlag();
GDFlagPermissionEvent.Set event = new GDFlagPermissionEvent.Set(this.subject, flagData.getFlag(), newValue, newContexts); GDFlagPermissionEvent.Set event = new GDFlagPermissionEvent.Set(this.subject, flagData.getFlag(), newValue, newContexts);
GriefDefender.getEventManager().post(event); GriefDefender.getEventManager().post(event);
@ -919,8 +927,11 @@ private Consumer<CommandSource> createCustomFlagConsumer(GDPermissionUser src, G
return; 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(); GDCauseStackManager.getInstance().popCause();
showCustomFlags(src, claim, displayType); showCustomFlags(src, claim, displayType);
}; };

View File

@ -91,6 +91,8 @@
import java.util.UUID; import java.util.UUID;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import java.util.function.Consumer; import java.util.function.Consumer;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@SuppressWarnings({ "unchecked", "rawtypes" }) @SuppressWarnings({ "unchecked", "rawtypes" })
public abstract class ClaimOptionBase extends BaseCommand { public abstract class ClaimOptionBase extends BaseCommand {
@ -121,17 +123,31 @@ public void execute(Player player, String[] args) throws InvalidCommandArgument
throw new InvalidCommandArgument(); throw new InvalidCommandArgument();
} }
commandOption = args[0]; commandOption = args[0];
// Check for quoted string
Pattern pattern = Pattern.compile("\"(.*)\"");
Matcher matcher = pattern.matcher(arguments);
if (matcher.find()) {
value = matcher.group(1);
} else {
value = args[1]; value = args[1];
} }
}
Option option = null; Option<?> option = null;
if (commandOption != null) { if (commandOption != null) {
option = GriefDefender.getRegistry().getType(Option.class, commandOption).orElse(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( TextAdapter.sendComponent(player, MessageStorage.MESSAGE_DATA.getMessage(MessageStorage.OPTION_NOT_FOUND, ImmutableMap.of(
"option", commandOption))); "option", commandOption)));
return; 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()); final GDPlayerData playerData = GriefDefenderPlugin.getInstance().dataStore.getOrCreatePlayerData(player.getWorld(), player.getUniqueId());
@ -142,7 +158,7 @@ public void execute(Player player, String[] args) throws InvalidCommandArgument
return; return;
} }
} else if (!claim.isTown() && !playerData.canManageAdminClaims && !playerData.canIgnoreClaim(claim)) { } 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; return;
} }
if (option != null) { if (option != null) {
@ -165,10 +181,32 @@ public void execute(Player player, String[] args) throws InvalidCommandArgument
} }
} }
final Set<Context> contextSet = CauseContextHelper.generateContexts(player, claim, contexts); final Set<Context> contextSet = CauseContextHelper.generateContexts(option.getPermission(), player, claim, contexts);
if (contextSet == null) { if (contextSet == null) {
return; 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 (claim != null) {
if (commandOption == null && value == null && player.hasPermission(GDPermissions.COMMAND_LIST_CLAIM_OPTIONS)) { if (commandOption == null && value == null && player.hasPermission(GDPermissions.COMMAND_LIST_CLAIM_OPTIONS)) {
@ -521,7 +559,11 @@ private Component getClickableOptionComponent(GDPermissionUser src, GDClaim clai
} }
} }
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); Component optionContexts = UIHelper.getFriendlyContextString(claim, contexts);
String currentValue = optionHolder.getValue(); String currentValue = optionHolder.getValue();
TextColor color = optionHolder.getColor(); TextColor color = optionHolder.getColor();
@ -549,11 +591,12 @@ private Component getClickableOptionComponent(GDPermissionUser src, GDClaim clai
} }
if (hasEditPermission) { if (hasEditPermission) {
if (!option.getAllowedType().isAssignableFrom(Integer.class) && !option.getAllowedType().isAssignableFrom(Double.class)) { 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)))); builder.clickEvent(ClickEvent.runCommand(GDCallbackHolder.getInstance().createCallbackRunCommand(newOptionValueConsumer(src, claim, option, optionHolder, contexts, displayType, false))));
} else { } else {
builder.append(TextComponent.builder() builder.append(TextComponent.builder().append(TextComponent.of(" >").decoration(TextDecoration.BOLD, true)));
.append(TextComponent.of(" >").decoration(TextDecoration.BOLD, true)) this.appendContexts(builder, contexts);
.clickEvent(ClickEvent.runCommand(GDCallbackHolder.getInstance().createCallbackRunCommand(newOptionValueConsumer(src, claim, option, optionHolder, contexts, displayType, false))))); builder.clickEvent(ClickEvent.runCommand(GDCallbackHolder.getInstance().createCallbackRunCommand(newOptionValueConsumer(src, claim, option, optionHolder, contexts, displayType, false))));
} }
if (option.getAllowedType().isAssignableFrom(String.class)) { if (option.getAllowedType().isAssignableFrom(String.class)) {
@ -568,9 +611,51 @@ private Component getClickableOptionComponent(GDPermissionUser src, GDClaim clai
"value", TextComponent.of(currentValue).color(TextColor.GOLD)))).build())); "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(); 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) { private boolean containsDefaultContext(Set<Context> contexts) {
for (Context context : contexts) { for (Context context : contexts) {
if (context.getKey().contains("gd_claim_default")) { if (context.getKey().contains("gd_claim_default")) {
@ -638,7 +723,7 @@ private Consumer<CommandSource> newOptionValueConsumer(GDPermissionUser src, GDC
if (value == null || value == WeatherTypes.UNDEFINED) { if (value == null || value == WeatherTypes.UNDEFINED) {
newValue = "clear"; newValue = "clear";
} else if (value == WeatherTypes.CLEAR) { } else if (value == WeatherTypes.CLEAR) {
newValue = "rain"; newValue = "downfall";
} else { } else {
newValue = "undefined"; newValue = "undefined";
} }
@ -722,6 +807,13 @@ private Consumer<CommandSource> newOptionValueConsumer(GDPermissionUser src, GDC
}; };
} }
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) { private Consumer<CommandSource> adjustNumberConsumer(GDPermissionUser src, GDClaim claim, Option option, String currentValue, MenuType menuType, Set<Context> contexts) {
return consumer -> { return consumer -> {
String newValue = ""; String newValue = "";
@ -882,8 +974,8 @@ private static <T> T getMenuTypeValue(TypeToken<T> type, String value) {
if (value.equalsIgnoreCase("clear")) { if (value.equalsIgnoreCase("clear")) {
return (T) WeatherTypes.CLEAR; return (T) WeatherTypes.CLEAR;
} }
if (value.equalsIgnoreCase("rain")) { if (value.equalsIgnoreCase("downfall")) {
return (T) WeatherTypes.RAIN; return (T) WeatherTypes.DOWNFALL;
} }
} }
if (type.getRawType().isAssignableFrom(CreateModeType.class)) { if (type.getRawType().isAssignableFrom(CreateModeType.class)) {

View File

@ -178,6 +178,7 @@ private static Consumer<CommandSource> createConfirmationConsumer(Player player,
return; return;
} }
playerData.onClaimDelete();
// remove all context permissions // remove all context permissions
PermissionUtil.getInstance().clearPermissions(claim); PermissionUtil.getInstance().clearPermissions(claim);
playerData.revertActiveVisual(player); playerData.revertActiveVisual(player);

View File

@ -155,6 +155,7 @@ private static Consumer<CommandSource> createConfirmationConsumer(GDPermissionUs
playerData.useRestoreSchematic = event.isRestoring(); playerData.useRestoreSchematic = event.isRestoring();
GriefDefenderPlugin.getInstance().dataStore.abandonClaimsForPlayer(user, allowedClaims); GriefDefenderPlugin.getInstance().dataStore.abandonClaimsForPlayer(user, allowedClaims);
playerData.useRestoreSchematic = false; playerData.useRestoreSchematic = false;
playerData.onClaimDelete();
if (GriefDefenderPlugin.getInstance().isEconomyModeEnabled()) { if (GriefDefenderPlugin.getInstance().isEconomyModeEnabled()) {
final Account playerAccount = GriefDefenderPlugin.getInstance().economyService.get().getOrCreateAccount(playerData.playerID).orElse(null); final Account playerAccount = GriefDefenderPlugin.getInstance().economyService.get().getOrCreateAccount(playerData.playerID).orElse(null);

View File

@ -105,6 +105,7 @@ private static Consumer<CommandSource> createConfirmationConsumer(Player player,
return; return;
} }
playerData.onClaimDelete();
PermissionUtil.getInstance().clearPermissions((GDClaim) claim); PermissionUtil.getInstance().clearPermissions((GDClaim) claim);
playerData.revertActiveVisual(player); playerData.revertActiveVisual(player);

View File

@ -98,6 +98,7 @@ private static Consumer<CommandSource> createConfirmationConsumer(Player src, Us
} }
GriefDefenderPlugin.getInstance().dataStore.deleteClaimsForPlayer(otherPlayer.getUniqueId()); GriefDefenderPlugin.getInstance().dataStore.deleteClaimsForPlayer(otherPlayer.getUniqueId());
playerData.onClaimDelete();
if (src != null) { if (src != null) {
final Component message = GriefDefenderPlugin.getInstance().messageData.getMessage(MessageStorage.DELETE_ALL_PLAYER_SUCCESS, ImmutableMap.of( final Component message = GriefDefenderPlugin.getInstance().messageData.getMessage(MessageStorage.DELETE_ALL_PLAYER_SUCCESS, ImmutableMap.of(
"player", TextComponent.of(otherPlayer.getName()).color(TextColor.AQUA))); "player", TextComponent.of(otherPlayer.getName()).color(TextColor.AQUA)));

View File

@ -83,7 +83,8 @@ private static Consumer<CommandSource> createConfirmationConsumer(Player player)
GriefDefenderPlugin.sendMessage(player, GriefDefenderPlugin.getInstance().messageData.getMessage(MessageStorage.DELETE_ALL_TYPE_SUCCESS, GriefDefenderPlugin.sendMessage(player, GriefDefenderPlugin.getInstance().messageData.getMessage(MessageStorage.DELETE_ALL_TYPE_SUCCESS,
ImmutableMap.of("type", TextComponent.of("ADMIN").color(TextColor.RED)))); 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); playerData.revertActiveVisual(player);
}; };
} }

View File

@ -55,7 +55,7 @@ public CommandClaimFlagGroup() {
@Syntax("<group> <flag> <target> <value> [context[key=value]]") @Syntax("<group> <flag> <target> <value> [context[key=value]]")
@Subcommand("flag group") @Subcommand("flag group")
public void execute(Player player, String group, @Optional String[] args) throws InvalidCommandArgument { 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(); throw new InvalidCommandArgument();
} }

View File

@ -24,7 +24,6 @@
*/ */
package com.griefdefender.command; package com.griefdefender.command;
import co.aikar.commands.BaseCommand;
import co.aikar.commands.InvalidCommandArgument; import co.aikar.commands.InvalidCommandArgument;
import co.aikar.commands.annotation.CommandAlias; import co.aikar.commands.annotation.CommandAlias;
import co.aikar.commands.annotation.CommandCompletion; import co.aikar.commands.annotation.CommandCompletion;
@ -33,36 +32,10 @@
import co.aikar.commands.annotation.Optional; import co.aikar.commands.annotation.Optional;
import co.aikar.commands.annotation.Subcommand; import co.aikar.commands.annotation.Subcommand;
import co.aikar.commands.annotation.Syntax; 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 com.griefdefender.GriefDefenderPlugin;
import java.util.List; import com.griefdefender.permission.GDPermissions;
import java.util.Map; import org.spongepowered.api.entity.living.player.Player;
import java.util.Set;
@CommandAlias("%griefdefender") @CommandAlias("%griefdefender")
@CommandPermission(GDPermissions.COMMAND_OPTIONS_CLAIM) @CommandPermission(GDPermissions.COMMAND_OPTIONS_CLAIM)

View File

@ -55,7 +55,7 @@ public CommandClaimOptionGroup() {
@Syntax("<group> <option> <value> [context[key=value]]") @Syntax("<group> <option> <value> [context[key=value]]")
@Subcommand("option group") @Subcommand("option group")
public void execute(Player player, String group, @Optional String[] args) throws InvalidCommandArgument { 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(); throw new InvalidCommandArgument();
} }

View File

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

View File

@ -104,6 +104,9 @@ public DefaultPermissionCategory() {
this.defaultUserOptions.put(Options.PLAYER_WALK_SPEED.getName(), "-1"); this.defaultUserOptions.put(Options.PLAYER_WALK_SPEED.getName(), "-1");
this.defaultUserOptions.put(Options.PLAYER_WEATHER.getName(), "undefined"); this.defaultUserOptions.put(Options.PLAYER_WEATHER.getName(), "undefined");
this.defaultUserOptions.put(Options.PVP.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_X.getName(), "5");
this.defaultBasicOptions.put(Options.MIN_SIZE_Y.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 WeatherType deserialize(TypeToken<?> type, ConfigurationNode node) throws
case "clear" : case "clear" :
return WeatherTypes.CLEAR; return WeatherTypes.CLEAR;
case "rain" : case "rain" :
return WeatherTypes.RAIN; return WeatherTypes.DOWNFALL;
default : default :
return WeatherTypes.UNDEFINED; return WeatherTypes.UNDEFINED;
} }

View File

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

View File

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

View File

@ -81,7 +81,6 @@
import org.spongepowered.api.event.cause.EventContextKeys; import org.spongepowered.api.event.cause.EventContextKeys;
import org.spongepowered.api.event.filter.cause.Root; import org.spongepowered.api.event.filter.cause.Root;
import org.spongepowered.api.event.world.ExplosionEvent; import org.spongepowered.api.event.world.ExplosionEvent;
import org.spongepowered.api.text.Text;
import org.spongepowered.api.util.Direction; import org.spongepowered.api.util.Direction;
import org.spongepowered.api.world.LocatableBlock; import org.spongepowered.api.world.LocatableBlock;
import org.spongepowered.api.world.Location; import org.spongepowered.api.world.Location;
@ -181,7 +180,7 @@ public void onBlockPre(ChangeBlockEvent.Pre event) {
} }
// check overrides // 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) { if (result != Tristate.TRUE) {
final Component message = GriefDefenderPlugin.getInstance().messageData.getMessage(MessageStorage.PERMISSION_BUILD, final Component message = GriefDefenderPlugin.getInstance().messageData.getMessage(MessageStorage.PERMISSION_BUILD,
ImmutableMap.of( ImmutableMap.of(
@ -228,44 +227,44 @@ public void onBlockPre(ChangeBlockEvent.Pre event) {
// If a player successfully interacted with a block recently such as a pressure plate, ignore check // 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 // 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) { 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; continue;
} }
if (user != null && targetClaim.isUserTrusted(user, TrustTypes.BUILDER)) { 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; continue;
} }
if (sourceClaim.getOwnerUniqueId().equals(targetClaim.getOwnerUniqueId()) && user == null && sourceEntity == null && !isFireSource && !isLeafDecay) { 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; continue;
} }
if (user != null && pistonExtend) { if (user != null && pistonExtend) {
if (targetClaim.isUserTrusted(user, TrustTypes.ACCESSOR)) { 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; continue;
} }
} }
if (isLeafDecay) { 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); event.setCancelled(true);
GDTimings.BLOCK_PRE_EVENT.stopTimingIfSync(); GDTimings.BLOCK_PRE_EVENT.stopTimingIfSync();
return; return;
} }
} else if (isFireSource) { } 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); event.setCancelled(true);
GDTimings.BLOCK_PRE_EVENT.stopTimingIfSync(); GDTimings.BLOCK_PRE_EVENT.stopTimingIfSync();
return; return;
} }
} else if (isLiquidSource) { } 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); event.setCancelled(true);
lastBlockPreCancelled = true; lastBlockPreCancelled = true;
GDTimings.BLOCK_PRE_EVENT.stopTimingIfSync(); GDTimings.BLOCK_PRE_EVENT.stopTimingIfSync();
return; return;
} }
continue; 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. // PRE events can be spammy so we need to avoid sending player messages here.
event.setCancelled(true); event.setCancelled(true);
lastBlockPreCancelled = true; lastBlockPreCancelled = true;
@ -290,29 +289,29 @@ public void onBlockPre(ChangeBlockEvent.Pre event) {
// If a player successfully interacted with a block recently such as a pressure plate, ignore check // 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 // 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) { 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; continue;
} }
if (targetClaim.isUserTrusted(user, TrustTypes.BUILDER)) { 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; continue;
} }
if (isFireSource) { 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); event.setCancelled(true);
GDTimings.BLOCK_PRE_EVENT.stopTimingIfSync(); GDTimings.BLOCK_PRE_EVENT.stopTimingIfSync();
return; return;
} }
} else if (isLiquidSource) { } 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); event.setCancelled(true);
lastBlockPreCancelled = true; lastBlockPreCancelled = true;
GDTimings.BLOCK_PRE_EVENT.stopTimingIfSync(); GDTimings.BLOCK_PRE_EVENT.stopTimingIfSync();
return; return;
} }
continue; 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); event.setCancelled(true);
lastBlockPreCancelled = true; lastBlockPreCancelled = true;
GDTimings.BLOCK_PRE_EVENT.stopTimingIfSync(); GDTimings.BLOCK_PRE_EVENT.stopTimingIfSync();
@ -463,13 +462,13 @@ public void onBlockCollide(CollideBlockEvent event, @Root Entity source) {
targetClaim = this.dataStore.getClaimAt(event.getTargetLocation()); 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); entityBlockCache.setLastResult(Tristate.TRUE);
GDTimings.BLOCK_COLLIDE_EVENT.stopTimingIfSync(); GDTimings.BLOCK_COLLIDE_EVENT.stopTimingIfSync();
return; return;
} }
if (GDFlags.PORTAL_USE && event.getTargetBlock().getType() == BlockTypes.PORTAL) { 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(); GDTimings.BLOCK_COLLIDE_EVENT.stopTimingIfSync();
return; return;
} }
@ -522,7 +521,7 @@ public void onProjectileImpactBlock(CollideBlockEvent.Impact event) {
targetClaim = this.dataStore.getClaimAt(impactPoint); 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) { if (result == Tristate.FALSE) {
event.setCancelled(true); event.setCancelled(true);
GDTimings.PROJECTILE_IMPACT_BLOCK_EVENT.stopTimingIfSync(); GDTimings.PROJECTILE_IMPACT_BLOCK_EVENT.stopTimingIfSync();
@ -566,7 +565,7 @@ public void onExplosionPre(ExplosionEvent.Pre event) {
for (Claim claim : surroundingClaims) { for (Claim claim : surroundingClaims) {
// Use any location for permission check // Use any location for permission check
Location<World> targetLocation = new Location<>(location.getExtent(), claim.getLesserBoundaryCorner()); 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) { if (result == Tristate.FALSE) {
event.setCancelled(true); event.setCancelled(true);
break; break;
@ -610,7 +609,7 @@ public void onExplosionDetonate(ExplosionEvent.Detonate event) {
continue; 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) { if (result == Tristate.FALSE) {
// Avoid lagging server from large explosions. // Avoid lagging server from large explosions.
@ -696,7 +695,7 @@ public void onBlockBreak(ChangeBlockEvent.Break event) {
} }
// check overrides // 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 (result != Tristate.TRUE) {
if (player != null) { if (player != null) {
final Component message = GriefDefenderPlugin.getInstance().messageData.getMessage(MessageStorage.PERMISSION_BUILD, final Component message = GriefDefenderPlugin.getInstance().messageData.getMessage(MessageStorage.PERMISSION_BUILD,
@ -787,7 +786,7 @@ public void onBlockPlace(ChangeBlockEvent.Place event) {
} }
// check overrides // 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) { if (result != Tristate.TRUE) {
// TODO - make sure this doesn't spam // TODO - make sure this doesn't spam
/*if (source instanceof Player) { /*if (source instanceof Player) {
@ -909,7 +908,7 @@ public void onSignChanged(ChangeSignEvent event) {
Location<World> location = event.getTargetTile().getLocation(); Location<World> location = event.getTargetTile().getLocation();
// Prevent users exploiting signs // Prevent users exploiting signs
GDClaim claim = GriefDefenderPlugin.getInstance().dataStore.getClaimAt(location); 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) { if (user instanceof Player) {
event.setCancelled(true); event.setCancelled(true);
final Component message = GriefDefenderPlugin.getInstance().messageData.getMessage(MessageStorage.PERMISSION_ACCESS, final Component message = GriefDefenderPlugin.getInstance().messageData.getMessage(MessageStorage.PERMISSION_ACCESS,
@ -973,7 +972,7 @@ private boolean checkSurroundings(org.spongepowered.api.event.Event event, Locat
} }
final GDClaim claim = this.dataStore.getClaimAt(loc, targetClaim); final GDClaim claim = this.dataStore.getClaimAt(loc, targetClaim);
if (!claim.isWilderness() && !targetClaim.equals(claim)) { 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) { if (result != Tristate.TRUE) {
final Component message = GriefDefenderPlugin.getInstance().messageData.getMessage(MessageStorage.PERMISSION_BUILD_NEAR_CLAIM, final Component message = GriefDefenderPlugin.getInstance().messageData.getMessage(MessageStorage.PERMISSION_BUILD_NEAR_CLAIM,
ImmutableMap.of( ImmutableMap.of(

View File

@ -25,6 +25,12 @@
package com.griefdefender.listener; package com.griefdefender.listener;
import java.lang.ref.WeakReference; 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.Sponge;
import org.spongepowered.api.data.key.Keys; import org.spongepowered.api.data.key.Keys;
@ -37,6 +43,7 @@
import org.spongepowered.api.text.Text; import org.spongepowered.api.text.Text;
import org.spongepowered.api.world.Location; import org.spongepowered.api.world.Location;
import org.spongepowered.api.world.World; import org.spongepowered.api.world.World;
import org.spongepowered.api.world.weather.Weather;
import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableMap;
import com.google.common.reflect.TypeToken; import com.google.common.reflect.TypeToken;
import com.griefdefender.GDPlayerData; import com.griefdefender.GDPlayerData;
@ -46,21 +53,31 @@
import com.griefdefender.api.GriefDefender; import com.griefdefender.api.GriefDefender;
import com.griefdefender.api.Tristate; import com.griefdefender.api.Tristate;
import com.griefdefender.api.claim.TrustTypes; import com.griefdefender.api.claim.TrustTypes;
import com.griefdefender.api.permission.Context;
import com.griefdefender.api.permission.flag.Flags; import com.griefdefender.api.permission.flag.Flags;
import com.griefdefender.api.permission.option.Options; 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.MessageCache;
import com.griefdefender.cache.PermissionHolderCache; import com.griefdefender.cache.PermissionHolderCache;
import com.griefdefender.claim.GDClaim; import com.griefdefender.claim.GDClaim;
import com.griefdefender.command.CommandHelper;
import com.griefdefender.configuration.MessageStorage; import com.griefdefender.configuration.MessageStorage;
import com.griefdefender.event.GDBorderClaimEvent; import com.griefdefender.event.GDBorderClaimEvent;
import com.griefdefender.internal.util.BlockUtil;
import com.griefdefender.internal.util.VecHelper; import com.griefdefender.internal.util.VecHelper;
import com.griefdefender.permission.GDPermissionManager; import com.griefdefender.permission.GDPermissionManager;
import com.griefdefender.permission.GDPermissionUser; import com.griefdefender.permission.GDPermissionUser;
import com.griefdefender.permission.GDPermissions; import com.griefdefender.permission.GDPermissions;
import com.griefdefender.permission.flag.GDFlags; import com.griefdefender.permission.flag.GDFlags;
import com.griefdefender.permission.option.OptionContexts;
import com.griefdefender.provider.MCClansProvider; import com.griefdefender.provider.MCClansProvider;
import com.griefdefender.storage.BaseStorage; import com.griefdefender.storage.BaseStorage;
import com.griefdefender.util.EntityUtils; import com.griefdefender.util.EntityUtils;
import com.griefdefender.util.PermissionUtil;
import com.griefdefender.util.PlayerUtil;
import com.griefdefender.util.SpongeUtil; import com.griefdefender.util.SpongeUtil;
import net.kyori.text.Component; import net.kyori.text.Component;
import net.kyori.text.TextComponent; import net.kyori.text.TextComponent;
@ -132,7 +149,7 @@ public boolean onEntityMove(MoveEntityEvent event, Location<World> fromLocation,
if (fromClaim != toClaim) { if (fromClaim != toClaim) {
GDBorderClaimEvent gpEvent = new GDBorderClaimEvent(targetEntity, fromClaim, toClaim); GDBorderClaimEvent gpEvent = new GDBorderClaimEvent(targetEntity, fromClaim, toClaim);
// enter // 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); gpEvent.cancelled(true);
if (event != null) { if (event != null) {
event.setCancelled(true); event.setCancelled(true);
@ -140,7 +157,7 @@ public boolean onEntityMove(MoveEntityEvent event, Location<World> fromLocation,
} }
// exit // 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); gpEvent.cancelled(true);
if (event != null) { if (event != null) {
event.setCancelled(true); event.setCancelled(true);
@ -173,7 +190,7 @@ public boolean onEntityMove(MoveEntityEvent event, Location<World> fromLocation,
if (player != null && GDFlags.ENTER_CLAIM && !enterBlacklisted && user != null && user.getInternalPlayerData().lastClaim != null) { if (player != null && GDFlags.ENTER_CLAIM && !enterBlacklisted && user != null && user.getInternalPlayerData().lastClaim != null) {
final GDClaim lastClaim = (GDClaim) user.getInternalPlayerData().lastClaim.get(); final GDClaim lastClaim = (GDClaim) user.getInternalPlayerData().lastClaim.get();
if (lastClaim != null && lastClaim != fromClaim) { 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> 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()); Location<World> safeLocation = Sponge.getGame().getTeleportHelper().getSafeLocation(claimCorner, 9, 9).orElse(player.getWorld().getSpawnLocation());
if (event != null) { if (event != null) {
@ -208,6 +225,7 @@ public boolean onEntityMove(MoveEntityEvent event, Location<World> fromLocation,
GDBorderClaimEvent gpEvent = new GDBorderClaimEvent(targetEntity, fromClaim, toClaim); GDBorderClaimEvent gpEvent = new GDBorderClaimEvent(targetEntity, fromClaim, toClaim);
if (user != null && toClaim.isUserTrusted(user, TrustTypes.ACCESSOR)) { if (user != null && toClaim.isUserTrusted(user, TrustTypes.ACCESSOR)) {
final GDPlayerData playerData = user.getInternalPlayerData();
GriefDefender.getEventManager().post(gpEvent); GriefDefender.getEventManager().post(gpEvent);
if (gpEvent.cancelled()) { if (gpEvent.cancelled()) {
event.setCancelled(true); event.setCancelled(true);
@ -254,6 +272,15 @@ public boolean onEntityMove(MoveEntityEvent event, Location<World> fromLocation,
} else { } else {
user.getInternalPlayerData().inTown = false; 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(); GDTimings.ENTITY_MOVE_EVENT.stopTimingIfSync();
@ -264,13 +291,13 @@ public boolean onEntityMove(MoveEntityEvent event, Location<World> fromLocation,
boolean enterCancelled = false; boolean enterCancelled = false;
boolean exitCancelled = false; boolean exitCancelled = false;
// enter // 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; enterCancelled = true;
gpEvent.cancelled(true); gpEvent.cancelled(true);
} }
// exit // 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; exitCancelled = true;
gpEvent.cancelled(true); gpEvent.cancelled(true);
} }
@ -301,8 +328,9 @@ public boolean onEntityMove(MoveEntityEvent event, Location<World> fromLocation,
} }
if (player != null) { if (player != null) {
final GDPlayerData playerData = user.getInternalPlayerData();
final boolean showGpPrefix = GriefDefenderPlugin.getGlobalConfig().getConfig().message.enterExitShowGdPrefix; 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); Component welcomeMessage = gpEvent.getEnterMessage().orElse(null);
if (welcomeMessage != null && !welcomeMessage.equals(TextComponent.empty())) { if (welcomeMessage != null && !welcomeMessage.equals(TextComponent.empty())) {
ChatType chatType = gpEvent.getEnterMessageChatType(); ChatType chatType = gpEvent.getEnterMessageChatType();
@ -336,7 +364,15 @@ public boolean onEntityMove(MoveEntityEvent event, Location<World> fromLocation,
} }
if (player != null) { 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 boolean onEntityMove(MoveEntityEvent event, Location<World> fromLocation,
return true; 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); final GameMode gameMode = player.get(Keys.GAME_MODE).orElse(null);
if (gameMode == null || gameMode == GameModes.CREATIVE || gameMode == GameModes.SPECTATOR) { if (gameMode == null || gameMode == GameModes.CREATIVE || gameMode == GameModes.SPECTATOR) {
return; return;
@ -366,7 +474,105 @@ private void checkPlayerFlight(Player player, GDPlayerData playerData, GDClaim f
player.offer(Keys.CAN_FLY, false); player.offer(Keys.CAN_FLY, false);
player.offer(Keys.IS_FLYING, false); player.offer(Keys.IS_FLYING, false);
playerData.ignoreFallDamage = true; 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.claim.Claim; import com.griefdefender.api.claim.Claim;
import com.griefdefender.api.claim.TrustType; import com.griefdefender.api.claim.TrustType;
import com.griefdefender.api.claim.TrustTypes; 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.flag.Flags;
import com.griefdefender.api.permission.option.Options; import com.griefdefender.api.permission.option.Options;
import com.griefdefender.cache.MessageCache; import com.griefdefender.cache.MessageCache;
@ -43,7 +44,6 @@
import com.griefdefender.internal.util.NMSUtil; import com.griefdefender.internal.util.NMSUtil;
import com.griefdefender.permission.GDPermissionManager; import com.griefdefender.permission.GDPermissionManager;
import com.griefdefender.permission.GDPermissionUser; import com.griefdefender.permission.GDPermissionUser;
import com.griefdefender.permission.GDPermissions;
import com.griefdefender.permission.flag.GDFlags; import com.griefdefender.permission.flag.GDFlags;
import com.griefdefender.storage.BaseStorage; import com.griefdefender.storage.BaseStorage;
import com.griefdefender.util.CauseContextHelper; import com.griefdefender.util.CauseContextHelper;
@ -142,7 +142,7 @@ public void onEntityExplosionPre(ExplosionEvent.Pre event) {
return; 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) { if(result == Tristate.FALSE) {
event.setCancelled(true); event.setCancelled(true);
@ -182,7 +182,7 @@ public void onEntityExplosionDetonate(ExplosionEvent.Detonate event) {
while (iterator.hasNext()) { while (iterator.hasNext()) {
Entity entity = iterator.next(); Entity entity = iterator.next();
targetClaim = GriefDefenderPlugin.getInstance().dataStore.getClaimAt(entity.getLocation(), targetClaim); 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(); iterator.remove();
} }
} }
@ -225,7 +225,7 @@ public void onEntityConstruct(ConstructEntityEvent.Pre event, @Root Object sourc
return; return;
} }
String permission = GDPermissions.ENTITY_SPAWN; Flag flag = Flags.ENTITY_SPAWN;
if (event.getTargetType() == EntityTypes.ITEM) { if (event.getTargetType() == EntityTypes.ITEM) {
if (user == null) { if (user == null) {
GDTimings.ENTITY_SPAWN_PRE_EVENT.stopTimingIfSync(); GDTimings.ENTITY_SPAWN_PRE_EVENT.stopTimingIfSync();
@ -240,7 +240,7 @@ public void onEntityConstruct(ConstructEntityEvent.Pre event, @Root Object sourc
return; return;
} }
permission = GDPermissions.ITEM_SPAWN; flag = Flags.ITEM_SPAWN;
if (source instanceof BlockSnapshot) { if (source instanceof BlockSnapshot) {
final BlockSnapshot block = (BlockSnapshot) source; final BlockSnapshot block = (BlockSnapshot) source;
final Location<World> blockLocation = block.getLocation().orElse(null); final Location<World> blockLocation = block.getLocation().orElse(null);
@ -249,11 +249,11 @@ public void onEntityConstruct(ConstructEntityEvent.Pre event, @Root Object sourc
GDTimings.ENTITY_SPAWN_PRE_EVENT.stopTimingIfSync(); GDTimings.ENTITY_SPAWN_PRE_EVENT.stopTimingIfSync();
return; 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.UNDEFINED) {
if (result == Tristate.TRUE) { if (result == Tristate.TRUE) {
// Check if item drop is allowed // 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); event.setCancelled(true);
} }
GDTimings.ENTITY_SPAWN_PRE_EVENT.stopTimingIfSync(); GDTimings.ENTITY_SPAWN_PRE_EVENT.stopTimingIfSync();
@ -266,7 +266,7 @@ public void onEntityConstruct(ConstructEntityEvent.Pre event, @Root Object sourc
} }
} }
} }
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); event.setCancelled(true);
} }
GDTimings.ENTITY_SPAWN_PRE_EVENT.stopTimingIfSync(); GDTimings.ENTITY_SPAWN_PRE_EVENT.stopTimingIfSync();
@ -334,7 +334,7 @@ public boolean test(Entity entity) {
return true; return true;
} }
String permission = GDPermissions.ENTITY_SPAWN; Flag flag = Flags.ENTITY_SPAWN;
if (isChunkSpawn) { if (isChunkSpawn) {
if (GriefDefenderPlugin.isTargetIdBlacklisted(Flags.ENTITY_CHUNK_SPAWN.getName(), entity, world.getProperties())) { if (GriefDefenderPlugin.isTargetIdBlacklisted(Flags.ENTITY_CHUNK_SPAWN.getName(), entity, world.getProperties())) {
return true; return true;
@ -343,7 +343,7 @@ public boolean test(Entity entity) {
if (entity instanceof ItemFrame) { if (entity instanceof ItemFrame) {
return true; return true;
} }
permission = GDPermissions.ENTITY_CHUNK_SPAWN; flag = Flags.ENTITY_CHUNK_SPAWN;
} }
if (!isChunkSpawn && entity instanceof Item) { if (!isChunkSpawn && entity instanceof Item) {
@ -356,7 +356,7 @@ public boolean test(Entity entity) {
if (GriefDefenderPlugin.isTargetIdBlacklisted(Flags.ITEM_SPAWN.getName(), entity, world.getProperties())) { if (GriefDefenderPlugin.isTargetIdBlacklisted(Flags.ITEM_SPAWN.getName(), entity, world.getProperties())) {
return true; return true;
} }
permission = GDPermissions.ITEM_SPAWN; flag = Flags.ITEM_SPAWN;
if (actualSource instanceof BlockSnapshot) { if (actualSource instanceof BlockSnapshot) {
final BlockSnapshot block = (BlockSnapshot) actualSource; final BlockSnapshot block = (BlockSnapshot) actualSource;
final Location<World> location = block.getLocation().orElse(null); final Location<World> location = block.getLocation().orElse(null);
@ -364,11 +364,11 @@ public boolean test(Entity entity) {
if (GriefDefenderPlugin.isTargetIdBlacklisted(Flags.BLOCK_BREAK.getName(), block, world.getProperties())) { if (GriefDefenderPlugin.isTargetIdBlacklisted(Flags.BLOCK_BREAK.getName(), block, world.getProperties())) {
return true; 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.UNDEFINED) {
if (result == Tristate.TRUE) { if (result == Tristate.TRUE) {
// Check if item drop is allowed // 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 false;
} }
return true; return true;
@ -379,7 +379,7 @@ public boolean test(Entity entity) {
} }
} }
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; return false;
} }
@ -467,7 +467,7 @@ public boolean protectEntity(Event event, Entity targetEntity, Cause cause, Dama
} }
final TrustType trustType = TrustTypes.BUILDER; 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; return true;
} }
@ -483,7 +483,7 @@ public boolean protectEntity(Event event, Entity targetEntity, Cause cause, Dama
if (!(source instanceof Player) && !(targetEntity instanceof Player)) { if (!(source instanceof Player) && !(targetEntity instanceof Player)) {
if (source instanceof User) { if (source instanceof User) {
User sourceUser = (User) source; 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) { if (targetEntity instanceof Living && perm == Tristate.TRUE) {
return false; return false;
} }
@ -501,7 +501,7 @@ public boolean protectEntity(Event event, Entity targetEntity, Cause cause, Dama
} else { } else {
if (targetEntity instanceof Player) { if (targetEntity instanceof Player) {
if (NMSUtil.getInstance().isEntityMonster((Entity) source)) { 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; return true;
} }
} }
@ -532,7 +532,7 @@ public boolean protectEntity(Event event, Entity targetEntity, Cause cause, Dama
} }
} }
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; return true;
} }
@ -635,7 +635,7 @@ public boolean test(Entity item) {
return true; 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 false;
} }
return true; return true;
@ -674,6 +674,21 @@ public void onEntityTeleport(MoveEntityEvent.Teleport event) {
if (entity instanceof Player) { if (entity instanceof Player) {
player = (Player) entity; player = (Player) entity;
user = PermissionHolderCache.getInstance().getOrCreateUser(player); 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 { } else {
user = PermissionHolderCache.getInstance().getOrCreateUser(entity.getCreator().orElse(null)); user = PermissionHolderCache.getInstance().getOrCreateUser(entity.getCreator().orElse(null));
} }
@ -706,10 +721,10 @@ public void onEntityTeleport(MoveEntityEvent.Teleport event) {
} }
if (sourceClaim != null) { 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; boolean cancelled = true;
if (GDFlags.PORTAL_USE && type.equals(TeleportTypes.PORTAL)) { 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; cancelled = false;
} }
} }
@ -736,10 +751,10 @@ public void onEntityTeleport(MoveEntityEvent.Teleport event) {
final GDClaim toClaim = this.dataStore.getClaimAt(destination); final GDClaim toClaim = this.dataStore.getClaimAt(destination);
if (toClaim != null) { 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; boolean cancelled = true;
if (GDFlags.PORTAL_USE && type.equals(TeleportTypes.PORTAL)) { 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; cancelled = false;
} }
} }
@ -851,9 +866,9 @@ public void onProjectileImpactEntity(CollideEntityEvent.Impact event) {
return; return;
} }
targetClaim = this.dataStore.getClaimAt(impactPoint, targetClaim); 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 (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(); GDTimings.PROJECTILE_IMPACT_ENTITY_EVENT.stopTimingIfSync();
return; return;
} }
@ -888,7 +903,7 @@ public void onEntityMount(RideEntityEvent event) {
final Location<World> location = entity.getLocation(); final Location<World> location = entity.getLocation();
final GDClaim targetClaim = GriefDefenderPlugin.getInstance().dataStore.getClaimAt(location); 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) { if (player != null) {
//sendInteractEntityDenyMessage(targetClaim, player, null, entity); //sendInteractEntityDenyMessage(targetClaim, player, null, entity);
} }
@ -901,17 +916,31 @@ public void onEntityMount(RideEntityEvent event) {
private boolean getPvpProtectResult(Event event, GDClaim claim, GDPermissionUser source, GDPermissionUser target) { private boolean getPvpProtectResult(Event event, GDClaim claim, GDPermissionUser source, GDPermissionUser target) {
final Player sourcePlayer = source.getOnlinePlayer(); final Player sourcePlayer = source.getOnlinePlayer();
final Player targetPlayer = target.getOnlinePlayer(); final Player targetPlayer = target.getOnlinePlayer();
final boolean sourceInCombat = source.getInternalPlayerData().inPvpCombat(claim.getWorld()); final boolean sourceInCombat = source.getInternalPlayerData().inPvpCombat();
final boolean targetInCombat = target.getInternalPlayerData().inPvpCombat(claim.getWorld()); final boolean targetInCombat = target.getInternalPlayerData().inPvpCombat();
if (sourceInCombat && targetInCombat) { // 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(); source.getInternalPlayerData().lastPvpTimestamp = Instant.now();
target.getInternalPlayerData().lastPvpTimestamp = Instant.now(); target.getInternalPlayerData().lastPvpTimestamp = Instant.now();
return false; 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 // Check flags
Tristate sourceResult = GDPermissionManager.getInstance().getFinalPermission(event, targetPlayer.getLocation(), claim, GDPermissions.ENTITY_DAMAGE, sourcePlayer, targetPlayer, sourcePlayer, 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, GDPermissions.ENTITY_DAMAGE, targetPlayer, sourcePlayer, targetPlayer, true); Tristate targetResult = GDPermissionManager.getInstance().getFinalPermission(event, sourcePlayer.getLocation(), claim, Flags.ENTITY_DAMAGE, targetPlayer, sourcePlayer, targetPlayer, true);
if (sourceResult == Tristate.FALSE) { if (sourceResult == Tristate.FALSE) {
GriefDefenderPlugin.sendMessage(sourcePlayer, MessageCache.getInstance().PVP_SOURCE_NOT_ALLOWED); GriefDefenderPlugin.sendMessage(sourcePlayer, MessageCache.getInstance().PVP_SOURCE_NOT_ALLOWED);
return true; return true;
@ -939,13 +968,9 @@ private boolean getPvpProtectResult(Event event, GDClaim claim, GDPermissionUser
return true; return true;
} }
final GDClaim sourceClaim = GriefDefenderPlugin.getInstance().dataStore.getClaimAtPlayer(source.getInternalPlayerData(), sourcePlayer.getLocation()); final Instant now = Instant.now();
if (!sourceClaim.isPvpEnabled()) { source.getInternalPlayerData().lastPvpTimestamp = now;
GriefDefenderPlugin.sendMessage(sourcePlayer, MessageCache.getInstance().PVP_CLAIM_NOT_ALLOWED); target.getInternalPlayerData().lastPvpTimestamp = now;
return true; return false;
}
source.getInternalPlayerData().lastPvpTimestamp = Instant.now();
target.getInternalPlayerData().lastPvpTimestamp = Instant.now();
return !claim.isPvpEnabled();
} }
} }

View File

@ -42,13 +42,13 @@
import com.griefdefender.api.claim.ShovelTypes; import com.griefdefender.api.claim.ShovelTypes;
import com.griefdefender.api.claim.TrustType; import com.griefdefender.api.claim.TrustType;
import com.griefdefender.api.claim.TrustTypes; 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.flag.Flags;
import com.griefdefender.api.permission.option.Options; import com.griefdefender.api.permission.option.Options;
import com.griefdefender.api.permission.option.type.CreateModeTypes; import com.griefdefender.api.permission.option.type.CreateModeTypes;
import com.griefdefender.cache.MessageCache; import com.griefdefender.cache.MessageCache;
import com.griefdefender.claim.GDClaim; import com.griefdefender.claim.GDClaim;
import com.griefdefender.claim.GDClaimManager; import com.griefdefender.claim.GDClaimManager;
import com.griefdefender.claim.GDClaimResult;
import com.griefdefender.command.CommandHelper; import com.griefdefender.command.CommandHelper;
import com.griefdefender.configuration.GriefDefenderConfig; import com.griefdefender.configuration.GriefDefenderConfig;
import com.griefdefender.configuration.MessageStorage; import com.griefdefender.configuration.MessageStorage;
@ -79,7 +79,6 @@
import org.spongepowered.api.command.CommandMapping; import org.spongepowered.api.command.CommandMapping;
import org.spongepowered.api.command.CommandSource; import org.spongepowered.api.command.CommandSource;
import org.spongepowered.api.data.key.Keys; 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.HandType;
import org.spongepowered.api.data.type.HandTypes; import org.spongepowered.api.data.type.HandTypes;
import org.spongepowered.api.entity.Entity; import org.spongepowered.api.entity.Entity;
@ -130,8 +129,6 @@
import org.spongepowered.api.world.World; import org.spongepowered.api.world.World;
import org.spongepowered.api.world.storage.WorldProperties; import org.spongepowered.api.world.storage.WorldProperties;
import org.spongepowered.common.SpongeImpl; import org.spongepowered.common.SpongeImpl;
import org.spongepowered.common.SpongeImplHooks;
import org.spongepowered.common.item.inventory.custom.CustomInventory;
import java.math.BigDecimal; import java.math.BigDecimal;
import java.time.Instant; import java.time.Instant;
@ -282,6 +279,19 @@ public void onPlayerCommand(SendCommandEvent event, @First Player player) {
return; 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 commandBaseTarget = pluginId + ":" + command;
String commandTargetWithArgs = commandBaseTarget; String commandTargetWithArgs = commandBaseTarget;
// first check the args // first check the args
@ -298,12 +308,32 @@ public void onPlayerCommand(SendCommandEvent event, @First Player player) {
commandExecuteTargetBlacklisted = true; commandExecuteTargetBlacklisted = true;
} }
if (GDFlags.COMMAND_EXECUTE && !commandExecuteSourceBlacklisted && !commandExecuteTargetBlacklisted) { if (GDFlags.COMMAND_EXECUTE && !inPvpCombat && !commandExecuteSourceBlacklisted && !commandExecuteTargetBlacklisted) {
// First check base command // 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) { if (result != Tristate.FALSE) {
// check with args // 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) { if (result == Tristate.FALSE) {
final Component denyMessage = GriefDefenderPlugin.getInstance().messageData.getMessage(MessageStorage.COMMAND_BLOCKED, final Component denyMessage = GriefDefenderPlugin.getInstance().messageData.getMessage(MessageStorage.COMMAND_BLOCKED,
@ -316,22 +346,6 @@ public void onPlayerCommand(SendCommandEvent event, @First Player player) {
return; 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(); GDTimings.PLAYER_COMMAND_EVENT.stopTimingIfSync();
} }
@ -461,7 +475,7 @@ public void onPlayerDispenseItem(DropItemEvent.Dispense event, @Root Entity spaw
Location<World> location = entityItem.getLocation(); Location<World> location = entityItem.getLocation();
GDClaim claim = this.dataStore.getClaimAtPlayer(playerData, location); GDClaim claim = this.dataStore.getClaimAtPlayer(playerData, location);
if (claim != null) { 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); event.setCancelled(true);
if (spawncause instanceof Player) { if (spawncause instanceof Player) {
final Component message = GriefDefenderPlugin.getInstance().messageData.getMessage(MessageStorage.PERMISSION_ITEM_DROP, final Component message = GriefDefenderPlugin.getInstance().messageData.getMessage(MessageStorage.PERMISSION_ITEM_DROP,
@ -497,7 +511,7 @@ public void onPlayerInteractInventoryOpen(InteractInventoryEvent.Open event, @Fi
GDTimings.PLAYER_INTERACT_INVENTORY_OPEN_EVENT.startTimingIfSync(); GDTimings.PLAYER_INTERACT_INVENTORY_OPEN_EVENT.startTimingIfSync();
final Location<World> location = blockSnapshot.getLocation().get(); final Location<World> location = blockSnapshot.getLocation().get();
final GDClaim claim = this.dataStore.getClaimAt(location); 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) { if (result == Tristate.FALSE) {
final Component message = GriefDefenderPlugin.getInstance().messageData.getMessage(MessageStorage.PERMISSION_INVENTORY_OPEN, final Component message = GriefDefenderPlugin.getInstance().messageData.getMessage(MessageStorage.PERMISSION_INVENTORY_OPEN,
ImmutableMap.of( ImmutableMap.of(
@ -524,7 +538,7 @@ public void onPlayerInteractInventoryClose(InteractInventoryEvent.Close event, @
GDTimings.PLAYER_INTERACT_INVENTORY_CLOSE_EVENT.startTimingIfSync(); GDTimings.PLAYER_INTERACT_INVENTORY_CLOSE_EVENT.startTimingIfSync();
final Location<World> location = player.getLocation(); final Location<World> location = player.getLocation();
final GDClaim claim = this.dataStore.getClaimAt(location); 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, final Component message = GriefDefenderPlugin.getInstance().messageData.getMessage(MessageStorage.PERMISSION_ITEM_DROP,
ImmutableMap.of( ImmutableMap.of(
"player", claim.getOwnerName(), "player", claim.getOwnerName(),
@ -552,7 +566,7 @@ public void onPlayerInteractInventoryClick(ClickInventoryEvent event, @First Pla
final ItemStackSnapshot cursorItem = event.getCursorTransaction().getOriginal(); final ItemStackSnapshot cursorItem = event.getCursorTransaction().getOriginal();
// check if original cursor item can be dropped // check if original cursor item can be dropped
if (isDrop && cursorItem != ItemStackSnapshot.NONE && !GriefDefenderPlugin.isTargetIdBlacklisted(Flags.ITEM_DROP.getName(), cursorItem, player.getWorld().getProperties())) { 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, final Component message = GriefDefenderPlugin.getInstance().messageData.getMessage(MessageStorage.PERMISSION_ITEM_DROP,
ImmutableMap.of( ImmutableMap.of(
"player", claim.getOwnerName(), "player", claim.getOwnerName(),
@ -572,7 +586,7 @@ public void onPlayerInteractInventoryClick(ClickInventoryEvent event, @First Pla
continue; 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) { if (result == Tristate.FALSE) {
Component message = GriefDefenderPlugin.getInstance().messageData.getMessage(MessageStorage.PERMISSION_INTERACT_ITEM, Component message = GriefDefenderPlugin.getInstance().messageData.getMessage(MessageStorage.PERMISSION_INTERACT_ITEM,
ImmutableMap.of( ImmutableMap.of(
@ -589,7 +603,7 @@ public void onPlayerInteractInventoryClick(ClickInventoryEvent event, @First Pla
continue; 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, final Component message = GriefDefenderPlugin.getInstance().messageData.getMessage(MessageStorage.PERMISSION_ITEM_DROP,
ImmutableMap.of( ImmutableMap.of(
"player", claim.getOwnerName(), "player", claim.getOwnerName(),
@ -630,9 +644,9 @@ public void onPlayerInteractEntity(InteractEntityEvent.Primary event, @First Pla
event.setCancelled(false); 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 (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, final Component message = GriefDefenderPlugin.getInstance().messageData.getMessage(MessageStorage.CLAIM_PROTECTED_ENTITY,
ImmutableMap.of( ImmutableMap.of(
"player", claim.getOwnerName())); "player", claim.getOwnerName()));
@ -670,9 +684,9 @@ public void onPlayerInteractEntity(InteractEntityEvent.Secondary event, @First P
return; 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) { 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) { if (result == Tristate.FALSE) {
event.setCancelled(true); event.setCancelled(true);
@ -711,7 +725,7 @@ public void onPlayerPickupItem(ChangeInventoryEvent.Pickup.Pre event, @Root Play
GDPlayerData playerData = this.dataStore.getOrCreatePlayerData(world, player.getUniqueId()); GDPlayerData playerData = this.dataStore.getOrCreatePlayerData(world, player.getUniqueId());
Location<World> location = player.getLocation(); Location<World> location = player.getLocation();
GDClaim claim = this.dataStore.getClaimAtPlayer(playerData, location); 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); event.setCancelled(true);
} }
@ -788,7 +802,7 @@ public void onPlayerUseItem(UseItemStackEvent.Start event, @First Player player)
GDPlayerData playerData = this.dataStore.getOrCreatePlayerData(location.getExtent(), player.getUniqueId()); GDPlayerData playerData = this.dataStore.getOrCreatePlayerData(location.getExtent(), player.getUniqueId());
GDClaim claim = this.dataStore.getClaimAtPlayer(playerData, location); 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) { if (result == Tristate.FALSE) {
final Component message = GriefDefenderPlugin.getInstance().messageData.getMessage(MessageStorage.PERMISSION_ITEM_USE, final Component message = GriefDefenderPlugin.getInstance().messageData.getMessage(MessageStorage.PERMISSION_ITEM_USE,
ImmutableMap.of( ImmutableMap.of(
@ -846,13 +860,13 @@ public void onPlayerInteractBlockPrimary(InteractBlockEvent.Primary.MainHand eve
} }
final GDClaim claim = this.dataStore.getClaimAt(location); 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 (result == Tristate.FALSE) {
if (GriefDefenderPlugin.isTargetIdBlacklisted(Flags.BLOCK_BREAK.getName(), clickedBlock.getState(), player.getWorld().getProperties())) { if (GriefDefenderPlugin.isTargetIdBlacklisted(Flags.BLOCK_BREAK.getName(), clickedBlock.getState(), player.getWorld().getProperties())) {
GDTimings.PLAYER_INTERACT_BLOCK_PRIMARY_EVENT.stopTimingIfSync(); GDTimings.PLAYER_INTERACT_BLOCK_PRIMARY_EVENT.stopTimingIfSync();
return; 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(); GDTimings.PLAYER_INTERACT_BLOCK_PRIMARY_EVENT.stopTimingIfSync();
return; return;
} }
@ -899,7 +913,7 @@ public void onPlayerInteractBlockSecondary(InteractBlockEvent.Secondary event, @
final TileEntity tileEntity = clickedBlock.getLocation().get().getTileEntity().orElse(null); final TileEntity tileEntity = clickedBlock.getLocation().get().getTileEntity().orElse(null);
final TrustType trustType = (tileEntity != null && NMSUtil.getInstance().containsInventory(tileEntity)) ? TrustTypes.CONTAINER : TrustTypes.ACCESSOR; final TrustType trustType = (tileEntity != null && NMSUtil.getInstance().containsInventory(tileEntity)) ? TrustTypes.CONTAINER : TrustTypes.ACCESSOR;
if (GDFlags.INTERACT_BLOCK_SECONDARY && playerData != null) { 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 (result == Tristate.FALSE) {
// if player is holding an item, check if it can be placed // if player is holding an item, check if it can be placed
if (GDFlags.BLOCK_PLACE && !itemInHand.isEmpty() && NMSUtil.getInstance().isItemBlock(itemInHand)) { if (GDFlags.BLOCK_PLACE && !itemInHand.isEmpty() && NMSUtil.getInstance().isItemBlock(itemInHand)) {
@ -907,7 +921,7 @@ public void onPlayerInteractBlockSecondary(InteractBlockEvent.Secondary event, @
GDTimings.PLAYER_INTERACT_BLOCK_SECONDARY_EVENT.stopTimingIfSync(); GDTimings.PLAYER_INTERACT_BLOCK_SECONDARY_EVENT.stopTimingIfSync();
return; 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(); GDTimings.PLAYER_INTERACT_BLOCK_SECONDARY_EVENT.stopTimingIfSync();
return; return;
} }
@ -961,11 +975,11 @@ public InteractEvent handleItemInteract(InteractEvent event, Player player, Worl
: player.getLocation(); : player.getLocation();
final GDClaim claim = this.dataStore.getClaimAt(location); 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()) || if (playerData.claimMode || (!itemInHand.isEmpty() && (itemInHand.getType().equals(GriefDefenderPlugin.getInstance().modificationTool.getType()) ||
itemInHand.getType().equals(GriefDefenderPlugin.getInstance().investigationTool.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); event.setCancelled(true);
if (investigateClaim(event, player, blockSnapshot, itemInHand)) { if (investigateClaim(event, player, blockSnapshot, itemInHand)) {
return event; return event;
@ -983,7 +997,7 @@ public InteractEvent handleItemInteract(InteractEvent event, Player player, Worl
return event; 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, Component message = GriefDefenderPlugin.getInstance().messageData.getMessage(MessageStorage.PERMISSION_INTERACT_ITEM,
ImmutableMap.of( ImmutableMap.of(
"player", claim.getOwnerName(), "player", claim.getOwnerName(),
@ -1582,7 +1596,8 @@ private boolean investigateClaim(InteractEvent event, Player player, BlockSnapsh
// if holding shift (sneaking), show all claims in area // if holding shift (sneaking), show all claims in area
GDClaim claim = null; GDClaim claim = null;
if (clickedBlock.getState().getType().equals(BlockTypes.AIR)) { 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 holding shift (sneaking), show all claims in area
if (player.get(Keys.IS_SNEAKING).get()) { if (player.get(Keys.IS_SNEAKING).get()) {
if (!playerData.canIgnoreClaim(claim) && !player.hasPermission(GDPermissions.VISUALIZE_CLAIMS_NEARBY)) { if (!playerData.canIgnoreClaim(claim) && !player.hasPermission(GDPermissions.VISUALIZE_CLAIMS_NEARBY)) {
@ -1592,7 +1607,7 @@ private boolean investigateClaim(InteractEvent event, Player player, BlockSnapsh
} }
Location<World> nearbyLocation = playerData.lastValidInspectLocation != null ? playerData.lastValidInspectLocation : player.getLocation(); 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)); int height = (int) (playerData.lastValidInspectLocation != null ? playerData.lastValidInspectLocation.getBlockY() : PlayerUtil.getInstance().getEyeHeight(player));
boolean hideBorders = this.worldEditProvider != null && boolean hideBorders = this.worldEditProvider != null &&
this.worldEditProvider.hasCUISupport(player) && this.worldEditProvider.hasCUISupport(player) &&
@ -1652,8 +1667,7 @@ private boolean investigateClaim(InteractEvent event, Player player, BlockSnapsh
return true; return true;
} }
private GDClaim findNearbyClaim(Player player) { private GDClaim findNearbyClaim(Player player, int maxDistance) {
int maxDistance = GriefDefenderPlugin.getInstance().maxInspectionDistance;
BlockRay<World> blockRay = BlockRay.from(player).distanceLimit(maxDistance).build(); BlockRay<World> blockRay = BlockRay.from(player).distanceLimit(maxDistance).build();
GDPlayerData playerData = GriefDefenderPlugin.getInstance().dataStore.getOrCreatePlayerData(player.getWorld(), player.getUniqueId()); GDPlayerData playerData = GriefDefenderPlugin.getInstance().dataStore.getOrCreatePlayerData(player.getWorld(), player.getUniqueId());
GDClaim claim = null; GDClaim claim = null;

View File

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

View File

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

View File

@ -30,12 +30,14 @@
public class ContextGroups { public class ContextGroups {
// Entity groups // 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_AMBIENT = new Context(ContextKeys.SOURCE, ContextGroupKeys.AMBIENT);
public static final Context SOURCE_ANIMAL = new Context(ContextKeys.SOURCE, ContextGroupKeys.ANIMAL); 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_AQUATIC = new Context(ContextKeys.SOURCE, ContextGroupKeys.AQUATIC);
public static final Context SOURCE_MISC = new Context(ContextKeys.SOURCE, ContextGroupKeys.MISC); 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_MONSTER = new Context(ContextKeys.SOURCE, ContextGroupKeys.MONSTER);
public static final Context SOURCE_VEHICLE = new Context(ContextKeys.SOURCE, ContextGroupKeys.VEHICLE); 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_AMBIENT = new Context(ContextKeys.TARGET, ContextGroupKeys.AMBIENT);
public static final Context TARGET_ANIMAL = new Context(ContextKeys.TARGET, ContextGroupKeys.ANIMAL); public static final Context TARGET_ANIMAL = new Context(ContextKeys.TARGET, ContextGroupKeys.ANIMAL);
public static final Context TARGET_AQUATIC = new Context(ContextKeys.TARGET, ContextGroupKeys.AQUATIC); public static final Context TARGET_AQUATIC = new Context(ContextKeys.TARGET, ContextGroupKeys.AQUATIC);

View File

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

View File

@ -97,6 +97,8 @@ public class GDPermissions {
// flags // flags
public static final String USER_CLAIM_FLAGS = "griefdefender.user.claim.flag"; 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 = "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_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_PLAYER = "griefdefender.user.claim.command.flag.player";
public static final String COMMAND_FLAGS_GROUP = "griefdefender.user.claim.command.flag.group"; 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_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_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_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_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_CLAIM_BASE = "griefdefender.admin.claim.command.delete.base";
public static final String COMMAND_DELETE_CLAIMS = "griefdefender.admin.claim.command.delete-claims"; 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_BUILDER = "griefdefender.trust.1.2";
public static final String TRUST_MANAGER = "griefdefender.trust.1"; 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) { public static String getTrustPermission(TrustType type) {
if (type == TrustTypes.ACCESSOR) { if (type == TrustTypes.ACCESSOR) {
return GDPermissions.TRUST_ACCESSOR; return GDPermissions.TRUST_ACCESSOR;

View File

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

View File

@ -22,14 +22,16 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE. * THE SOFTWARE.
*/ */
package com.griefdefender.configuration.category; package com.griefdefender.permission.option;
import ninja.leaping.configurate.objectmapping.Setting; import com.griefdefender.api.permission.Context;
import ninja.leaping.configurate.objectmapping.serialize.ConfigSerializable; import com.griefdefender.api.permission.ContextKeys;
@ConfigSerializable public class OptionContexts {
public class PvpCategory extends ConfigCategory {
@Setting(value = "combat-timeout", comment = "How long combat is considered to continue after the most recent damage.") public static final Context COMMAND_RUNAS_CONSOLE = new Context(ContextKeys.RUN_AS, "console");
public int combatTimeout = 15; 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.PermissionResult; import com.griefdefender.api.permission.PermissionResult;
import com.griefdefender.api.permission.ResultTypes; import com.griefdefender.api.permission.ResultTypes;
import com.griefdefender.api.permission.flag.Flag; import com.griefdefender.api.permission.flag.Flag;
import com.griefdefender.api.permission.flag.Flags;
import com.griefdefender.api.permission.option.Option; import com.griefdefender.api.permission.option.Option;
import com.griefdefender.cache.PermissionHolderCache; import com.griefdefender.cache.PermissionHolderCache;
import com.griefdefender.claim.GDClaim; import com.griefdefender.claim.GDClaim;
import com.griefdefender.permission.GDPermissionHolder; import com.griefdefender.permission.GDPermissionHolder;
import com.griefdefender.permission.GDPermissionManager;
import com.griefdefender.permission.GDPermissionResult; import com.griefdefender.permission.GDPermissionResult;
import com.griefdefender.permission.GDPermissionUser; import com.griefdefender.permission.GDPermissionUser;
import com.griefdefender.registry.OptionRegistryModule;
import net.kyori.text.TextComponent;
import net.luckperms.api.LuckPerms; import net.luckperms.api.LuckPerms;
import net.luckperms.api.cacheddata.CachedMetaData; import net.luckperms.api.cacheddata.CachedMetaData;
import net.luckperms.api.cacheddata.CachedPermissionData; import net.luckperms.api.cacheddata.CachedPermissionData;
@ -78,6 +77,7 @@
import java.util.TreeMap; import java.util.TreeMap;
import java.util.UUID; import java.util.UUID;
import java.util.Map.Entry; import java.util.Map.Entry;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
@ -107,6 +107,8 @@ public int compare(Set<Context> s1, Set<Context> s2) {
private final LuckPerms luckPermsApi; private final LuckPerms luckPermsApi;
private final static DefaultDataQueryOrderFunction DEFAULT_DATA_QUERY_ORDER = new DefaultDataQueryOrderFunction(); 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() { public LuckPermsProvider() {
final ProviderRegistration<LuckPerms> service = Sponge.getServiceManager().getRegistration(LuckPerms.class).orElse(null); final ProviderRegistration<LuckPerms> service = Sponge.getServiceManager().getRegistration(LuckPerms.class).orElse(null);
@ -117,6 +119,11 @@ public LuckPerms getApi() {
return this.luckPermsApi; return this.luckPermsApi;
} }
@Override
public String getServerName() {
return this.luckPermsApi.getServerName();
}
@Override @Override
public boolean hasGroupSubject(String identifier) { public boolean hasGroupSubject(String identifier) {
return this.getGroupSubject(identifier) != null; return this.getGroupSubject(identifier) != null;
@ -715,44 +722,65 @@ public String getOptionValue(GDPermissionHolder holder, Option option, Set<Conte
return metaData.getMetaValue(option.getPermission()); 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; DataMutateResult result = null;
ImmutableContextSet set = this.getLPContexts(contexts).immutableCopy(); ImmutableContextSet set = this.getLPContexts(contexts).immutableCopy();
final PermissionHolder permissionHolder = this.getLuckPermsHolder(holder); final PermissionHolder permissionHolder = this.getLuckPermsHolder(holder);
if (permissionHolder == null) { if (permissionHolder == null) {
return new GDPermissionResult(ResultTypes.FAILURE); return RESULT_FAILURE;
} }
// Always unset existing meta first final Option option = OptionRegistryModule.getInstance().getById(key).orElse(null);
final Node currentNode = this.luckPermsApi.getNodeBuilderRegistry().forMeta().key(permission).context(set).build(); if (option == null) {
result = permissionHolder.data().remove(currentNode); 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 (!value.equalsIgnoreCase("undefined")) {
if (!option.multiValued()) {
this.clearMeta(permissionHolder, key, set);
}
result = permissionHolder.data().add(node); result = permissionHolder.data().add(node);
} } else {
if (result != null && result.wasSuccessful()) { this.clearMeta(permissionHolder, key, set);
this.savePermissionHolder(permissionHolder); 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());
} }
public PermissionResult setPermissionValue(GDPermissionHolder holder, Flag flag, Tristate value, Set<Context> contexts) { return RESULT_FAILURE;
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; DataMutateResult result = null;
ImmutableContextSet set = this.getLPContexts(contexts).immutableCopy(); ImmutableContextSet set = this.getLPContexts(contexts).immutableCopy();
final Node node = this.luckPermsApi.getNodeBuilderRegistry().forPermission().permission(permission).value(value.asBoolean()).context(set).build(); final Node node = this.luckPermsApi.getNodeBuilderRegistry().forPermission().permission(permission).value(value.asBoolean()).context(set).build();
final PermissionHolder permissionHolder = this.getLuckPermsHolder(holder); final PermissionHolder permissionHolder = this.getLuckPermsHolder(holder);
if (permissionHolder == null) { if (permissionHolder == null) {
return false; return RESULT_FAILURE;
} }
if (value == Tristate.UNDEFINED) { if (value == Tristate.UNDEFINED) {
@ -763,11 +791,6 @@ public boolean setPermissionValue(GDPermissionHolder holder, String permission,
if (result.wasSuccessful()) { if (result.wasSuccessful()) {
if (permissionHolder instanceof Group) { 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 // If a group is changed, we invalidate all cache
PermissionHolderCache.getInstance().invalidateAllPermissionCache(); PermissionHolderCache.getInstance().invalidateAllPermissionCache();
} else { } else {
@ -775,9 +798,14 @@ public boolean setPermissionValue(GDPermissionHolder holder, String permission,
PermissionHolderCache.getInstance().getOrCreatePermissionCache(holder).invalidateAll(); PermissionHolderCache.getInstance().getOrCreatePermissionCache(holder).invalidateAll();
} }
if (save) {
this.savePermissionHolder(permissionHolder); this.savePermissionHolder(permissionHolder);
} }
return result.wasSuccessful();
return new GDPermissionResult(ResultTypes.SUCCESS, TextComponent.builder().append(result.name()).build());
}
return new GDPermissionResult(ResultTypes.FAILURE, TextComponent.builder().append(result.name()).build());
} }
public void setTransientOption(GDPermissionHolder holder, String permission, String value, Set<Context> contexts) { public void setTransientOption(GDPermissionHolder holder, String permission, String value, Set<Context> contexts) {
@ -798,7 +826,7 @@ public void setTransientPermission(GDPermissionHolder holder, String permission,
return; 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); permissionHolder.transientData().add(node);
} }
@ -818,6 +846,20 @@ public void refreshCachedData(GDPermissionHolder holder) {
permissionHolder.getCachedData().invalidate(); 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) { public Set<Context> getGDContexts(ContextSet contexts) {
final Set<Context> gdContexts = new HashSet<>(); final Set<Context> gdContexts = new HashSet<>();
contexts.forEach(entry -> { contexts.forEach(entry -> {
@ -846,6 +888,10 @@ public Tristate getGDTristate(net.luckperms.api.util.Tristate state) {
return Tristate.UNDEFINED; 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 { private static class DefaultDataQueryOrderFunction implements DataQueryOrderFunction {
@Override @Override

View File

@ -28,6 +28,7 @@
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
import java.util.UUID; import java.util.UUID;
import java.util.concurrent.CompletableFuture;
import org.checkerframework.checker.nullness.qual.Nullable; import org.checkerframework.checker.nullness.qual.Nullable;
@ -49,6 +50,13 @@
*/ */
public interface PermissionProvider { public interface PermissionProvider {
/**
* Get server name.
*
* @return The server name
*/
String getServerName();
/** /**
* Checks if the group identifier exists. * Checks if the group identifier exists.
* *
@ -273,6 +281,18 @@ public interface PermissionProvider {
*/ */
String getOptionValue(GDPermissionHolder holder, Option option, Set<Context> contexts); 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. * Sets an option and value with contexts to a holder.
* *
@ -293,7 +313,23 @@ public interface PermissionProvider {
* @param contexts The contexts * @param contexts The contexts
* @return The permission result * @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. * Sets a permission and value with contexts to a holder.
@ -304,7 +340,21 @@ public interface PermissionProvider {
* @param contexts The contexts * @param contexts The contexts
* @return Whether the set permission operation was successful * @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. * Sets a transient option and value with contexts to a holder.
@ -334,4 +384,12 @@ public interface PermissionProvider {
* @param holder The holder * @param holder The holder
*/ */
void refreshCachedData(GDPermissionHolder 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 java.util.Collection; import java.util.Collection;
import java.util.HashMap; import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Locale; import java.util.Locale;
import java.util.Map; import java.util.Map;
import java.util.Optional; import java.util.Optional;
import java.util.Set;
@SuppressWarnings("rawtypes") @SuppressWarnings("rawtypes")
public class OptionRegistryModule implements CatalogRegistryModule<Option> { public class OptionRegistryModule implements CatalogRegistryModule<Option> {
@ -111,7 +114,8 @@ public void registerDefaults() {
this.createKey("griefdefender:radius-inspect", "radius-inspect", Integer.class); this.createKey("griefdefender:radius-inspect", "radius-inspect", Integer.class);
this.createKey("griefdefender:raid", "raid", Boolean.class); this.createKey("griefdefender:raid", "raid", Boolean.class);
this.createKey("griefdefender:spawn-limit", "spawn-limit", Integer.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-flight", "player-deny-flight", Boolean.class);
this.createKey("griefdefender:player-deny-godmode", "player-deny-godmode", Boolean.class); this.createKey("griefdefender:player-deny-godmode", "player-deny-godmode", Boolean.class);
this.createKey("griefdefender:player-deny-hunger", "player-deny-hunger", Boolean.class); this.createKey("griefdefender:player-deny-hunger", "player-deny-hunger", Boolean.class);
@ -120,9 +124,12 @@ public void registerDefaults() {
this.createKey("griefdefender:player-keep-inventory", "player-keep-inventory", Tristate.class); 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-keep-level", "player-keep-level", Tristate.class);
this.createKey("griefdefender:player-teleport-delay", "player-teleport-delay", Integer.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:player-weather", "player-weather", WeatherType.class);
this.createKey("griefdefender:pvp", "pvp", Tristate.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 -> { RegistryHelper.mapFields(Options.class, input -> {
final String name = input.replace("_", "-"); final String name = input.replace("_", "-");
@ -131,7 +138,15 @@ public void registerDefaults() {
} }
private void createKey(String id, String name, Class<?> clazz) { 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 @Override

View File

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

View File

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

View File

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

View File

@ -24,6 +24,8 @@
*/ */
package com.griefdefender.util; package com.griefdefender.util;
import com.google.common.collect.BiMap;
import com.google.common.collect.ImmutableBiMap;
import com.griefdefender.GDPlayerData; import com.griefdefender.GDPlayerData;
import com.griefdefender.GriefDefenderPlugin; import com.griefdefender.GriefDefenderPlugin;
import com.griefdefender.api.claim.ClaimType; import com.griefdefender.api.claim.ClaimType;
@ -31,6 +33,10 @@
import com.griefdefender.api.claim.ShovelType; import com.griefdefender.api.claim.ShovelType;
import com.griefdefender.api.claim.ShovelTypes; import com.griefdefender.api.claim.ShovelTypes;
import com.griefdefender.api.permission.option.type.CreateModeTypes; 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.cache.PermissionHolderCache;
import com.griefdefender.internal.visual.ClaimVisual; import com.griefdefender.internal.visual.ClaimVisual;
import com.griefdefender.internal.visual.GDClaimVisualType; import com.griefdefender.internal.visual.GDClaimVisualType;
@ -38,11 +44,15 @@
import net.kyori.text.Component; import net.kyori.text.Component;
import net.kyori.text.TextComponent; import net.kyori.text.TextComponent;
import net.kyori.text.format.TextColor; 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.Sponge;
import org.spongepowered.api.data.property.entity.EyeLocationProperty; import org.spongepowered.api.data.property.entity.EyeLocationProperty;
import org.spongepowered.api.data.type.HandTypes; import org.spongepowered.api.data.type.HandTypes;
import org.spongepowered.api.entity.living.player.Player; import org.spongepowered.api.entity.living.player.Player;
import org.spongepowered.api.entity.living.player.User; 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.ItemType;
import org.spongepowered.api.item.inventory.ItemStack; import org.spongepowered.api.item.inventory.ItemStack;
import org.spongepowered.api.service.user.UserStorageService; import org.spongepowered.api.service.user.UserStorageService;
@ -56,6 +66,16 @@
public class PlayerUtil { public class PlayerUtil {
private static Direction[] faces = { Direction.NORTH, Direction.EAST, Direction.SOUTH, Direction.WEST}; 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; private static PlayerUtil instance;
@ -204,4 +224,23 @@ public int getVisualClaimHeight(GDPlayerData playerData, int height) {
} }
return 0; 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": [ "libraries": [
{ {
"name": "com.griefdefender:api:1.0.0", "name": "com.griefdefender:api:1.0.0",
"sha1": "fb161e9877869876bbf07131c1a7682d37c6664d", "sha1": "a87c88ecf7f4aaa4cc18decef9f0cbb013a0e602",
"path": "com/griefdefender/api/1.0.0-SNAPSHOT/api-1.0.0-20191219.230903-12.jar", "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-20191219.230903-12.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", "name": "com.griefdefender:reflect-helper:1.0",

View File

@ -157,9 +157,9 @@ GriefDefender {
claimlist-ui-title=Grundstücksliste claimlist-ui-title=Grundstücksliste
claimlist-ui-title-child-claims=Teilgrundstücke claimlist-ui-title-child-claims=Teilgrundstücke
command-blocked="&cDer Befehl &f{command}&c wurde vom Grundstücksbesitzer &6{player}&c deaktiviert." 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-block="&aErfolgreich folgenden Block &cgeblockt&a: {id}."
command-claimban-success-entity="&aErfolgreich folgendes Objekt &cgeblockt: &a{id}." command-claimban-success-entity="&aErfolgreich folgendes Objekt &cgeblock&at: {id}."
command-claimban-success-item="&aErfolgreich folgendes Item &cgeblockt: &a{id}." command-claimban-success-item="&aErfolgreich folgendes Item &cgeblockt&a: {id}."
command-claimbuy-title="&bKäufliche Grundstücke." command-claimbuy-title="&bKäufliche Grundstücke."
command-claimclear-killed="&c&6{amount}&a Objekte vom Typ {type} getötet&f." 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." 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-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-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-claimspawn-not-found="&aKein Grundstück {name}&a gefunden."
command-claimunban-success-block="&aErfolgreich folgenden Block &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-entity="&aErfolgreich folgendes Objekt &centblockt&a: {id}."
command-claimunban-success-item="&aErfolgreich folgendes Item &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-disabled="&aGrundstücksmodus: 2D (Automatisch von 0 bis maximale Bauhöhe)."
command-cuboid-enabled="&aGrundstücksmodus: 3D." command-cuboid-enabled="&aGrundstücksmodus: 3D."
command-execute-failed="&cKonnte den Befehl '{command} {args}' nicht ausführen." 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." command-worldedit-missing="&cDieser Befehl benötigt installiertes WorldEdit auf dem Server."
create-cancel="&cDie Erstellung des Grundstückes wurde abgebrochen." 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-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-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-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})" 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-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-subdivision="&aUnterteilungsmodus. Unterteile deine existierendes Grundstück. Nutze &f/modebasic&a zum Verlassen."
mode-town="&aStadt-Erstellungsmodus aktiviert." 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-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-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." 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-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-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-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-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-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." 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-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-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-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-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-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-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-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="&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-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." 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-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-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-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-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-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." 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-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-edit-claim="&cDu hast keine Berechtigung dieses Grundstück zu bearbeiten."
permission-fire-spread="&cDu hast keine Berechtigung Feuer zu legen." 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-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-overrides="&cDu hast keine Berechtigung überschreibende Einstellungen zu verwalten."
permission-flag-use="&cDu hast keine Berechtigung diese Einstellung zu nutzen." 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." 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-not-found="&cKonnte kein Plugin &b{id}&c finden."
plugin-reload="&aGriefDefender neu geladen." plugin-reload="&aGriefDefender neu geladen."
pvp-claim-not-allowed="&aPvP ist auf diesem Grundstück nicht erlaubt." 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-source-not-allowed="&aPvP ist für dich nicht erlaubt."
pvp-target-not-allowed="&aDu kannst keine Spieler attackieren, die PvP ausgestellt haben." 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." 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-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-subdivision="&aSubdivision creation mode enabled. Use &f/modebasic&a to exit."
mode-town="&aTown creation mode enabled." 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-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-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." 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-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-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-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-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-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." 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-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-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-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-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-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-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-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="&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-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." 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-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-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-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-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-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." 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-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-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-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-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-overrides="&cYou don't have permission to manage flag overrides."
permission-flag-use="&cYou don't have permission to use this flag." 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." 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-not-found="&cCould not locate plugin with id &b{id}&c."
plugin-reload="&aGriefDefender has been reloaded." plugin-reload="&aGriefDefender has been reloaded."
pvp-claim-not-allowed="&aYou are not allowed to PvP in this claim." 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-source-not-allowed="&aYou are not allowed to PvP."
pvp-target-not-allowed="&aYou cannot attack players who are not participating in 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." 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-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-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." 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-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-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." 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-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-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-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-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-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." 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-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-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-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-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-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-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-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="&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-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." 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-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-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-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-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-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}'" 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-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-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-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-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-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-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." 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-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." 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-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-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." 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." 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-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-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é." 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-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-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." 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-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-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-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-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-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." 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-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-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-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-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-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-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-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="&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-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." 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-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-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-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-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-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." 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-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-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-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-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-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-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." 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-not-found="&cImpossible de localiser le plug-in avec l'id &b{id}&c."
plugin-reload="&aGriefDefender a été rechargé." plugin-reload="&aGriefDefender a été rechargé."
pvp-claim-not-allowed="&aTu n'as pas le droit de PvP dans cette protection." 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-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." 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." 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-nature="&aГотов восстанавливать природу! ПКМ для начала, &f/modebasic&c - для выхода из режима."
mode-subdivision="&aВключён режим создания суб-регионов. Используйте лопату, чтобы создавать суб-регионы в существующих регионах. Воспользуйтесь &f/modebasic&a, чтобы выйти из этого режима." mode-subdivision="&aВключён режим создания суб-регионов. Используйте лопату, чтобы создавать суб-регионы в существующих регионах. Воспользуйтесь &f/modebasic&a, чтобы выйти из этого режима."
mode-town="&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-delay="&aКоличество дней до того, как свежесозданный регион может быть удалён."
option-description-abandon-return-ratio="&aДоля базовых блоков региона, возвращаемых игроку при удалении региона." option-description-abandon-return-ratio="&aДоля базовых блоков региона, возвращаемых игроку при удалении региона."
option-description-blocks-accrued-per-hour="&aЗарабатываемые блоки в час.\n&dПримечание&f: См. /playerinfo." 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-x="&aМинимальный размер региона по оси x."
option-description-min-size-y="&aМинимальный размер региона по оси y." option-description-min-size-y="&aМинимальный размер региона по оси y."
option-description-min-size-z="&aМинимальный размер региона по оси z." 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-flight="&aОпределяет, может ли игрок летать в регионе.\n&dПримечание&f: не даёт игрокам возможность летать, только удаляет её при необходимости. Даёт наибольшую совместимость с другими плагинами."
option-description-player-deny-godmode="&aОпределяет, может ли игрок быть в режиме бога в регионе.\n&dПримечание&f: не даёт игрокам возможность входить в режим бога, только удаляет её при необходимости. Даёт наибольшую совместимость с другими плагинами." option-description-player-deny-godmode="&aОпределяет, может ли игрок быть в режиме бога в регионе.\n&dПримечание&f: не даёт игрокам возможность входить в режим бога, только удаляет её при необходимости. Даёт наибольшую совместимость с другими плагинами."
option-description-player-deny-hunger="&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-health-regen="&aОпределяет скорость восстановления здоровья игроков в регионе.\n&dПримечание&f: не имеет эффекта на игроков с полным запасом здоровья. \n&dПримечание&f: значение &6-1&f отключает эту опцию."
option-description-player-keep-inventory="&aОпределяет, сохранит ли игрок содержимое своего инвентаря при смерти в регионе." option-description-player-keep-inventory="&aОпределяет, сохранит ли игрок содержимое своего инвентаря при смерти в регионе."
option-description-player-keep-level="&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-walk-speed="&aОпределяет скорость ходьбы игроков в регионе.\n&dПримечание&f: значение &6-1&f отключает эту опцию."
option-description-player-weather="&aОпределяет погоду для игрока в регионе." 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-inspect="&aРадиус в блоках для поиска регионов поблизости при инспектировании."
option-description-radius-list="&aРадиус в блоках для составления списка регионов поблизости." option-description-radius-list="&aРадиус в блоках для составления списка регионов поблизости."
option-description-spawn-limit="&aОпределяет предел появления сущностей в регионе для определённых контекстов."
option-description-tax-expiration="&aКоличество дней без оплаты налогов, после которых регион будет заморожен.\n&dПримечание&f: заморозка означает отсутствие доступа к строительству и инвентарям в регионе до совершения оплаты." option-description-tax-expiration="&aКоличество дней без оплаты налогов, после которых регион будет заморожен.\n&dПримечание&f: заморозка означает отсутствие доступа к строительству и инвентарям в регионе до совершения оплаты."
option-description-tax-expiration-days-keep="&aКоличество дней после заморозки региона до его удаления.\n&dПримечание&f: по истечении срока регион может быть просто удалён или откачен на состояние при создании. Это зависит от настроек сервера. Свяжитесь с администратором для дополнительной информации." option-description-tax-expiration-days-keep="&aКоличество дней после заморозки региона до его удаления.\n&dПримечание&f: по истечении срока регион может быть просто удалён или откачен на состояние при создании. Это зависит от настроек сервера. Свяжитесь с администратором для дополнительной информации."
option-description-tax-rate="&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-not-set="&a{option}&f не установлена.\nПрименяется стандартное значение &a{value}&f."
option-override-not-supported="&cРегионы вида &f{type}&c не поддерживают переопределение опций." option-override-not-supported="&cРегионы вида &f{type}&c не поддерживают переопределение опций."
option-player-deny-flight="&cУ вас нет разрешения на полёт в этом регионе. Вы были телепортированы на безопасное место на земле." option-player-deny-flight="&cУ вас нет разрешения на полёт в этом регионе. Вы были телепортированы на безопасное место на земле."
option-requires-contexts="&cЭта опция требует следующие контексты: '&a{contexts}&c'."
option-reset-success="&aОпции региона успешно откачены на стандартные значения." option-reset-success="&aОпции региона успешно откачены на стандартные значения."
option-set-target="&aОпция &b{option}&a вида &b{type}&a с контекстами &7{contexts}&a установлена в значение {value}&a для &6{target}&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." option-ui-click-toggle="Нажмите здесь, чтобы переключить опцию &f{option}&r."
@ -494,7 +508,9 @@ GriefDefender {
permission-cuboid="&cУ вас нет разрешения на создание/изменение размера базовых регионов в 3D-режиме." permission-cuboid="&cУ вас нет разрешения на создание/изменение размера базовых регионов в 3D-режиме."
permission-edit-claim="&cУ вас нет разрешения на изменение этого региона." permission-edit-claim="&cУ вас нет разрешения на изменение этого региона."
permission-fire-spread="&cУ вас нет разрешения на поджигание блоков в этом регионе." permission-fire-spread="&cУ вас нет разрешения на поджигание блоков в этом регионе."
permission-flag-arg="&cУ вас нет разрешения на использование команды flag с аргументами."
permission-flag-defaults="&cУ вас нет разрешения на изменение стандартных значений флагов." permission-flag-defaults="&cУ вас нет разрешения на изменение стандартных значений флагов."
permission-flag-gui="&cУ вас нет разрешения на использование GUI флагов."
permission-flag-overrides="&cУ вас нет разрешения на редактирование переопределённых значений флагов." permission-flag-overrides="&cУ вас нет разрешения на редактирование переопределённых значений флагов."
permission-flag-use="&cУ вас нет разрешения на использование этого флага." permission-flag-use="&cУ вас нет разрешения на использование этого флага."
permission-flow-liquid="&cУ вас нет разрешения на разливание жидкостей в этом регионе." permission-flow-liquid="&cУ вас нет разрешения на разливание жидкостей в этом регионе."
@ -551,6 +567,7 @@ GriefDefender {
plugin-not-found="&cНе удалось найти плагин с идентификатором &b{id}&c." plugin-not-found="&cНе удалось найти плагин с идентификатором &b{id}&c."
plugin-reload="&aGriefDefender перезагружен." plugin-reload="&aGriefDefender перезагружен."
pvp-claim-not-allowed="&aВ этом регионе сражения между игроками запрещены." pvp-claim-not-allowed="&aВ этом регионе сражения между игроками запрещены."
pvp-in-combat-not-allowed="&aВы не можете выполнить это действие, находясь в PvP-драке. Вы должны быть в безопасности ещё &6{time-remaining}&a секунд."
pvp-source-not-allowed="&aУ вас нет разрешения на сражение с другим игроком." pvp-source-not-allowed="&aУ вас нет разрешения на сражение с другим игроком."
pvp-target-not-allowed="&aВы не можете атаковать игроков, которые не могут участвовать в сражениях." pvp-target-not-allowed="&aВы не можете атаковать игроков, которые не могут участвовать в сражениях."
registry-block-not-found="&cБлок {id}&c не найден в реестре." registry-block-not-found="&cБлок {id}&c не найден в реестре."