mirror of
https://github.com/bloodmc/GriefDefender.git
synced 2024-12-22 16:57:38 +01:00
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:
parent
4db8346de1
commit
11d9f1f278
@ -1 +1 @@
|
||||
Subproject commit f1b2d4fc1646f06f9ef9aa6f5a07f13abb7cf60b
|
||||
Subproject commit 920a6101dc1a616c431321fffa31516b951b2fa8
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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");
|
||||
|
@ -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) {
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
@ -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);
|
||||
}
|
||||
}
|
@ -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";
|
||||
|
@ -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."
|
||||
|
@ -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");
|
||||
|
@ -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;
|
||||
|
@ -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,
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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) {
|
||||
|
@ -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);
|
||||
|
@ -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";
|
||||
|
@ -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) {
|
||||
|
@ -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);
|
||||
|
@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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) {
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
@ -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",
|
||||
|
@ -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",
|
||||
|
@ -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",
|
||||
|
@ -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",
|
||||
|
@ -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",
|
||||
|
@ -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",
|
||||
|
@ -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",
|
||||
|
@ -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",
|
||||
|
@ -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",
|
||||
|
@ -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",
|
||||
|
@ -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",
|
||||
|
@ -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})"
|
||||
|
@ -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 aren’t 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})"
|
||||
|
@ -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---------------------------------------------"
|
||||
|
@ -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 aren’t 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})"
|
||||
|
@ -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})"
|
||||
|
@ -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} блоков)"
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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");
|
||||
|
@ -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) {
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
@ -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);
|
||||
}
|
||||
}
|
@ -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";
|
||||
|
@ -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."
|
||||
|
@ -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");
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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();
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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";
|
||||
|
@ -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) {
|
||||
|
@ -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);
|
||||
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user