More improvements and fixes.

* Add '/trapped' command to assist players when stuck.
  - Use setting 'player-trapped-cooldown' in 'global.conf' to configure the cooldown of this command. Default '300' seconds.
  - Use option 'player-teleport-delay' to add a delay when used.
* Add '/unlockdrops' command to unlock protected item drops after death.
  - Use option 'player-item-drop-lock' to control item drop protection on death.
  - Use option 'pvp-item-drop-lock' to control item drop protection on pvp death.
  Note: In order to use this feature, one of the item drop options must be enabled in 'options.conf'
* Add setting 'explosion-surface-block-level' to control surface block level during explosions. Fixes #280
* Verify chunk is loaded before sending block change to player. Fixes #309
* Remove 'player-deny-flight' option cache. Fixes #308
* Improve player afk location handling.
* Improve option config lookups.
* Update GriefDefenderAPI.
This commit is contained in:
bloodshot 2020-11-17 02:22:52 -05:00
parent 4db8346de1
commit 11d9f1f278
62 changed files with 1108 additions and 197 deletions

@ -1 +1 @@
Subproject commit f1b2d4fc1646f06f9ef9aa6f5a07f13abb7cf60b
Subproject commit 920a6101dc1a616c431321fffa31516b951b2fa8

View File

@ -110,6 +110,8 @@ public class GDPlayerData implements PlayerData {
public boolean debugClaimPermissions = false;
public boolean inTown = false;
public boolean townChat = false;
public boolean lockPlayerDeathDrops = false;
public boolean trappedRequest = false;
public List<Component> chatLines = new ArrayList<>();
public Instant recordChatTimestamp;
public Instant commandInputTimestamp;
@ -140,6 +142,7 @@ public class GDPlayerData implements PlayerData {
public Location teleportLocation;
public Instant lastPvpTimestamp;
public Instant lastTrappedTimestamp;
// cached global option values
public int minClaimLevel;
@ -170,7 +173,6 @@ public class GDPlayerData implements PlayerData {
public boolean userOptionBypassPlayerGamemode = false;
// option cache
public Boolean optionNoFly = null;
public Boolean optionNoGodMode = null;
public Double optionFlySpeed = null;
public Double optionWalkSpeed = null;
@ -356,8 +358,8 @@ private void revertVisualBlocks(Player player, GDClaim claim, UUID visualUniqueI
for (int i = 0; i < visualTransactions.size(); i++) {
BlockSnapshot snapshot = visualTransactions.get(i).getOriginal();
// If original block does not exist, do not send to player
if (!snapshot.matchesWorldState()) {
// If original block does not exist or chunk is not loaded, do not send to player
if (!snapshot.matchesWorldState() || !snapshot.getLocation().getChunk().isLoaded()) {
if (claim != null) {
claim.markVisualDirty = true;
}
@ -794,7 +796,7 @@ public int getPvpCombatTimeRemaining(GDClaim claim) {
final Instant now = Instant.now();
int combatTimeout = 0;
if (GDOptions.isOptionEnabled(Options.PVP_COMBAT_TIMEOUT)) {
if (GDOptions.PVP_COMBAT_TIMEOUT) {
combatTimeout = GDPermissionManager.getInstance().getInternalOptionValue(TypeToken.of(Integer.class), player, Options.PVP_COMBAT_TIMEOUT, claim);
}
if (combatTimeout <= 0) {
@ -860,7 +862,6 @@ public void onClaimDelete() {
}
public void resetOptionCache() {
this.optionNoFly = null;
this.optionNoGodMode = null;
this.optionFlySpeed = null;
this.optionWalkSpeed = null;

View File

@ -161,6 +161,8 @@
import com.griefdefender.command.CommandUntrustPlayerAll;
import com.griefdefender.command.gphelper.CommandAccessTrust;
import com.griefdefender.command.gphelper.CommandContainerTrust;
import com.griefdefender.command.gphelper.CommandTrapped;
import com.griefdefender.command.gphelper.CommandUnlockDrops;
import com.griefdefender.configuration.FlagConfig;
import com.griefdefender.configuration.GriefDefenderConfig;
import com.griefdefender.configuration.MessageDataConfig;
@ -203,6 +205,7 @@
import com.griefdefender.permission.flag.GDFlagData;
import com.griefdefender.permission.flag.GDFlagDefinition;
import com.griefdefender.permission.flag.GDFlags;
import com.griefdefender.permission.option.GDOptions;
import com.griefdefender.provider.DynmapProvider;
import com.griefdefender.provider.LuckPermsProvider;
import com.griefdefender.provider.PermissionProvider;
@ -557,7 +560,6 @@ public void onEnable(boolean reload) {
CreateModeTypeRegistryModule.getInstance().registerDefaults();
GameModeTypeRegistryModule.getInstance().registerDefaults();
WeatherTypeRegistryModule.getInstance().registerDefaults();
OptionRegistryModule.getInstance().registerDefaults();
if (!reload) {
GriefDefender.getRegistry().registerBuilderSupplier(PaymentTransaction.Builder.class, GDPaymentTransaction.PaymentTransactionBuilder::new);
GriefDefender.getRegistry().registerBuilderSupplier(Claim.Builder.class, GDClaim.ClaimBuilder::new);
@ -815,10 +817,12 @@ public void registerBaseCommands() {
manager.registerCommand(new CommandSetAccruedClaimBlocks());
manager.registerCommand(new CommandTownChat());
manager.registerCommand(new CommandTownTag());
manager.registerCommand(new CommandTrapped());
manager.registerCommand(new CommandTrustGroup());
manager.registerCommand(new CommandTrustPlayer());
manager.registerCommand(new CommandTrustGroupAll());
manager.registerCommand(new CommandTrustPlayerAll());
manager.registerCommand(new CommandUnlockDrops());
manager.registerCommand(new CommandUntrustGroup());
manager.registerCommand(new CommandUntrustPlayer());
manager.registerCommand(new CommandUntrustGroupAll());
@ -1066,12 +1070,14 @@ public void loadConfig() {
flagConfig.save();
flagConfig.getConfig().defaultFlagCategory.refreshFlags();
flagConfig.save();
OptionRegistryModule.getInstance().registerDefaults();
optionConfig = new OptionConfig(this.getConfigPath().resolve("options.conf"));
optionConfig.getConfig().defaultOptionCategory.checkOptions();
optionConfig.save();
BaseStorage.globalConfig.save();
BaseStorage.USE_GLOBAL_PLAYER_STORAGE = !BaseStorage.globalConfig.getConfig().playerdata.useWorldPlayerData();
GDFlags.populateFlagStatus();
GDOptions.populateOptionStatus();
CLAIM_BLOCK_SYSTEM = BaseStorage.globalConfig.getConfig().playerdata.claimBlockSystem;
final GDBlockType defaultCreateVisualBlock = BlockTypeRegistryModule.getInstance().getById("minecraft:diamond_block").orElse(null);
this.createVisualBlock = BlockTypeRegistryModule.getInstance().getById(BaseStorage.globalConfig.getConfig().visual.claimCreateStartBlock).orElse(defaultCreateVisualBlock);

View File

@ -134,6 +134,12 @@ public static MessageCache getInstance() {
public Component COMMAND_PET_CONFIRMATION;
public Component COMMAND_PET_TRANSFER_READY;
public Component COMMAND_PET_TRANSFER_CANCEL;
public Component COMMAND_TRAPPED_BUILD_ACCESS;
public Component COMMAND_TRAPPED_CANCEL_MOVE;
public Component COMMAND_TRAPPED_PVP_COMBAT;
public Component COMMAND_TRAPPED_SUCCESS;
public Component COMMAND_UNLOCK_DROPS;
public Component COMMAND_UNLOCK_DROPS_NONE;
public Component COMMAND_WORLDEDIT_MISSING;
public Component CONFIRM_NOT_FOUND;
public Component CREATE_CANCEL;
@ -318,6 +324,7 @@ public static MessageCache getInstance() {
public Component LABEL_DEFAULT;
public Component LABEL_DISPLAYING;
public Component LABEL_EXPIRED;
public Component LABEL_FALSE;
public Component LABEL_FAREWELL;
public Component LABEL_FILTER;
public Component LABEL_FLAG;
@ -353,11 +360,12 @@ public static MessageCache getInstance() {
public Component LABEL_SPAWN;
public Component LABEL_STATUS;
public Component LABEL_TARGET;
public Component LABEL_TRUE;
public Component LABEL_TRUST;
public Component LABEL_TYPE;
public Component LABEL_WORLD;
public Component LABEL_UNKNOWN;
public Component LABEL_USER;
public Component LABEL_WORLD;
public Component LABEL_YES;
public Component MODE_ADMIN;
public Component MODE_BASIC;
@ -435,6 +443,7 @@ public static MessageCache getInstance() {
public Component PERMISSION_PLAYER_VIEW_OTHERS;
public Component PERMISSION_TAX;
public Component PERMISSION_VISUAL_CLAIMS_NEARBY;
public Component PLAYER_ITEM_DROPS_LOCK;
public Component PLUGIN_EVENT_CANCEL;
public Component PLUGIN_RELOAD;
public Component PVP_CLAIM_NOT_ALLOWED;
@ -599,6 +608,12 @@ public void loadCache() {
COMMAND_PET_CONFIRMATION = MessageStorage.MESSAGE_DATA.getMessage("command-pet-confirmation");
COMMAND_PET_TRANSFER_READY = MessageStorage.MESSAGE_DATA.getMessage("command-pet-transfer-ready");
COMMAND_PET_TRANSFER_CANCEL = MessageStorage.MESSAGE_DATA.getMessage("command-pet-transfer-cancel");
COMMAND_TRAPPED_BUILD_ACCESS = MessageStorage.MESSAGE_DATA.getMessage("command-trapped-build-access");
COMMAND_TRAPPED_CANCEL_MOVE = MessageStorage.MESSAGE_DATA.getMessage("command-trapped-cancel-move");
COMMAND_TRAPPED_PVP_COMBAT = MessageStorage.MESSAGE_DATA.getMessage("command-trapped-pvp-combat");
COMMAND_TRAPPED_SUCCESS = MessageStorage.MESSAGE_DATA.getMessage("command-trapped-success");
COMMAND_UNLOCK_DROPS = MessageStorage.MESSAGE_DATA.getMessage("command-unlock-drops");
COMMAND_UNLOCK_DROPS_NONE = MessageStorage.MESSAGE_DATA.getMessage("command-unlock-drops-none");
COMMAND_WORLDEDIT_MISSING = MessageStorage.MESSAGE_DATA.getMessage("command-worldedit-missing");
CONFIRM_NOT_FOUND = MessageStorage.MESSAGE_DATA.getMessage("confirm-not-found");
CREATE_CANCEL = MessageStorage.MESSAGE_DATA.getMessage("create-cancel");
@ -781,6 +796,7 @@ public void loadCache() {
LABEL_DEFAULT = MessageStorage.MESSAGE_DATA.getMessage("label-default");
LABEL_DISPLAYING = MessageStorage.MESSAGE_DATA.getMessage("label-displaying");
LABEL_EXPIRED = MessageStorage.MESSAGE_DATA.getMessage("label-expired");
LABEL_FALSE = MessageStorage.MESSAGE_DATA.getMessage("label-false");
LABEL_FAREWELL = MessageStorage.MESSAGE_DATA.getMessage("label-farewell");
LABEL_FILTER = MessageStorage.MESSAGE_DATA.getMessage("label-filter");
LABEL_FLAG = MessageStorage.MESSAGE_DATA.getMessage("label-flag");
@ -816,6 +832,7 @@ public void loadCache() {
LABEL_SPAWN = MessageStorage.MESSAGE_DATA.getMessage("label-spawn");
LABEL_STATUS = MessageStorage.MESSAGE_DATA.getMessage("label-status");
LABEL_TARGET = MessageStorage.MESSAGE_DATA.getMessage("label-target");
LABEL_TRUE = MessageStorage.MESSAGE_DATA.getMessage("label-true");
LABEL_TRUST = MessageStorage.MESSAGE_DATA.getMessage("label-trust");
LABEL_TYPE = MessageStorage.MESSAGE_DATA.getMessage("label-type");
LABEL_UNKNOWN = MessageStorage.MESSAGE_DATA.getMessage("label-unknown");
@ -898,6 +915,7 @@ public void loadCache() {
PERMISSION_PLAYER_VIEW_OTHERS = MessageStorage.MESSAGE_DATA.getMessage("permission-player-view-others");
PERMISSION_TAX = MessageStorage.MESSAGE_DATA.getMessage("permission-tax");
PERMISSION_VISUAL_CLAIMS_NEARBY = MessageStorage.MESSAGE_DATA.getMessage("permission-visual-claims-nearby");
PLAYER_ITEM_DROPS_LOCK = MessageStorage.MESSAGE_DATA.getMessage("player-item-drops-lock");
PLUGIN_EVENT_CANCEL = MessageStorage.MESSAGE_DATA.getMessage("plugin-event-cancel");
PLUGIN_RELOAD = MessageStorage.MESSAGE_DATA.getMessage("plugin-reload");
PVP_CLAIM_NOT_ALLOWED = MessageStorage.MESSAGE_DATA.getMessage("pvp-claim-not-allowed");

View File

@ -107,7 +107,7 @@ public void execute(Player player, @Optional String claimName, @Optional Offline
final Location spawnLocation = new Location(claim.getWorld(), spawnPos.getX(), spawnPos.getY(), spawnPos.getZ());
int teleportDelay = 0;
if (GDOptions.isOptionEnabled(Options.PLAYER_TELEPORT_DELAY)) {
if (GDOptions.PLAYER_TELEPORT_DELAY) {
teleportDelay = GDPermissionManager.getInstance().getInternalOptionValue(TypeToken.of(Integer.class), player, Options.PLAYER_TELEPORT_DELAY, claim);
}
if (teleportDelay > 0) {

View File

@ -29,6 +29,7 @@
import co.aikar.commands.annotation.CommandCompletion;
import co.aikar.commands.annotation.CommandPermission;
import co.aikar.commands.annotation.Description;
import co.aikar.commands.annotation.Optional;
import co.aikar.commands.annotation.Subcommand;
import co.aikar.commands.annotation.Syntax;
@ -70,13 +71,18 @@ public class CommandTrustGroup extends BaseCommand {
+ "\nContainer: access to interact with all blocks including inventory."
+ "\nBuilder: access to everything above including ability to place and break blocks."
+ "\nManager: access to everything above including ability to manage claim settings.")
@Syntax("<group> <accessor|builder|container|manager>")
@Syntax("<group> [<accessor|builder|container|manager>]")
@Subcommand("trust group")
public void execute(Player player, String groupName, String type) {
final TrustType trustType = CommandHelper.getTrustType(type);
if (trustType == null) {
GriefDefenderPlugin.sendMessage(player, MessageCache.getInstance().TRUST_INVALID);
return;
public void execute(Player player, String groupName, @Optional String type) {
TrustType trustType = null;
if (type == null) {
trustType = TrustTypes.BUILDER;
} else {
trustType = CommandHelper.getTrustType(type);
if (trustType == null) {
GriefDefenderPlugin.sendMessage(player, MessageCache.getInstance().TRUST_INVALID);
return;
}
}
final GDPermissionGroup group = PermissionHolderCache.getInstance().getOrCreateGroup(groupName);

View File

@ -0,0 +1,158 @@
/*
* This file is part of GriefDefender, licensed under the MIT License (MIT).
*
* Copyright (c) bloodmc
* Copyright (c) contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package com.griefdefender.command.gphelper;
import co.aikar.commands.BaseCommand;
import co.aikar.commands.annotation.CommandAlias;
import co.aikar.commands.annotation.CommandPermission;
import co.aikar.commands.annotation.Description;
import co.aikar.commands.annotation.Subcommand;
import net.kyori.text.Component;
import com.google.common.collect.ImmutableMap;
import com.google.common.reflect.TypeToken;
import com.griefdefender.GDPlayerData;
import com.griefdefender.GriefDefenderPlugin;
import com.griefdefender.api.Tristate;
import com.griefdefender.api.claim.TrustTypes;
import com.griefdefender.api.permission.flag.Flags;
import com.griefdefender.api.permission.option.Options;
import com.griefdefender.cache.MessageCache;
import com.griefdefender.claim.GDClaim;
import com.griefdefender.configuration.MessageStorage;
import com.griefdefender.permission.GDPermissionManager;
import com.griefdefender.permission.GDPermissions;
import com.griefdefender.permission.option.GDOptions;
import com.griefdefender.util.SafeTeleportHelper;
import java.time.Duration;
import java.time.Instant;
import java.util.concurrent.ThreadLocalRandom;
import org.bukkit.GameMode;
import org.bukkit.Location;
import org.bukkit.entity.Player;
@CommandAlias("%griefdefender")
@CommandPermission(GDPermissions.COMMAND_TRAPPED)
public class CommandTrapped extends BaseCommand {
@CommandAlias("trapped")
@Description("Teleports the player to a safe location if stuck and unable to build.")
@Subcommand("player trapped")
public void execute(Player player) {
final GameMode gameMode = player.getGameMode();
if (gameMode == GameMode.SPECTATOR) {
return;
}
final GDPlayerData playerData = GriefDefenderPlugin.getInstance().dataStore.getOrCreatePlayerData(player.getWorld(), player.getUniqueId());
final GDClaim claim = GriefDefenderPlugin.getInstance().dataStore.getClaimAtPlayer(playerData, player.getLocation());
if (playerData.inPvpCombat()) {
GriefDefenderPlugin.sendMessage(player, MessageCache.getInstance().COMMAND_TRAPPED_PVP_COMBAT);
return;
}
if (player.getUniqueId().equals(claim.getOwnerUniqueId()) || claim.isUserTrusted(player, TrustTypes.BUILDER)) {
GriefDefenderPlugin.sendMessage(player, MessageCache.getInstance().COMMAND_TRAPPED_BUILD_ACCESS);
return;
}
final Instant now = Instant.now();
final int cooldown = GriefDefenderPlugin.getActiveConfig(player.getWorld()).getConfig().claim.trappedCooldown;
if (playerData.lastTrappedTimestamp != null && !playerData.lastTrappedTimestamp.plusSeconds(cooldown).isBefore(now)) {
final int duration = (int) Duration.between(playerData.lastTrappedTimestamp, now).getSeconds();
final Component message = GriefDefenderPlugin.getInstance().messageData.getMessage(MessageStorage.COMMAND_TRAPPED_CANCEL_COOLDOWN, ImmutableMap.of(
"time-remaining", cooldown - duration));
GriefDefenderPlugin.sendMessage(player, message);
return;
}
playerData.lastTrappedTimestamp = null;
// check place
boolean canBuild = true;
final Tristate placeResult = GDPermissionManager.getInstance().getFinalPermission(null, player.getLocation(), claim, Flags.BLOCK_PLACE, player, player.getLocation(), player, TrustTypes.BUILDER, true);
if (placeResult == Tristate.FALSE) {
canBuild = false;
} else {
// check break
final Tristate breakResult = GDPermissionManager.getInstance().getFinalPermission(null, player.getLocation(), claim, Flags.BLOCK_BREAK, player, player.getLocation(), player, TrustTypes.BUILDER, true);
if (breakResult == Tristate.FALSE) {
canBuild = false;
}
}
if (canBuild) {
GriefDefenderPlugin.sendMessage(player, MessageCache.getInstance().COMMAND_TRAPPED_BUILD_ACCESS);
return;
}
final int minClaimLevel = claim.getOwnerMinClaimLevel();
double claimY = claim.getOwnerPlayerData() == null ? 65.0D : (minClaimLevel > 65.0D ? minClaimLevel : 65);
if (claim.isCuboid()) {
claimY = claim.lesserBoundaryCorner.getY();
}
final int random = ThreadLocalRandom.current().nextInt(2, 20 + 1);
final int randomCorner = ThreadLocalRandom.current().nextInt(1, 4 + 1);
Location claimCorner = null;
switch (randomCorner) {
case 1: // SW
claimCorner = new Location(claim.getWorld(), claim.lesserBoundaryCorner.getX() - random, claimY, claim.greaterBoundaryCorner.getZ() + random);
case 2: // NW
claimCorner = new Location(claim.getWorld(), claim.lesserBoundaryCorner.getX() - random, claimY, claim.lesserBoundaryCorner.getZ() - random);
case 3: // SE
claimCorner = new Location(claim.getWorld(), claim.greaterBoundaryCorner.getX() + random, claimY, claim.greaterBoundaryCorner.getZ() + random);
case 4: // NE
claimCorner = new Location(claim.getWorld(), claim.greaterBoundaryCorner.getX() + random, claimY, claim.lesserBoundaryCorner.getZ() - random);
}
final Location safeLocation = SafeTeleportHelper.getInstance().getSafeLocation(claimCorner, 64, 16, 2).orElse(null);
if (safeLocation != null) {
playerData.teleportLocation = safeLocation;
} else {
// If no safe location was found, fall back to corner
playerData.teleportLocation = claimCorner;
}
int teleportDelay = 0;
if (GDOptions.PLAYER_TELEPORT_DELAY) {
teleportDelay = GDPermissionManager.getInstance().getInternalOptionValue(TypeToken.of(Integer.class), player, Options.PLAYER_TELEPORT_DELAY, claim);
}
if (teleportDelay > 0) {
playerData.trappedRequest = true;
playerData.teleportDelay = teleportDelay + 1;
final Component message = GriefDefenderPlugin.getInstance().messageData.getMessage(MessageStorage.COMMAND_TRAPPED_REQUEST, ImmutableMap.of(
"time-remaining", teleportDelay));
GriefDefenderPlugin.sendMessage(player, message);
return;
}
playerData.lastTrappedTimestamp = now;
player.teleport(playerData.teleportLocation);
playerData.teleportLocation = null;
GriefDefenderPlugin.sendMessage(player, MessageCache.getInstance().COMMAND_TRAPPED_SUCCESS);
}
}

View File

@ -0,0 +1,56 @@
/*
* This file is part of GriefDefender, licensed under the MIT License (MIT).
*
* Copyright (c) bloodmc
* Copyright (c) contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package com.griefdefender.command.gphelper;
import co.aikar.commands.BaseCommand;
import co.aikar.commands.annotation.CommandAlias;
import co.aikar.commands.annotation.CommandPermission;
import co.aikar.commands.annotation.Description;
import co.aikar.commands.annotation.Subcommand;
import com.griefdefender.GDPlayerData;
import com.griefdefender.GriefDefenderPlugin;
import com.griefdefender.cache.MessageCache;
import com.griefdefender.permission.GDPermissions;
import org.bukkit.entity.Player;
@CommandAlias("%griefdefender")
@CommandPermission(GDPermissions.COMMAND_UNLOCK_DROPS)
public class CommandUnlockDrops extends BaseCommand {
@CommandAlias("unlockdrops")
@Description("Allows other players to pickup any items dropped from death.")
@Subcommand("player unlockdrops")
public void execute(Player player) {
final GDPlayerData playerData = GriefDefenderPlugin.getInstance().dataStore.getOrCreatePlayerData(player.getWorld(), player.getUniqueId());
if (!playerData.lockPlayerDeathDrops) {
//send not locked msg
GriefDefenderPlugin.sendMessage(player, MessageCache.getInstance().COMMAND_UNLOCK_DROPS_NONE);
return;
}
playerData.lockPlayerDeathDrops = false;
GriefDefenderPlugin.sendMessage(player, MessageCache.getInstance().COMMAND_UNLOCK_DROPS);
}
}

View File

@ -163,6 +163,8 @@ public class MessageStorage {
public static final String COMMAND_OPTION_EXCEEDS_ADMIN = "command-option-exceeds-admin";
public static final String COMMAND_PET_INVALID = "command-pet-invalid";
public static final String COMMAND_PLAYER_NOT_FOUND = "command-player-not-found";
public static final String COMMAND_TRAPPED_CANCEL_COOLDOWN = "command-trapped-cancel-cooldown";
public static final String COMMAND_TRAPPED_REQUEST = "command-trapped-request";
public static final String COMMAND_WORLD_NOT_FOUND = "command-world-not-found";
public static final String CREATE_FAILED_CLAIM_LIMIT = "create-failed-claim-limit";
public static final String CREATE_FAILED_RESULT = "create-failed-result";

View File

@ -41,6 +41,8 @@ public class ClaimCategory extends ConfigCategory {
+ "\nEx. If you add 'minecraft:creeper' to the list, creepers would not be able to hurt entities above sea level."
+ "\nNote: This will have higher priority than 'explosion-entity' flag.")
public List<String> explosionEntitySurfaceBlacklist = new ArrayList<>();
@Setting(value = "explosion-surface-block-level", comment = "The 'Y' block level that is considered the surface for explosions. (Default: 63)")
public int explosionSurfaceBlockLevel = 63;
@Setting(value = "piston-protection-in-claims", comment = "Whether piston protection should be enabled within claims. Note: This does not affect pistons crossing into another claim, that is always protected. This only determines whether or not GD should process pistons if it doesn't cross into another claim.")
public boolean pistonProtectionInClaims = false;
@Setting(value = "auto-chest-claim-block-radius", comment = "Radius used (in blocks) for auto-created claim when a chest is placed. Set to -1 to disable chest claim creation.")
@ -68,6 +70,8 @@ public class ClaimCategory extends ConfigCategory {
@Setting(value = "claims-enabled",
comment = "Whether claiming is enabled or not. (0 = Disabled, 1 = Enabled)")
public int claimsEnabled = 1;
@Setting(value = "player-trapped-cooldown", comment = "The cooldown time, in seconds, when using the '/trapped' command. (Default: 300)")
public int trappedCooldown = 300;
@Setting(value = "protect-tamed-entities", comment = "Whether tamed entities should be protected in claims. Default: true")
public boolean protectTamedEntities = true;
@Setting(value = "reserved-claim-names", comment = "A list of reserved claim names for use only by administrators."

View File

@ -71,6 +71,7 @@ public DefaultOptionCategory() {
this.defaultUserOptions.put(Options.PLAYER_FLY_SPEED.getName(), "0");
this.defaultUserOptions.put(Options.PLAYER_GAMEMODE.getName(), "undefined");
this.defaultUserOptions.put(Options.PLAYER_HEALTH_REGEN.getName(), "0");
this.defaultUserOptions.put(Options.PLAYER_ITEM_DROP_LOCK.getName(), "false");
this.defaultUserOptions.put(Options.PLAYER_KEEP_INVENTORY.getName(), "undefined");
this.defaultUserOptions.put(Options.PLAYER_KEEP_LEVEL.getName(), "undefined");
this.defaultUserOptions.put(Options.PLAYER_TELEPORT_DELAY.getName(), "0");
@ -80,6 +81,7 @@ public DefaultOptionCategory() {
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.defaultUserOptions.put(Options.PVP_ITEM_DROP_LOCK.getName(), "false");
this.defaultUserOptions.put(Options.RAID.getName(), "true");
this.defaultUserOptions.put(Options.RADIUS_INSPECT.getName(), "100");
this.defaultUserOptions.put(Options.RENT_EXPIRATION.getName(), "7");

View File

@ -503,13 +503,14 @@ public void onExplosionEvent(BlockExplodeEvent event) {
if (!denySurfaceExplosion) {
denySurfaceExplosion = GriefDefenderPlugin.getActiveConfig(world.getUID()).getConfig().claim.explosionBlockSurfaceBlacklist.contains("any");
}
final int surfaceBlockLevel = GriefDefenderPlugin.getActiveConfig(world.getUID()).getConfig().claim.explosionSurfaceBlockLevel;
for (Block block : event.blockList()) {
final Location location = block.getLocation();
if (location.getBlock().isEmpty()) {
continue;
}
targetClaim = GriefDefenderPlugin.getInstance().dataStore.getClaimAt(location);
if (denySurfaceExplosion && block.getWorld().getEnvironment() != Environment.NETHER && location.getBlockY() >= location.getWorld().getSeaLevel()) {
if (denySurfaceExplosion && block.getWorld().getEnvironment() != Environment.NETHER && location.getBlockY() >= surfaceBlockLevel) {
filteredLocations.add(block);
GDPermissionManager.getInstance().processEventLog(event, location, targetClaim, Flags.EXPLOSION_BLOCK.getPermission(), source, block, user, "explosion-surface", Tristate.FALSE);
continue;

View File

@ -179,7 +179,7 @@ public void onPlayerCommand(PlayerCommandPreprocessEvent event) {
final int combatTimeRemaining = playerData.getPvpCombatTimeRemaining(claim);
final boolean inPvpCombat = combatTimeRemaining > 0;
if (GDOptions.isOptionEnabled(Options.PVP_COMBAT_COMMAND)) {
if (GDOptions.PVP_COMBAT_COMMAND) {
final boolean pvpCombatCommand = GDPermissionManager.getInstance().getInternalOptionValue(TypeToken.of(Boolean.class), player, Options.PVP_COMBAT_COMMAND, claim);
if (!pvpCombatCommand && inPvpCombat) {
final Component denyMessage = GriefDefenderPlugin.getInstance().messageData.getMessage(MessageStorage.PVP_IN_COMBAT_NOT_ALLOWED,

View File

@ -109,16 +109,26 @@ public boolean onEntityMove(Event event, Location fromLocation, Location toLocat
final Vector3i fromPos = VecHelper.toVector3i(fromLocation);
final Vector3i toPos = VecHelper.toVector3i(toLocation);
final Player player = targetEntity instanceof Player ? (Player) targetEntity : null;
final GDPermissionUser user = player != null ? PermissionHolderCache.getInstance().getOrCreateUser(player) : null;
if (fromPos.equals(toPos)) {
if (user != null) {
user.getInternalPlayerData().lastAfkCheckLocation = toLocation;
}
return true;
}
if (user != null) {
user.getInternalPlayerData().lastAfkCheckLocation = null;
if (user.getInternalPlayerData().trappedRequest) {
GriefDefenderPlugin.sendMessage(player, MessageCache.getInstance().COMMAND_TRAPPED_CANCEL_MOVE);
user.getInternalPlayerData().trappedRequest = false;
user.getInternalPlayerData().teleportDelay = 0;
}
}
if ((!GDFlags.ENTER_CLAIM && !GDFlags.EXIT_CLAIM)) {
return true;
}
final Player player = targetEntity instanceof Player ? (Player) targetEntity : null;
final GDPermissionUser user = player != null ? PermissionHolderCache.getInstance().getOrCreateUser(player) : null;
if (user != null && user.getOnlinePlayer() != null) {
final boolean preInLiquid = user.getInternalPlayerData().inLiquid;
final boolean inLiquid = user.getOnlinePlayer().getPlayer().getLocation().getBlock().isLiquid();
@ -350,7 +360,7 @@ private void runPlayerCommands(GDClaim claim, GDPermissionUser user, boolean ent
// Most likely Citizens NPC
return;
}
if (!GDOptions.isOptionEnabled(Options.PLAYER_COMMAND_ENTER) && !GDOptions.isOptionEnabled(Options.PLAYER_COMMAND_EXIT)) {
if (!GDOptions.PLAYER_COMMAND_ENTER && !GDOptions.PLAYER_COMMAND_EXIT) {
return;
}
@ -429,7 +439,7 @@ private void checkPlayerFlight(GDPermissionUser user, GDClaim fromClaim, GDClaim
// Most likely Citizens NPC
return;
}
if (!GDOptions.isOptionEnabled(Options.PLAYER_DENY_FLIGHT)) {
if (!GDOptions.PLAYER_DENY_FLIGHT) {
return;
}
@ -472,12 +482,8 @@ private void checkPlayerFlight(GDPermissionUser user, GDClaim fromClaim, GDClaim
return;
}
Boolean noFly = playerData.optionNoFly;
if (noFly == null || fromClaim != toClaim) {
noFly = GDPermissionManager.getInstance().getInternalOptionValue(TypeToken.of(Boolean.class), playerData.getSubject(), Options.PLAYER_DENY_FLIGHT, toClaim);
playerData.optionNoFly = noFly;
}
if (noFly) {
final Boolean noFly = GDPermissionManager.getInstance().getInternalOptionValue(TypeToken.of(Boolean.class), playerData.getSubject(), Options.PLAYER_DENY_FLIGHT, toClaim);
if (noFly != null && noFly) {
player.setAllowFlight(false);
player.setFlying(false);
playerData.ignoreFallDamage = true;
@ -494,7 +500,7 @@ private void checkPlayerGodMode(GDPermissionUser user, GDClaim fromClaim, GDClai
// Most likely Citizens NPC
return;
}
if (!GDOptions.isOptionEnabled(Options.PLAYER_DENY_GODMODE)) {
if (!GDOptions.PLAYER_DENY_GODMODE) {
return;
}
@ -525,7 +531,7 @@ private void checkPlayerGameMode(GDPermissionUser user, GDClaim fromClaim, GDCla
// Most likely Citizens NPC
return;
}
if (!GDOptions.isOptionEnabled(Options.PLAYER_GAMEMODE)) {
if (!GDOptions.PLAYER_GAMEMODE) {
return;
}
@ -564,7 +570,7 @@ private void checkPlayerFlySpeed(GDPermissionUser user, GDClaim fromClaim, GDCla
// Most likely Citizens NPC
return;
}
if (!GDOptions.isOptionEnabled(Options.PLAYER_FLY_SPEED)) {
if (!GDOptions.PLAYER_FLY_SPEED) {
return;
}
@ -616,7 +622,7 @@ private void checkPlayerWalkSpeed(GDPermissionUser user, GDClaim fromClaim, GDCl
// Most likely Citizens NPC
return;
}
if (!GDOptions.isOptionEnabled(Options.PLAYER_WALK_SPEED)) {
if (!GDOptions.PLAYER_WALK_SPEED) {
return;
}
@ -668,7 +674,7 @@ public void checkPlayerWeather(GDPermissionUser user, GDClaim fromClaim, GDClaim
// Most likely Citizens NPC
return;
}
if (!GDOptions.isOptionEnabled(Options.PLAYER_WEATHER)) {
if (!GDOptions.PLAYER_WEATHER) {
return;
}

View File

@ -248,6 +248,7 @@ public void onEntityExplodeEvent(EntityExplodeEvent event) {
}
final String sourceId = GDPermissionManager.getInstance().getPermissionIdentifier(source);
final int surfaceBlockLevel = GriefDefenderPlugin.getActiveConfig(world.getUID()).getConfig().claim.explosionSurfaceBlockLevel;
boolean denySurfaceExplosion = GriefDefenderPlugin.getActiveConfig(world.getUID()).getConfig().claim.explosionBlockSurfaceBlacklist.contains(sourceId);
if (!denySurfaceExplosion) {
denySurfaceExplosion = GriefDefenderPlugin.getActiveConfig(world.getUID()).getConfig().claim.explosionBlockSurfaceBlacklist.contains("any");
@ -259,7 +260,7 @@ public void onEntityExplodeEvent(EntityExplodeEvent event) {
for (Block block : event.blockList()) {
final Location location = block.getLocation();
targetClaim = GriefDefenderPlugin.getInstance().dataStore.getClaimAt(location);
if (denySurfaceExplosion && block.getWorld().getEnvironment() != Environment.NETHER && location.getBlockY() >= location.getWorld().getSeaLevel()) {
if (denySurfaceExplosion && block.getWorld().getEnvironment() != Environment.NETHER && location.getBlockY() >= surfaceBlockLevel) {
filteredLocations.add(block);
GDPermissionManager.getInstance().processEventLog(event, location, targetClaim, Flags.EXPLOSION_BLOCK.getPermission(), source, block, user, "explosion-surface", Tristate.FALSE);
continue;
@ -435,6 +436,13 @@ public boolean protectEntity(Event event, Object source, Entity targetEntity) {
}
// Ignore entity items
if (targetEntity instanceof Item) {
if (GDOptions.PLAYER_ITEM_DROP_LOCK || GDOptions.PVP_ITEM_DROP_LOCK) {
final Item item = (Item) targetEntity;
final String data = NMSUtil.getInstance().getItemPersistentData(item.getItemStack(), "owner");
if (data != null) {
return true;
}
}
return false;
}
@ -493,11 +501,12 @@ public boolean protectEntity(Event event, Object source, Entity targetEntity) {
if (source instanceof Creeper || source instanceof TNTPrimed || (damageCause != null && damageCause == DamageCause.ENTITY_EXPLOSION)) {
final String sourceId = GDPermissionManager.getInstance().getPermissionIdentifier(source);
final int surfaceBlockLevel = GriefDefenderPlugin.getActiveConfig(world.getUID()).getConfig().claim.explosionSurfaceBlockLevel;
boolean denySurfaceExplosion = GriefDefenderPlugin.getActiveConfig(world.getUID()).getConfig().claim.explosionEntitySurfaceBlacklist.contains(sourceId);
if (!denySurfaceExplosion) {
denySurfaceExplosion = GriefDefenderPlugin.getActiveConfig(world.getUID()).getConfig().claim.explosionEntitySurfaceBlacklist.contains("any");
}
if (denySurfaceExplosion && world.getEnvironment() != Environment.NETHER && location.getBlockY() >= location.getWorld().getSeaLevel()) {
if (denySurfaceExplosion && world.getEnvironment() != Environment.NETHER && location.getBlockY() >= surfaceBlockLevel) {
GDPermissionManager.getInstance().processEventLog(event, location, claim, Flags.EXPLOSION_ENTITY.getPermission(), source, targetEntity, user, "explosion-surface", Tristate.FALSE);
return true;
}
@ -620,7 +629,7 @@ private boolean getPvpProtectResult(Event event, GDClaim claim, GDPermissionUser
}
// Check options
if (GDOptions.isOptionEnabled(Options.PVP)) {
if (GDOptions.PVP) {
sourceResult = GDPermissionManager.getInstance().getInternalOptionValue(TypeToken.of(Tristate.class), source, Options.PVP, sourceClaim);
targetResult = GDPermissionManager.getInstance().getInternalOptionValue(TypeToken.of(Tristate.class), target, Options.PVP, claim);
}

View File

@ -267,11 +267,11 @@ public void onPlayerDeath(PlayerDeathEvent event) {
final GDPlayerData playerData = GriefDefenderPlugin.getInstance().dataStore.getOrCreatePlayerData(player.getWorld(), player.getUniqueId());
final GDClaim claim = GriefDefenderPlugin.getInstance().dataStore.getClaimAtPlayer(playerData, player.getLocation());
Tristate keepInventory = Tristate.UNDEFINED;
if (GDOptions.isOptionEnabled(Options.PLAYER_KEEP_INVENTORY)) {
if (GDOptions.PLAYER_KEEP_INVENTORY) {
keepInventory = GDPermissionManager.getInstance().getInternalOptionValue(TypeToken.of(Tristate.class), playerData.getSubject(), Options.PLAYER_KEEP_INVENTORY, claim);
}
Tristate keepLevel = Tristate.UNDEFINED;
if (GDOptions.isOptionEnabled(Options.PLAYER_KEEP_LEVEL)) {
if (GDOptions.PLAYER_KEEP_LEVEL) {
keepLevel = GDPermissionManager.getInstance().getInternalOptionValue(TypeToken.of(Tristate.class), playerData.getSubject(), Options.PLAYER_KEEP_LEVEL, claim);
}
if (keepInventory != Tristate.UNDEFINED) {
@ -286,6 +286,25 @@ public void onPlayerDeath(PlayerDeathEvent event) {
event.setDroppedExp(0);
}
}
if (GDOptions.PLAYER_ITEM_DROP_LOCK || GDOptions.PVP_ITEM_DROP_LOCK) {
boolean itemDropLock = false;
if (playerData.inPvpCombat() && GDOptions.PVP_ITEM_DROP_LOCK) {
itemDropLock = GDPermissionManager.getInstance().getInternalOptionValue(TypeToken.of(Boolean.class), player, Options.PVP_ITEM_DROP_LOCK, claim);
} else if (GDOptions.PLAYER_ITEM_DROP_LOCK) {
itemDropLock = GDPermissionManager.getInstance().getInternalOptionValue(TypeToken.of(Boolean.class), player, Options.PLAYER_ITEM_DROP_LOCK, claim);
}
if (itemDropLock) {
for (ItemStack item : event.getDrops()) {
NMSUtil.getInstance().addItemPersistentData(item, "owner", player.getUniqueId().toString());
}
if (event.getDrops().size() > 0) {
playerData.lockPlayerDeathDrops = true;
GriefDefenderPlugin.sendMessage(player, MessageCache.getInstance().PLAYER_ITEM_DROPS_LOCK);
}
}
}
}
@EventHandler(priority = EventPriority.LOWEST)
@ -415,6 +434,18 @@ public void onPlayerPickupItem(PlayerPickupItemEvent event) {
final GDClaim targetClaim = GriefDefenderPlugin.getInstance().dataStore.getClaimAt(location);
if (GDPermissionManager.getInstance().getFinalPermission(event, location, targetClaim, Flags.ITEM_PICKUP, player, event.getItem(), player, TrustTypes.ACCESSOR, true) == Tristate.FALSE) {
event.setCancelled(true);
return;
}
if (GDOptions.PLAYER_ITEM_DROP_LOCK || GDOptions.PVP_ITEM_DROP_LOCK) {
final String data = NMSUtil.getInstance().getItemPersistentData(event.getItem().getItemStack(), "owner");
if (data != null && !data.equalsIgnoreCase(player.getUniqueId().toString())) {
final UUID ownerUniqueId = UUID.fromString(data);
final GDPlayerData playerData = this.dataStore.getOrCreatePlayerData(location.getWorld(), ownerUniqueId);
if (playerData.lockPlayerDeathDrops) {
event.setCancelled(true);
}
}
}
}
@ -929,8 +960,6 @@ public void onPlayerTeleport(PlayerTeleportEvent event) {
return;
}
GDCauseStackManager.getInstance().pushCause(player);
final GDPlayerData playerData = GriefDefenderPlugin.getInstance().dataStore.getOrCreatePlayerData(player.getWorld(), player.getUniqueId());
playerData.optionNoFly = null; // Reset no fly option on teleports as from/to claim would be the same
if (!GDFlags.ENTITY_TELEPORT_FROM && !GDFlags.ENTITY_TELEPORT_TO) {
return;
}
@ -953,8 +982,9 @@ public void onPlayerTeleport(PlayerTeleportEvent event) {
if (type == TeleportCause.UNKNOWN && !sourceLocation.getWorld().getUID().equals(destination.getWorld().getUID())) {
source = destination.getWorld().getEnvironment().name().toLowerCase().replace("the_", "") + "_portal";
}
final GDPlayerData playerData = GriefDefenderPlugin.getInstance().dataStore.getOrCreatePlayerData(player.getWorld(), player.getUniqueId());
final GDClaim sourceClaim = this.dataStore.getClaimAtPlayer(playerData, player.getLocation());
if (playerData.inPvpCombat() && GDOptions.isOptionEnabled(Options.PVP_COMBAT_TELEPORT)) {
if (playerData.inPvpCombat() && GDOptions.PVP_COMBAT_TELEPORT) {
// 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) {

View File

@ -218,7 +218,7 @@ public Tristate getFinalPermission(Event event, Location location, Set<Context>
this.eventPlayerData = playerData;
final String targetPermission = flag.getPermission();
if (flag == Flags.ENTITY_SPAWN && GDOptions.isOptionEnabled(Options.SPAWN_LIMIT) && target instanceof LivingEntity) {
if (flag == Flags.ENTITY_SPAWN && GDOptions.SPAWN_LIMIT && target instanceof LivingEntity) {
// Check spawn limit
final GDClaim gdClaim = (GDClaim) claim;
final int spawnLimit = gdClaim.getSpawnLimit(contexts);

View File

@ -78,6 +78,7 @@ public class GDPermissions {
public static final String COMMAND_TOWN_TAX = "griefdefender.user.town.command.tax";
public static final String COMMAND_TOWN_MODE = "griefdefender.user.claim.command.town-mode";
public static final String COMMAND_TRANSFER_CLAIM = "griefdefender.user.claim.command.transfer";
public static final String COMMAND_TRAPPED = "griefdefender.user.claim.command.trapped";
public static final String COMMAND_BUY_CLAIM_BLOCKS = "griefdefender.user.claim.command.buy-blocks";
public static final String COMMAND_SELL_CLAIM_BLOCKS = "griefdefender.user.claim.command.sell-blocks";
public static final String COMMAND_LIST_CLAIM_FLAGS = "griefdefender.user.claim.command.list-flags";
@ -85,6 +86,7 @@ public class GDPermissions {
public static final String COMMAND_BAN_ITEM = "griefdefender.user.claim.command.ban-item";
public static final String COMMAND_UNBAN_ITEM = "griefdefender.user.claim.command.unban-item";
public static final String COMMAND_CLAIM_INHERIT = "griefdefender.user.claim.command.inherit";
public static final String COMMAND_UNLOCK_DROPS = "griefdefender.user.claim.command.unlock-drops";
public static final String CLAIM_CREATE = "griefdefender.user.claim.create.base";
public static final String CLAIM_CREATE_BASIC = "griefdefender.user.claim.create.basic";
public static final String CLAIM_CREATE_SUBDIVISION = "griefdefender.user.claim.create.subdivision";

View File

@ -38,6 +38,7 @@ public class GDOptions {
public static boolean PLAYER_FLY_SPEED;
public static boolean PLAYER_GAMEMODE;
public static boolean PLAYER_HEALTH_REGEN;
public static boolean PLAYER_ITEM_DROP_LOCK;
public static boolean PLAYER_KEEP_INVENTORY;
public static boolean PLAYER_KEEP_LEVEL;
public static boolean PLAYER_TELEPORT_DELAY;
@ -47,27 +48,30 @@ public class GDOptions {
public static boolean PVP_COMBAT_COMMAND;
public static boolean PVP_COMBAT_TELEPORT;
public static boolean PVP_COMBAT_TIMEOUT;
public static boolean PVP_ITEM_DROP_LOCK;
public static boolean SPAWN_LIMIT;
public static void populateOptionStatus() {
PLAYER_COMMAND_ENTER = GriefDefenderPlugin.getOptionConfig().getConfig().isOptionEnabled(Options.PLAYER_COMMAND_ENTER.getName());
PLAYER_COMMAND_EXIT = GriefDefenderPlugin.getOptionConfig().getConfig().isOptionEnabled(Options.PLAYER_COMMAND_EXIT.getName());
PLAYER_DENY_FLIGHT = GriefDefenderPlugin.getOptionConfig().getConfig().isOptionEnabled(Options.PLAYER_DENY_FLIGHT.getName());
PLAYER_DENY_GODMODE = GriefDefenderPlugin.getOptionConfig().getConfig().isOptionEnabled(Options.PLAYER_DENY_GODMODE.getName());
PLAYER_DENY_HUNGER = GriefDefenderPlugin.getOptionConfig().getConfig().isOptionEnabled(Options.PLAYER_DENY_HUNGER.getName());
PLAYER_FLY_SPEED = GriefDefenderPlugin.getOptionConfig().getConfig().isOptionEnabled(Options.PLAYER_FLY_SPEED.getName());
PLAYER_GAMEMODE = GriefDefenderPlugin.getOptionConfig().getConfig().isOptionEnabled(Options.PLAYER_GAMEMODE.getName());
PLAYER_HEALTH_REGEN = GriefDefenderPlugin.getOptionConfig().getConfig().isOptionEnabled(Options.PLAYER_HEALTH_REGEN.getName());
PLAYER_KEEP_INVENTORY = GriefDefenderPlugin.getOptionConfig().getConfig().isOptionEnabled(Options.PLAYER_KEEP_INVENTORY.getName());
PLAYER_KEEP_LEVEL = GriefDefenderPlugin.getOptionConfig().getConfig().isOptionEnabled(Options.PLAYER_KEEP_LEVEL.getName());
PLAYER_TELEPORT_DELAY = GriefDefenderPlugin.getOptionConfig().getConfig().isOptionEnabled(Options.PLAYER_TELEPORT_DELAY.getName());
PLAYER_WALK_SPEED = GriefDefenderPlugin.getOptionConfig().getConfig().isOptionEnabled(Options.PLAYER_WALK_SPEED.getName());
PLAYER_WEATHER = GriefDefenderPlugin.getOptionConfig().getConfig().isOptionEnabled(Options.PLAYER_WEATHER.getName());
PVP = GriefDefenderPlugin.getOptionConfig().getConfig().isOptionEnabled(Options.PVP.getName());
PVP_COMBAT_COMMAND = GriefDefenderPlugin.getOptionConfig().getConfig().isOptionEnabled(Options.PVP_COMBAT_COMMAND.getName());
PVP_COMBAT_TELEPORT = GriefDefenderPlugin.getOptionConfig().getConfig().isOptionEnabled(Options.PVP_COMBAT_TELEPORT.getName());
PVP_COMBAT_TIMEOUT = GriefDefenderPlugin.getOptionConfig().getConfig().isOptionEnabled(Options.PVP_COMBAT_TIMEOUT.getName());
SPAWN_LIMIT = GriefDefenderPlugin.getOptionConfig().getConfig().isOptionEnabled(Options.SPAWN_LIMIT.getName());
PLAYER_COMMAND_ENTER = GriefDefenderPlugin.getOptionConfig().getConfig().isOptionEnabled(Options.PLAYER_COMMAND_ENTER.getName().toLowerCase());
PLAYER_COMMAND_EXIT = GriefDefenderPlugin.getOptionConfig().getConfig().isOptionEnabled(Options.PLAYER_COMMAND_EXIT.getName().toLowerCase());
PLAYER_DENY_FLIGHT = GriefDefenderPlugin.getOptionConfig().getConfig().isOptionEnabled(Options.PLAYER_DENY_FLIGHT.getName().toLowerCase());
PLAYER_DENY_GODMODE = GriefDefenderPlugin.getOptionConfig().getConfig().isOptionEnabled(Options.PLAYER_DENY_GODMODE.getName().toLowerCase());
PLAYER_DENY_HUNGER = GriefDefenderPlugin.getOptionConfig().getConfig().isOptionEnabled(Options.PLAYER_DENY_HUNGER.getName().toLowerCase());
PLAYER_FLY_SPEED = GriefDefenderPlugin.getOptionConfig().getConfig().isOptionEnabled(Options.PLAYER_FLY_SPEED.getName().toLowerCase());
PLAYER_GAMEMODE = GriefDefenderPlugin.getOptionConfig().getConfig().isOptionEnabled(Options.PLAYER_GAMEMODE.getName().toLowerCase());
PLAYER_HEALTH_REGEN = GriefDefenderPlugin.getOptionConfig().getConfig().isOptionEnabled(Options.PLAYER_HEALTH_REGEN.getName().toLowerCase());
PLAYER_ITEM_DROP_LOCK = GriefDefenderPlugin.getOptionConfig().getConfig().isOptionEnabled(Options.PLAYER_ITEM_DROP_LOCK.getName().toLowerCase());
PLAYER_KEEP_INVENTORY = GriefDefenderPlugin.getOptionConfig().getConfig().isOptionEnabled(Options.PLAYER_KEEP_INVENTORY.getName().toLowerCase());
PLAYER_KEEP_LEVEL = GriefDefenderPlugin.getOptionConfig().getConfig().isOptionEnabled(Options.PLAYER_KEEP_LEVEL.getName().toLowerCase());
PLAYER_TELEPORT_DELAY = GriefDefenderPlugin.getOptionConfig().getConfig().isOptionEnabled(Options.PLAYER_TELEPORT_DELAY.getName().toLowerCase());
PLAYER_WALK_SPEED = GriefDefenderPlugin.getOptionConfig().getConfig().isOptionEnabled(Options.PLAYER_WALK_SPEED.getName().toLowerCase());
PLAYER_WEATHER = GriefDefenderPlugin.getOptionConfig().getConfig().isOptionEnabled(Options.PLAYER_WEATHER.getName().toLowerCase());
PVP = GriefDefenderPlugin.getOptionConfig().getConfig().isOptionEnabled(Options.PVP.getName().toLowerCase());
PVP_COMBAT_COMMAND = GriefDefenderPlugin.getOptionConfig().getConfig().isOptionEnabled(Options.PVP_COMBAT_COMMAND.getName().toLowerCase());
PVP_COMBAT_TELEPORT = GriefDefenderPlugin.getOptionConfig().getConfig().isOptionEnabled(Options.PVP_COMBAT_TELEPORT.getName().toLowerCase());
PVP_COMBAT_TIMEOUT = GriefDefenderPlugin.getOptionConfig().getConfig().isOptionEnabled(Options.PVP_COMBAT_TIMEOUT.getName().toLowerCase());
PVP_ITEM_DROP_LOCK = GriefDefenderPlugin.getOptionConfig().getConfig().isOptionEnabled(Options.PVP_ITEM_DROP_LOCK.getName().toLowerCase());
SPAWN_LIMIT = GriefDefenderPlugin.getOptionConfig().getConfig().isOptionEnabled(Options.SPAWN_LIMIT.getName().toLowerCase());
}
public static boolean isOptionEnabled(Option option) {

View File

@ -117,6 +117,7 @@ public void registerDefaults() {
this.createKey("griefdefender:player-fly-speed", Double.class);
this.createKey("griefdefender:player-gamemode", GameModeType.class);
this.createKey("griefdefender:player-health-regen", Double.class);
this.createKey("griefdefender:player-item-drop-lock", Boolean.class);
this.createKey("griefdefender:player-keep-inventory", Tristate.class);
this.createKey("griefdefender:player-keep-level", Tristate.class);
this.createKey("griefdefender:player-teleport-delay", Integer.class);
@ -126,6 +127,7 @@ public void registerDefaults() {
this.createKey("griefdefender:pvp-combat-command", Boolean.class);
this.createKey("griefdefender:pvp-combat-teleport", Boolean.class);
this.createKey("griefdefender:pvp-combat-timeout", Integer.class);
this.createKey("griefdefender:pvp-item-drop-lock", Boolean.class);
this.createKey("griefdefender:radius-inspect", Integer.class);
this.createKey("griefdefender:raid", Boolean.class);
this.createKey("griefdefender:rent-balance", Double.class);

View File

@ -77,15 +77,12 @@ public void run() {
int currentTotal = playerData.getAccruedClaimBlocks();
if ((currentTotal + accruedBlocks) > playerData.getMaxAccruedClaimBlocks()) {
playerData.setAccruedClaimBlocks(playerData.getMaxAccruedClaimBlocks());
playerData.lastAfkCheckLocation = player.getLocation();
return;
}
playerData.setAccruedClaimBlocks(playerData.getAccruedClaimBlocks() + accruedBlocks);
}
}
playerData.lastAfkCheckLocation = player.getLocation();
}
}
}

View File

@ -45,6 +45,7 @@
import net.kyori.text.event.HoverEvent;
import net.kyori.text.format.TextColor;
import java.time.Instant;
import java.util.Iterator;
import java.util.function.Consumer;
@ -89,7 +90,7 @@ public void run() {
if (world.getFullTime() % 100 == 0L) {
final GameMode gameMode = player.getGameMode();
// Handle player health regen
if (gameMode != GameMode.CREATIVE && gameMode != GameMode.SPECTATOR && GDOptions.isOptionEnabled(Options.PLAYER_HEALTH_REGEN)) {
if (gameMode != GameMode.CREATIVE && gameMode != GameMode.SPECTATOR && GDOptions.PLAYER_HEALTH_REGEN) {
final double maxHealth = player.getMaxHealth();
if (player.getHealth() < maxHealth) {
final double regenAmount = GDPermissionManager.getInstance().getInternalOptionValue(TypeToken.of(Double.class), playerData.getSubject(), Options.PLAYER_HEALTH_REGEN, claim);
@ -110,6 +111,12 @@ public void run() {
final int delay = playerData.teleportDelay - 1;
if (delay == 0) {
playerData.teleportDelay = 0;
if (playerData.trappedRequest) {
playerData.lastTrappedTimestamp = Instant.now();
GriefDefenderPlugin.sendMessage(player, MessageCache.getInstance().COMMAND_TRAPPED_SUCCESS);
}
// This must be set BEFORE teleport
playerData.trappedRequest = false;
player.teleport(playerData.teleportLocation);
playerData.teleportLocation = null;
playerData.teleportSourceLocation = null;

View File

@ -263,7 +263,7 @@ public boolean canPlayerPvP(GDClaim claim, GDPermissionUser source) {
}
Tristate sourceResult = Tristate.UNDEFINED;
if (GDOptions.isOptionEnabled(Options.PVP)) {
if (GDOptions.PVP) {
sourceResult = GDPermissionManager.getInstance().getInternalOptionValue(TypeToken.of(Tristate.class), source, Options.PVP, claim);
}
if (sourceResult == Tristate.FALSE) {

View File

@ -0,0 +1,226 @@
/*
* This file is part of GriefDefender, licensed under the MIT License (MIT).
*
* Copyright (c) SpongePowered <https://www.spongepowered.org>
* 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.util;
import com.flowpowered.math.GenericMath;
import com.flowpowered.math.vector.Vector3d;
import com.flowpowered.math.vector.Vector3i;
import com.google.common.collect.ImmutableSet;
import com.griefdefender.internal.util.NMSUtil;
import com.griefdefender.internal.util.VecHelper;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.stream.Stream;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.World;
import org.bukkit.block.Block;
public final class SafeTeleportHelper {
/** The default height radius to scan for safe locations. */
int DEFAULT_HEIGHT = 9;
/** The default width radius to scan for safe locations. */
int DEFAULT_WIDTH = 9;
/**
* The default distance to check for a suitable floor below any candidate
* location.
*/
int DEFAULT_FLOOR_CHECK_DISTANCE = 2;
private static SafeTeleportHelper instance;
public static SafeTeleportHelper getInstance() {
if (instance == null) {
instance = new SafeTeleportHelper();
}
return instance;
}
public Optional<Location> getSafeLocation(Location location, int height, int width, int distanceToDrop) {
final World world = location.getWorld();
// Get the vectors to check, and get the block types with them.
// The vectors should be sorted by distance from the centre of the checking region, so
// this makes it easier to try to get close, because we can just iterate and get progressively further out.
Optional<Vector3i> result = this.getSafeLocation(world, this.getBlockLocations(location, height, width), distanceToDrop);
if (result.isPresent()) {
final Vector3d pos = new Vector3d(result.get().toDouble().add(0.5, 0, 0.5));
return Optional.of(new Location(world, pos.getX(), pos.getY(), pos.getZ()));
}
return Optional.empty();
}
private Stream<Vector3i> getBlockLocations(Location worldLocation, int height, int width) {
// We don't want to warp outside of the world border, so we want to check that we're within it.
int worldBorderMinX = GenericMath.floor(NMSUtil.getInstance().getWorldBorderMinX(worldLocation.getWorld()));
int worldBorderMinZ = GenericMath.floor(NMSUtil.getInstance().getWorldBorderMinZ(worldLocation.getWorld()));
int worldBorderMaxX = GenericMath.floor(NMSUtil.getInstance().getWorldBorderMaxX(worldLocation.getWorld()));
int worldBorderMaxZ = GenericMath.floor(NMSUtil.getInstance().getWorldBorderMaxZ(worldLocation.getWorld()));
// Get the World and get the maximum Y value.
int worldMaxY = worldLocation.getWorld().getMaxHeight();
Vector3i vectorLocation = new Vector3i(worldLocation.getBlockX(), worldLocation.getBlockY(), worldLocation.getBlockZ());
// We use clamp to remain within the world confines, so we don't waste time checking blocks outside of the
// world border and the world height.
int minY = GenericMath.clamp(vectorLocation.getY() - height, 0, worldMaxY);
int maxY = GenericMath.clamp(vectorLocation.getY() + height, 0, worldMaxY);
int minX = GenericMath.clamp(vectorLocation.getX() - width, worldBorderMinX, worldBorderMaxX);
int maxX = GenericMath.clamp(vectorLocation.getX() + width, worldBorderMinX, worldBorderMaxX);
int minZ = GenericMath.clamp(vectorLocation.getZ() - width, worldBorderMinZ, worldBorderMaxZ);
int maxZ = GenericMath.clamp(vectorLocation.getZ() + width, worldBorderMinZ, worldBorderMaxZ);
// We now iterate over all possible x, y and z positions to get all possible vectors.
List<Vector3i> vectors = new ArrayList<>();
for (int y = minY; y <= maxY; y++) {
for (int x = minX; x <= maxX; x++) {
for (int z = minZ; z <= maxZ; z++) {
vectors.add(new Vector3i(x, y, z));
}
}
}
Comparator<Vector3i> c = Comparator.comparingInt(vectorLocation::distanceSquared);
// The compiler seems to need this to be a new line.
// We check to see what the y location is, preferring changes in Y over X and Z, and higher over lower locations.
c = c.thenComparing(x -> -Math.abs(vectorLocation.getY() - x.getY())).thenComparing(x -> -x.getY());
// Sort them according to the distance to the provided worldLocation.
return vectors.stream().sorted(c);
}
private Optional<Vector3i> getSafeLocation(World world, Stream<Vector3i> positionsToCheck, int floorDistanceCheck) {
// We cache the various block lookup results so we don't check a block twice.
final Map<Vector3i, BlockData> blockCache = new HashMap<>();
return positionsToCheck.filter(currentTarget -> {
// Get the block, add it to the cache.
BlockData block = this.getBlockData(currentTarget, world, blockCache);
// If the block isn't safe, no point in continuing on this run.
if (block.isSafeBody) {
// Check the block ABOVE is safe for the body, and the two BELOW are safe too.
if (this.getBlockData(
currentTarget.add(0, 1, 0), world, blockCache).isSafeBody
&& (floorDistanceCheck <= 0 || this.isFloorSafe(currentTarget, world, blockCache, floorDistanceCheck))) {
// This position should be safe. Get the center of the block to spawn into.
return true;
}
}
return false;
}).findFirst();
}
private boolean isFloorSafe(Vector3i currentTarget, World world, Map<Vector3i, BlockData> blockCache, int floorDistanceCheck) {
for (int i = 1; i < floorDistanceCheck; ++i) {
BlockData data = this.getBlockData(currentTarget.sub(0, i, 0), world, blockCache);
// If it's a safe floor, we can just say yes now.
if (data.isSafeFloor) {
return true;
}
// If it's not safe for the body, then we don't want to go through it anyway.
if (!data.isSafeBody) {
return false;
}
}
// Check the next block down, if it's a floor, then we're good to go, otherwise we'd fall too far for our liking.
return this.getBlockData(currentTarget.sub(0, floorDistanceCheck, 0), world, blockCache).isSafeFloor;
}
private BlockData getBlockData(Vector3i vector3i, World world, Map<Vector3i, BlockData> cache) {
if (vector3i.getY() < 0) {
// Anything below this isn't safe, no point going further.
return new BlockData();
}
if (cache.containsKey(vector3i)) {
return cache.get(vector3i);
}
BlockData data = new BlockData(world.getBlockAt(VecHelper.toLocation(world, vector3i)));
cache.put(vector3i, data);
return data;
}
private class BlockData {
private final Set<Material> NOT_SAFE_FLOOR = ImmutableSet.of(Material.AIR, Material.CACTUS, Material.FIRE, Material.LAVA);
private final boolean isSafeFloor;
private final boolean isSafeBody;
private BlockData() {
this.isSafeFloor = false;
this.isSafeBody = false;
}
private BlockData(Block blockState) {
this.isSafeFloor = isSafeFloorMaterial(blockState);
this.isSafeBody = isSafeBodyMaterial(blockState);
}
private boolean isSafeFloorMaterial(Block block) {
return !NOT_SAFE_FLOOR.contains(block.getType());
}
private boolean isSafeBodyMaterial(Block block) {
Material material = block.getType();
// Deny blocks that suffocate
if (block.getType().isOccluding()) {
return false;
}
// Deny dangerous lava
if (material == Material.LAVA) {
return false;
}
// Deny non-passable non "full" blocks
return NMSUtil.getInstance().isBlockTransparent(block);
}
}
}

View File

@ -3,15 +3,15 @@
"libraries": [
{
"name": "com.griefdefender:adapter:1.12.2",
"sha1": "ff8cf01a85b52f8f07f0b07500489c6cf06885dc",
"path": "com/griefdefender/adapter/1.12.2-SNAPSHOT/adapter-1.12.2-20201114.023606-49.jar",
"url": "https://repo.glaremasters.me/repository/bloodshot/com/griefdefender/adapter/1.12.2-SNAPSHOT/adapter-1.12.2-20201114.023606-49.jar"
"sha1": "ba160138712a42dedb910f7b4730400666a1f336",
"path": "com/griefdefender/adapter/1.12.2-SNAPSHOT/adapter-1.12.2-20201116.073333-50.jar",
"url": "https://repo.glaremasters.me/repository/bloodshot/com/griefdefender/adapter/1.12.2-SNAPSHOT/adapter-1.12.2-20201116.073333-50.jar"
},
{
"name": "com.griefdefender:api:1.0.0",
"sha1": "da0dc8ccd0682a439b5d215a2fb5b0d2c9049c97",
"path": "com/griefdefender/api/1.0.0-SNAPSHOT/api-1.0.0-20201114.003714-25.jar",
"url": "https://repo.glaremasters.me/repository/bloodshot/com/griefdefender/api/1.0.0-SNAPSHOT/api-1.0.0-20201114.003714-25.jar"
"sha1": "bceb911861b8df467d6b29b6be56d02b58ac5467",
"path": "com/griefdefender/api/1.0.0-SNAPSHOT/api-1.0.0-20201116.204822-26.jar",
"url": "https://repo.glaremasters.me/repository/bloodshot/com/griefdefender/api/1.0.0-SNAPSHOT/api-1.0.0-20201116.204822-26.jar"
},
{
"name": "com.griefdefender:reflect-helper:1.0",

View File

@ -3,15 +3,15 @@
"libraries": [
{
"name": "com.griefdefender:adapter:1.13.2",
"sha1": "b8f588f31e1d09fba8998557f868fcd47b11a102",
"path": "com/griefdefender/adapter/1.13.2-SNAPSHOT/adapter-1.13.2-20201114.022735-47.jar",
"url": "https://repo.glaremasters.me/repository/bloodshot/com/griefdefender/adapter/1.13.2-SNAPSHOT/adapter-1.13.2-20201114.022735-47.jar"
"sha1": "64dd782fa3a3b9c0c6ec1e8db06865562330edd5",
"path": "com/griefdefender/adapter/1.13.2-SNAPSHOT/adapter-1.13.2-20201116.073141-48.jar",
"url": "https://repo.glaremasters.me/repository/bloodshot/com/griefdefender/adapter/1.13.2-SNAPSHOT/adapter-1.13.2-20201116.073141-48.jar"
},
{
"name": "com.griefdefender:api:1.0.0",
"sha1": "da0dc8ccd0682a439b5d215a2fb5b0d2c9049c97",
"path": "com/griefdefender/api/1.0.0-SNAPSHOT/api-1.0.0-20201114.003714-25.jar",
"url": "https://repo.glaremasters.me/repository/bloodshot/com/griefdefender/api/1.0.0-SNAPSHOT/api-1.0.0-20201114.003714-25.jar"
"sha1": "bceb911861b8df467d6b29b6be56d02b58ac5467",
"path": "com/griefdefender/api/1.0.0-SNAPSHOT/api-1.0.0-20201116.204822-26.jar",
"url": "https://repo.glaremasters.me/repository/bloodshot/com/griefdefender/api/1.0.0-SNAPSHOT/api-1.0.0-20201116.204822-26.jar"
},
{
"name": "com.griefdefender:reflect-helper:1.0",

View File

@ -3,15 +3,15 @@
"libraries": [
{
"name": "com.griefdefender:adapter:1.14.2",
"sha1": "b19c58ca092ff22c0beef649d79f95c21677871b",
"path": "com/griefdefender/adapter/1.14.2-SNAPSHOT/adapter-1.14.2-20201114.021619-47.jar",
"url": "https://repo.glaremasters.me/repository/bloodshot/com/griefdefender/adapter/1.14.2-SNAPSHOT/adapter-1.14.2-20201114.021619-47.jar"
"sha1": "a011f6cf39392eff76af6d1c3120b993d4eaebef",
"path": "com/griefdefender/adapter/1.14.2-SNAPSHOT/adapter-1.14.2-20201116.072822-48.jar",
"url": "https://repo.glaremasters.me/repository/bloodshot/com/griefdefender/adapter/1.14.2-SNAPSHOT/adapter-1.14.2-20201116.072822-48.jar"
},
{
"name": "com.griefdefender:api:1.0.0",
"sha1": "da0dc8ccd0682a439b5d215a2fb5b0d2c9049c97",
"path": "com/griefdefender/api/1.0.0-SNAPSHOT/api-1.0.0-20201114.003714-25.jar",
"url": "https://repo.glaremasters.me/repository/bloodshot/com/griefdefender/api/1.0.0-SNAPSHOT/api-1.0.0-20201114.003714-25.jar"
"sha1": "bceb911861b8df467d6b29b6be56d02b58ac5467",
"path": "com/griefdefender/api/1.0.0-SNAPSHOT/api-1.0.0-20201116.204822-26.jar",
"url": "https://repo.glaremasters.me/repository/bloodshot/com/griefdefender/api/1.0.0-SNAPSHOT/api-1.0.0-20201116.204822-26.jar"
},
{
"name": "com.griefdefender:reflect-helper:1.0",

View File

@ -3,15 +3,15 @@
"libraries": [
{
"name": "com.griefdefender:adapter:1.14.3",
"sha1": "e168e41140545240e196858fdf8d982f5d93bd58",
"path": "com/griefdefender/adapter/1.14.3-SNAPSHOT/adapter-1.14.3-20201114.021212-49.jar",
"url": "https://repo.glaremasters.me/repository/bloodshot/com/griefdefender/adapter/1.14.3-SNAPSHOT/adapter-1.14.3-20201114.021212-49.jar"
"sha1": "003468e4132615899fbeee30b514025b44f1ed1d",
"path": "com/griefdefender/adapter/1.14.3-SNAPSHOT/adapter-1.14.3-20201116.072740-50.jar",
"url": "https://repo.glaremasters.me/repository/bloodshot/com/griefdefender/adapter/1.14.3-SNAPSHOT/adapter-1.14.3-20201116.072740-50.jar"
},
{
"name": "com.griefdefender:api:1.0.0",
"sha1": "da0dc8ccd0682a439b5d215a2fb5b0d2c9049c97",
"path": "com/griefdefender/api/1.0.0-SNAPSHOT/api-1.0.0-20201114.003714-25.jar",
"url": "https://repo.glaremasters.me/repository/bloodshot/com/griefdefender/api/1.0.0-SNAPSHOT/api-1.0.0-20201114.003714-25.jar"
"sha1": "bceb911861b8df467d6b29b6be56d02b58ac5467",
"path": "com/griefdefender/api/1.0.0-SNAPSHOT/api-1.0.0-20201116.204822-26.jar",
"url": "https://repo.glaremasters.me/repository/bloodshot/com/griefdefender/api/1.0.0-SNAPSHOT/api-1.0.0-20201116.204822-26.jar"
},
{
"name": "com.griefdefender:reflect-helper:1.0",

View File

@ -3,15 +3,15 @@
"libraries": [
{
"name": "com.griefdefender:adapter:1.14.4",
"sha1": "6a7495ebd84a02eff57d9ad4d1dd5651ebf69374",
"path": "com/griefdefender/adapter/1.14.4-SNAPSHOT/adapter-1.14.4-20201114.021020-47.jar",
"url": "https://repo.glaremasters.me/repository/bloodshot/com/griefdefender/adapter/1.14.4-SNAPSHOT/adapter-1.14.4-20201114.021020-47.jar"
"sha1": "0315521b33b732eaed58b0c23ed04767ef9f23c5",
"path": "com/griefdefender/adapter/1.14.4-SNAPSHOT/adapter-1.14.4-20201116.072707-48.jar",
"url": "https://repo.glaremasters.me/repository/bloodshot/com/griefdefender/adapter/1.14.4-SNAPSHOT/adapter-1.14.4-20201116.072707-48.jar"
},
{
"name": "com.griefdefender:api:1.0.0",
"sha1": "da0dc8ccd0682a439b5d215a2fb5b0d2c9049c97",
"path": "com/griefdefender/api/1.0.0-SNAPSHOT/api-1.0.0-20201114.003714-25.jar",
"url": "https://repo.glaremasters.me/repository/bloodshot/com/griefdefender/api/1.0.0-SNAPSHOT/api-1.0.0-20201114.003714-25.jar"
"sha1": "bceb911861b8df467d6b29b6be56d02b58ac5467",
"path": "com/griefdefender/api/1.0.0-SNAPSHOT/api-1.0.0-20201116.204822-26.jar",
"url": "https://repo.glaremasters.me/repository/bloodshot/com/griefdefender/api/1.0.0-SNAPSHOT/api-1.0.0-20201116.204822-26.jar"
},
{
"name": "com.griefdefender:reflect-helper:1.0",

View File

@ -3,15 +3,15 @@
"libraries": [
{
"name": "com.griefdefender:adapter:1.15.2",
"sha1": "d0200bbdd86597119ae3b945454ccd642343d406",
"path": "com/griefdefender/adapter/1.15.2-SNAPSHOT/adapter-1.15.2-20201114.020309-30.jar",
"url": "https://repo.glaremasters.me/repository/bloodshot/com/griefdefender/adapter/1.15.2-SNAPSHOT/adapter-1.15.2-20201114.020309-30.jar"
"sha1": "d9dee65c3db2895d2f6830604ad398466e82be81",
"path": "com/griefdefender/adapter/1.15.2-SNAPSHOT/adapter-1.15.2-20201116.033004-31.jar",
"url": "https://repo.glaremasters.me/repository/bloodshot/com/griefdefender/adapter/1.15.2-SNAPSHOT/adapter-1.15.2-20201116.033004-31.jar"
},
{
"name": "com.griefdefender:api:1.0.0",
"sha1": "da0dc8ccd0682a439b5d215a2fb5b0d2c9049c97",
"path": "com/griefdefender/api/1.0.0-SNAPSHOT/api-1.0.0-20201114.003714-25.jar",
"url": "https://repo.glaremasters.me/repository/bloodshot/com/griefdefender/api/1.0.0-SNAPSHOT/api-1.0.0-20201114.003714-25.jar"
"sha1": "bceb911861b8df467d6b29b6be56d02b58ac5467",
"path": "com/griefdefender/api/1.0.0-SNAPSHOT/api-1.0.0-20201116.204822-26.jar",
"url": "https://repo.glaremasters.me/repository/bloodshot/com/griefdefender/api/1.0.0-SNAPSHOT/api-1.0.0-20201116.204822-26.jar"
},
{
"name": "com.griefdefender:reflect-helper:1.0",

View File

@ -3,15 +3,15 @@
"libraries": [
{
"name": "com.griefdefender:adapter:1.15",
"sha1": "e91f93c0381be8e8bd3d3ea09d0ddb0eeba487d6",
"path": "com/griefdefender/adapter/1.15-SNAPSHOT/adapter-1.15-20201114.020556-30.jar",
"url": "https://repo.glaremasters.me/repository/bloodshot/com/griefdefender/adapter/1.15-SNAPSHOT/adapter-1.15-20201114.020556-30.jar"
"sha1": "446cb0bf17cee8edfb92e12b6f818b309aff4d61",
"path": "com/griefdefender/adapter/1.15-SNAPSHOT/adapter-1.15-20201116.033118-31.jar",
"url": "https://repo.glaremasters.me/repository/bloodshot/com/griefdefender/adapter/1.15-SNAPSHOT/adapter-1.15-20201116.033118-31.jar"
},
{
"name": "com.griefdefender:api:1.0.0",
"sha1": "da0dc8ccd0682a439b5d215a2fb5b0d2c9049c97",
"path": "com/griefdefender/api/1.0.0-SNAPSHOT/api-1.0.0-20201114.003714-25.jar",
"url": "https://repo.glaremasters.me/repository/bloodshot/com/griefdefender/api/1.0.0-SNAPSHOT/api-1.0.0-20201114.003714-25.jar"
"sha1": "bceb911861b8df467d6b29b6be56d02b58ac5467",
"path": "com/griefdefender/api/1.0.0-SNAPSHOT/api-1.0.0-20201116.204822-26.jar",
"url": "https://repo.glaremasters.me/repository/bloodshot/com/griefdefender/api/1.0.0-SNAPSHOT/api-1.0.0-20201116.204822-26.jar"
},
{
"name": "com.griefdefender:reflect-helper:1.0",

View File

@ -3,15 +3,15 @@
"libraries": [
{
"name": "com.griefdefender:adapter:1.16.1",
"sha1": "ea905b3efa9c21c90422ea005baeeea25252a04a",
"path": "com/griefdefender/adapter/1.16.1-SNAPSHOT/adapter-1.16.1-20201114.014103-10.jar",
"url": "https://repo.glaremasters.me/repository/bloodshot/com/griefdefender/adapter/1.16.1-SNAPSHOT/adapter-1.16.1-20201114.014103-10.jar"
"sha1": "5c81832d3b8570a0bd78384e8642f619e787b34a",
"path": "com/griefdefender/adapter/1.16.1-SNAPSHOT/adapter-1.16.1-20201116.032656-11.jar",
"url": "https://repo.glaremasters.me/repository/bloodshot/com/griefdefender/adapter/1.16.1-SNAPSHOT/adapter-1.16.1-20201116.032656-11.jar"
},
{
"name": "com.griefdefender:api:1.0.0",
"sha1": "da0dc8ccd0682a439b5d215a2fb5b0d2c9049c97",
"path": "com/griefdefender/api/1.0.0-SNAPSHOT/api-1.0.0-20201114.003714-25.jar",
"url": "https://repo.glaremasters.me/repository/bloodshot/com/griefdefender/api/1.0.0-SNAPSHOT/api-1.0.0-20201114.003714-25.jar"
"sha1": "bceb911861b8df467d6b29b6be56d02b58ac5467",
"path": "com/griefdefender/api/1.0.0-SNAPSHOT/api-1.0.0-20201116.204822-26.jar",
"url": "https://repo.glaremasters.me/repository/bloodshot/com/griefdefender/api/1.0.0-SNAPSHOT/api-1.0.0-20201116.204822-26.jar"
},
{
"name": "com.griefdefender:reflect-helper:1.0",

View File

@ -3,15 +3,15 @@
"libraries": [
{
"name": "com.griefdefender:adapter:1.16.2",
"sha1": "604406c516a85a22d2be5d5cf299022e7d741ce6",
"path": "com/griefdefender/adapter/1.16.2-SNAPSHOT/adapter-1.16.2-20201114.013638-3.jar",
"url": "https://repo.glaremasters.me/repository/bloodshot/com/griefdefender/adapter/1.16.2-SNAPSHOT/adapter-1.16.2-20201114.013638-3.jar"
"sha1": "dc88329c5d311cda3bd4847c224d9322b9ec019f",
"path": "com/griefdefender/adapter/1.16.2-SNAPSHOT/adapter-1.16.2-20201116.032543-4.jar",
"url": "https://repo.glaremasters.me/repository/bloodshot/com/griefdefender/adapter/1.16.2-SNAPSHOT/adapter-1.16.2-20201116.032543-4.jar"
},
{
"name": "com.griefdefender:api:1.0.0",
"sha1": "da0dc8ccd0682a439b5d215a2fb5b0d2c9049c97",
"path": "com/griefdefender/api/1.0.0-SNAPSHOT/api-1.0.0-20201114.003714-25.jar",
"url": "https://repo.glaremasters.me/repository/bloodshot/com/griefdefender/api/1.0.0-SNAPSHOT/api-1.0.0-20201114.003714-25.jar"
"sha1": "bceb911861b8df467d6b29b6be56d02b58ac5467",
"path": "com/griefdefender/api/1.0.0-SNAPSHOT/api-1.0.0-20201116.204822-26.jar",
"url": "https://repo.glaremasters.me/repository/bloodshot/com/griefdefender/api/1.0.0-SNAPSHOT/api-1.0.0-20201116.204822-26.jar"
},
{
"name": "com.griefdefender:reflect-helper:1.0",

View File

@ -3,15 +3,15 @@
"libraries": [
{
"name": "com.griefdefender:adapter:1.16.4",
"sha1": "c614e94ab107870b600c810f095c8e49e0eef816",
"path": "com/griefdefender/adapter/1.16.4-SNAPSHOT/adapter-1.16.4-20201114.010319-2.jar",
"url": "https://repo.glaremasters.me/repository/bloodshot/com/griefdefender/adapter/1.16.4-SNAPSHOT/adapter-1.16.4-20201114.010319-2.jar"
"sha1": "4838b9941cd55e2d097a73be2194d6a865afc03c",
"path": "com/griefdefender/adapter/1.16.4-SNAPSHOT/adapter-1.16.4-20201116.032340-3.jar",
"url": "https://repo.glaremasters.me/repository/bloodshot/com/griefdefender/adapter/1.16.4-SNAPSHOT/adapter-1.16.4-20201116.032340-3.jar"
},
{
"name": "com.griefdefender:api:1.0.0",
"sha1": "da0dc8ccd0682a439b5d215a2fb5b0d2c9049c97",
"path": "com/griefdefender/api/1.0.0-SNAPSHOT/api-1.0.0-20201114.003714-25.jar",
"url": "https://repo.glaremasters.me/repository/bloodshot/com/griefdefender/api/1.0.0-SNAPSHOT/api-1.0.0-20201114.003714-25.jar"
"sha1": "bceb911861b8df467d6b29b6be56d02b58ac5467",
"path": "com/griefdefender/api/1.0.0-SNAPSHOT/api-1.0.0-20201116.204822-26.jar",
"url": "https://repo.glaremasters.me/repository/bloodshot/com/griefdefender/api/1.0.0-SNAPSHOT/api-1.0.0-20201116.204822-26.jar"
},
{
"name": "com.griefdefender:reflect-helper:1.0",

View File

@ -3,15 +3,15 @@
"libraries": [
{
"name": "com.griefdefender:adapter:1.8.8",
"sha1": "c04d370eeb09f0880ee93ada5ba832a24ade4d42",
"path": "com/griefdefender/adapter/1.8.8-SNAPSHOT/adapter-1.8.8-20201114.024042-47.jar",
"url": "https://repo.glaremasters.me/repository/bloodshot/com/griefdefender/adapter/1.8.8-SNAPSHOT/adapter-1.8.8-20201114.024042-47.jar"
"sha1": "65304ed1652fe4d3ea237d0e6c265915afe1c77d",
"path": "com/griefdefender/adapter/1.8.8-SNAPSHOT/adapter-1.8.8-20201116.073548-48.jar",
"url": "https://repo.glaremasters.me/repository/bloodshot/com/griefdefender/adapter/1.8.8-SNAPSHOT/adapter-1.8.8-20201116.073548-48.jar"
},
{
"name": "com.griefdefender:api:1.0.0",
"sha1": "da0dc8ccd0682a439b5d215a2fb5b0d2c9049c97",
"path": "com/griefdefender/api/1.0.0-SNAPSHOT/api-1.0.0-20201114.003714-25.jar",
"url": "https://repo.glaremasters.me/repository/bloodshot/com/griefdefender/api/1.0.0-SNAPSHOT/api-1.0.0-20201114.003714-25.jar"
"sha1": "bceb911861b8df467d6b29b6be56d02b58ac5467",
"path": "com/griefdefender/api/1.0.0-SNAPSHOT/api-1.0.0-20201116.204822-26.jar",
"url": "https://repo.glaremasters.me/repository/bloodshot/com/griefdefender/api/1.0.0-SNAPSHOT/api-1.0.0-20201116.204822-26.jar"
},
{
"name": "com.griefdefender:reflect-helper:1.0",

View File

@ -219,6 +219,14 @@ GriefDefender {
command-pet-transfer-cancel="&aÜbertragung abgebrochen."
command-pet-transfer-ready="&aBereit zum Übertragen! Rechtsklick auf das Tier, welches du übertragen möchtest oder Linksklick zum Abbrechen."
command-player-not-found="&cSpieler '&6{player}&c' nicht gefunden."
command-trapped-build-access="&bDu steckst nicht fest, du kannst auf diesem Grundstück bauen."
command-trapped-cancel-cooldown="&f/trapped&c ist noch nicht wieder verfügbar. Du musst noch &6{time-remaining} Sekunden warten, bis du den Befehl wieder benutzen kannst."
command-trapped-cancel-move="&bDeine &ftrapped&b Anfrage wurde &cabgebrochen&b weil du dich bewegt hast.\nFalls du immer noch gefangen bist, nutze den Befehl noch einmal."
command-trapped-pvp-combat="&cDu kannst &f/trapped&c nicht nutzen, während du im PvP Modus bist."
command-trapped-request="&bYDu hast &ftrapped&b benutzt.\nUm in Sicherheit teleportiert zu werden &cBEWEGE DICH NICHT &bfür &6{time-remaining}&b weitere Sekunden sonst wird die Teleportation unterbrochen."
command-trapped-success="&bDu wurdest erfolgreich an einen sicheren Ort teleportiert."
command-unlock-drops="&aDeine fallengelassenen Gegenstände können nun von anderen Spielern aufgesammelt werden."
command-unlock-drops-none="&aKeiner deiner fallengelassenen Gegenständen ist geschützt."
command-world-not-found="&cWelt '&6{world}&c' nicht gefunden."
command-worldedit-missing="&cDieser Befehl benötigt installiertes WorldEdit auf dem Server."
confirm-not-found="Keine Bestätigung gefunden."
@ -651,6 +659,7 @@ GriefDefender {
permission-trust="&cDir fehlt &6{player}s&c Berechtigung Berechtigungen zu verwalten."
permission-visual-claims-nearby="&cDu hast keine Berechtigung dir Grundstücke in der Nähe anzeigen zu lassen."
player-accrued-blocks-exceeded="&cSpieler &6{player}&c hat eine Maximalgrenze von &6{total}&c und würde mit zusätzlichen &6{amount}&c Baublöcken diese überschreiten.\nVersuche eine niedrige Anzahl oder lasse einen Admin die Aktion vornehmen."
player-item-drops-lock="&aDeine fallengelassenen Gegenstände sind nun geschützt. Benutze &f/unlockdrops&a falls du möchtest, dass andere Spieler diese aufheben können."
player-no-claims-to-delete="&aSpieler &6{player}&a hat keine löschbaren Grundstücke."
player-remaining-blocks-2d="&aDu hast noch &6{block-amount}&a freie Baublöcke."
player-remaining-blocks-3d="&aDu kannst noch bis zu &6{chunk-amount}&a Chunks sichern. &f({block-amount})"

View File

@ -219,6 +219,14 @@ GriefDefender {
command-pet-transfer-cancel="&aPet giveaway cancelled."
command-pet-transfer-ready="&aReady to transfer! Right-click the pet you'd like to give away, or cancel by left-clicking."
command-player-not-found="&cPlayer '&6{player}&c' could not be found."
command-trapped-build-access="&bYou arent trapped since you have build access in this claim."
command-trapped-cancel-cooldown="&cYour usage of &f/trapped&c is on cooldown. The cooldown will end in &6{time-remaining} seconds."
command-trapped-cancel-move="&bYour &ftrapped&b request has been &ccancelled&b due to movement.\nYou must issue another request if you want to be teleported."
command-trapped-pvp-combat="&cYou may not use &f/trapped&c while in PvP combat."
command-trapped-request="&bYou have issued a &ftrapped&b request.\nIn order to be teleported, you must &cNOT &bmove for &6{time-remaining}&b seconds or the request will be cancelled."
command-trapped-success="&bYou have successfully been teleported to a safe location."
command-unlock-drops="&aYour dropped items can now be picked up by other players."
command-unlock-drops-none="&aNone of your dropped items are protected."
command-world-not-found="&cWorld '&6{world}&c' could not be found."
command-worldedit-missing="&cThis command requires WorldEdit to be installed on server."
confirm-not-found="No confirmation found."
@ -651,6 +659,7 @@ GriefDefender {
permission-trust="&cYou don't have &6{player}'s&c permission to manage permissions here."
permission-visual-claims-nearby="&cYou don't have permission to visualize nearby claims."
player-accrued-blocks-exceeded="&cPlayer &6{player}&c has a total of &6{total}&c and will exceed the maximum allowed accrued claim blocks if granted an additional &6{amount}&c of blocks.\nEither lower the amount or have an admin grant the user with an override."
player-item-drops-lock="&aYour dropped items are protected. Use &f/unlockdrops&a to allow other players to pick them up."
player-no-claims-to-delete="&aPlayer &6{player}&a has no claims to delete."
player-remaining-blocks-2d="&aYou may claim up to &6{block-amount}&a more blocks."
player-remaining-blocks-3d="&aYou may claim up to &6{chunk-amount}&a more chunks. &f({block-amount})"

View File

@ -219,6 +219,14 @@ GriefDefender {
command-pet-transfer-cancel="&2&l[SORTEO DE MASCOTAS] &a➜ &c&lCancelado"
command-pet-transfer-ready="&2&l[TRANSFERENCIA PREPARADA]\n&6&lCLICK-DERECHO&a a la mascota que quieres &2&lregalar&a.\n&6&lCLICK-IZQUIERDO&a para &c&lcancelar&a."
command-player-not-found="&4&l[ERROR] &cJugador ➜ &6&o'{player}'&c ➜ &lNO ENCONTRADO"
command-trapped-build-access="&bNo te encuentras atorado ya que tienes acceso para construir en esta protección."
command-trapped-cancel-cooldown="&cEl uso de &f/trapped&c está en espera. La espera termina en &6{time-remaining} segundos."
command-trapped-cancel-move="&bTu petición de &fatorado&b ha sido &ccancelada&b ya que te moviste.\nEnvía el comando nuevamente si quieres teleportarte."
command-trapped-pvp-combat="&cNo puedes usar el comando &f/trapped&c mientras estás en combate PVP."
command-trapped-request="&bHas solicitado una petición de &fatorado&b.\nPara ser teleportado, es importante que &cNO &bte muevas durante &6{time-remaining}&b segundos o la petición será cancelada."
command-trapped-success="&bHas sido teleportado a una ubicación segura."
command-unlock-drops="&aTus items dropeados ahora pueden ser recogidos por otro jugador."
command-unlock-drops-none="&aNinguno de tus objetoa dropeados están protegidos."
command-world-not-found="&4&l[ERROR] &cMundo ➜ &6&o'{world}'&c ➜ &lNO ENCONTRADO"
command-worldedit-missing="&4&l[ERROR] &cEste comando necesita tener instalado en el Servidor el plugin &6&l'WorldEdit'"
confirm-not-found="Confirmación no encontrada."
@ -651,6 +659,7 @@ GriefDefender {
permission-trust="&4&l[PERMISO-DENEGADO] &cNo puedes &nadministras&c los permisos de este terreno porque &6&o{player}&c no te considera de confianza."
permission-visual-claims-nearby="&4&l[PERMISO-DENEGADO] &cNo puedes &nvisualizar&c los terrenos cercanos."
player-accrued-blocks-exceeded="&cEl jugador &6&o{player}&c tiene un total de &6&o{total}CB's&c y ha excedido el máximo permitido de &lCBA's &r&c(&nClaim Block Adquiridos&r&c) que garantiza &a&l+&6&o{amount} &abloques adicionales&c.\n&4&l[NOTA] &cReduzca la cantidad general o que un &4Administrador&c disminuya al Jugador la cantidad excedida de CB's."
player-item-drops-lock="&aTus objetos dropeados están protegidos. Usa &f/unlockdrops&a para permitir que otros jugadores puedan recogerlos."
player-no-claims-to-delete="&aEl jugador &6{player}&a no tiene claims para eliminar"
player-remaining-blocks-2d="&3&l---------------------------------------------\n&2&l[INFO] &aTienes &6&o{block-amount} ClaimBlocks&a para reclamar más terreno.\n&3&l---------------------------------------------"
player-remaining-blocks-3d="&3&l---------------------------------------------\n&2&l[INFO] &6&o{chunk-amount}Chunks &f&l= &6&o{block-amount} ClaimBlocks&a para reclamar más terreno.\n&3&l---------------------------------------------"

View File

@ -219,6 +219,14 @@ GriefDefender {
command-pet-transfer-cancel="&aTransfert animal annulé."
command-pet-transfer-ready="&aPrêt pour le transfert! Fait un clique droit sur l'animal que tu veux donner, ou annule avec un clique gauche."
command-player-not-found="&cJoueur '&6{player}&c' introuvable."
command-trapped-build-access="&bYou arent trapped since you have build access in this claim."
command-trapped-cancel-cooldown="&cYour usage of &f/trapped&c is on cooldown. The cooldown will end in &6{time-remaining} seconds."
command-trapped-cancel-move="&bYour &ftrapped&b request has been &ccancelled&b due to movement.\nYou must issue another request if you want to be teleported."
command-trapped-pvp-combat="&cYou may not use &f/trapped&c while in PvP combat."
command-trapped-request="&bYou have issued a &ftrapped&b request.\nIn order to be teleported, you must &cNOT &bmove for &6{time-remaining}&b seconds or the request will be cancelled."
command-trapped-success="&bYou have successfully been teleported to a safe location."
command-unlock-drops="&aYour dropped items can now be picked up by other players."
command-unlock-drops-none="&aNone of your dropped items are protected."
command-world-not-found="&cMonde '&6{world}&c' introuvable."
command-worldedit-missing="&cCette commande a besoin que WorldEdit soit installé sur le serveur."
confirm-not-found="Pas de confirmation trouvé."
@ -651,6 +659,7 @@ GriefDefender {
permission-trust="&cTu n'as pas la permission de &6{player}&c pour gérer les permissions ici."
permission-visual-claims-nearby="&cTu n'as pas la permission pour voir les protections à proximité."
player-accrued-blocks-exceeded="&cLe joueur &6{player}&c a un total de &6{total}&c et vas dépasser le maximum autorisé de blocs de protection gagnés s'il est donné un nombre additionnel de &6{amount}&c bloc.\nDescends le nombre ou demande un admin de donner à l'utilisateur un outrepassement."
player-item-drops-lock="&aYour dropped items are protected. Use &f/unlockdrops&a to allow other players to pick them up."
player-no-claims-to-delete="&aLe joueur &6{player}&a n'a pas de terrain à supprimer."
player-remaining-blocks-2d="&aTu peut protéger jusqu'à &6{block-amount}&a blocs supplémentaires."
player-remaining-blocks-3d="&aTu peut protéger jusqu'à &6{chunk-amount}&a chunks supplémentaire. &f({block-amount})"

View File

@ -219,6 +219,14 @@ GriefDefender {
command-pet-transfer-cancel="&aPrzekazanie zwierzaczka anulowane."
command-pet-transfer-ready="&aTryb transferu zwierzaczka! Kliknij prawym zwierzaczka do oddania, albo lewym aby anulować."
command-player-not-found="&cGracz '&6{player}&c' nie został znaleziony."
command-trapped-build-access="&bJuż masz możliwość budowania na działce."
command-trapped-cancel-cooldown="&cPoczekaj kolejne &6{time-remaining} sekund, aby użyć komendy &f/trapped&c."
command-trapped-cancel-move="&bKomenda &ftrapped&b została &canulowana&b przez poruszenie się.\nUżyj komendy jeszcze raz i stój w miejscu!"
command-trapped-pvp-combat="&cNie można używać &f/trapped&c w trakcie walki."
command-trapped-request="&bUżywasz komendy &ftrapped&b.\n&cNIE RUSZAJ SIĘ &bprzez &6{time-remaining}&b sekund, inaczej teleportacja zostanie anulowana."
command-trapped-success="&bTeleportowano w bezpieczne miejsce."
command-unlock-drops="&aPrzedmioty odblokowane."
command-unlock-drops-none="&aNie masz zablokowanych przedmiotów."
command-world-not-found="&cŚwiat '&6{world}&c' nie został znaleziony."
command-worldedit-missing="&cTa komenda wymaga instalacji pluginu WorldEdit."
confirm-not-found="Brak potwierdzenia."
@ -651,6 +659,7 @@ GriefDefender {
permission-trust="&cNie masz permisji od &6{player}&c do zarządzania permisjami."
permission-visual-claims-nearby="&cNie masz permisji do wizualizacji pobliskich działek."
player-accrued-blocks-exceeded="&cGracz &6{player}&c posiada łącznie &6{total}&c szt. bloków i przekroczy limit, jeżeli dostanie dodatkowe &6{amount}&c szt. bloków.\nZmniejsz liczbę, albo użyj komendy nadpisującej."
player-item-drops-lock="&aPodnoszenie Twoich przedmiotów jest zablokowane. Wpisz &f/unlockdrops&a aby to zmienić."
player-no-claims-to-delete="&aGracz &6{player}&a nie ma działek do usunięcia."
player-remaining-blocks-2d="&aMożesz zająć jeszcze do &6{block-amount}&a szt. bloków."
player-remaining-blocks-3d="&aMożesz zająć jeszcze &6{chunk-amount}&a szt. chunków. &f({block-amount})"

View File

@ -219,6 +219,14 @@ GriefDefender {
command-pet-transfer-cancel="&aПередача питомца отменена."
command-pet-transfer-ready="&aГотов к передаче! Нажмите на питомца, которого хотите передать, или нажмите ЛКМ для отмены."
command-player-not-found="&cИгрок '&6{player}&c' не найден."
command-trapped-build-access="&bУ вас уже есть доступ к строительству в этом регионе."
command-trapped-cancel-cooldown="&cВы сможете снова использовать команду &f/trapped&c через &6{time-remaining} секунд."
command-trapped-cancel-move="&bВаш запрос команды &f/trapped&b &cотменён&b из-за движения.\nЧтобы телепортироваться, повторите запрос."
command-trapped-pvp-combat="&cКомандой &f/trapped&c нельзя воспользоваться во время битвы с другим игроком."
command-trapped-request="&bЗапрос &f/trapped&b принят.\nЧтобы телепортироваться, вы должны &cНЕ&b двигаться &6{time-remaining}&b секунд, иначе запрос будет отменён."
command-trapped-success="&bВы были успешно телепортированы в безопасное место."
command-unlock-drops="&aВаши предметы разблокированы."
command-unlock-drops-none="&aЗаблокированных вами предметов не найдено."
command-world-not-found="&cМир '&6{world}&c' не найден."
command-worldedit-missing="&cДля использования этой команды на сервер должен быть установлен WorldEdit."
confirm-not-found="Подтверждение не найдено."
@ -651,6 +659,7 @@ GriefDefender {
permission-trust="&cУ вас нет разрешения от игрока &6{player}&c на изменение разрешений в этом регионе."
permission-visual-claims-nearby="&cУ вас нет разрешения на отображение регионов поблизости."
player-accrued-blocks-exceeded="&cУ игрока &6{player}&c есть &6{total}&c блоков и добавление ему ещё &6{amount}&c блоков превысит максимальное возможное количество.\n. Уменьшите добавляемое количество или попросите администратора выдать игроку нужное количество блоков."
player-item-drops-lock="&aПодбор ваших предметов другими игроками заблокирован. Воспользуйтесь &f/unlockdrops&a, чтобы разблокировать их.
player-no-claims-to-delete="&aУ игрока &6{player}&a нет регионов, которые можно было бы удалить."
player-remaining-blocks-2d="&aВы можете занять ещё &6{block-amount}&a блоков."
player-remaining-blocks-3d="&aВы можете занять ещё &6{chunk-amount}&a чанков. &f({block-amount} блоков)"

View File

@ -3,9 +3,9 @@ name=GriefDefender
group=com.griefdefender
url=https://github.com/bloodmc/GriefDefender
version=1.5.4-DEV
apiVersion=1.0.0-20201114.003714-25
apiVersion=1.0.0-20201116.204822-26
# Bukkit
adapterVersion=1.16.4-20201114.010319-2
adapterVersion=1.16.4-20201116.032340-3
spigotVersion=1.16.4-R0.1-SNAPSHOT
# Sponge
adapterSpongeVersion=1.12.2-20201114.012057-13

View File

@ -112,6 +112,8 @@ public class GDPlayerData implements PlayerData {
public boolean debugClaimPermissions = false;
public boolean inTown = false;
public boolean townChat = false;
public boolean lockPlayerDeathDrops = false;
public boolean trappedRequest = false;
public List<Component> chatLines = new ArrayList<>();
public Instant recordChatTimestamp;
public Instant commandInputTimestamp;
@ -142,6 +144,7 @@ public class GDPlayerData implements PlayerData {
public Location<World> teleportLocation;
public Instant lastPvpTimestamp;
public Instant lastTrappedTimestamp;
public WeatherType lastWeatherType;
// cached global option values
@ -173,7 +176,6 @@ public class GDPlayerData implements PlayerData {
public boolean userOptionBypassPlayerGamemode = false;
// option cache
public Boolean optionNoFly = null;
public Boolean optionNoGodMode = null;
public Double optionFlySpeed = null;
public Double optionWalkSpeed = null;
@ -368,7 +370,7 @@ private void revertVisualBlocks(Player player, GDClaim claim, UUID visualUniqueI
}
boolean ignoreVisual = false;
for (Transaction<BlockSnapshot> createVisualTransaction : createBlockVisualTransactions) {
if (createVisualTransaction.getOriginal().getLocation().equals(snapshot.getLocation().get())) {
if (createVisualTransaction.getOriginal().getLocation().get().equals(snapshot.getLocation().get())) {
ignoreVisual = true;
break;
}
@ -799,7 +801,7 @@ public int getPvpCombatTimeRemaining(GDClaim claim) {
final Instant now = Instant.now();
int combatTimeout = 0;
if (GDOptions.isOptionEnabled(Options.PVP_COMBAT_TIMEOUT)) {
if (GDOptions.PVP_COMBAT_TIMEOUT) {
combatTimeout = GDPermissionManager.getInstance().getInternalOptionValue(TypeToken.of(Integer.class), player, Options.PVP_COMBAT_TIMEOUT, claim);
}
if (combatTimeout <= 0) {
@ -865,7 +867,6 @@ public void onClaimDelete() {
}
public void resetOptionCache() {
this.optionNoFly = null;
this.optionNoGodMode = null;
this.optionFlySpeed = null;
this.optionWalkSpeed = null;

View File

@ -135,6 +135,8 @@
import com.griefdefender.command.CommandUntrustPlayerAll;
import com.griefdefender.command.gphelper.CommandAccessTrust;
import com.griefdefender.command.gphelper.CommandContainerTrust;
import com.griefdefender.command.gphelper.CommandTrapped;
import com.griefdefender.command.gphelper.CommandUnlockDrops;
import com.griefdefender.configuration.FlagConfig;
import com.griefdefender.configuration.GriefDefenderConfig;
import com.griefdefender.configuration.MessageDataConfig;
@ -175,6 +177,7 @@
import com.griefdefender.permission.flag.GDFlagData;
import com.griefdefender.permission.flag.GDFlagDefinition;
import com.griefdefender.permission.flag.GDFlags;
import com.griefdefender.permission.option.GDOptions;
import com.griefdefender.provider.DynmapProvider;
import com.griefdefender.provider.LuckPermsProvider;
import com.griefdefender.provider.MCClansProvider;
@ -613,7 +616,6 @@ public void onPreInit(GamePreInitializationEvent event, Logger logger, Path path
CreateModeTypeRegistryModule.getInstance().registerDefaults();
GameModeTypeRegistryModule.getInstance().registerDefaults();
WeatherTypeRegistryModule.getInstance().registerDefaults();
OptionRegistryModule.getInstance().registerDefaults();
GriefDefender.getRegistry().registerBuilderSupplier(PaymentTransaction.Builder.class, GDPaymentTransaction.PaymentTransactionBuilder::new);
GriefDefender.getRegistry().registerBuilderSupplier(Claim.Builder.class, GDClaim.ClaimBuilder::new);
GriefDefender.getRegistry().registerBuilderSupplier(FlagData.Builder.class, GDFlagData.FlagDataBuilder::new);
@ -890,10 +892,12 @@ public void registerBaseCommands() {
manager.registerCommand(new CommandSetAccruedClaimBlocks());
manager.registerCommand(new CommandTownChat());
manager.registerCommand(new CommandTownTag());
manager.registerCommand(new CommandTrapped());
manager.registerCommand(new CommandTrustGroup());
manager.registerCommand(new CommandTrustPlayer());
manager.registerCommand(new CommandTrustGroupAll());
manager.registerCommand(new CommandTrustPlayerAll());
manager.registerCommand(new CommandUnlockDrops());
manager.registerCommand(new CommandUntrustGroup());
manager.registerCommand(new CommandUntrustPlayer());
manager.registerCommand(new CommandUntrustGroupAll());
@ -1129,12 +1133,14 @@ public void loadConfig() {
flagConfig.save();
flagConfig.getConfig().defaultFlagCategory.refreshFlags();
flagConfig.save();
OptionRegistryModule.getInstance().registerDefaults();
optionConfig = new OptionConfig(this.getConfigPath().resolve("options.conf"));
optionConfig.getConfig().defaultOptionCategory.checkOptions();
optionConfig.save();
BaseStorage.globalConfig.save();
BaseStorage.USE_GLOBAL_PLAYER_STORAGE = !BaseStorage.globalConfig.getConfig().playerdata.useWorldPlayerData();
GDFlags.populateFlagStatus();
GDOptions.populateOptionStatus();
CLAIM_BLOCK_SYSTEM = BaseStorage.globalConfig.getConfig().playerdata.claimBlockSystem;
final GDItemType defaultModTool = ItemTypeRegistryModule.getInstance().getById("minecraft:golden_shovel").orElse(null);
final GDBlockType defaultCreateVisualBlock = BlockTypeRegistryModule.getInstance().getById("minecraft:diamond_block").orElse(null);

View File

@ -134,6 +134,12 @@ public static MessageCache getInstance() {
public Component COMMAND_PET_CONFIRMATION;
public Component COMMAND_PET_TRANSFER_READY;
public Component COMMAND_PET_TRANSFER_CANCEL;
public Component COMMAND_TRAPPED_BUILD_ACCESS;
public Component COMMAND_TRAPPED_CANCEL_MOVE;
public Component COMMAND_TRAPPED_PVP_COMBAT;
public Component COMMAND_TRAPPED_SUCCESS;
public Component COMMAND_UNLOCK_DROPS;
public Component COMMAND_UNLOCK_DROPS_NONE;
public Component COMMAND_WORLDEDIT_MISSING;
public Component CONFIRM_NOT_FOUND;
public Component CREATE_CANCEL;
@ -318,6 +324,7 @@ public static MessageCache getInstance() {
public Component LABEL_DEFAULT;
public Component LABEL_DISPLAYING;
public Component LABEL_EXPIRED;
public Component LABEL_FALSE;
public Component LABEL_FAREWELL;
public Component LABEL_FILTER;
public Component LABEL_FLAG;
@ -353,6 +360,7 @@ public static MessageCache getInstance() {
public Component LABEL_SPAWN;
public Component LABEL_STATUS;
public Component LABEL_TARGET;
public Component LABEL_TRUE;
public Component LABEL_TRUST;
public Component LABEL_TYPE;
public Component LABEL_WORLD;
@ -435,6 +443,7 @@ public static MessageCache getInstance() {
public Component PERMISSION_PLAYER_VIEW_OTHERS;
public Component PERMISSION_TAX;
public Component PERMISSION_VISUAL_CLAIMS_NEARBY;
public Component PLAYER_ITEM_DROPS_LOCK;
public Component PLUGIN_EVENT_CANCEL;
public Component PLUGIN_RELOAD;
public Component PVP_CLAIM_NOT_ALLOWED;
@ -599,6 +608,12 @@ public void loadCache() {
COMMAND_PET_CONFIRMATION = MessageStorage.MESSAGE_DATA.getMessage("command-pet-confirmation");
COMMAND_PET_TRANSFER_READY = MessageStorage.MESSAGE_DATA.getMessage("command-pet-transfer-ready");
COMMAND_PET_TRANSFER_CANCEL = MessageStorage.MESSAGE_DATA.getMessage("command-pet-transfer-cancel");
COMMAND_TRAPPED_BUILD_ACCESS = MessageStorage.MESSAGE_DATA.getMessage("command-trapped-build-access");
COMMAND_TRAPPED_CANCEL_MOVE = MessageStorage.MESSAGE_DATA.getMessage("command-trapped-cancel-move");
COMMAND_TRAPPED_PVP_COMBAT = MessageStorage.MESSAGE_DATA.getMessage("command-trapped-pvp-combat");
COMMAND_TRAPPED_SUCCESS = MessageStorage.MESSAGE_DATA.getMessage("command-trapped-success");
COMMAND_UNLOCK_DROPS = MessageStorage.MESSAGE_DATA.getMessage("command-unlock-drops");
COMMAND_UNLOCK_DROPS_NONE = MessageStorage.MESSAGE_DATA.getMessage("command-unlock-drops-none");
COMMAND_WORLDEDIT_MISSING = MessageStorage.MESSAGE_DATA.getMessage("command-worldedit-missing");
CONFIRM_NOT_FOUND = MessageStorage.MESSAGE_DATA.getMessage("confirm-not-found");
CREATE_CANCEL = MessageStorage.MESSAGE_DATA.getMessage("create-cancel");
@ -781,6 +796,7 @@ public void loadCache() {
LABEL_DEFAULT = MessageStorage.MESSAGE_DATA.getMessage("label-default");
LABEL_DISPLAYING = MessageStorage.MESSAGE_DATA.getMessage("label-displaying");
LABEL_EXPIRED = MessageStorage.MESSAGE_DATA.getMessage("label-expired");
LABEL_FALSE = MessageStorage.MESSAGE_DATA.getMessage("label-false");
LABEL_FAREWELL = MessageStorage.MESSAGE_DATA.getMessage("label-farewell");
LABEL_FILTER = MessageStorage.MESSAGE_DATA.getMessage("label-filter");
LABEL_FLAG = MessageStorage.MESSAGE_DATA.getMessage("label-flag");
@ -816,6 +832,7 @@ public void loadCache() {
LABEL_SPAWN = MessageStorage.MESSAGE_DATA.getMessage("label-spawn");
LABEL_STATUS = MessageStorage.MESSAGE_DATA.getMessage("label-status");
LABEL_TARGET = MessageStorage.MESSAGE_DATA.getMessage("label-target");
LABEL_TRUE = MessageStorage.MESSAGE_DATA.getMessage("label-true");
LABEL_TRUST = MessageStorage.MESSAGE_DATA.getMessage("label-trust");
LABEL_TYPE = MessageStorage.MESSAGE_DATA.getMessage("label-type");
LABEL_UNKNOWN = MessageStorage.MESSAGE_DATA.getMessage("label-unknown");
@ -898,6 +915,7 @@ public void loadCache() {
PERMISSION_PLAYER_VIEW_OTHERS = MessageStorage.MESSAGE_DATA.getMessage("permission-player-view-others");
PERMISSION_TAX = MessageStorage.MESSAGE_DATA.getMessage("permission-tax");
PERMISSION_VISUAL_CLAIMS_NEARBY = MessageStorage.MESSAGE_DATA.getMessage("permission-visual-claims-nearby");
PLAYER_ITEM_DROPS_LOCK = MessageStorage.MESSAGE_DATA.getMessage("player-item-drops-lock");
PLUGIN_EVENT_CANCEL = MessageStorage.MESSAGE_DATA.getMessage("plugin-event-cancel");
PLUGIN_RELOAD = MessageStorage.MESSAGE_DATA.getMessage("plugin-reload");
PVP_CLAIM_NOT_ALLOWED = MessageStorage.MESSAGE_DATA.getMessage("pvp-claim-not-allowed");

View File

@ -107,7 +107,7 @@ public void execute(Player player, @Optional String claimName, @Optional User ta
final Location<World> spawnLocation = new Location<>(claim.getWorld(), spawnPos.getX(), spawnPos.getY(), spawnPos.getZ());
int teleportDelay = 0;
if (GDOptions.isOptionEnabled(Options.PLAYER_TELEPORT_DELAY)) {
if (GDOptions.PLAYER_TELEPORT_DELAY) {
teleportDelay = GDPermissionManager.getInstance().getInternalOptionValue(TypeToken.of(Integer.class), player, Options.PLAYER_TELEPORT_DELAY, claim);
}
if (teleportDelay > 0) {

View File

@ -29,6 +29,7 @@
import co.aikar.commands.annotation.CommandCompletion;
import co.aikar.commands.annotation.CommandPermission;
import co.aikar.commands.annotation.Description;
import co.aikar.commands.annotation.Optional;
import co.aikar.commands.annotation.Subcommand;
import co.aikar.commands.annotation.Syntax;
import com.google.common.collect.ImmutableList;
@ -69,13 +70,18 @@ public class CommandTrustGroup extends BaseCommand {
+ "\nContainer: access to interact with all blocks including inventory."
+ "\nBuilder: access to everything above including ability to place and break blocks."
+ "\nManager: access to everything above including ability to manage claim settings.")
@Syntax("<group> <accessor|builder|container|manager>")
@Syntax("<group> [<accessor|builder|container|manager>]")
@Subcommand("trust group")
public void execute(Player player, String groupName, String type) {
final TrustType trustType = CommandHelper.getTrustType(type);
if (trustType == null) {
GriefDefenderPlugin.sendMessage(player, MessageCache.getInstance().TRUST_INVALID);
return;
public void execute(Player player, String groupName, @Optional String type) {
TrustType trustType = null;
if (type == null) {
trustType = TrustTypes.BUILDER;
} else {
trustType = CommandHelper.getTrustType(type);
if (trustType == null) {
GriefDefenderPlugin.sendMessage(player, MessageCache.getInstance().TRUST_INVALID);
return;
}
}
final GDPermissionGroup group = PermissionHolderCache.getInstance().getOrCreateGroup(groupName);

View File

@ -0,0 +1,161 @@
/*
* This file is part of GriefDefender, licensed under the MIT License (MIT).
*
* Copyright (c) bloodmc
* Copyright (c) contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package com.griefdefender.command.gphelper;
import co.aikar.commands.BaseCommand;
import co.aikar.commands.annotation.CommandAlias;
import co.aikar.commands.annotation.CommandPermission;
import co.aikar.commands.annotation.Description;
import co.aikar.commands.annotation.Subcommand;
import net.kyori.text.Component;
import com.google.common.collect.ImmutableMap;
import com.google.common.reflect.TypeToken;
import com.griefdefender.GDPlayerData;
import com.griefdefender.GriefDefenderPlugin;
import com.griefdefender.api.Tristate;
import com.griefdefender.api.claim.TrustTypes;
import com.griefdefender.api.permission.flag.Flags;
import com.griefdefender.api.permission.option.Options;
import com.griefdefender.cache.MessageCache;
import com.griefdefender.claim.GDClaim;
import com.griefdefender.configuration.MessageStorage;
import com.griefdefender.permission.GDPermissionManager;
import com.griefdefender.permission.GDPermissions;
import com.griefdefender.permission.option.GDOptions;
import java.time.Duration;
import java.time.Instant;
import java.util.concurrent.ThreadLocalRandom;
import org.spongepowered.api.Sponge;
import org.spongepowered.api.data.key.Keys;
import org.spongepowered.api.entity.living.player.Player;
import org.spongepowered.api.entity.living.player.gamemode.GameMode;
import org.spongepowered.api.entity.living.player.gamemode.GameModes;
import org.spongepowered.api.world.Location;
import org.spongepowered.api.world.World;
@CommandAlias("%griefdefender")
@CommandPermission(GDPermissions.COMMAND_TRAPPED)
public class CommandTrapped extends BaseCommand {
@CommandAlias("trapped")
@Description("Teleports the player to a safe location if stuck and unable to build.")
@Subcommand("player trapped")
public void execute(Player player) {
final GameMode gameMode = player.get(Keys.GAME_MODE).orElse(null);
if (gameMode == GameModes.SPECTATOR) {
return;
}
final GDPlayerData playerData = GriefDefenderPlugin.getInstance().dataStore.getOrCreatePlayerData(player.getWorld(), player.getUniqueId());
final GDClaim claim = GriefDefenderPlugin.getInstance().dataStore.getClaimAtPlayer(playerData, player.getLocation());
if (playerData.inPvpCombat()) {
GriefDefenderPlugin.sendMessage(player, MessageCache.getInstance().COMMAND_TRAPPED_PVP_COMBAT);
return;
}
if (player.getUniqueId().equals(claim.getOwnerUniqueId()) || claim.isUserTrusted(player, TrustTypes.BUILDER)) {
GriefDefenderPlugin.sendMessage(player, MessageCache.getInstance().COMMAND_TRAPPED_BUILD_ACCESS);
return;
}
final Instant now = Instant.now();
final int cooldown = GriefDefenderPlugin.getActiveConfig(player.getWorld().getUniqueId()).getConfig().claim.trappedCooldown;
if (playerData.lastTrappedTimestamp != null && !playerData.lastTrappedTimestamp.plusSeconds(cooldown).isBefore(now)) {
final int duration = (int) Duration.between(playerData.lastTrappedTimestamp, now).getSeconds();
final Component message = GriefDefenderPlugin.getInstance().messageData.getMessage(MessageStorage.COMMAND_TRAPPED_CANCEL_COOLDOWN, ImmutableMap.of(
"time-remaining", cooldown - duration));
GriefDefenderPlugin.sendMessage(player, message);
return;
}
playerData.lastTrappedTimestamp = null;
// check place
boolean canBuild = true;
final Tristate placeResult = GDPermissionManager.getInstance().getFinalPermission(null, player.getLocation(), claim, Flags.BLOCK_PLACE, player, player.getLocation(), player, TrustTypes.BUILDER, true);
if (placeResult == Tristate.FALSE) {
canBuild = false;
} else {
// check break
final Tristate breakResult = GDPermissionManager.getInstance().getFinalPermission(null, player.getLocation(), claim, Flags.BLOCK_BREAK, player, player.getLocation(), player, TrustTypes.BUILDER, true);
if (breakResult == Tristate.FALSE) {
canBuild = false;
}
}
if (canBuild) {
GriefDefenderPlugin.sendMessage(player, MessageCache.getInstance().COMMAND_TRAPPED_BUILD_ACCESS);
return;
}
final int minClaimLevel = claim.getOwnerMinClaimLevel();
double claimY = claim.getOwnerPlayerData() == null ? 65.0D : (minClaimLevel > 65.0D ? minClaimLevel : 65);
if (claim.isCuboid()) {
claimY = claim.lesserBoundaryCorner.getY();
}
final int random = ThreadLocalRandom.current().nextInt(2, 20 + 1);
final int randomCorner = ThreadLocalRandom.current().nextInt(1, 4 + 1);
Location<World> claimCorner = null;
switch (randomCorner) {
case 1: // SW
claimCorner = new Location<>(claim.getWorld(), claim.lesserBoundaryCorner.getX() - random, claimY, claim.greaterBoundaryCorner.getZ() + random);
case 2: // NW
claimCorner = new Location<>(claim.getWorld(), claim.lesserBoundaryCorner.getX() - random, claimY, claim.lesserBoundaryCorner.getZ() - random);
case 3: // SE
claimCorner = new Location<>(claim.getWorld(), claim.greaterBoundaryCorner.getX() + random, claimY, claim.greaterBoundaryCorner.getZ() + random);
case 4: // NE
claimCorner = new Location<>(claim.getWorld(), claim.greaterBoundaryCorner.getX() + random, claimY, claim.lesserBoundaryCorner.getZ() - random);
}
final Location<World> safeLocation = Sponge.getTeleportHelper().getSafeLocation(claimCorner, 64, 16, 2).orElse(null);
if (safeLocation != null) {
playerData.teleportLocation = safeLocation;
} else {
// If no safe location was found, fall back to corner
playerData.teleportLocation = claimCorner;
}
int teleportDelay = 0;
if (GDOptions.PLAYER_TELEPORT_DELAY) {
teleportDelay = GDPermissionManager.getInstance().getInternalOptionValue(TypeToken.of(Integer.class), player, Options.PLAYER_TELEPORT_DELAY, claim);
}
if (teleportDelay > 0) {
playerData.trappedRequest = true;
playerData.teleportDelay = teleportDelay + 1;
final Component message = GriefDefenderPlugin.getInstance().messageData.getMessage(MessageStorage.COMMAND_TRAPPED_REQUEST, ImmutableMap.of(
"time-remaining", teleportDelay));
GriefDefenderPlugin.sendMessage(player, message);
return;
}
playerData.lastTrappedTimestamp = now;
player.setLocation(playerData.teleportLocation);
playerData.teleportLocation = null;
GriefDefenderPlugin.sendMessage(player, MessageCache.getInstance().COMMAND_TRAPPED_SUCCESS);
}
}

View File

@ -0,0 +1,58 @@
/*
* This file is part of GriefDefender, licensed under the MIT License (MIT).
*
* Copyright (c) bloodmc
* Copyright (c) contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package com.griefdefender.command.gphelper;
import co.aikar.commands.BaseCommand;
import co.aikar.commands.annotation.CommandAlias;
import co.aikar.commands.annotation.CommandPermission;
import co.aikar.commands.annotation.Description;
import co.aikar.commands.annotation.Subcommand;
import org.spongepowered.api.entity.living.player.Player;
import com.griefdefender.GDPlayerData;
import com.griefdefender.GriefDefenderPlugin;
import com.griefdefender.cache.MessageCache;
import com.griefdefender.permission.GDPermissions;
@CommandAlias("%griefdefender")
@CommandPermission(GDPermissions.COMMAND_UNLOCK_DROPS)
public class CommandUnlockDrops extends BaseCommand {
@CommandAlias("unlockdrops")
@Description("Allows other players to pickup any items dropped from death.")
@Subcommand("player unlockdrops")
public void execute(Player player) {
final GDPlayerData playerData = GriefDefenderPlugin.getInstance().dataStore.getOrCreatePlayerData(player.getWorld(), player.getUniqueId());
if (!playerData.lockPlayerDeathDrops) {
//send not locked msg
GriefDefenderPlugin.sendMessage(player, MessageCache.getInstance().COMMAND_UNLOCK_DROPS_NONE);
return;
}
playerData.lockPlayerDeathDrops = false;
GriefDefenderPlugin.sendMessage(player, MessageCache.getInstance().COMMAND_UNLOCK_DROPS);
}
}

View File

@ -161,6 +161,8 @@ public class MessageStorage {
public static final String COMMAND_OPTION_EXCEEDS_ADMIN = "command-option-exceeds-admin";
public static final String COMMAND_PET_INVALID = "command-pet-invalid";
public static final String COMMAND_PLAYER_NOT_FOUND = "command-player-not-found";
public static final String COMMAND_TRAPPED_CANCEL_COOLDOWN = "command-trapped-cancel-cooldown";
public static final String COMMAND_TRAPPED_REQUEST = "command-trapped-request";
public static final String COMMAND_WORLD_NOT_FOUND = "command-world-not-found";
public static final String CREATE_FAILED_CLAIM_LIMIT = "create-failed-claim-limit";
public static final String CREATE_FAILED_RESULT = "create-failed-result";

View File

@ -41,6 +41,8 @@ public class ClaimCategory extends ConfigCategory {
+ "\nEx. If you add 'minecraft:creeper' to the list, creepers would not be able to hurt entities above sea level."
+ "\nNote: This will have higher priority than 'explosion-entity' flag.")
public List<String> explosionEntitySurfaceBlacklist = new ArrayList<>();
@Setting(value = "explosion-surface-block-level", comment = "The 'Y' block level that is considered the surface for explosions. (Default: 63)")
public int explosionSurfaceBlockLevel = 63;
@Setting(value = "worldedit-schematics", comment = "Whether to use WorldEdit for schematics. Default: false"
+ "\nNote: If you were using schematics in older GD/GP versions and want old schematics to work then you should keep this setting disabled.")
public boolean useWorldEditSchematics = false;
@ -69,6 +71,8 @@ public class ClaimCategory extends ConfigCategory {
@Setting(value = "claims-enabled",
comment = "Whether claiming is enabled or not. (0 = Disabled, 1 = Enabled)")
public int claimsEnabled = 1;
@Setting(value = "player-trapped-cooldown", comment = "The cooldown time, in seconds, when using the '/trapped' command. (Default: 300)")
public int trappedCooldown = 300;
@Setting(value = "protect-tamed-entities", comment = "Whether tamed entities should be protected in claims. Default: true")
public boolean protectTamedEntities = true;
@Setting(value = "reserved-claim-names", comment = "A list of reserved claim names for use only by administrators."

View File

@ -71,6 +71,7 @@ public DefaultOptionCategory() {
this.defaultUserOptions.put(Options.PLAYER_FLY_SPEED.getName(), "0");
this.defaultUserOptions.put(Options.PLAYER_GAMEMODE.getName(), "undefined");
this.defaultUserOptions.put(Options.PLAYER_HEALTH_REGEN.getName(), "0");
this.defaultUserOptions.put(Options.PLAYER_ITEM_DROP_LOCK.getName(), "false");
this.defaultUserOptions.put(Options.PLAYER_KEEP_INVENTORY.getName(), "undefined");
this.defaultUserOptions.put(Options.PLAYER_KEEP_LEVEL.getName(), "undefined");
this.defaultUserOptions.put(Options.PLAYER_TELEPORT_DELAY.getName(), "0");
@ -80,6 +81,7 @@ public DefaultOptionCategory() {
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.defaultUserOptions.put(Options.PVP_ITEM_DROP_LOCK.getName(), "false");
this.defaultUserOptions.put(Options.RAID.getName(), "true");
this.defaultUserOptions.put(Options.RADIUS_INSPECT.getName(), "100");
this.defaultUserOptions.put(Options.RENT_EXPIRATION.getName(), "7");

View File

@ -652,6 +652,7 @@ public void onExplosionDetonate(ExplosionEvent.Detonate event) {
GDClaim targetClaim = null;
final List<Location<World>> filteredLocations = new ArrayList<>();
final String sourceId = GDPermissionManager.getInstance().getPermissionIdentifier(source);
final int surfaceBlockLevel = GriefDefenderPlugin.getActiveConfig(world.getUniqueId()).getConfig().claim.explosionSurfaceBlockLevel;
boolean denySurfaceExplosion = GriefDefenderPlugin.getActiveConfig(world.getUniqueId()).getConfig().claim.explosionBlockSurfaceBlacklist.contains(sourceId);
if (!denySurfaceExplosion) {
denySurfaceExplosion = GriefDefenderPlugin.getActiveConfig(world.getUniqueId()).getConfig().claim.explosionBlockSurfaceBlacklist.contains("any");
@ -661,7 +662,7 @@ public void onExplosionDetonate(ExplosionEvent.Detonate event) {
continue;
}
targetClaim = GriefDefenderPlugin.getInstance().dataStore.getClaimAt(location, targetClaim);
if (denySurfaceExplosion && world.getDimension().getType() != DimensionTypes.NETHER && location.getBlockY() >= world.getSeaLevel()) {
if (denySurfaceExplosion && world.getDimension().getType() != DimensionTypes.NETHER && location.getBlockY() >= surfaceBlockLevel) {
filteredLocations.add(location);
GDPermissionManager.getInstance().processEventLog(event, location, targetClaim, Flags.EXPLOSION_BLOCK.getPermission(), source, location.getBlock(), user, "explosion-surface", Tristate.FALSE);
continue;

View File

@ -107,16 +107,7 @@ public boolean onEntityMove(MoveEntityEvent event, Location<World> fromLocation,
if (targetEntity instanceof Item || targetEntity instanceof Projectile) {
return true;
}
if ((!GDFlags.ENTER_CLAIM && !GDFlags.EXIT_CLAIM) || fromLocation.getBlockPosition().equals(toLocation.getBlockPosition())) {
return true;
}
World world = targetEntity.getWorld();
if (!GriefDefenderPlugin.getInstance().claimsEnabledForWorld(world.getUniqueId())) {
return true;
}
GDTimings.ENTITY_MOVE_EVENT.startTimingIfSync();
Player player = null;
GDPermissionUser user = null;
boolean onMount = false;
@ -136,6 +127,27 @@ public boolean onEntityMove(MoveEntityEvent event, Location<World> fromLocation,
}
}
}
if ((!GDFlags.ENTER_CLAIM && !GDFlags.EXIT_CLAIM) || fromLocation.getBlockPosition().equals(toLocation.getBlockPosition())) {
if (player != null && user != null) {
user.getInternalPlayerData().lastAfkCheckLocation = toLocation;
}
return true;
}
if (user != null) {
user.getInternalPlayerData().lastAfkCheckLocation = null;
if (user.getInternalPlayerData().trappedRequest) {
GriefDefenderPlugin.sendMessage(player, MessageCache.getInstance().COMMAND_TRAPPED_CANCEL_MOVE);
user.getInternalPlayerData().trappedRequest = false;
user.getInternalPlayerData().teleportDelay = 0;
}
}
World world = targetEntity.getWorld();
if (!GriefDefenderPlugin.getInstance().claimsEnabledForWorld(world.getUniqueId())) {
return true;
}
GDTimings.ENTITY_MOVE_EVENT.startTimingIfSync();
if (user != null && user.getOnlinePlayer() != null) {
final boolean preInLiquid = user.getInternalPlayerData().inLiquid;
@ -409,7 +421,7 @@ private void runPlayerCommands(GDClaim claim, GDPermissionUser user, boolean ent
// Most likely NPC
return;
}
if (!GDOptions.isOptionEnabled(Options.PLAYER_COMMAND_ENTER) && !GDOptions.isOptionEnabled(Options.PLAYER_COMMAND_EXIT)) {
if (!GDOptions.PLAYER_COMMAND_ENTER && !GDOptions.PLAYER_COMMAND_EXIT) {
return;
}
@ -488,7 +500,7 @@ private void checkPlayerFlight(GDPermissionUser user, GDClaim fromClaim, GDClaim
// Most likely NPC
return;
}
if (!GDOptions.isOptionEnabled(Options.PLAYER_DENY_FLIGHT)) {
if (!GDOptions.PLAYER_DENY_FLIGHT) {
return;
}
@ -538,12 +550,8 @@ private void checkPlayerFlight(GDPermissionUser user, GDClaim fromClaim, GDClaim
return;
}
Boolean noFly = playerData.optionNoFly;
if (noFly == null || fromClaim != toClaim) {
noFly = GDPermissionManager.getInstance().getInternalOptionValue(TypeToken.of(Boolean.class), playerData.getSubject(), Options.PLAYER_DENY_FLIGHT, toClaim);
playerData.optionNoFly = noFly;
}
if (noFly) {
final Boolean noFly = GDPermissionManager.getInstance().getInternalOptionValue(TypeToken.of(Boolean.class), playerData.getSubject(), Options.PLAYER_DENY_FLIGHT, toClaim);
if (noFly != null && noFly) {
player.offer(Keys.CAN_FLY, false);
player.offer(Keys.IS_FLYING, false);
playerData.ignoreFallDamage = true;
@ -567,7 +575,7 @@ private void checkPlayerGodMode(GDPermissionUser user, GDClaim fromClaim, GDClai
// Most likely NPC
return;
}
if (!GDOptions.isOptionEnabled(Options.PLAYER_DENY_GODMODE)) {
if (!GDOptions.PLAYER_DENY_GODMODE) {
return;
}
@ -598,7 +606,7 @@ private void checkPlayerGameMode(GDPermissionUser user, GDClaim fromClaim, GDCla
// Most likely Citizens NPC
return;
}
if (!GDOptions.isOptionEnabled(Options.PLAYER_GAMEMODE)) {
if (!GDOptions.PLAYER_GAMEMODE) {
return;
}
@ -637,7 +645,7 @@ private void checkPlayerFlySpeed(GDPermissionUser user, GDClaim fromClaim, GDCla
// Most likely Citizens NPC
return;
}
if (!GDOptions.isOptionEnabled(Options.PLAYER_FLY_SPEED)) {
if (!GDOptions.PLAYER_FLY_SPEED) {
return;
}
@ -689,7 +697,7 @@ private void checkPlayerWalkSpeed(GDPermissionUser user, GDClaim fromClaim, GDCl
// Most likely Citizens NPC
return;
}
if (!GDOptions.isOptionEnabled(Options.PLAYER_WALK_SPEED)) {
if (!GDOptions.PLAYER_WALK_SPEED) {
return;
}
@ -741,7 +749,7 @@ public void checkPlayerWeather(GDPermissionUser user, GDClaim fromClaim, GDClaim
// Most likely Citizens NPC
return;
}
if (!GDOptions.isOptionEnabled(Options.PLAYER_WEATHER)) {
if (!GDOptions.PLAYER_WEATHER) {
return;
}

View File

@ -147,6 +147,7 @@ public void onEntityExplosionDetonate(ExplosionEvent.Detonate event) {
}
final String sourceId = GDPermissionManager.getInstance().getPermissionIdentifier(source);
final int surfaceBlockLevel = GriefDefenderPlugin.getActiveConfig(event.getTargetWorld().getUniqueId()).getConfig().claim.explosionSurfaceBlockLevel;
boolean denySurfaceExplosion = GriefDefenderPlugin.getActiveConfig(event.getTargetWorld().getUniqueId()).getConfig().claim.explosionEntitySurfaceBlacklist.contains(sourceId);
if (!denySurfaceExplosion) {
denySurfaceExplosion = GriefDefenderPlugin.getActiveConfig(event.getTargetWorld().getUniqueId()).getConfig().claim.explosionEntitySurfaceBlacklist.contains("any");
@ -156,7 +157,7 @@ public void onEntityExplosionDetonate(ExplosionEvent.Detonate event) {
Entity entity = iterator.next();
final Location<World> location = entity.getLocation();
targetClaim = GriefDefenderPlugin.getInstance().dataStore.getClaimAt(entity.getLocation(), targetClaim);
if (denySurfaceExplosion && location.getExtent().getDimension().getType() != DimensionTypes.NETHER && location.getBlockY() >= location.getExtent().getSeaLevel()) {
if (denySurfaceExplosion && location.getExtent().getDimension().getType() != DimensionTypes.NETHER && location.getBlockY() >= surfaceBlockLevel) {
iterator.remove();
GDPermissionManager.getInstance().processEventLog(event, location, targetClaim, Flags.EXPLOSION_ENTITY.getPermission(), source, entity, user, "explosion-surface", Tristate.FALSE);
continue;
@ -429,6 +430,17 @@ public boolean protectEntity(Event event, Entity targetEntity, Cause cause, Dama
if (GriefDefenderPlugin.isTargetIdBlacklisted(Flags.ENTITY_DAMAGE.getName(), targetEntity, targetEntity.getWorld().getProperties())) {
return false;
}
if (targetEntity instanceof Item) {
if (GDOptions.PLAYER_ITEM_DROP_LOCK || GDOptions.PVP_ITEM_DROP_LOCK) {
final UUID creatorUniqueId = targetEntity.getCreator().orElse(null);
if (creatorUniqueId != null) {
final Player itemPlayer = Sponge.getServer().getPlayer(creatorUniqueId).orElse(null);
if (itemPlayer != null) {
return true;
}
}
}
}
User user = CauseContextHelper.getEventUser(event);
Player player = cause.first(Player.class).orElse(null);
@ -715,11 +727,10 @@ public void onEntityTeleport(MoveEntityEvent.Teleport event) {
player = (Player) entity;
user = PermissionHolderCache.getInstance().getOrCreateUser(player);
playerData = user.getInternalPlayerData();
playerData.optionNoFly = null; // Reset no fly option on teleports as from/to claim would be the same
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 && GDOptions.isOptionEnabled(Options.PVP_COMBAT_TELEPORT)) {
if (!pvpCombatTeleport && GDOptions.PVP_COMBAT_TELEPORT) {
final int combatTimeRemaining = playerData.getPvpCombatTimeRemaining();
if (combatTimeRemaining > 0) {
final Component denyMessage = GriefDefenderPlugin.getInstance().messageData.getMessage(MessageStorage.PVP_IN_COMBAT_NOT_ALLOWED,
@ -1011,7 +1022,7 @@ private boolean getPvpProtectResult(Event event, GDClaim claim, GDPermissionUser
}
// Check options
if (GDOptions.isOptionEnabled(Options.PVP)) {
if (GDOptions.PVP) {
sourceResult = GDPermissionManager.getInstance().getInternalOptionValue(TypeToken.of(Tristate.class), source, Options.PVP, sourceClaim);
targetResult = GDPermissionManager.getInstance().getInternalOptionValue(TypeToken.of(Tristate.class), target, Options.PVP, claim);
}

View File

@ -348,7 +348,7 @@ public void onPlayerCommand(SendCommandEvent event, @First Player player) {
final int combatTimeRemaining = playerData.getPvpCombatTimeRemaining(claim);
final boolean inPvpCombat = combatTimeRemaining > 0;
if (GDOptions.isOptionEnabled(Options.PVP_COMBAT_COMMAND)) {
if (GDOptions.PVP_COMBAT_COMMAND) {
final boolean pvpCombatCommand = GDPermissionManager.getInstance().getInternalOptionValue(TypeToken.of(Boolean.class), player, Options.PVP_COMBAT_COMMAND, claim);
if (!pvpCombatCommand && inPvpCombat) {
final Component denyMessage = GriefDefenderPlugin.getInstance().messageData.getMessage(MessageStorage.PVP_IN_COMBAT_NOT_ALLOWED,
@ -525,7 +525,7 @@ public void onPlayerDeath(DestructEntityEvent.Death event) {
final GDPlayerData playerData = GriefDefenderPlugin.getInstance().dataStore.getOrCreatePlayerData(player.getWorld(), player.getUniqueId());
final GDClaim claim = GriefDefenderPlugin.getInstance().dataStore.getClaimAtPlayer(playerData, player.getLocation());
Tristate keepInventory = Tristate.UNDEFINED;
if (GDOptions.isOptionEnabled(Options.PLAYER_KEEP_INVENTORY)) {
if (GDOptions.PLAYER_KEEP_INVENTORY) {
keepInventory = GDPermissionManager.getInstance().getInternalOptionValue(TypeToken.of(Tristate.class), playerData.getSubject(), Options.PLAYER_KEEP_INVENTORY, claim);
}
if (keepInventory != Tristate.UNDEFINED) {
@ -540,6 +540,27 @@ public void onPlayerDeath(DestructEntityEvent.Death event) {
}*/
}
@Listener(order = Order.FIRST, beforeModifications = true)
public void onPlayerDeathDropItem(DropItemEvent.Destruct event, @First Player player) {
final GDClaim claim = this.dataStore.getClaimAt(player.getLocation());
final GDPlayerData playerData = this.dataStore.getOrCreatePlayerData(player.getWorld(), player.getUniqueId());
if (GDOptions.PLAYER_ITEM_DROP_LOCK || GDOptions.PVP_ITEM_DROP_LOCK) {
boolean itemDropLock = false;
if (playerData.inPvpCombat() && GDOptions.PVP_ITEM_DROP_LOCK) {
itemDropLock = GDPermissionManager.getInstance().getInternalOptionValue(TypeToken.of(Boolean.class), player, Options.PVP_ITEM_DROP_LOCK, claim);
} else if (GDOptions.PLAYER_ITEM_DROP_LOCK) {
itemDropLock = GDPermissionManager.getInstance().getInternalOptionValue(TypeToken.of(Boolean.class), player, Options.PLAYER_ITEM_DROP_LOCK, claim);
}
if (itemDropLock) {
if (event.getEntities().size() > 0) {
playerData.lockPlayerDeathDrops = true;
GriefDefenderPlugin.sendMessage(player, MessageCache.getInstance().PLAYER_ITEM_DROPS_LOCK);
}
}
}
}
@Listener(order = Order.FIRST, beforeModifications = true)
public void onPlayerRespawn(RespawnPlayerEvent event) {
final World world = event.getToTransform().getExtent();
@ -890,6 +911,15 @@ public void onPlayerPickupItem(ChangeInventoryEvent.Pickup.Pre event, @Root Play
event.setCancelled(true);
}
if (GDOptions.PLAYER_ITEM_DROP_LOCK || GDOptions.PVP_ITEM_DROP_LOCK) {
final UUID creatorUniqueId = event.getTargetEntity().getCreator().orElse(null);
if (creatorUniqueId != null && !creatorUniqueId.equals(player.getUniqueId())) {
final GDPlayerData ownerPlayerData = this.dataStore.getOrCreatePlayerData(player.getWorld(), creatorUniqueId);
if (ownerPlayerData.lockPlayerDeathDrops) {
event.setCancelled(true);
}
}
}
GDTimings.PLAYER_PICKUP_ITEM_EVENT.stopTimingIfSync();
}

View File

@ -280,7 +280,7 @@ public Tristate getFinalPermission(Event event, Location<World> location, Set<Co
this.eventPlayerData = playerData;
final String targetPermission = flag.getPermission();
if (flag == Flags.ENTITY_SPAWN && GDOptions.isOptionEnabled(Options.SPAWN_LIMIT) && target instanceof Living) {
if (flag == Flags.ENTITY_SPAWN && GDOptions.SPAWN_LIMIT && target instanceof Living) {
// Check spawn limit
final GDClaim gdClaim = (GDClaim) claim;
final int spawnLimit = gdClaim.getSpawnLimit(contexts);

View File

@ -78,6 +78,7 @@ public class GDPermissions {
public static final String COMMAND_TOWN_TAX = "griefdefender.user.town.command.tax";
public static final String COMMAND_TOWN_MODE = "griefdefender.user.claim.command.town-mode";
public static final String COMMAND_TRANSFER_CLAIM = "griefdefender.user.claim.command.transfer";
public static final String COMMAND_TRAPPED = "griefdefender.user.claim.command.trapped";
public static final String COMMAND_BUY_CLAIM_BLOCKS = "griefdefender.user.claim.command.buy-blocks";
public static final String COMMAND_SELL_CLAIM_BLOCKS = "griefdefender.user.claim.command.sell-blocks";
public static final String COMMAND_LIST_CLAIM_FLAGS = "griefdefender.user.claim.command.list-flags";
@ -85,6 +86,7 @@ public class GDPermissions {
public static final String COMMAND_BAN_ITEM = "griefdefender.user.claim.command.ban-item";
public static final String COMMAND_UNBAN_ITEM = "griefdefender.user.claim.command.unban-item";
public static final String COMMAND_CLAIM_INHERIT = "griefdefender.user.claim.command.inherit";
public static final String COMMAND_UNLOCK_DROPS = "griefdefender.user.claim.command.unlock-drops";
public static final String CLAIM_CREATE = "griefdefender.user.claim.create.base";
public static final String CLAIM_CREATE_BASIC = "griefdefender.user.claim.create.basic";
public static final String CLAIM_CREATE_SUBDIVISION = "griefdefender.user.claim.create.subdivision";

View File

@ -38,6 +38,7 @@ public class GDOptions {
public static boolean PLAYER_FLY_SPEED;
public static boolean PLAYER_GAMEMODE;
public static boolean PLAYER_HEALTH_REGEN;
public static boolean PLAYER_ITEM_DROP_LOCK;
public static boolean PLAYER_KEEP_INVENTORY;
public static boolean PLAYER_KEEP_LEVEL;
public static boolean PLAYER_TELEPORT_DELAY;
@ -47,27 +48,30 @@ public class GDOptions {
public static boolean PVP_COMBAT_COMMAND;
public static boolean PVP_COMBAT_TELEPORT;
public static boolean PVP_COMBAT_TIMEOUT;
public static boolean PVP_ITEM_DROP_LOCK;
public static boolean SPAWN_LIMIT;
public static void populateOptionStatus() {
PLAYER_COMMAND_ENTER = GriefDefenderPlugin.getOptionConfig().getConfig().isOptionEnabled(Options.PLAYER_COMMAND_ENTER.getName());
PLAYER_COMMAND_EXIT = GriefDefenderPlugin.getOptionConfig().getConfig().isOptionEnabled(Options.PLAYER_COMMAND_EXIT.getName());
PLAYER_DENY_FLIGHT = GriefDefenderPlugin.getOptionConfig().getConfig().isOptionEnabled(Options.PLAYER_DENY_FLIGHT.getName());
PLAYER_DENY_GODMODE = GriefDefenderPlugin.getOptionConfig().getConfig().isOptionEnabled(Options.PLAYER_DENY_GODMODE.getName());
PLAYER_DENY_HUNGER = GriefDefenderPlugin.getOptionConfig().getConfig().isOptionEnabled(Options.PLAYER_DENY_HUNGER.getName());
PLAYER_FLY_SPEED = GriefDefenderPlugin.getOptionConfig().getConfig().isOptionEnabled(Options.PLAYER_FLY_SPEED.getName());
PLAYER_GAMEMODE = GriefDefenderPlugin.getOptionConfig().getConfig().isOptionEnabled(Options.PLAYER_GAMEMODE.getName());
PLAYER_HEALTH_REGEN = GriefDefenderPlugin.getOptionConfig().getConfig().isOptionEnabled(Options.PLAYER_HEALTH_REGEN.getName());
PLAYER_KEEP_INVENTORY = GriefDefenderPlugin.getOptionConfig().getConfig().isOptionEnabled(Options.PLAYER_KEEP_INVENTORY.getName());
PLAYER_KEEP_LEVEL = GriefDefenderPlugin.getOptionConfig().getConfig().isOptionEnabled(Options.PLAYER_KEEP_LEVEL.getName());
PLAYER_TELEPORT_DELAY = GriefDefenderPlugin.getOptionConfig().getConfig().isOptionEnabled(Options.PLAYER_TELEPORT_DELAY.getName());
PLAYER_WALK_SPEED = GriefDefenderPlugin.getOptionConfig().getConfig().isOptionEnabled(Options.PLAYER_WALK_SPEED.getName());
PLAYER_WEATHER = GriefDefenderPlugin.getOptionConfig().getConfig().isOptionEnabled(Options.PLAYER_WEATHER.getName());
PVP = GriefDefenderPlugin.getOptionConfig().getConfig().isOptionEnabled(Options.PVP.getName());
PVP_COMBAT_COMMAND = GriefDefenderPlugin.getOptionConfig().getConfig().isOptionEnabled(Options.PVP_COMBAT_COMMAND.getName());
PVP_COMBAT_TELEPORT = GriefDefenderPlugin.getOptionConfig().getConfig().isOptionEnabled(Options.PVP_COMBAT_TELEPORT.getName());
PVP_COMBAT_TIMEOUT = GriefDefenderPlugin.getOptionConfig().getConfig().isOptionEnabled(Options.PVP_COMBAT_TIMEOUT.getName());
SPAWN_LIMIT = GriefDefenderPlugin.getOptionConfig().getConfig().isOptionEnabled(Options.SPAWN_LIMIT.getName());
PLAYER_COMMAND_ENTER = GriefDefenderPlugin.getOptionConfig().getConfig().isOptionEnabled(Options.PLAYER_COMMAND_ENTER.getName().toLowerCase());
PLAYER_COMMAND_EXIT = GriefDefenderPlugin.getOptionConfig().getConfig().isOptionEnabled(Options.PLAYER_COMMAND_EXIT.getName().toLowerCase());
PLAYER_DENY_FLIGHT = GriefDefenderPlugin.getOptionConfig().getConfig().isOptionEnabled(Options.PLAYER_DENY_FLIGHT.getName().toLowerCase());
PLAYER_DENY_GODMODE = GriefDefenderPlugin.getOptionConfig().getConfig().isOptionEnabled(Options.PLAYER_DENY_GODMODE.getName().toLowerCase());
PLAYER_DENY_HUNGER = GriefDefenderPlugin.getOptionConfig().getConfig().isOptionEnabled(Options.PLAYER_DENY_HUNGER.getName().toLowerCase());
PLAYER_FLY_SPEED = GriefDefenderPlugin.getOptionConfig().getConfig().isOptionEnabled(Options.PLAYER_FLY_SPEED.getName().toLowerCase());
PLAYER_GAMEMODE = GriefDefenderPlugin.getOptionConfig().getConfig().isOptionEnabled(Options.PLAYER_GAMEMODE.getName().toLowerCase());
PLAYER_HEALTH_REGEN = GriefDefenderPlugin.getOptionConfig().getConfig().isOptionEnabled(Options.PLAYER_HEALTH_REGEN.getName().toLowerCase());
PLAYER_ITEM_DROP_LOCK = GriefDefenderPlugin.getOptionConfig().getConfig().isOptionEnabled(Options.PLAYER_ITEM_DROP_LOCK.getName().toLowerCase());
PLAYER_KEEP_INVENTORY = GriefDefenderPlugin.getOptionConfig().getConfig().isOptionEnabled(Options.PLAYER_KEEP_INVENTORY.getName().toLowerCase());
PLAYER_KEEP_LEVEL = GriefDefenderPlugin.getOptionConfig().getConfig().isOptionEnabled(Options.PLAYER_KEEP_LEVEL.getName().toLowerCase());
PLAYER_TELEPORT_DELAY = GriefDefenderPlugin.getOptionConfig().getConfig().isOptionEnabled(Options.PLAYER_TELEPORT_DELAY.getName().toLowerCase());
PLAYER_WALK_SPEED = GriefDefenderPlugin.getOptionConfig().getConfig().isOptionEnabled(Options.PLAYER_WALK_SPEED.getName().toLowerCase());
PLAYER_WEATHER = GriefDefenderPlugin.getOptionConfig().getConfig().isOptionEnabled(Options.PLAYER_WEATHER.getName().toLowerCase());
PVP = GriefDefenderPlugin.getOptionConfig().getConfig().isOptionEnabled(Options.PVP.getName().toLowerCase());
PVP_COMBAT_COMMAND = GriefDefenderPlugin.getOptionConfig().getConfig().isOptionEnabled(Options.PVP_COMBAT_COMMAND.getName().toLowerCase());
PVP_COMBAT_TELEPORT = GriefDefenderPlugin.getOptionConfig().getConfig().isOptionEnabled(Options.PVP_COMBAT_TELEPORT.getName().toLowerCase());
PVP_COMBAT_TIMEOUT = GriefDefenderPlugin.getOptionConfig().getConfig().isOptionEnabled(Options.PVP_COMBAT_TIMEOUT.getName().toLowerCase());
PVP_ITEM_DROP_LOCK = GriefDefenderPlugin.getOptionConfig().getConfig().isOptionEnabled(Options.PVP_ITEM_DROP_LOCK.getName().toLowerCase());
SPAWN_LIMIT = GriefDefenderPlugin.getOptionConfig().getConfig().isOptionEnabled(Options.SPAWN_LIMIT.getName().toLowerCase());
}
public static boolean isOptionEnabled(Option option) {

View File

@ -117,6 +117,7 @@ public void registerDefaults() {
this.createKey("griefdefender:player-fly-speed", Double.class);
this.createKey("griefdefender:player-gamemode", GameModeType.class);
this.createKey("griefdefender:player-health-regen", Double.class);
this.createKey("griefdefender:player-item-drop-lock", Boolean.class);
this.createKey("griefdefender:player-keep-inventory", Tristate.class);
this.createKey("griefdefender:player-keep-level", Tristate.class);
this.createKey("griefdefender:player-teleport-delay", Integer.class);
@ -126,6 +127,7 @@ public void registerDefaults() {
this.createKey("griefdefender:pvp-combat-command", Boolean.class);
this.createKey("griefdefender:pvp-combat-teleport", Boolean.class);
this.createKey("griefdefender:pvp-combat-timeout", Integer.class);
this.createKey("griefdefender:pvp-item-drop-lock", Boolean.class);
this.createKey("griefdefender:radius-inspect", Integer.class);
this.createKey("griefdefender:raid", Boolean.class);
this.createKey("griefdefender:rent-balance", Double.class);

View File

@ -106,14 +106,11 @@ public void run() {
int currentTotal = playerData.getAccruedClaimBlocks();
if ((currentTotal + accruedBlocks) > playerData.getMaxAccruedClaimBlocks()) {
playerData.setAccruedClaimBlocks(playerData.getMaxAccruedClaimBlocks());
playerData.lastAfkCheckLocation = player.getLocation();
return;
}
playerData.setAccruedClaimBlocks(playerData.getAccruedClaimBlocks() + accruedBlocks);
}
}
playerData.lastAfkCheckLocation = player.getLocation();
}
}

View File

@ -29,6 +29,7 @@
import com.griefdefender.GDPlayerData;
import com.griefdefender.GriefDefenderPlugin;
import com.griefdefender.api.permission.option.Options;
import com.griefdefender.cache.MessageCache;
import com.griefdefender.claim.GDClaim;
import com.griefdefender.configuration.MessageStorage;
import com.griefdefender.permission.GDPermissionManager;
@ -45,6 +46,7 @@
import org.spongepowered.api.entity.living.player.gamemode.GameModes;
import org.spongepowered.api.world.World;
import java.time.Instant;
import java.util.Iterator;
public class PlayerTickTask implements Runnable {
@ -81,7 +83,7 @@ public void run() {
if (world.getProperties().getTotalTime() % 100 == 0L) {
final GameMode gameMode = player.get(Keys.GAME_MODE).get();
// Handle player health regen
if (gameMode != GameModes.CREATIVE && gameMode != GameModes.SPECTATOR && GDOptions.isOptionEnabled(Options.PLAYER_HEALTH_REGEN)) {
if (gameMode != GameModes.CREATIVE && gameMode != GameModes.SPECTATOR && GDOptions.PLAYER_HEALTH_REGEN) {
final double maxHealth = player.get(Keys.MAX_HEALTH).get();
final double currentHealth = player.get(Keys.HEALTH).get();
if (currentHealth < maxHealth) {
@ -102,6 +104,11 @@ public void run() {
if (playerData.teleportDelay > 0) {
final int delay = playerData.teleportDelay - 1;
if (delay == 0) {
if (playerData.trappedRequest) {
playerData.lastTrappedTimestamp = Instant.now();
GriefDefenderPlugin.sendMessage(player, MessageCache.getInstance().COMMAND_TRAPPED_SUCCESS);
}
// This must be set BEFORE teleport
player.setLocation(playerData.teleportLocation);
playerData.teleportDelay = 0;
playerData.teleportLocation = null;