Update for 1.5.0

* Fix blockstate id lookup not using proper id when block data was different than actual block.
* Fix block-break showing air as target when source block broke on its own.
* Fix race condition when migrating GP Bukkit playerdata.
* Fix race condition during flag definition saves.
* Fix wrong owner showing in claim when non-owner changes claim type.
* Fix explosions causing no sound when cancelling event.
* Fix rent min message showing max.
* Fix rent min payment not being applied as credit.
* Fix rent restore not working on rent end.
* Fix sell sign not working when rent system was disabled.
* Fix '/abandonall' not giving all money back when using economy mode.
* Fix '/claimsell' requiring for sale to be turned on.
* Fix '/givepet' taming pets without owner.
* Fix explosion sounds not triggering on cancel.
* Fix pvp 'allow-fly' only affecting creative mode.
* Fix confirmation message not showing after abandoning a subdivision.
* Fix wrong location being checked when placing water/lava with bucket.
* Fix dynmap owner style colors not being used.
* Fix NPE when using /reload.
* Fix ghost claim overlap error when creating claim.
* Fix user showing up as cause when using rtp.
* Fix high memory usage caused by GDClaimManager fastutil usage.
* (Bukkit) Fix NPE during InventoryMoveItemEvent.
* (Sponge) Fix explosion-surface being triggered with no settings.
* Refactor CompletableFuture handling when applying LP permissions and meta to avoid race conditions.
* Remove owner override context for flag definition 'fire-spread' as it doesn't affect global overrides.
* Change flag definition 'turtle-egg-hatch' target from 'air' to 'turtle-egg-hatch'
* Change flag definition 'snow-melt' target from 'air' to 'snow'
* Change onPlayerInteractBlockSecondary event priority from lowest to low in order to support plugins that need to cancel early.
* Add support for CustomItems. Any customitem used in game will show up in debug as customitems:<item_id>. You can also use customitems for modification and investigation tool in config.
* Add support for Slimefun4. Any slimefun item/block used in game will show up in debug as slimefun:<id>. You can also use slimefun items for modification and investigation tool in config.
* Add '/acball' command for adjusting all online players' bonus blocks.
* Add '/claiminvestigate' command to investigate claims.
* Add '/claimtool' to toggle claim tool usage.
* Add source/target any contexts to flag definitions.
* Add 'piston-protection-in-claims' setting to control piston protection within claims.
* Add pvp setting 'combat-logout' to determine if a player should be killed on logout during combat. Default 'false'.
* Add `projectile-impact-entity` to `endcrystal-use` flag definition.
* Add aquatic target for `monster-animal-damage` flag definition.
* Add `restrict-world-max-height` to determine if claiming should be restricted to world max height. Default 'true'.
* Add ability to control dynmap color settings by claim type.
* Add permission griefdefender.user.claim.command.info.teleport.inside which controls whether a player can ONLY teleport within the claim they are in. This is useful if players become trapped.
Note: This does not allow players to teleport to any other claim except the one they are in. It can only be used if the player cannot build in claim.
* Add permission griefdefender.user.claim.command.info.others.creation-date to control whether a player sees creation date in /claiminfo
* Add permission griefdefender.user.claim.command.info.others.last-active to control whether a player sees last active date in /claiminfo
* Add permission griefdefender.user.claim.command.info.others.claim-uuid to control whether a player sees claim uuid in /claiminfo
* All flag definitions will now persist.
* Refresh player option cache on permission change.
* Show TP info in '/claiminfo' when player does not have TP permission.
* (Sponge) Use 'tnt' as identifier instead of 'primedtnt' to match bukkit.
* (Sponge) Use 'item_frame' as identifier instead of 'itemframe' to
  match bukkit.
This commit is contained in:
bloodshot 2020-08-16 00:39:38 -04:00
parent 26efaf2b73
commit e8e57c5f5d
116 changed files with 3577 additions and 1102 deletions

View File

@ -95,6 +95,8 @@ public void onEnable() {
bukkitJsonVersion = "1.15";
} else if (Bukkit.getVersion().contains("1.16.1")) {
bukkitJsonVersion = "1.16.1";
} else if (Bukkit.getVersion().contains("1.16.2")) {
bukkitJsonVersion = "1.16.2";
} else {
this.getLogger().severe("Detected unsupported version '" + Bukkit.getVersion() + "'. GriefDefender only supports 1.8.8, 1.12.2, 1.13.2, 1.14.x, 1.15.0-1.15.2, 1.16.1. GriefDefender will NOT load.");
return;

View File

@ -185,6 +185,7 @@ public void pasteRecords() {
final String SOURCE = PlainComponentSerializer.INSTANCE.serialize(MessageCache.getInstance().LABEL_SOURCE);
final String TARGET = PlainComponentSerializer.INSTANCE.serialize(MessageCache.getInstance().LABEL_TARGET);
final String USER = PlainComponentSerializer.INSTANCE.serialize(MessageCache.getInstance().LABEL_USER);
final String GROUP = PlainComponentSerializer.INSTANCE.serialize(MessageCache.getInstance().LABEL_GROUP);
final String CONTEXT = PlainComponentSerializer.INSTANCE.serialize(MessageCache.getInstance().LABEL_CONTEXT);
final String RESULT = PlainComponentSerializer.INSTANCE.serialize(MessageCache.getInstance().LABEL_RESULT);
debugOutput.add("| " + RECORD_END + " | " + DATE_FORMAT.format(new Date(endTime)) + "|");
@ -192,7 +193,7 @@ public void pasteRecords() {
debugOutput.add("| " + TIME_ELAPSED + " | " + elapsed + " seconds" + "|");
debugOutput.add("");
debugOutput.add("### " + OUTPUT) ;
debugOutput.add("| " + FLAG + " | " + TRUST + " | " + SOURCE + " | " + TARGET + " | " + LOCATION + " | " + USER + " | " + CONTEXT + " | " + RESULT + " |");
debugOutput.add("| " + FLAG + " | " + TRUST + " | " + SOURCE + " | " + TARGET + " | " + LOCATION + " | " + USER + "/" + GROUP + " | " + CONTEXT + " | " + RESULT + " |");
debugOutput.add("|------|-------|--------|--------|----------|------|----------|--------|");
debugOutput.addAll(this.records);

View File

@ -91,6 +91,7 @@ public class GDPlayerData implements PlayerData {
public Location lastValidInspectLocation;
public Location lastNonAirInspectLocation;
public boolean claimMode = false;
public boolean claimTool = true;
public ShovelType shovelMode = ShovelTypes.BASIC;
public GDClaim claimResizing;
@ -178,7 +179,7 @@ public class GDPlayerData implements PlayerData {
public boolean dataInitialized = false;
public boolean showNoClaimsFoundMessage = true;
public boolean useRestoreSchematic = false;
private boolean checkedDimensionHeight = false;
private final int worldMaxHeight;
public GDPlayerData(UUID worldUniqueId, String worldName, UUID playerUniqueId, Set<Claim> claims) {
this.worldUniqueId = worldUniqueId;
@ -199,6 +200,7 @@ public GDPlayerData(UUID worldUniqueId, String worldName, UUID playerUniqueId, S
contexts.add(new Context("server", PermissionUtil.getInstance().getServerName()));
}
}
this.worldMaxHeight = GriefDefenderPlugin.getInstance().dataStore.getClaimWorldManager(this.worldUniqueId).getWorldMaxHeight();
this.optionContexts = contexts;
this.refreshPlayerOptions();
}
@ -238,7 +240,6 @@ public void refreshPlayerOptions() {
this.userOptionBypassPlayerGamemode = PermissionUtil.getInstance().getPermissionValue(subject, GDPermissions.BYPASS_OPTION + "." + Options.PLAYER_GAMEMODE.getName().toLowerCase(), activeContexts).asBoolean();
this.playerID = subject.getUniqueId();
this.dataInitialized = true;
this.checkedDimensionHeight = false;
});
}
@ -699,15 +700,8 @@ public int getMinClaimZ(ClaimType type) {
@Override
public int getMaxClaimLevel() {
int maxClaimLevel = GDPermissionManager.getInstance().getInternalOptionValue(TypeToken.of(Integer.class), this.getSubject(), Options.MAX_LEVEL);
if (!this.checkedDimensionHeight) {
final World world = Bukkit.getServer().getWorld(this.worldUniqueId);
if (world != null) {
final int buildHeight = world.getMaxHeight() - 1;
if (buildHeight < maxClaimLevel) {
maxClaimLevel = buildHeight;
}
}
this.checkedDimensionHeight = true;
if (this.worldMaxHeight > -1 && this.worldMaxHeight < maxClaimLevel) {
maxClaimLevel = this.worldMaxHeight;
}
return maxClaimLevel;
}
@ -876,6 +870,7 @@ public void onDisconnect() {
this.createBlockVisualRevertRunnables.clear();
this.queuedVisuals.clear();
this.claimMode = false;
this.claimTool = true;
this.debugClaimPermissions = false;
this.ignoreClaims = false;
this.lastShovelLocation = null;

View File

@ -81,6 +81,7 @@
import com.griefdefender.claim.GDClaim;
import com.griefdefender.claim.GDClaimManager;
import com.griefdefender.command.CommandAdjustBonusClaimBlocks;
import com.griefdefender.command.CommandAdjustBonusClaimBlocksAll;
import com.griefdefender.command.CommandCallback;
import com.griefdefender.command.CommandClaimAbandon;
import com.griefdefender.command.CommandClaimAbandonAll;
@ -111,6 +112,7 @@
import com.griefdefender.command.CommandClaimIgnore;
import com.griefdefender.command.CommandClaimInfo;
import com.griefdefender.command.CommandClaimInherit;
import com.griefdefender.command.CommandClaimInvestigate;
import com.griefdefender.command.CommandClaimList;
import com.griefdefender.command.CommandClaimMode;
import com.griefdefender.command.CommandClaimName;
@ -128,6 +130,7 @@
import com.griefdefender.command.CommandClaimSpawn;
import com.griefdefender.command.CommandClaimSubdivision;
import com.griefdefender.command.CommandClaimTax;
import com.griefdefender.command.CommandClaimTool;
import com.griefdefender.command.CommandClaimTown;
import com.griefdefender.command.CommandClaimTransfer;
import com.griefdefender.command.CommandClaimUnban;
@ -204,6 +207,7 @@
import com.griefdefender.provider.LuckPermsProvider;
import com.griefdefender.provider.PermissionProvider;
import com.griefdefender.provider.PlaceholderProvider;
import com.griefdefender.provider.SlimefunProvider;
import com.griefdefender.provider.VaultProvider;
import com.griefdefender.registry.ChatTypeRegistryModule;
import com.griefdefender.registry.ClaimTypeRegistryModule;
@ -273,7 +277,18 @@ public class GriefDefenderPlugin {
public static final String PUBLIC_NAME = "[GDPublic]";
public static final String WORLD_USER_NAME = "[GDWorld]";
public static GDPermissionHolder DEFAULT_HOLDER;
public static final String DEFAULT_GROUP_NAME = "default";
public static final String GD_CLAIM_GROUP_NAME = "griefdefender_claim";
public static final String GD_DEFAULT_GROUP_NAME = "griefdefender_default";
public static final String GD_DEFINITION_GROUP_NAME = "griefdefender_definition";
public static final String GD_OPTION_GROUP_NAME = "griefdefender_option";
public static final String GD_OVERRIDE_GROUP_NAME = "griefdefender_override";
public static GDPermissionGroup DEFAULT_HOLDER;
public static GDPermissionGroup GD_DEFAULT_HOLDER;
public static GDPermissionGroup GD_CLAIM_HOLDER;
public static GDPermissionGroup GD_DEFINITION_HOLDER;
public static GDPermissionGroup GD_OPTION_HOLDER;
public static GDPermissionGroup GD_OVERRIDE_HOLDER;
private PaperCommandManager commandManager;
private static TimingManager timingManager;
@ -285,14 +300,16 @@ public class GriefDefenderPlugin {
private WorldGuardProvider worldGuardProvider;
private VaultProvider vaultProvider;
private PermissionProvider permissionProvider;
private SlimefunProvider slimefunProvider;
private List<BukkitRunnable> runningTasks = new ArrayList<>();
public Executor executor;
public GDBlockType createVisualBlock;
public GDItemType modificationTool;
public GDItemType investigationTool;
public String modificationTool;
public String investigationTool;
public boolean isCustomItemsInstalled = false;
public static boolean debugLogging = false;
public static boolean debugActive = false;
@ -315,15 +332,16 @@ public Path getConfigPath() {
public static void addEventLogEntry(Event event, Claim claim, Location location, String sourceId, String targetId, GDPermissionHolder permissionSubject, String permission, String trust, Tristate result, Set<Context> contexts) {
final String eventName = event.getClass().getSimpleName().replace('$', '.').replace(".Impl", "");
final String eventLocation = location == null ? "none" : VecHelper.toVector3i(location).toString();
final GDPermissionHolder debugHolder = PermissionUtil.getInstance().getGDPermissionHolder(permissionSubject, contexts);
for (GDDebugData debugEntry : GriefDefenderPlugin.getInstance().getDebugUserMap().values()) {
final CommandSender debugSource = debugEntry.getSource();
final GDPermissionUser debugUser = debugEntry.getUser();
if (debugUser != null) {
if (permissionSubject == null) {
if (debugHolder == null) {
continue;
}
// Check event source user
if (!permissionSubject.getIdentifier().equals(debugUser.getUniqueId().toString())) {
if (!debugHolder.getIdentifier().equals(debugUser.getUniqueId().toString())) {
continue;
}
} else if (debugEntry.getClaimUniqueId() != null) {
@ -358,9 +376,9 @@ public static void addEventLogEntry(Event event, Claim claim, Location location,
}
}
String messageUser = permissionSubject.getFriendlyName();
if (permissionSubject instanceof GDPermissionUser) {
messageUser = ((GDPermissionUser) permissionSubject).getName();
String messageUser = debugHolder.getFriendlyName().replaceAll("griefdefender_", "");
if (debugHolder instanceof GDPermissionUser) {
messageUser = ((GDPermissionUser) debugHolder).getName();
}
// record
@ -501,7 +519,28 @@ public void onEnable(boolean reload) {
}
instance = this;
timingManager = TimingManager.of(GDBootstrap.getInstance());
DEFAULT_HOLDER = new GDPermissionGroup("default");
DEFAULT_HOLDER = new GDPermissionGroup(DEFAULT_GROUP_NAME);
GD_DEFAULT_HOLDER = new GDPermissionGroup(GD_DEFAULT_GROUP_NAME);
GD_CLAIM_HOLDER = new GDPermissionGroup(GD_CLAIM_GROUP_NAME);
GD_DEFINITION_HOLDER = new GDPermissionGroup(GD_DEFINITION_GROUP_NAME);
GD_OPTION_HOLDER = new GDPermissionGroup(GD_OPTION_GROUP_NAME);
GD_OVERRIDE_HOLDER = new GDPermissionGroup(GD_OVERRIDE_GROUP_NAME);
if (!this.permissionProvider.hasGroupSubject(GD_OPTION_GROUP_NAME)) {
this.permissionProvider.createDefaultGroup(GD_OPTION_GROUP_NAME);
}
if (!this.permissionProvider.hasGroupSubject(GD_CLAIM_GROUP_NAME)) {
this.permissionProvider.createDefaultGroup(GD_CLAIM_GROUP_NAME);
}
if (!this.permissionProvider.hasGroupSubject(GD_OVERRIDE_GROUP_NAME)) {
this.permissionProvider.createDefaultGroup(GD_OVERRIDE_GROUP_NAME);
}
if (!this.permissionProvider.hasGroupSubject(GD_DEFAULT_GROUP_NAME)) {
this.permissionProvider.createDefaultGroup(GD_DEFAULT_GROUP_NAME);
}
if (!this.permissionProvider.hasGroupSubject(GD_DEFINITION_GROUP_NAME)) {
this.permissionProvider.createDefaultGroup(GD_DEFINITION_GROUP_NAME);
}
this.permissionProvider.refreshCachedData(DEFAULT_HOLDER);
PUBLIC_USER = new GDPermissionUser(PUBLIC_UUID, PUBLIC_NAME);
WORLD_USER = new GDPermissionUser(WORLD_USER_UUID, WORLD_USER_NAME);
Guice.createInjector(Stage.PRODUCTION, new GriefDefenderImplModule());
@ -528,8 +567,6 @@ public void onEnable(boolean reload) {
this.loadConfig();
this.executor = Executors.newFixedThreadPool(GriefDefenderPlugin.getGlobalConfig().getConfig().thread.numExecutorThreads);
if (Bukkit.getPluginManager().getPlugin("Vault") != null) {
this.vaultProvider = new VaultProvider();
this.getLogger().info("Detected Vault. Checking for compatible economy plugin...");
@ -567,6 +604,12 @@ public void onEnable(boolean reload) {
new PlaceholderProvider();
this.getLogger().info("GriefDefender PlaceholderAPI expansion enabled!");
}
if (Bukkit.getPluginManager().getPlugin("CustomItems") != null) {
this.isCustomItemsInstalled = true;
}
if (Bukkit.getPluginManager().getPlugin("Slimefun") != null) {
this.slimefunProvider = new SlimefunProvider();
}
if (getMajorMinecraftVersion() > 13) {
this.tagProvider = new GDTagProvider();
@ -702,6 +745,7 @@ public void registerBaseCommands() {
manager.getCommandReplacements().addReplacement("griefdefender", "gd|griefdefender");
manager.registerCommand(new CommandAccessTrust());
manager.registerCommand(new CommandAdjustBonusClaimBlocks());
manager.registerCommand(new CommandAdjustBonusClaimBlocksAll());
manager.registerCommand(new CommandCallback());
manager.registerCommand(new CommandClaimAbandon());
manager.registerCommand(new CommandClaimAbandonAll());
@ -732,6 +776,7 @@ public void registerBaseCommands() {
manager.registerCommand(new CommandClaimIgnore());
manager.registerCommand(new CommandClaimInfo());
manager.registerCommand(new CommandClaimInherit());
manager.registerCommand(new CommandClaimInvestigate());
manager.registerCommand(new CommandClaimList());
manager.registerCommand(new CommandClaimMode());
manager.registerCommand(new CommandClaimName());
@ -749,6 +794,7 @@ public void registerBaseCommands() {
manager.registerCommand(new CommandClaimSpawn());
manager.registerCommand(new CommandClaimSubdivision());
manager.registerCommand(new CommandClaimTax());
manager.registerCommand(new CommandClaimTool());
manager.registerCommand(new CommandClaimTown());
manager.registerCommand(new CommandClaimTransfer());
manager.registerCommand(new CommandClaimUnban());
@ -1010,6 +1056,9 @@ public void loadConfig() {
messageStorage = new MessageStorage(localePath);
messageData = messageStorage.getConfig();
MessageCache.getInstance().loadCache();
if (this.executor == null) {
this.executor = Executors.newFixedThreadPool(GriefDefenderPlugin.getGlobalConfig().getConfig().thread.numExecutorThreads);
}
flagConfig = new FlagConfig(this.getConfigPath().resolve("flags.conf"));
// FlagDefinition registry needs to init after config load
FlagDefinitionRegistryModule.getInstance().registerDefaults();
@ -1023,12 +1072,11 @@ public void loadConfig() {
BaseStorage.globalConfig.save();
BaseStorage.USE_GLOBAL_PLAYER_STORAGE = !BaseStorage.globalConfig.getConfig().playerdata.useWorldPlayerData();
GDFlags.populateFlagStatus();
PermissionHolderCache.getInstance().getOrCreatePermissionCache(GriefDefenderPlugin.DEFAULT_HOLDER).invalidateAll();
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);
this.modificationTool = ItemTypeRegistryModule.getInstance().getById(BaseStorage.globalConfig.getConfig().claim.modificationTool).orElse(null);
this.investigationTool = ItemTypeRegistryModule.getInstance().getById(BaseStorage.globalConfig.getConfig().claim.investigationTool).orElse(null);
this.modificationTool = BaseStorage.globalConfig.getConfig().claim.modificationTool;
this.investigationTool = BaseStorage.globalConfig.getConfig().claim.investigationTool;
if (this.dataStore != null) {
for (World world : Bukkit.getServer().getWorlds()) {
final String dimType = world.getEnvironment().name().toLowerCase();
@ -1277,6 +1325,10 @@ public PermissionProvider getPermissionProvider() {
return this.permissionProvider;
}
public SlimefunProvider getSlimefunProvider() {
return this.slimefunProvider;
}
public static int getMajorMinecraftVersion() {
final String version = Bukkit.getVersion();
if (version.contains("1.8.8")) {

View File

@ -112,6 +112,7 @@ public static MessageCache getInstance() {
public Component CLAIMLIST_UI_RETURN_CLAIMSLIST;
public Component CLAIMLIST_UI_TITLE;
public Component CLAIMLIST_UI_TITLE_CHILD_CLAIMS;
public Component CLAIMTOOL_NOT_ENABLED;
public Component COMMAND_CLAIMBUY_TITLE;
public Component COMMAND_CLAIMCLEAR_UUID_DENY;
public Component COMMAND_CLAIMFLAGDEBUG_DISABLED;
@ -122,6 +123,8 @@ public static MessageCache getInstance() {
public Component COMMAND_CLAIMINHERIT_ENABLED;
public Component COMMAND_CLAIMMODE_DISABLED;
public Component COMMAND_CLAIMMODE_ENABLED;
public Component COMMAND_CLAIMTOOL_DISABLED;
public Component COMMAND_CLAIMTOOL_ENABLED;
public Component COMMAND_CUBOID_DISABLED;
public Component COMMAND_CUBOID_ENABLED;
public Component COMMAND_INHERIT_ONLY_CHILD;
@ -574,6 +577,7 @@ public void loadCache() {
CLAIMLIST_UI_RETURN_CLAIMSLIST = MessageStorage.MESSAGE_DATA.getMessage("claimlist-ui-return-claimlist");
CLAIMLIST_UI_TITLE = MessageStorage.MESSAGE_DATA.getMessage("claimlist-ui-title");
CLAIMLIST_UI_TITLE_CHILD_CLAIMS = MessageStorage.MESSAGE_DATA.getMessage("claimlist-ui-title-child-claims");
CLAIMTOOL_NOT_ENABLED = MessageStorage.MESSAGE_DATA.getMessage("claimtool-not-enabled");
COMMAND_CLAIMBUY_TITLE = MessageStorage.MESSAGE_DATA.getMessage("command-claimbuy-title");
COMMAND_CLAIMCLEAR_UUID_DENY = MessageStorage.MESSAGE_DATA.getMessage("command-claimclear-uuid-deny");
COMMAND_CLAIMFLAGDEBUG_DISABLED = MessageStorage.MESSAGE_DATA.getMessage("command-claimflagdebug-disabled");
@ -584,6 +588,8 @@ public void loadCache() {
COMMAND_CLAIMINHERIT_ENABLED = MessageStorage.MESSAGE_DATA.getMessage("command-claiminherit-enabled");
COMMAND_CLAIMMODE_DISABLED = MessageStorage.MESSAGE_DATA.getMessage("command-claimmode-disabled");
COMMAND_CLAIMMODE_ENABLED = MessageStorage.MESSAGE_DATA.getMessage("command-claimmode-enabled");
COMMAND_CLAIMTOOL_DISABLED = MessageStorage.MESSAGE_DATA.getMessage("command-claimtool-disabled");
COMMAND_CLAIMTOOL_ENABLED = MessageStorage.MESSAGE_DATA.getMessage("command-claimtool-enabled");
COMMAND_CUBOID_DISABLED = MessageStorage.MESSAGE_DATA.getMessage("command-cuboid-disabled");
COMMAND_CUBOID_ENABLED = MessageStorage.MESSAGE_DATA.getMessage("command-cuboid-enabled");
COMMAND_INHERIT_ONLY_CHILD = MessageStorage.MESSAGE_DATA.getMessage("command-inherit-only-child");

View File

@ -27,17 +27,14 @@
import com.github.benmanes.caffeine.cache.Cache;
import com.github.benmanes.caffeine.cache.Caffeine;
import com.griefdefender.GriefDefenderPlugin;
import com.griefdefender.api.Tristate;
import com.griefdefender.permission.GDPermissionGroup;
import com.griefdefender.permission.GDPermissionHolder;
import com.griefdefender.permission.GDPermissionUser;
import com.griefdefender.util.PermissionUtil;
import org.bukkit.Bukkit;
import org.bukkit.OfflinePlayer;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.TimeUnit;
public class PermissionHolderCache {
@ -47,7 +44,6 @@ public class PermissionHolderCache {
.build();
private final Cache<String, GDPermissionGroup> groupCache = Caffeine.newBuilder().expireAfterAccess(10, TimeUnit.MINUTES)
.build();
private final ConcurrentHashMap<GDPermissionHolder, Cache<Integer, Tristate>> permissionCache = new ConcurrentHashMap<>();
public GDPermissionUser getOrCreateUser(OfflinePlayer user) {
if (user == null) {
@ -120,21 +116,6 @@ public GDPermissionHolder getOrCreateHolder(String identifier) {
return this.getOrCreateUser(uuid);
}
public Cache<Integer, Tristate> getOrCreatePermissionCache(GDPermissionHolder holder) {
Cache<Integer, Tristate> cache = this.permissionCache.get(holder);
if (cache == null) {
cache = Caffeine.newBuilder().expireAfterAccess(10, TimeUnit.MINUTES).build();
this.permissionCache.put(holder, cache);
}
return cache;
}
public void invalidateAllPermissionCache() {
for (Cache<Integer, Tristate> cache : this.permissionCache.values()) {
cache.invalidateAll();
}
}
static {
instance = new PermissionHolderCache();
}

View File

@ -1115,6 +1115,18 @@ public ClaimResult checkArea(boolean resize) {
continue;
}
// validate this claim exists
boolean claimExists = false;
for (Claim claim : this.worldClaimManager.getWorldClaims()) {
if (claim.getUniqueId().equals(chunkClaim.getUniqueId())) {
claimExists = true;
break;
}
}
if (!claimExists) {
//GriefDefenderPlugin.getInstance().getLogger().warning("Detected Ghost chunk claim with the following data [UUID: " + chunkClaim.getUniqueId() + ", Owner: " + chunkClaim.getOwnerName() + ", Type: " + chunkClaim.getType().getName() + "]. Ignoring...");
continue;
}
// First check if new claim is crossing another
if (this.isBandingAcross(gpChunkClaim) || gpChunkClaim.isBandingAcross(this)) {
return new GDClaimResult(gpChunkClaim, ClaimResultType.OVERLAPPING_CLAIM);

View File

@ -51,7 +51,6 @@
import com.griefdefender.util.BlockUtil;
import com.griefdefender.util.Direction;
import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap;
import net.kyori.text.Component;
import net.kyori.text.TextComponent;
import net.kyori.text.serializer.plain.PlainComponentSerializer;
@ -69,6 +68,7 @@
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
@ -81,6 +81,7 @@ public class GDClaimManager implements ClaimManager {
private static final BaseStorage DATASTORE = GriefDefenderPlugin.getInstance().dataStore;
private UUID worldUniqueId;
private String worldName;
private final int worldMaxHeight;
// Player UUID -> player data
private Map<UUID, GDPlayerData> playerDataList = Maps.newHashMap();
@ -89,10 +90,10 @@ public class GDClaimManager implements ClaimManager {
// Claim UUID -> Claim
private Map<UUID, Claim> claimUniqueIdMap = Maps.newHashMap();
// String -> Claim
private Map<Long, Set<Claim>> chunksToClaimsMap = new Long2ObjectOpenHashMap<>(4096);
private Map<Long, Set<Claim>> chunksToClaimsMap = new HashMap<>();
// Entity Index
public PlayerIndexStorage playerIndexStorage;
private Map<Long, GDChunk> chunksToGDChunks = new Long2ObjectOpenHashMap<>(4096);
private Map<Long, GDChunk> chunksToGDChunks = new HashMap<>();
private GDClaim theWildernessClaim;
@ -100,6 +101,11 @@ public GDClaimManager(World world) {
this.worldUniqueId = world.getUID();
this.worldName = world.getName();
this.playerIndexStorage = new PlayerIndexStorage(world);
if (GriefDefenderPlugin.getActiveConfig(this.worldUniqueId).getConfig().claim.restrictWorldMaxHeight) {
this.worldMaxHeight = world.getMaxHeight() - 1;
} else {
this.worldMaxHeight = -1;
}
}
public GDPlayerData getOrCreatePlayerData(UUID playerUniqueId) {
@ -652,6 +658,10 @@ public UUID getWorldId() {
return this.worldUniqueId;
}
public int getWorldMaxHeight() {
return this.worldMaxHeight;
}
public GDChunk getChunk(Chunk chunk) {
return this.getChunk(chunk, true);
}

View File

@ -42,6 +42,7 @@
import com.griefdefender.api.permission.ResultTypes;
import com.griefdefender.api.permission.flag.Flag;
import com.griefdefender.api.permission.flag.FlagData;
import com.griefdefender.api.permission.flag.Flags;
import com.griefdefender.cache.MessageCache;
import com.griefdefender.cache.PermissionHolderCache;
import com.griefdefender.claim.GDClaim;
@ -426,7 +427,7 @@ protected void showFlagPermissions(GDPermissionUser src, GDClaim claim, MenuType
overrideContexts.add(claim.getOverrideClaimContext());
Map<String, UIFlagData> filteredContextMap = new HashMap<>();
for (Map.Entry<Set<Context>, Map<String, Boolean>> mapEntry : PermissionUtil.getInstance().getTransientPermissions(this.subject).entrySet()) {
for (Map.Entry<Set<Context>, Map<String, Boolean>> mapEntry : PermissionUtil.getInstance().getTransientPermissions(GriefDefenderPlugin.GD_DEFAULT_HOLDER).entrySet()) {
final Set<Context> contextSet = mapEntry.getKey();
if (contextSet.contains(claim.getDefaultTypeContext())) {
this.addFilteredContexts(filteredContextMap, contextSet, MenuType.DEFAULT, mapEntry.getValue());
@ -436,7 +437,7 @@ protected void showFlagPermissions(GDPermissionUser src, GDClaim claim, MenuType
}
final List<Claim> inheritParents = claim.getInheritedParents();
for (Map.Entry<Set<Context>, Map<String, Boolean>> mapEntry : PermissionUtil.getInstance().getPermanentPermissions(this.subject).entrySet()) {
for (Map.Entry<Set<Context>, Map<String, Boolean>> mapEntry : PermissionUtil.getInstance().getAllPermanentPermissions().entrySet()) {
final Set<Context> contextSet = mapEntry.getKey();
if (contextSet.contains(claim.getDefaultTypeContext())) {
this.addFilteredContexts(filteredContextMap, contextSet, MenuType.DEFAULT, mapEntry.getValue());
@ -627,17 +628,21 @@ private Component getCustomClickableText(GDPermissionUser src, GDClaim claim, GD
boolean hasHover = false;
TextComponent.Builder hoverBuilder = TextComponent.builder();
final Player player = src.getOnlinePlayer();
final boolean canIgnoreClaim = src.getInternalPlayerData().canIgnoreClaim(claim);
boolean hasEditPermission = true;
Component denyReason = claim.allowEdit(player);
if (denyReason != null) {
hasEditPermission = false;
hasHover = true;
Component denyReason = null;
if (!canIgnoreClaim) {
denyReason = claim.allowEdit(player);
if (denyReason != null) {
hasEditPermission = false;
hasHover = true;
}
}
final boolean isAdminGroup = GriefDefenderPlugin.getFlagConfig().getConfig().customFlags.getGroups().get(flagGroup).isAdminGroup();
final String permission = isAdminGroup ? GDPermissions.FLAG_CUSTOM_ADMIN_BASE : GDPermissions.FLAG_CUSTOM_USER_BASE;
// check flag perm
if (!player.hasPermission(permission + "." + flagGroup + "." + customFlag.getName())) {
if (!canIgnoreClaim && !player.hasPermission(permission + "." + flagGroup + "." + customFlag.getName())) {
hoverBuilder.append(MessageCache.getInstance().PERMISSION_FLAG_USE).append("\n");
hasEditPermission = false;
hasHover = true;
@ -654,8 +659,7 @@ private Component getCustomClickableText(GDPermissionUser src, GDClaim claim, GD
hasOverride = true;
hasEditPermission = false;
} else if (activeData.getType() == GDActiveFlagData.Type.OWNER_OVERRIDE_PARENT_INHERIT || activeData.getType() == GDActiveFlagData.Type.CLAIM_PARENT_INHERIT) {
if (claim.allowEdit(src) != null) {
hasEditPermission = false;
if (!hasEditPermission) {
parentInheritUniqueId = activeData.getInheritParentUniqueId();
parentInheritFriendlyType = activeData.getInheritParentFriendlyType();
}
@ -913,14 +917,14 @@ public GDActiveFlagData getActiveDefinitionResult(GDClaim claim, GDFlagDefinitio
if (!claim.isWilderness()) {
permissionContexts.add(ClaimContexts.GLOBAL_DEFAULT_CONTEXT);
permissionContexts.add(ClaimContexts.USER_DEFAULT_CONTEXT);
result = PermissionUtil.getInstance().getPermissionValue(claim, (GDPermissionHolder) flagDefinition.getSubject(), flagData.getFlag().getPermission(), permissionContexts, PermissionDataType.ALL);
result = PermissionUtil.getInstance().getPermissionValue(claim, (GDPermissionHolder) flagDefinition.getSubject(), flagData.getFlag().getPermission(), permissionContexts, PermissionDataType.PERSISTENT);
if (result != Tristate.UNDEFINED) {
return new GDActiveFlagData(flagDefinition, flagData, result, permissionContexts, GDActiveFlagData.Type.DEFAULT);
}
permissionContexts.remove(ClaimContexts.USER_DEFAULT_CONTEXT);
} else {
permissionContexts.add(ClaimContexts.GLOBAL_DEFAULT_CONTEXT);
result = PermissionUtil.getInstance().getPermissionValue(claim, (GDPermissionHolder) flagDefinition.getSubject(), flagData.getFlag().getPermission(), permissionContexts, PermissionDataType.ALL);
result = PermissionUtil.getInstance().getPermissionValue(claim, (GDPermissionHolder) flagDefinition.getSubject(), flagData.getFlag().getPermission(), permissionContexts, PermissionDataType.PERSISTENT);
if (result != Tristate.UNDEFINED) {
return new GDActiveFlagData(flagDefinition, flagData, result, permissionContexts, GDActiveFlagData.Type.DEFAULT);
}
@ -928,6 +932,7 @@ public GDActiveFlagData getActiveDefinitionResult(GDClaim claim, GDFlagDefinitio
permissionContexts.remove(ClaimContexts.GLOBAL_DEFAULT_CONTEXT);
permissionContexts.add(claim.getDefaultTypeContext());
permissionContexts.add(ClaimContexts.USER_DEFAULT_CONTEXT);
result = PermissionUtil.getInstance().getPermissionValue(claim, (GDPermissionHolder) flagDefinition.getSubject(), flagData.getFlag().getPermission(), permissionContexts, PermissionDataType.TRANSIENT);
if (result != Tristate.UNDEFINED) {
return new GDActiveFlagData(flagDefinition, flagData, result, permissionContexts, GDActiveFlagData.Type.DEFAULT);
@ -1084,11 +1089,11 @@ public int compare(Context o1, Context o2) {
return textBuilder.build();
}
private Consumer<CommandSender> createCustomFlagConsumer(GDPermissionUser src, GDClaim claim, GDFlagDefinition customFlag, Tristate currentValue, String flagGroup) {
private Consumer<CommandSender> createCustomFlagConsumer(GDPermissionUser src, GDClaim claim, GDFlagDefinition flagDefinition, Tristate currentValue, String flagGroup) {
final Player player = src.getOnlinePlayer();
return consumer -> {
GDCauseStackManager.getInstance().pushCause(player);
Set<Context> definitionContexts = new HashSet<>(customFlag.getContexts());
Set<Context> definitionContexts = new HashSet<>(flagDefinition.getContexts());
boolean addClaimContext = false;
boolean addClaimOverrideContext = false;
final Iterator<Context> iterator = definitionContexts.iterator();
@ -1107,28 +1112,15 @@ private Consumer<CommandSender> createCustomFlagConsumer(GDPermissionUser src, G
} else if (addClaimContext) {
definitionContexts.add(claim.getContext());
}
CompletableFuture<PermissionResult> result = null;
for (FlagData flagData : customFlag.getFlagData()) {
final Set<Context> newContexts = new HashSet<>(definitionContexts);
newContexts.addAll(flagData.getContexts());
Tristate newValue = Tristate.UNDEFINED;
if (currentValue == Tristate.TRUE) {
newValue = Tristate.FALSE;
} else {
newValue = Tristate.TRUE;
}
final Flag flag = flagData.getFlag();
GDFlagPermissionEvent.Set event = new GDFlagPermissionEvent.Set(this.subject, flagData.getFlag(), newValue, newContexts);
GriefDefender.getEventManager().post(event);
if (event.cancelled()) {
return;
}
result = GriefDefenderPlugin.getInstance().getPermissionProvider().setPermissionValue(GriefDefenderPlugin.DEFAULT_HOLDER, flag, newValue, newContexts);
Tristate newValue = Tristate.UNDEFINED;
if (currentValue == Tristate.TRUE) {
newValue = Tristate.FALSE;
} else {
newValue = Tristate.TRUE;
}
result.thenAccept(r -> {
PermissionUtil.getInstance().setFlagDefinition(GriefDefenderPlugin.GD_DEFINITION_HOLDER, flagDefinition, newValue, definitionContexts, false).thenAccept(r -> {
Bukkit.getScheduler().runTask(GDBootstrap.getInstance(), () -> {
GDCauseStackManager.getInstance().popCause();
showCustomFlags(src, claim, flagGroup);

View File

@ -385,7 +385,7 @@ protected void showOptionPermissions(GDPermissionUser src, GDClaim claim, MenuTy
overrideContexts.add(claim.getOverrideClaimContext());
Map<String, OptionData> filteredContextMap = new HashMap<>();
for (Map.Entry<Set<Context>, Map<String, String>> mapEntry : PermissionUtil.getInstance().getTransientOptions(this.subject).entrySet()) {
for (Map.Entry<Set<Context>, Map<String, String>> mapEntry : PermissionUtil.getInstance().getTransientOptions(GriefDefenderPlugin.GD_OPTION_HOLDER).entrySet()) {
final Set<Context> contextSet = mapEntry.getKey();
if (contextSet.contains(claim.getDefaultTypeContext()) || (contextSet.contains(ClaimContexts.GLOBAL_DEFAULT_CONTEXT) || (!claim.isWilderness() && contextSet.contains(ClaimContexts.USER_DEFAULT_CONTEXT)))) {
this.addFilteredContexts(src, filteredContextMap, contextSet, MenuType.DEFAULT, mapEntry.getValue());

View File

@ -53,7 +53,7 @@ public class CommandAdjustBonusClaimBlocks extends BaseCommand {
@CommandCompletion("@gdplayers @gddummy")
@CommandAlias("acb|adjustclaimblocks")
@Description("Updates a player's accrued claim block total")
@Description("Adjusts a player's bonus claim block total by amount specified")
@Syntax("<player> <amount>")
@Subcommand("player adjustbonusblocks")
public void execute(CommandSender src, OfflinePlayer user, int amount, @Optional String worldName) {
@ -70,19 +70,14 @@ public void execute(CommandSender src, OfflinePlayer user, int amount, @Optional
return;
}
// parse the adjustment amount
int adjustment = amount;
//User user = args.<User>getOne("user").get();
// give blocks to player
GDPlayerData playerData = GriefDefenderPlugin.getInstance().dataStore.getOrCreatePlayerData(world.getUID(), user.getUniqueId());
playerData.setBonusClaimBlocks(playerData.getBonusClaimBlocks() + adjustment);
playerData.setBonusClaimBlocks(playerData.getBonusClaimBlocks() + amount);
final Component message = GriefDefenderPlugin.getInstance().messageData.getMessage(MessageStorage.ADJUST_BONUS_BLOCKS_SUCCESS, ImmutableMap.of(
"player", user.getName(),
"amount", adjustment,
"total", playerData.getBonusClaimBlocks()));
"amount", amount,
"total", playerData.getBonusClaimBlocks() + amount));
TextAdapter.sendComponent(src, message);
GriefDefenderPlugin.getInstance().getLogger().info(
src.getName() + " adjusted " + user.getName() + "'s bonus claim blocks by " + adjustment + ".");
src.getName() + " adjusted " + user.getName() + "'s bonus claim blocks by " + amount + ".");
}
}

View File

@ -0,0 +1,107 @@
/*
* 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;
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 co.aikar.commands.annotation.Syntax;
import com.google.common.collect.ImmutableMap;
import com.griefdefender.GDPlayerData;
import com.griefdefender.GriefDefenderPlugin;
import com.griefdefender.cache.MessageCache;
import com.griefdefender.configuration.MessageStorage;
import com.griefdefender.permission.GDPermissions;
import com.griefdefender.text.action.GDCallbackHolder;
import net.kyori.text.Component;
import net.kyori.text.TextComponent;
import net.kyori.text.adapter.bukkit.TextAdapter;
import net.kyori.text.event.ClickEvent;
import net.kyori.text.event.HoverEvent;
import net.kyori.text.format.TextColor;
import java.util.function.Consumer;
import org.bukkit.Bukkit;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
@CommandAlias("%griefdefender")
@CommandPermission(GDPermissions.COMMAND_SET_ACCRUED_CLAIM_BLOCKS_ALL)
public class CommandAdjustBonusClaimBlocksAll extends BaseCommand {
@CommandAlias("acball|adjustclaimblocksall")
@Description("Adjusts bonus claim block total for all online players by amount specified")
@Syntax("<amount>")
@Subcommand("player adjustbonusblocksall")
public void execute(CommandSender src, int amount) {
if (!(src instanceof Player)) {
updateOnlinePlayerBonusBlocks(src, amount);
return;
}
final Component message = GriefDefenderPlugin.getInstance().messageData.getMessage(MessageStorage.ADJUST_BONUS_BLOCKS_ALL_WARNING, ImmutableMap.of(
"amount", amount));
final Component confirmationText = TextComponent.builder()
.append(message)
.append(TextComponent.builder()
.append("\n[")
.append(MessageCache.getInstance().LABEL_CONFIRM.color(TextColor.GREEN))
.append("]\n")
.clickEvent(ClickEvent.runCommand(GDCallbackHolder.getInstance().createCallbackRunCommand(src, createConfirmationConsumer(src, amount), true)))
.hoverEvent(HoverEvent.showText(MessageCache.getInstance().UI_CLICK_CONFIRM)).build())
.build();
TextAdapter.sendComponent(src, confirmationText);
}
private static Consumer<CommandSender> createConfirmationConsumer(CommandSender src, int amount) {
return confirm -> {
updateOnlinePlayerBonusBlocks(src, amount);
};
}
private static void updateOnlinePlayerBonusBlocks(CommandSender src, int amount) {
int count = 0;
for (Player player : Bukkit.getOnlinePlayers()) {
// give blocks to player
GDPlayerData playerData = GriefDefenderPlugin.getInstance().dataStore.getOrCreateGlobalPlayerData(player.getUniqueId());
playerData.setBonusClaimBlocks(playerData.getBonusClaimBlocks() + amount);
count++;
}
final Component message = GriefDefenderPlugin.getInstance().messageData.getMessage(MessageStorage.ADJUST_BONUS_BLOCKS_ALL_SUCCESS, ImmutableMap.of(
"count", count,
"amount", amount));
TextAdapter.sendComponent(src, message);
GriefDefenderPlugin.getInstance().getLogger().info(
src.getName() + " adjusted " + count + " online player's bonus claim blocks by " + amount + ".");
}
}

View File

@ -188,7 +188,15 @@ private static Consumer<CommandSender> createConfirmationConsumer(Player source,
playerData.townChat = false;
}
if (!claim.isSubdivision() && !claim.isAdminClaim()) {
if (claim.isSubdivision()) {
int remainingBlocks = playerData.getRemainingClaimBlocks();
final Component message = GriefDefenderPlugin.getInstance().messageData.getMessage(MessageStorage.ABANDON_SUCCESS, ImmutableMap.of(
"amount", remainingBlocks));
GriefDefenderPlugin.sendMessage(source, message);
return;
}
if (!claim.isAdminClaim()) {
final double abandonReturnRatio = GDPermissionManager.getInstance().getInternalOptionValue(TypeToken.of(Double.class), user, Options.ABANDON_RETURN_RATIO, claim);
if (GriefDefenderPlugin.getInstance().isEconomyModeEnabled()) {
final Economy economy = GriefDefenderPlugin.getInstance().getVaultProvider().getApi();

View File

@ -185,7 +185,8 @@ private static Consumer<CommandSender> createConfirmationConsumer(GDPermissionUs
}
final double abandonReturnRatio = GDPermissionManager.getInstance().getInternalOptionValue(TypeToken.of(Double.class), user, Options.ABANDON_RETURN_RATIO, claim);
if (GriefDefenderPlugin.getInstance().isEconomyModeEnabled()) {
refund += claim.getClaimBlocks() * abandonReturnRatio;
final double requiredClaimBlocks = claim.getClaimBlocks() * abandonReturnRatio;
refund += requiredClaimBlocks * ((GDClaim) claim).getOwnerEconomyBlockCost();
} else {
playerData.setAccruedClaimBlocks(playerData.getAccruedClaimBlocks() - ((int) Math.ceil(claim.getClaimBlocks() * (1 - abandonReturnRatio))));
}

View File

@ -186,6 +186,7 @@ public void execute(CommandSender src, String[] args) {
final GDPermissionUser owner = PermissionHolderCache.getInstance().getOrCreateUser(claim.getOwnerUniqueId());
final UUID ownerUniqueId = claim.getOwnerUniqueId();
final boolean isAdmin = playerData.canManageAdminClaims;
final boolean canPlayerTeleport = (player != null && PermissionUtil.getInstance().canPlayerTeleport(player, gdClaim)) ? true : false;
// if not owner of claim, validate perms
if (!isAdmin && !player.getUniqueId().equals(claim.getOwnerUniqueId())) {
if (!gdClaim.getInternalClaimData().getContainers().contains(player.getUniqueId())
@ -521,66 +522,72 @@ public void execute(CommandSender src, String[] args) {
.append(" : ")
.append(getClickableInfoText(src, claim, RAID_OVERRIDE, GDPermissionManager.getInstance().getInternalOptionValue(TypeToken.of(Boolean.class), owner, Options.RAID, gdClaim) == true ? TextComponent.of("ON", TextColor.GREEN) : TextComponent.of("OFF", TextColor.RED))).build();
Component claimSpawn = null;
if (claim.getData().getSpawnPos().isPresent() && player != null && PermissionUtil.getInstance().canPlayerTeleport(player, gdClaim)) {
if (claim.getData().getSpawnPos().isPresent() && player != null) {
Vector3i spawnPos = claim.getData().getSpawnPos().get();
Location spawnLoc = new Location(gdClaim.getWorld(), spawnPos.getX(), spawnPos.getY(), spawnPos.getZ());
claimSpawn = TextComponent.builder()
TextComponent.Builder spawnBuilder = TextComponent.builder()
.append(MessageCache.getInstance().LABEL_SPAWN.color(TextColor.GREEN))
.append(" : ")
.append(spawnPos.toString(), TextColor.GRAY)
.clickEvent(ClickEvent.runCommand(GDCallbackHolder.getInstance().createCallbackRunCommand(CommandHelper.createTeleportConsumer(player, spawnLoc, claim, true))))
.hoverEvent(HoverEvent.showText(MessageCache.getInstance().CLAIMINFO_UI_TELEPORT_SPAWN))
.build();
.append(spawnPos.toString(), TextColor.GRAY);
if (canPlayerTeleport) {
spawnBuilder.clickEvent(ClickEvent.runCommand(GDCallbackHolder.getInstance().createCallbackRunCommand(CommandHelper.createTeleportConsumer(player, spawnLoc, claim, true))))
.hoverEvent(HoverEvent.showText(MessageCache.getInstance().CLAIMINFO_UI_TELEPORT_SPAWN));
}
claimSpawn = spawnBuilder.build();
}
Component southCorners = null;
Component northCorners = null;
if (!claim.isWilderness() && player != null && PermissionUtil.getInstance().canPlayerTeleport(player, gdClaim)) {
Component southWestCorner = TextComponent.builder()
if (!claim.isWilderness() && player != null) {
TextComponent.Builder southWestCorner = TextComponent.builder()
.append("SW", TextColor.LIGHT_PURPLE)
.append(" : ")
.append(VecHelper.toVector3i(southWest).toString(), TextColor.GRAY)
.append(" ")
.append(VecHelper.toVector3i(southWest).toString(), TextColor.GRAY);
if (canPlayerTeleport) {
southWestCorner.append(" ")
.clickEvent(ClickEvent.runCommand(GDCallbackHolder.getInstance().createCallbackRunCommand(CommandHelper.createTeleportConsumer(player, southWest, claim))))
.hoverEvent(HoverEvent.showText(MessageStorage.MESSAGE_DATA.getMessage(MessageStorage.CLAIMINFO_UI_TELEPORT_DIRECTION,
ImmutableMap.of("direction", TextComponent.of("SW").color(TextColor.AQUA)))))
.build();
Component southEastCorner = TextComponent.builder()
ImmutableMap.of("direction", TextComponent.of("SW").color(TextColor.AQUA)))));
}
TextComponent.Builder southEastCorner = TextComponent.builder()
.append("SE", TextColor.LIGHT_PURPLE)
.append(" : ")
.append(VecHelper.toVector3i(southEast).toString(), TextColor.GRAY)
.append(" ")
.append(VecHelper.toVector3i(southEast).toString(), TextColor.GRAY);
if (canPlayerTeleport) {
southEastCorner.append(" ")
.clickEvent(ClickEvent.runCommand(GDCallbackHolder.getInstance().createCallbackRunCommand(CommandHelper.createTeleportConsumer(player, southEast, claim))))
.hoverEvent(HoverEvent.showText(MessageStorage.MESSAGE_DATA.getMessage(MessageStorage.CLAIMINFO_UI_TELEPORT_DIRECTION,
ImmutableMap.of("direction", TextComponent.of("SE").color(TextColor.AQUA)))))
.build();
ImmutableMap.of("direction", TextComponent.of("SE").color(TextColor.AQUA)))));
}
southCorners = TextComponent.builder()
.append(MessageCache.getInstance().CLAIMINFO_UI_SOUTH_CORNERS.color(TextColor.YELLOW))
.append(" : ")
.append(southWestCorner)
.append(southEastCorner).build();
Component northWestCorner = TextComponent.builder()
.append(southWestCorner.build())
.append(southEastCorner.build()).build();
TextComponent.Builder northWestCorner = TextComponent.builder()
.append("NW", TextColor.LIGHT_PURPLE)
.append(" : ")
.append(VecHelper.toVector3i(northWest).toString(), TextColor.GRAY)
.append(" ")
.append(VecHelper.toVector3i(northWest).toString(), TextColor.GRAY);
if (canPlayerTeleport) {
northWestCorner.append(" ")
.clickEvent(ClickEvent.runCommand(GDCallbackHolder.getInstance().createCallbackRunCommand(CommandHelper.createTeleportConsumer(player, northWest, claim))))
.hoverEvent(HoverEvent.showText(MessageStorage.MESSAGE_DATA.getMessage(MessageStorage.CLAIMINFO_UI_TELEPORT_DIRECTION,
ImmutableMap.of("direction", TextComponent.of("NW").color(TextColor.AQUA)))))
.build();
Component northEastCorner = TextComponent.builder()
ImmutableMap.of("direction", TextComponent.of("NW").color(TextColor.AQUA)))));
}
TextComponent.Builder northEastCorner = TextComponent.builder()
.append("NE", TextColor.LIGHT_PURPLE)
.append(" : ")
.append(VecHelper.toVector3i(northEast).toString(), TextColor.GRAY)
.append(" ")
.append(VecHelper.toVector3i(northEast).toString(), TextColor.GRAY);
if (canPlayerTeleport) {
northEastCorner.append(" ")
.clickEvent(ClickEvent.runCommand(GDCallbackHolder.getInstance().createCallbackRunCommand(CommandHelper.createTeleportConsumer(player, northEast, claim))))
.hoverEvent(HoverEvent.showText(MessageStorage.MESSAGE_DATA.getMessage(MessageStorage.CLAIMINFO_UI_TELEPORT_DIRECTION,
ImmutableMap.of("direction", TextComponent.of("NE").color(TextColor.AQUA)))))
.build();
ImmutableMap.of("direction", TextComponent.of("NE").color(TextColor.AQUA)))));
}
northCorners = TextComponent.builder()
.append(MessageCache.getInstance().CLAIMINFO_UI_NORTH_CORNERS.color(TextColor.YELLOW))
.append(" : ")
.append(northWestCorner)
.append(northEastCorner).build();
.append(northWestCorner.build())
.append(northEastCorner.build()).build();
}
Component dateCreated = TextComponent.builder()
.append(MessageCache.getInstance().LABEL_CREATED.color(TextColor.YELLOW))
@ -654,9 +661,17 @@ public void execute(CommandSender src, String[] args) {
}
textList.add(claimGreeting);
textList.add(claimFarewell);
textList.add(dateCreated);
textList.add(dateLastActive);
textList.add(claimId);
if (allowEdit == null || isAdmin) {
if (src.hasPermission(GDPermissions.COMMAND_CLAIM_INFO_OTHERS_CREATION_DATE)) {
textList.add(dateCreated);
}
if (src.hasPermission(GDPermissions.COMMAND_CLAIM_INFO_OTHERS_LAST_ACTIVE)) {
textList.add(dateLastActive);
}
if (src.hasPermission(GDPermissions.COMMAND_CLAIM_INFO_OTHERS_CLAIM_UUID)) {
textList.add(claimId);
}
}
if (northCorners != null && southCorners != null) {
textList.add(northCorners);
textList.add(southCorners);
@ -879,7 +894,8 @@ private static Consumer<CommandSender> createClaimTypeConsumer(CommandSender src
TextAdapter.sendComponent(src, MessageCache.getInstance().CLAIM_NOT_YOURS);
return;
}
final ClaimResult result = claim.changeType(clicked, Optional.of(player.getUniqueId()), src);
// Use same claim owner when changing claim type
final ClaimResult result = claim.changeType(clicked, Optional.empty(), src);
if (result.successful()) {
CommandHelper.executeCommand(src, "claiminfo", gpClaim.getUniqueId().toString());
} else {

View File

@ -0,0 +1,210 @@
/*
* 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;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import org.bukkit.Location;
import org.bukkit.entity.Player;
import org.bukkit.event.block.Action;
import com.google.common.collect.ImmutableMap;
import com.google.common.reflect.TypeToken;
import com.griefdefender.GDPlayerData;
import com.griefdefender.GriefDefenderPlugin;
import com.griefdefender.api.claim.Claim;
import com.griefdefender.api.permission.option.Options;
import com.griefdefender.api.permission.option.type.CreateModeTypes;
import com.griefdefender.cache.MessageCache;
import com.griefdefender.claim.GDClaim;
import com.griefdefender.configuration.MessageStorage;
import com.griefdefender.internal.provider.GDWorldEditProvider;
import com.griefdefender.internal.visual.GDClaimVisual;
import com.griefdefender.permission.GDPermissionManager;
import com.griefdefender.permission.GDPermissions;
import com.griefdefender.util.BlockUtil;
import com.griefdefender.util.PlayerUtil;
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.Optional;
import co.aikar.commands.annotation.Subcommand;
import co.aikar.commands.annotation.Syntax;
import net.kyori.text.Component;
import net.kyori.text.TextComponent;
import net.kyori.text.format.TextColor;
@CommandAlias("%griefdefender")
@CommandPermission(GDPermissions.COMMAND_CLAIM_INVESTIGATE)
public class CommandClaimInvestigate extends BaseCommand {
@CommandAlias("claiminvestigate")
@Description("Investigates the target or nearby claims.")
@Syntax("[area|hide|hideall]")
@Subcommand("claim investigate")
public void execute(Player player, @Optional String cmd) {
final GDPlayerData playerData = GriefDefenderPlugin.getInstance().dataStore.getOrCreatePlayerData(player.getWorld(), player.getUniqueId());
if (!playerData.queuedVisuals.isEmpty()) {
final Component message = GriefDefenderPlugin.getInstance().messageData.getMessage(MessageStorage.VISUAL_UPDATE_IN_PROGRESS,
ImmutableMap.of(
"count", playerData.queuedVisuals.size()));
GriefDefenderPlugin.sendMessage(player, message);
return;
}
final GDWorldEditProvider worldEditProvider = GriefDefenderPlugin.getInstance().getWorldEditProvider();
if (cmd != null && cmd.equalsIgnoreCase("hideall")) {
if (worldEditProvider != null) {
worldEditProvider.revertVisuals(player, playerData, null);
}
playerData.revertAllVisuals();
return;
}
final boolean hideTargetClaimVisual = cmd != null && cmd.equalsIgnoreCase("hide");
final boolean checkArea = cmd != null && cmd.equalsIgnoreCase("area");
GDClaim claim = null;
Location location = null;
if (hideTargetClaimVisual || checkArea) {
final int maxDistance = GDPermissionManager.getInstance().getInternalOptionValue(TypeToken.of(Integer.class), player, Options.RADIUS_INSPECT);
claim = PlayerUtil.getInstance().findNearbyClaim(player, playerData, maxDistance, hideTargetClaimVisual);
if (checkArea) {
if (!playerData.canIgnoreClaim(claim) && !player.hasPermission(GDPermissions.VISUALIZE_CLAIMS_NEARBY)) {
GriefDefenderPlugin.sendMessage(player, MessageCache.getInstance().PERMISSION_VISUAL_CLAIMS_NEARBY);
return;
}
Location nearbyLocation = playerData.lastValidInspectLocation != null ? playerData.lastValidInspectLocation : player.getLocation();
Set<Claim> claims = BlockUtil.getInstance().getNearbyClaims(nearbyLocation, maxDistance, true);
List<Claim> visualClaims = new ArrayList<>();
for (Claim nearbyClaim : claims) {
if (!((GDClaim) nearbyClaim).hasActiveVisual(player)) {
visualClaims.add(nearbyClaim);
}
}
int height = (int) (playerData.lastValidInspectLocation != null ? playerData.lastValidInspectLocation.getBlockY() : PlayerUtil.getInstance().getEyeHeight(player));
boolean hideBorders = worldEditProvider != null &&
worldEditProvider.hasCUISupport(player) &&
GriefDefenderPlugin.getActiveConfig(player.getWorld().getUID()).getConfig().visual.hideBorders;
if (!hideBorders) {
for (Claim visualClaim : visualClaims) {
final GDClaimVisual visual = ((GDClaim) visualClaim).getVisualizer();
visual.createClaimBlockVisuals(playerData.getClaimCreateMode() == CreateModeTypes.VOLUME ? height : PlayerUtil.getInstance().getEyeHeight(player), player.getLocation(), playerData);
visual.apply(player);
}
}
final Component message = GriefDefenderPlugin.getInstance().messageData.getMessage(MessageStorage.CLAIM_SHOW_NEARBY,
ImmutableMap.of(
"amount", claims.size()));
GriefDefenderPlugin.sendMessage(player, message);
if (!claims.isEmpty()) {
if (worldEditProvider != null && !visualClaims.isEmpty()) {
worldEditProvider.visualizeClaims(visualClaims, player, playerData, true);
}
CommandHelper.showClaims(player, claims);
}
return;
}
if (claim != null && claim.isWilderness()) {
playerData.lastValidInspectLocation = null;
GriefDefenderPlugin.sendMessage(player, GriefDefenderPlugin.getInstance().messageData.getMessage(MessageStorage.BLOCK_NOT_CLAIMED));
return;
}
} else {
boolean ignoreAir = false;
if (worldEditProvider != null) {
// Ignore air so players can use client-side WECUI block target which uses max reach distance
if (worldEditProvider.hasCUISupport(player) && playerData.getClaimCreateMode() == CreateModeTypes.VOLUME && playerData.lastShovelLocation != null) {
ignoreAir = true;
}
}
final int distance = !ignoreAir ? 100 : 5;
location = BlockUtil.getInstance().getTargetBlock(player, playerData, distance, ignoreAir).orElse(null);
if (location == null) {
return;
}
claim = GriefDefenderPlugin.getInstance().dataStore.getClaimAtPlayer(location, playerData, true);
if (claim.isWilderness()) {
GriefDefenderPlugin.sendMessage(player, GriefDefenderPlugin.getInstance().messageData.getMessage(MessageStorage.BLOCK_NOT_CLAIMED));
return;
}
}
// Handle left-click visual revert
if (claim != null && !claim.isWilderness() && hideTargetClaimVisual) {
if (claim.hasActiveVisual(player)) {
final int maxDistance = GDPermissionManager.getInstance().getInternalOptionValue(TypeToken.of(Integer.class), player, Options.RADIUS_INSPECT);
if (!((GDClaim) claim).children.isEmpty()) {
claim = PlayerUtil.getInstance().findNearbyClaim(player, playerData, maxDistance, true);
}
if (!claim.hasActiveVisual(player) && claim.parent != null) {
GDClaim parent = claim.parent;
while (parent != null) {
if (parent.hasActiveVisual(player)) {
claim = parent;
parent = null;
} else {
parent = parent.parent;
}
}
}
if (claim != null && claim.hasActiveVisual(player)) {
playerData.revertClaimVisual(claim);
}
return;
}
}
int height = PlayerUtil.getInstance().getEyeHeight(player);
if (playerData.lastValidInspectLocation != null || location != null) {
height = playerData.lastValidInspectLocation != null ? playerData.lastValidInspectLocation.getBlockY() : location.getBlockY();
}
if (claim != null) {
// always show visual borders for resize purposes
final GDClaimVisual visual = claim.getVisualizer();
visual.createClaimBlockVisuals(playerData.getClaimCreateMode() == CreateModeTypes.VOLUME ? height : PlayerUtil.getInstance().getEyeHeight(player), player.getLocation(), playerData);
visual.apply(player);
if (worldEditProvider != null) {
worldEditProvider.displayClaimCUIVisual(claim, player, playerData, true);
}
Set<Claim> claims = new HashSet<>();
claims.add(claim);
playerData.showNoClaimsFoundMessage = false;
CommandHelper.showClaims(player, claims);
Component message = GriefDefenderPlugin.getInstance().messageData.getMessage(MessageStorage.BLOCK_CLAIMED,
ImmutableMap.of(
"player", claim.getOwnerDisplayName()));
GriefDefenderPlugin.sendMessage(player, message);
}
}
}

View File

@ -51,7 +51,7 @@ public CommandClaimOption() {
@Syntax("[<option> <value> [context[key=value]]")
@Subcommand("option claim")
public void execute(Player player, @Optional String[] args) throws InvalidCommandArgument {
this.subject = GriefDefenderPlugin.DEFAULT_HOLDER;
this.subject = GriefDefenderPlugin.GD_OPTION_HOLDER;
this.friendlySubjectName = "ALL";
super.execute(player, args);
}

View File

@ -79,10 +79,6 @@ public void execute(Player player, String arg) throws InvalidCommandArgument {
}
Double salePrice = null;
if (!claim.getEconomyData().isForSale()) {
GriefDefenderPlugin.sendMessage(player, MessageCache.getInstance().ECONOMY_CLAIM_NOT_FOR_SALE);
return;
}
if (arg.equalsIgnoreCase("cancel")) {
claim.getEconomyData().setForSale(false);
claim.getEconomyData().setSalePrice(-1);

View File

@ -0,0 +1,56 @@
/*
* This file is part of GriefDefender, licensed under the MIT License (MIT).
*
* Copyright (c) bloodmc
* Copyright (c) contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package com.griefdefender.command;
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.adapter.bukkit.TextAdapter;
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_CLAIM_TOOL)
public class CommandClaimTool extends BaseCommand {
@CommandAlias("claimtool")
@Description("Toggles claim tool on/off.")
@Subcommand("mode tool")
public void execute(Player player) {
final GDPlayerData playerData = GriefDefenderPlugin.getInstance().dataStore.getOrCreatePlayerData(player.getWorld(), player.getUniqueId());
playerData.claimTool = !playerData.claimTool;
if (!playerData.claimTool) {
TextAdapter.sendComponent(player, MessageCache.getInstance().COMMAND_CLAIMTOOL_DISABLED);
} else {
TextAdapter.sendComponent(player, MessageCache.getInstance().COMMAND_CLAIMTOOL_ENABLED);
}
}
}

View File

@ -328,7 +328,13 @@ public static PermissionResult applyFlagPermission(CommandSender src, GDPermissi
}
if (subject == GriefDefenderPlugin.DEFAULT_HOLDER) {
PermissionUtil.getInstance().setPermissionValue(GriefDefenderPlugin.DEFAULT_HOLDER, flag, value, contexts);
if (flagType == MenuType.OVERRIDE) {
PermissionUtil.getInstance().setPermissionValue(GriefDefenderPlugin.GD_OVERRIDE_HOLDER, flag, value, contexts);
} else if (flagType == MenuType.CLAIM) {
PermissionUtil.getInstance().setPermissionValue(GriefDefenderPlugin.GD_CLAIM_HOLDER, flag, value, contexts);
} else {
PermissionUtil.getInstance().setPermissionValue(GriefDefenderPlugin.GD_DEFAULT_HOLDER, flag, value, contexts);
}
if (!clicked && src instanceof Player) {
TextAdapter.sendComponent(src, TextComponent.builder("")
.append(TextComponent.builder("\n[").append(MessageCache.getInstance().FLAG_UI_RETURN_FLAGS.color(TextColor.AQUA)).append("]\n")

View File

@ -58,7 +58,7 @@ public void execute(Player player) {
if (!NMSUtil.getInstance().hasItemInOneHand(player, GriefDefenderPlugin.getInstance().modificationTool)) {
TextAdapter.sendComponent(player, GriefDefenderPlugin.getInstance().messageData.getMessage(MessageStorage.TOOL_NOT_EQUIPPED,
ImmutableMap.of("tool", TextComponent.of(GriefDefenderPlugin.getInstance().modificationTool.getName().toLowerCase(), TextColor.GREEN))));
ImmutableMap.of("tool", TextComponent.of(GriefDefenderPlugin.getInstance().modificationTool.toLowerCase(), TextColor.GREEN))));
return;
}

View File

@ -437,10 +437,6 @@ public double getRentBalance(UUID uuid) {
@Override
public void setRentBalance(UUID uuid, double balance) {
if (balance <= 0) {
this.rentBalances.remove(uuid);
return;
}
this.rentBalances.put(uuid, balance);
}
}

View File

@ -100,6 +100,8 @@ public class MessageStorage {
public static final String ABANDON_WORLD_WARNING = "abandon-world-warning";
public static final String ADJUST_ACCRUED_BLOCKS_SUCCESS = "adjust-accrued-blocks-success";
public static final String ADJUST_BONUS_BLOCKS_SUCCESS = "adjust-bonus-blocks-success";
public static final String ADJUST_BONUS_BLOCKS_ALL_SUCCESS = "adjust-bonus-blocks-all-success";
public static final String ADJUST_BONUS_BLOCKS_ALL_WARNING = "adjust-bonus-blocks-all-warning";
public static final String BANK_DEPOSIT = "bank-deposit";
public static final String BANK_INFO = "bank-info";
public static final String BANK_NO_PERMISSION = "bank-no-permission";
@ -201,6 +203,8 @@ public class MessageStorage {
public static final String ECONOMY_CLAIM_RENT_CONFIRMATION_MIN = "economy-claim-rent-confirmation-min";
public static final String ECONOMY_CLAIM_RENT_CONFIRMATION_MIN_MAX = "economy-claim-rent-confirmation-min-max";
public static final String ECONOMY_CLAIM_RENT_CONFIRMED = "economy-claim-rent-confirmed";
public static final String ECONOMY_CLAIM_RENT_END = "economy-claim-rent-end";
public static final String ECONOMY_CLAIM_RENT_END_RESTORE = "economy-claim-rent-end-restore";
public static final String ECONOMY_CLAIM_RENT_INVALID_PRICE = "economy-claim-rent-invalid-price";
public static final String ECONOMY_CLAIM_RENT_NOT_ENOUGH_FUNDS = "economy-claim-rent-not-enough-funds";
public static final String ECONOMY_CLAIM_RENT_PAYMENT_FAILURE = "economy-claim-rent-payment-failure";
@ -214,6 +218,7 @@ public class MessageStorage {
public static final String ECONOMY_CLAIM_RENTER_CONFIRMATION_MIN = "economy-claim-renter-confirmation-min";
public static final String ECONOMY_CLAIM_RENTER_CONFIRMATION_MIN_MAX = "economy-claim-renter-confirmation-min-max";
public static final String ECONOMY_CLAIM_RENTER_CONFIRMED = "economy-claim-renter-confirmed";
public static final String ECONOMY_CLAIM_RENTER_END = "economy-claim-renter-end";
public static final String ECONOMY_CLAIM_RENTED_TIME_WARNING = "economy-claim-rented-time-warning";
public static final String ECONOMY_CLAIM_RENTED_TIME_WARNING_RESTORE_ = "economy-claim-rented-time-warning-restore";
public static final String ECONOMY_CLAIM_RENTED_NO_CANCEL = "economy-claim-rented-no-cancel";

View File

@ -41,7 +41,7 @@
public class OptionStorage extends ConfigCategory {
@Setting(value = "option-control", comment = "Controls which options are enabled.\nNote: To enable an option, set the value to 'true'."
+ "\nSee https://github.com/bloodmc/GriefDefender/wiki/Advanced-Options for info on how each option works.")
+ "\nSee https://github.com/bloodmc/GriefDefender/wiki/Options for info on how each option works.")
private Map<String, Boolean> control = Maps.newHashMap();
@Setting(value = "default-options")

View File

@ -45,11 +45,15 @@ public class ClaimCategory extends ConfigCategory {
+ "\nEx. If set to '50' and an explosion affects 51+ blocks, the event will cancel when the first protected block is found."
+ "\nNote: To disable, set value to '0'.")
public int explosionCancelBlockLimit = 50;
@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.")
public int autoChestClaimBlockRadius = 4;
@Setting(value = "border-block-radius", comment = "Set claim border of specified radius (in blocks), centered on claim. If set to 1, adds an additional 1 block protected radius around claim.\n" +
"Note: It is not recommended to set this value too high as performance can degrade due to deeper claim searches.")
public int borderBlockRadius = 0;
@Setting(value = "restrict-world-max-height", comment = "Whether to restrict claiming to world max height. (Default: True")
public boolean restrictWorldMaxHeight = true;
@Setting(value = "expiration-cleanup-interval", comment = "The interval in minutes for cleaning up expired claims. Default: 0. Set to 0 to disable.")
public int expirationCleanupInterval = 0;
@Setting(value = "auto-nature-restore", comment = "Whether survival claims will be automatically restored to world generated state when expired. \nNote: This only supports world generated blocks. Consider using 'auto-schematic-restore' if using a custom world.")

View File

@ -32,7 +32,6 @@
import com.griefdefender.GriefDefenderPlugin;
import com.griefdefender.api.permission.Context;
import com.griefdefender.api.permission.flag.FlagData;
import com.griefdefender.api.permission.flag.FlagDefinition;
import com.griefdefender.cache.PermissionHolderCache;
import com.griefdefender.permission.GDPermissionHolder;
@ -106,30 +105,21 @@ public void initDefaults() {
groupStr = context.getValue();
}
}
GDPermissionHolder holder = GriefDefenderPlugin.DEFAULT_HOLDER;
GDPermissionHolder holder = GriefDefenderPlugin.GD_DEFINITION_HOLDER;
if (groupStr != null) {
if (PermissionUtil.getInstance().hasGroupSubject(groupStr)) {
holder = PermissionHolderCache.getInstance().getOrCreateGroup(groupStr);
if (holder == null) {
holder = GriefDefenderPlugin.DEFAULT_HOLDER;
holder = GriefDefenderPlugin.GD_DEFINITION_HOLDER;
}
}
}
for (FlagData flagData : flagDefinition.getFlagData()) {
Set<Context> permissionContexts = new HashSet<>();
permissionContexts.addAll(flagData.getContexts());
// apply defaults
for (Context context : defaultContexts) {
permissionContexts.add(context);
PermissionUtil.getInstance().setTransientPermission(holder, flagData.getFlag().getPermission(), flagDefinition.getDefaultValue(), permissionContexts);
permissionContexts.remove(context);
}
// apply overrides
for (Context context : overrideContexts) {
permissionContexts.add(context);
PermissionUtil.getInstance().setPermissionValue(holder, flagData.getFlag().getPermission(), flagDefinition.getDefaultValue(), permissionContexts);
permissionContexts.remove(context);
}
if (!defaultContexts.isEmpty()) {
PermissionUtil.getInstance().setFlagDefinition(holder, flagDefinition, flagDefinition.getDefaultValue(), defaultContexts, false);
}
if (!overrideContexts.isEmpty()) {
PermissionUtil.getInstance().setFlagDefinition(holder, flagDefinition, flagDefinition.getDefaultValue(), overrideContexts, false);
}
}
}

View File

@ -29,6 +29,10 @@
import java.util.List;
import java.util.Map;
import com.griefdefender.api.claim.ClaimType;
import com.griefdefender.api.claim.ClaimTypes;
import com.griefdefender.registry.ClaimTypeRegistryModule;
import ninja.leaping.configurate.objectmapping.Setting;
import ninja.leaping.configurate.objectmapping.serialize.ConfigSerializable;
@ -38,6 +42,9 @@ public class DynmapCategory {
@Setting("enabled")
public boolean enabled = true;
@Setting("claimtype-styles")
public Map<String, DynmapOwnerStyleCategory> claimTypeStyles = new HashMap<>();
@Setting("owner-styles")
public Map<String, DynmapOwnerStyleCategory> ownerStyles = new HashMap<>();
@ -74,4 +81,15 @@ public class DynmapCategory {
+ "Trust: <span style=\"font-weight:bold;\">%builders%</span><br/>"
+ "Container Trust: <span style=\"font-weight:bold;\">%containers%</span><br/>"
+ "Access Trust: <span style=\"font-weight:bold;\">%accessors%</span></div>";
public DynmapCategory() {
for (ClaimType type : ClaimTypeRegistryModule.getInstance().getAll()) {
if (type == ClaimTypes.WILDERNESS) {
continue;
}
if (this.claimTypeStyles.get(type.getName().toLowerCase()) == null) {
this.claimTypeStyles.put(type.getName().toLowerCase(), new DynmapOwnerStyleCategory(type));
}
}
}
}

View File

@ -24,6 +24,9 @@
*/
package com.griefdefender.configuration.category;
import com.griefdefender.api.claim.ClaimType;
import com.griefdefender.api.claim.ClaimTypes;
import ninja.leaping.configurate.objectmapping.Setting;
import ninja.leaping.configurate.objectmapping.serialize.ConfigSerializable;
@ -47,4 +50,26 @@ public class DynmapOwnerStyleCategory {
@Setting("label")
public String label = "none";
public DynmapOwnerStyleCategory() {
}
public DynmapOwnerStyleCategory(ClaimType type) {
if (type.equals(ClaimTypes.ADMIN)) {
this.strokeColor = "#FF0000";
this.fillColor = "#FF0000";
} else if (type.equals(ClaimTypes.BASIC)) {
this.strokeColor = "#FFFF00";
this.fillColor = "#FFFF00";
} else if (type.equals(ClaimTypes.TOWN)) {
this.strokeColor = "#00FF00";
this.fillColor = "#00FF00";
} else if (type.equals(ClaimTypes.SUBDIVISION)) {
this.strokeColor = "#FF9C00";
this.fillColor = "#FF9C00";
} else {
this.strokeColor = "#FF0000";
this.fillColor = "#FF0000";
}
}
}

View File

@ -35,4 +35,7 @@ public class PvpCategory extends ConfigCategory {
@Setting(value = "allow-fly", comment = "Whether flying is allowed during PvP.")
public boolean allowFly = false;
@Setting(value = "combat-logout", comment = "Whether players should be killed if they logout while in pvp combat.")
public boolean combatLogout = false;
}

View File

@ -80,6 +80,9 @@ public GDCauseStackManager pushCause(Object obj) {
public Object popCause() {
this.cached_cause = null;
if (this.cause.isEmpty()) {
return null;
}
return this.cause.pop();
}

View File

@ -113,7 +113,12 @@ public void onInventoryMoveItemEvent(InventoryMoveItemEvent event) {
if (!GDFlags.INVENTORY_ITEM_MOVE || !GriefDefenderPlugin.getGlobalConfig().getConfig().economy.rentSystem) {
return;
}
final World world = event.getSource().getLocation().getWorld();
final Location location = event.getSource().getLocation();
if (location == null) {
return;
}
final World world = location.getWorld();
if (!GriefDefenderPlugin.getInstance().claimsEnabledForWorld(world.getUID()) || GriefDefenderPlugin.getInstance().getVaultProvider() == null) {
return;
}
@ -169,12 +174,16 @@ public void onBlockPistonExtend(BlockPistonExtendEvent event) {
return;
}
final boolean pistonProtectionInClaims = GriefDefenderPlugin.getActiveConfig(sourceBlock.getWorld().getUID()).getConfig().claim.pistonProtectionInClaims;
final GDClaim sourceClaim = this.storage.getClaimAt(sourceBlock.getLocation());
for (Block block : event.getBlocks()) {
// always check next block in direction
final Location location = BlockUtil.getInstance().getBlockRelative(block.getLocation(), event.getDirection());
final GDClaim targetClaim = this.storage.getClaimAt(location);
if (targetClaim.isWilderness() || sourceClaim.getUniqueId().equals(targetClaim.getUniqueId())) {
if (targetClaim.isWilderness()) {
continue;
}
if (!pistonProtectionInClaims && sourceClaim.getUniqueId().equals(targetClaim.getUniqueId())) {
continue;
}
@ -612,7 +621,14 @@ public void onBlockPlace(BlockPlaceEvent event) {
if (GDFlags.BLOCK_PLACE) {
// check overrides
final Tristate result = GDPermissionManager.getInstance().getFinalPermission(event, location, targetClaim, Flags.BLOCK_PLACE, player, block, player, TrustTypes.BUILDER, true);
Object placedBlock = block;
if (GriefDefenderPlugin.getInstance().getSlimefunProvider() != null && event.getItemInHand() != null) {
final String customItemId = GriefDefenderPlugin.getInstance().getSlimefunProvider().getSlimeItemId(event.getItemInHand());
if (customItemId != null && !customItemId.isEmpty()) {
placedBlock = event.getItemInHand();
}
}
final Tristate result = GDPermissionManager.getInstance().getFinalPermission(event, location, targetClaim, Flags.BLOCK_PLACE, player, placedBlock, player, TrustTypes.BUILDER, true);
if (result == Tristate.FALSE) {
if (!PlayerUtil.getInstance().isFakePlayer(player)) {
Component message = GDPermissionManager.getInstance().getEventMessage();
@ -722,7 +738,7 @@ public void onSignChangeEvent(SignChangeEvent event) {
}
final GriefDefenderConfig<?> activeConfig = GriefDefenderPlugin.getActiveConfig(event.getBlock().getWorld().getUID());
if (!activeConfig.getConfig().economy.rentSystem || (!activeConfig.getConfig().economy.isRentSignEnabled() && !activeConfig.getConfig().economy.isSellSignEnabled())) {
if (!activeConfig.getConfig().economy.isRentSignEnabled() && !activeConfig.getConfig().economy.isSellSignEnabled()) {
return;
}
@ -758,7 +774,7 @@ public void onSignChangeEvent(SignChangeEvent event) {
SignUtil.setClaimForSale(claim, player, sign, price);
} else if (line1.equalsIgnoreCase("rent") && activeConfig.getConfig().economy.isRentSignEnabled()) {
} else if (line1.equalsIgnoreCase("rent") && activeConfig.getConfig().economy.isRentSignEnabled() && activeConfig.getConfig().economy.rentSystem) {
if (!player.hasPermission(GDPermissions.USER_RENT_SIGN)) {
return;
}

View File

@ -98,7 +98,7 @@ public void handleBlockModify(Event event, Object source, BlockState newState) {
if (source instanceof Block) {
fromBlock = (Block) source;
// Air -> block should always be recorded as place
if (fromBlock.isEmpty()) {
if (fromBlock.isEmpty() && !NMSUtil.getInstance().isMaterialAir(newState.getType())) {
handleBlockPlace(event, source, newState);
return;
}
@ -156,7 +156,7 @@ public void handleBlockModify(Event event, Object source, BlockState newState) {
}
}
final Tristate result = GDPermissionManager.getInstance().getFinalPermission(event, location, targetClaim, Flags.BLOCK_MODIFY, source, newState.getBlock().isEmpty() ? newState.getType() : newState, user, TrustTypes.BUILDER, true);
final Tristate result = GDPermissionManager.getInstance().getFinalPermission(event, location, targetClaim, Flags.BLOCK_MODIFY, source, newState, user, TrustTypes.BUILDER, true);
if (result == Tristate.FALSE) {
((Cancellable) event).setCancelled(true);
}
@ -193,7 +193,7 @@ public void handleBlockPlace(Event event, Object source, BlockState newState) {
}
GDClaim targetClaim = this.storage.getClaimAt(location);
final Tristate result = GDPermissionManager.getInstance().getFinalPermission(event, location, targetClaim, Flags.BLOCK_PLACE, source, newState.getBlock().isEmpty() ? newState.getType() : newState, user, TrustTypes.BUILDER, true);
final Tristate result = GDPermissionManager.getInstance().getFinalPermission(event, location, targetClaim, Flags.BLOCK_PLACE, source, newState, user, TrustTypes.BUILDER, true);
if (result == Tristate.FALSE) {
((Cancellable) event).setCancelled(true);
}
@ -203,10 +203,6 @@ public void handleBlockBreak(Event event, Object source, BlockState blockState)
if (!GDFlags.BLOCK_BREAK) {
return;
}
// Ignore air blocks
if (blockState.getBlock().isEmpty()) {
return;
}
// Special case
if (source instanceof Block) {
@ -227,8 +223,8 @@ public void handleBlockBreak(Event event, Object source, BlockState blockState)
}
GDClaim targetClaim = this.storage.getClaimAt(location);
final Tristate result = GDPermissionManager.getInstance().getFinalPermission(event, location, targetClaim, Flags.BLOCK_BREAK, source, blockState, player, TrustTypes.BUILDER, true);
// Always pass the actual block being broken
final Tristate result = GDPermissionManager.getInstance().getFinalPermission(event, location, targetClaim, Flags.BLOCK_BREAK, source, blockState.getBlock(), player, TrustTypes.BUILDER, true);
if (result == Tristate.FALSE) {
((Cancellable) event).setCancelled(true);
}

View File

@ -438,14 +438,11 @@ private void checkPlayerFlight(GDPermissionUser user, GDClaim fromClaim, GDClaim
if (gameMode == GameMode.SPECTATOR) {
return;
}
if (gameMode == GameMode.CREATIVE) {
if (playerData.inPvpCombat() && !GriefDefenderPlugin.getActiveConfig(player.getWorld().getUID()).getConfig().pvp.allowFly) {
player.setAllowFlight(false);
player.setFlying(false);
playerData.ignoreFallDamage = true;
GriefDefenderPlugin.sendMessage(player, MessageCache.getInstance().OPTION_APPLY_PLAYER_DENY_FLIGHT);
return;
}
if (playerData.inPvpCombat() && !GriefDefenderPlugin.getActiveConfig(player.getWorld().getUID()).getConfig().pvp.allowFly) {
player.setAllowFlight(false);
player.setFlying(false);
playerData.ignoreFallDamage = true;
GriefDefenderPlugin.sendMessage(player, MessageCache.getInstance().OPTION_APPLY_PLAYER_DENY_FLIGHT);
return;
}

View File

@ -98,6 +98,7 @@
import org.bukkit.event.entity.ProjectileLaunchEvent;
import org.bukkit.event.entity.SlimeSplitEvent;
import org.bukkit.event.entity.SpawnerSpawnEvent;
import org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason;
import org.bukkit.event.hanging.HangingBreakByEntityEvent;
import org.bukkit.event.vehicle.VehicleDamageEvent;
import org.bukkit.event.vehicle.VehicleDestroyEvent;
@ -249,6 +250,7 @@ public void onEntityExplodeEvent(EntityExplodeEvent event) {
GDClaim targetClaim = null;
final int cancelBlockLimit = GriefDefenderPlugin.getGlobalConfig().getConfig().claim.explosionCancelBlockLimit;
final List<Block> filteredLocations = new ArrayList<>();
boolean clearAll = false;
for (Block block : event.blockList()) {
final Location location = block.getLocation();
targetClaim = GriefDefenderPlugin.getInstance().dataStore.getClaimAt(location);
@ -261,14 +263,16 @@ public void onEntityExplodeEvent(EntityExplodeEvent event) {
if (result == Tristate.FALSE) {
// Avoid lagging server from large explosions.
if (event.blockList().size() > cancelBlockLimit) {
event.setCancelled(true);
// Avoid cancelling as it causing clients not to receive explosion sound
//event.setCancelled(true);
clearAll = true;
break;
}
filteredLocations.add(block);
}
}
if (event.isCancelled()) {
if (clearAll) {
event.blockList().clear();
} else if (!filteredLocations.isEmpty()) {
event.blockList().removeAll(filteredLocations);
@ -683,7 +687,7 @@ public void handleEntitySpawn(Event event, Object source, Entity entity) {
}
final Object root = GDCauseStackManager.getInstance().getCurrentCause().root();
if (root != null && root instanceof GDPermissionUser) {
if (root != null && root instanceof GDPermissionUser && source != SpawnReason.DEFAULT) {
final GDPermissionUser user = (GDPermissionUser) root;
final GDEntity gdEntity = new GDEntity(entity.getEntityId());
gdEntity.setOwnerUUID(user.getUniqueId());

View File

@ -24,6 +24,8 @@
*/
package com.griefdefender.listener;
import java.util.Collection;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
@ -33,6 +35,9 @@
import net.luckperms.api.LuckPerms;
import net.luckperms.api.event.group.GroupDataRecalculateEvent;
import net.luckperms.api.event.user.UserDataRecalculateEvent;
import net.luckperms.api.model.group.Group;
import net.luckperms.api.model.user.User;
import net.luckperms.api.query.QueryOptions;
public class LuckPermsEventHandler {
@ -48,6 +53,15 @@ public void onGroupDataRecalculate(GroupDataRecalculateEvent event) {
for (Player player : Bukkit.getOnlinePlayers()) {
final GDPermissionUser user = PermissionHolderCache.getInstance().getOrCreateUser(player);
user.getInternalPlayerData().resetOptionCache();
final User lpUser = this.luckPermsApi.getUserManager().getUser(player.getUniqueId());
if (lpUser != null) {
final Collection<Group> groups = lpUser.getInheritedGroups(QueryOptions.defaultContextualOptions());
for (Group group : groups) {
if (group.equals(event.getGroup())) {
user.getInternalPlayerData().refreshPlayerOptions();
}
}
}
}
}
@ -55,6 +69,7 @@ public void onUserDataRecalculate(UserDataRecalculateEvent event) {
final GDPermissionUser user = PermissionHolderCache.getInstance().getOrCreateUser(event.getUser().getUniqueId());
if (user.getOnlinePlayer() != null) {
user.getInternalPlayerData().resetOptionCache();
user.getInternalPlayerData().refreshPlayerOptions();
}
}
}

View File

@ -237,6 +237,9 @@ public void onPlayerQuit(PlayerQuitEvent event) {
//this.worldEditProvider.removePlayer(player);
}
if (GriefDefenderPlugin.getActiveConfig(player.getWorld()).getConfig().pvp.combatLogout && playerData.inPvpCombat() && !player.hasPermission(GDPermissions.BYPASS_PVP_LOGOUT)) {
player.setHealth(0);
}
playerData.onDisconnect();
PaginationUtil.getInstance().removeActivePageData(player.getUniqueId());
if (playerData.getClaims().isEmpty()) {
@ -314,7 +317,13 @@ public void onPlayerChangeHeldItem(PlayerItemHeldEvent event) {
int newSlot = event.getNewSlot();
ItemStack newItemStack = player.getInventory().getItem(newSlot);
if(newItemStack != null && GriefDefenderPlugin.getInstance().modificationTool != null && NMSUtil.getInstance().itemsEqual(newItemStack, GriefDefenderPlugin.getInstance().modificationTool)) {
final String itemId = GDPermissionManager.getInstance().getPermissionIdentifier(newItemStack);
if(newItemStack != null && itemId.equalsIgnoreCase(GriefDefenderPlugin.getInstance().modificationTool)) {
if (!playerData.claimTool) {
GriefDefenderPlugin.sendMessage(player, MessageCache.getInstance().CLAIMTOOL_NOT_ENABLED);
GDTimings.PLAYER_CHANGE_HELD_ITEM_EVENT.stopTiming();
return;
}
playerData.lastShovelLocation = null;
playerData.endShovelLocation = null;
playerData.claimResizing = null;
@ -528,14 +537,14 @@ public void onPlayerInteractItem(PlayerInteractEvent event) {
final boolean primaryEvent = event.getAction() == Action.LEFT_CLICK_AIR || event.getAction() == Action.LEFT_CLICK_BLOCK ? true : false;
final Flag flag = primaryEvent ? Flags.INTERACT_ITEM_PRIMARY : Flags.INTERACT_ITEM_SECONDARY;
if ((playerData.claimMode && (NMSUtil.getInstance().isMainHand(event) && event.getAction() == Action.LEFT_CLICK_AIR|| event.getAction() == Action.LEFT_CLICK_BLOCK)) || (!playerData.claimMode && GriefDefenderPlugin.getInstance().investigationTool != null && NMSUtil.getInstance().itemsEqual(itemInHand, GriefDefenderPlugin.getInstance().investigationTool))) {
final String itemId = GDPermissionManager.getInstance().getPermissionIdentifier(itemInHand);
if ((playerData.claimMode && (NMSUtil.getInstance().isMainHand(event) && event.getAction() == Action.LEFT_CLICK_AIR|| event.getAction() == Action.LEFT_CLICK_BLOCK)) || (!playerData.claimMode && playerData.claimTool && GriefDefenderPlugin.getInstance().investigationTool != null && itemId.equalsIgnoreCase(GriefDefenderPlugin.getInstance().investigationTool))) {
investigateClaim(event, player, clickedBlock, itemInHand);
event.setCancelled(true);
return;
}
if ((playerData.claimMode && (NMSUtil.getInstance().isMainHand(event) && (event.getAction() == Action.RIGHT_CLICK_AIR|| event.getAction() == Action.RIGHT_CLICK_BLOCK))) || (!playerData.claimMode && itemInHand != null && GriefDefenderPlugin.getInstance().modificationTool != null && NMSUtil.getInstance().itemsEqual(itemInHand, GriefDefenderPlugin.getInstance().modificationTool))) {
if ((playerData.claimMode && (NMSUtil.getInstance().isMainHand(event) && (event.getAction() == Action.RIGHT_CLICK_AIR|| event.getAction() == Action.RIGHT_CLICK_BLOCK))) || (!playerData.claimMode && playerData.claimTool && itemInHand != null && GriefDefenderPlugin.getInstance().modificationTool != null && itemId.equalsIgnoreCase(GriefDefenderPlugin.getInstance().modificationTool))) {
onPlayerHandleClaimCreateAction(event, clickedBlock, player, itemInHand, playerData);
// avoid changing blocks after using a shovel
event.setUseInteractedBlock(Result.DENY);
@ -599,18 +608,17 @@ public void onPlayerInteractEntity(PlayerInteractEntityEvent event) {
final GDPlayerData playerData = this.dataStore.getOrCreatePlayerData(player.getWorld(), player.getUniqueId());
if (targetEntity instanceof Tameable) {
if (playerData.petRecipientUniqueId != null) {
final Tameable tameableEntity = (Tameable) targetEntity;
final GDPermissionUser recipientUser = PermissionHolderCache.getInstance().getOrCreateUser(playerData.petRecipientUniqueId);
tameableEntity.setOwner(recipientUser.getOfflinePlayer());
playerData.petRecipientUniqueId = null;
TextAdapter.sendComponent(player, MessageCache.getInstance().COMMAND_PET_CONFIRMATION);
event.setCancelled(true);
return;
}
final UUID uuid = NMSUtil.getInstance().getTameableOwnerUUID(targetEntity);
if (uuid != null) {
if (playerData.petRecipientUniqueId != null) {
final Tameable tameableEntity = (Tameable) targetEntity;
final GDPermissionUser recipientUser = PermissionHolderCache.getInstance().getOrCreateUser(playerData.petRecipientUniqueId);
tameableEntity.setOwner(recipientUser.getOfflinePlayer());
playerData.petRecipientUniqueId = null;
TextAdapter.sendComponent(player, MessageCache.getInstance().COMMAND_PET_CONFIRMATION);
event.setCancelled(true);
return;
}
// always allow owner to interact with their pets
if (player.getUniqueId().equals(uuid)) {
return;
@ -694,7 +702,8 @@ public void onPlayerBucketEvent(PlayerBucketEvent event) {
GDTimings.PLAYER_INTERACT_BLOCK_SECONDARY_EVENT.startTiming();
final Object source = player;
final Location location = clickedBlock.getLocation();
// Get relative location where water ends up
final Location location = clickedBlock.getRelative(event.getBlockFace()).getLocation();
final GDClaim claim = this.dataStore.getClaimAt(location);
Tristate result = GDPermissionManager.getInstance().getFinalPermission(event, location, claim, Flags.INTERACT_BLOCK_SECONDARY, source, clickedBlock, player, TrustTypes.BUILDER, true);
if (result == Tristate.FALSE) {
@ -799,7 +808,7 @@ public void onPlayerInteractBlockPrimary(PlayerInteractEvent event, Player playe
}
// Don't send a deny message if the player is in claim mode or is holding an investigation tool
if (!playerData.claimMode && (GriefDefenderPlugin.getInstance().investigationTool == null || !NMSUtil.getInstance().hasItemInOneHand(player, GriefDefenderPlugin.getInstance().investigationTool))) {
if (!playerData.claimMode && (itemInHand == null || !GDPermissionManager.getInstance().getPermissionIdentifier(itemInHand).equalsIgnoreCase(GriefDefenderPlugin.getInstance().investigationTool))) {
this.sendInteractBlockDenyMessage(itemInHand, clickedBlock, claim, player, playerData);
}
event.setCancelled(true);
@ -809,7 +818,7 @@ public void onPlayerInteractBlockPrimary(PlayerInteractEvent event, Player playe
GDTimings.PLAYER_INTERACT_BLOCK_PRIMARY_EVENT.stopTiming();
}
@EventHandler(priority = EventPriority.LOWEST)
@EventHandler(priority = EventPriority.LOW, ignoreCancelled = true)
public void onPlayerInteractBlockSecondary(PlayerInteractEvent event) {
final Block clickedBlock = event.getClickedBlock();
if (clickedBlock == null) {
@ -885,7 +894,7 @@ public void onPlayerInteractBlockSecondary(PlayerInteractEvent event) {
}
// Don't send a deny message if the player is in claim mode or is holding an investigation tool
if (lastInteractItemCancelled != true) {
if (!playerData.claimMode && (GriefDefenderPlugin.getInstance().investigationTool == null || !NMSUtil.getInstance().hasItemInOneHand(player, GriefDefenderPlugin.getInstance().investigationTool))) {
if (!playerData.claimMode && (itemInHand == null || !GDPermissionManager.getInstance().getPermissionIdentifier(itemInHand).equalsIgnoreCase(GriefDefenderPlugin.getInstance().investigationTool))) {
if (event.getAction() == Action.PHYSICAL) {
if (player.getWorld().getTime() % 100 == 0L) {
this.sendInteractBlockDenyMessage(itemInHand, clickedBlock, claim, player, playerData);
@ -1635,7 +1644,7 @@ private boolean investigateClaim(PlayerInteractEvent event, Player player, Block
// claim mode inspects with left-click
return false;
}
if (!playerData.claimMode && (itemInHand == null || GriefDefenderPlugin.getInstance().investigationTool == null || !NMSUtil.getInstance().itemsEqual(itemInHand, GriefDefenderPlugin.getInstance().investigationTool))){
if (!playerData.claimMode && (itemInHand == null || !GDPermissionManager.getInstance().getPermissionIdentifier(itemInHand).equalsIgnoreCase(GriefDefenderPlugin.getInstance().investigationTool))) {
return false;
}
@ -1644,7 +1653,7 @@ private boolean investigateClaim(PlayerInteractEvent event, Player player, Block
if (event.getAction() == Action.LEFT_CLICK_AIR || event.getAction() == Action.RIGHT_CLICK_AIR) {
final int maxDistance = GDPermissionManager.getInstance().getInternalOptionValue(TypeToken.of(Integer.class), player, Options.RADIUS_INSPECT);
final boolean hidingVisuals = event.getAction() == Action.LEFT_CLICK_AIR && !playerData.claimMode;
claim = this.findNearbyClaim(player, playerData, maxDistance, hidingVisuals);
claim = PlayerUtil.getInstance().findNearbyClaim(player, playerData, maxDistance, hidingVisuals);
if (player.isSneaking()) {
if (!playerData.claimMode && (event.getAction() == Action.LEFT_CLICK_AIR || event.getAction() == Action.LEFT_CLICK_BLOCK)) {
if (this.worldEditProvider != null) {
@ -1715,7 +1724,7 @@ private boolean investigateClaim(PlayerInteractEvent event, Player player, Block
if (!playerData.claimMode || claim.hasActiveVisual(player)) {
final int maxDistance = GDPermissionManager.getInstance().getInternalOptionValue(TypeToken.of(Integer.class), player, Options.RADIUS_INSPECT);
if (!((GDClaim) claim).children.isEmpty()) {
claim = this.findNearbyClaim(player, playerData, maxDistance, true);
claim = PlayerUtil.getInstance().findNearbyClaim(player, playerData, maxDistance, true);
}
if (!claim.hasActiveVisual(player) && claim.parent != null) {
GDClaim parent = claim.parent;
@ -1763,53 +1772,6 @@ private boolean investigateClaim(PlayerInteractEvent event, Player player, Block
return true;
}
private GDClaim findNearbyClaim(Player player, GDPlayerData playerData, int maxDistance, boolean hidingVisuals) {
if (maxDistance <= 20) {
maxDistance = 100;
}
BlockRay blockRay = BlockRay.from(player).distanceLimit(maxDistance).build();
GDClaim playerClaim = GriefDefenderPlugin.getInstance().dataStore.getClaimAtPlayer(playerData, player.getLocation());
GDClaim firstClaim = null;
GDClaim claim = null;
playerData.lastNonAirInspectLocation = null;
playerData.lastValidInspectLocation = null;
while (blockRay.hasNext()) {
BlockRayHit blockRayHit = blockRay.next();
Location location = blockRayHit.getLocation();
claim = this.dataStore.getClaimAt(location);
if (firstClaim == null && !claim.isWilderness()) {
if (hidingVisuals) {
if (claim.hasActiveVisual(player)) {
firstClaim = claim;
}
} else {
firstClaim = claim;
}
}
if (playerData.lastNonAirInspectLocation == null && !location.getBlock().isEmpty()) {
playerData.lastNonAirInspectLocation = location;
}
if (claim != null && !claim.isWilderness() && !playerClaim.getUniqueId().equals(claim.getUniqueId())) {
playerData.lastValidInspectLocation = location;
}
final Block block = location.getBlock();
if (!block.isEmpty() && !NMSUtil.getInstance().isBlockTransparent(block)) {
break;
}
}
if (claim == null || claim.isWilderness()) {
if (firstClaim == null) {
return GriefDefenderPlugin.getInstance().dataStore.getClaimWorldManager(player.getWorld().getUID()).getWildernessClaim();
}
return firstClaim;
}
return claim;
}
private void sendInteractBlockDenyMessage(ItemStack playerItem, Block block, GDClaim claim, Player player, GDPlayerData playerData) {
if (claim.getData() != null && !claim.getData().allowDenyMessages()) {
return;

View File

@ -475,14 +475,14 @@ private static void migratePlayerData(World world) {
}
File[] files = path.toFile().listFiles();
final List<File> fileList = new ArrayList<>();
if (files != null) {
GriefDefenderPlugin.getInstance().getLogger().info("Migrating " + files.length + " player data files...");
GriefDefenderPlugin.getInstance().getLogger().info("Scanning " + files.length + " player data files...");
for (int i = 0; i < files.length; i++) {
final File file = files[i];
if (file.getName().endsWith("ignore")) {
continue;
}
GriefDefenderPlugin.getInstance().getLogger().info("Migrating playerdata " + file.getName() + "...");
UUID uuid = null;
try {
uuid = UUID.fromString(file.getName().replaceFirst("[.][^.]+$", ""));
@ -500,17 +500,18 @@ private static void migratePlayerData(World world) {
if (lines.size() < 3) {
continue;
}
try {
final int accruedBlocks = Integer.parseInt(lines.get(1));
final int bonusBlocks = Integer.parseInt(lines.get(2));
final GDPlayerData playerData = GriefDefenderPlugin.getInstance().dataStore.getOrCreatePlayerData(world, uuid);
// Set directly in storage as subject data has not been initialized
playerData.setAccruedClaimBlocks(accruedBlocks, false);
playerData.setBonusClaimBlocks(bonusBlocks);
} catch (NumberFormatException e) {
e.printStackTrace();
continue;
}
fileList.add(file);
}
GriefDefenderPlugin.getInstance().getLogger().info("Migrating " + files.length + " player data files...");
// Migrate each meta separately to avoid race conditions in LP
for (File file : fileList) {
GriefDefenderPlugin.getInstance().getLogger().info("Migrating playerdata " + file.getName() + " accrued blocks...");
migrateAccruedBlocks(world, file);
}
for (File file : fileList) {
GriefDefenderPlugin.getInstance().getLogger().info("Migrating playerdata " + file.getName() + " bonus blocks...");
migrateBonusBlocks(world, file);
}
}
@ -527,6 +528,62 @@ private static void migratePlayerData(World world) {
}
}
private static void migrateAccruedBlocks(World world, File file) {
UUID uuid = null;
try {
uuid = UUID.fromString(file.getName().replaceFirst("[.][^.]+$", ""));
} catch (IllegalArgumentException e) {
e.printStackTrace();
return;
}
List<String> lines;
try {
lines = Files.readAllLines(file.toPath());
} catch (IOException e) {
e.printStackTrace();
return;
}
if (lines.size() < 3) {
return;
}
try {
final int accruedBlocks = Integer.parseInt(lines.get(1));
final GDPlayerData playerData = GriefDefenderPlugin.getInstance().dataStore.getOrCreatePlayerData(world, uuid);
// Set directly in storage as subject data has not been initialized
playerData.setAccruedClaimBlocks(accruedBlocks, false);
} catch (NumberFormatException e) {
e.printStackTrace();
}
}
private static void migrateBonusBlocks(World world, File file) {
UUID uuid = null;
try {
uuid = UUID.fromString(file.getName().replaceFirst("[.][^.]+$", ""));
} catch (IllegalArgumentException e) {
e.printStackTrace();
return;
}
List<String> lines;
try {
lines = Files.readAllLines(file.toPath());
} catch (IOException e) {
e.printStackTrace();
return;
}
if (lines.size() < 3) {
return;
}
try {
final int bonusBlocks = Integer.parseInt(lines.get(2));
final GDPlayerData playerData = GriefDefenderPlugin.getInstance().dataStore.getOrCreatePlayerData(world, uuid);
// Set directly in storage as subject data has not been initialized
playerData.setBonusClaimBlocks(bonusBlocks);
} catch (NumberFormatException e) {
e.printStackTrace();
}
}
private static void migrateClaims(World world, File[] files, boolean parentsOnly) {
for (int i = 0; i < files.length; i++) {
File file = files[i];

View File

@ -42,7 +42,6 @@
import com.griefdefender.api.permission.PermissionResult;
import com.griefdefender.api.permission.ResultTypes;
import com.griefdefender.api.permission.flag.Flag;
import com.griefdefender.api.permission.flag.FlagData;
import com.griefdefender.api.permission.flag.FlagDefinition;
import com.griefdefender.api.permission.flag.Flags;
import com.griefdefender.api.permission.option.Option;
@ -108,6 +107,7 @@
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
@ -314,7 +314,7 @@ public Tristate getFinalPermission(Event event, Location location, Set<Context>
return processResult(claim, targetPermission, type.getName().toLowerCase(), Tristate.TRUE, permissionHolder);
}
}
return getUserPermission(user, claim, targetPermission, PermissionDataType.ALL);
return getUserPermission(user, claim, targetPermission, PermissionDataType.PERSISTENT);
}
return getClaimFlagPermission(claim, targetPermission);
@ -396,24 +396,25 @@ private Tristate getFlagDefaultPermission(Claim claim, String permission, Set<Co
if (!claim.isWilderness()) {
contexts.add(ClaimContexts.GLOBAL_DEFAULT_CONTEXT);
contexts.add(ClaimContexts.USER_DEFAULT_CONTEXT);
value = PermissionUtil.getInstance().getPermissionValue((GDClaim) claim, GriefDefenderPlugin.DEFAULT_HOLDER, permission, contexts, PermissionDataType.ALL);
value = PermissionUtil.getInstance().getPermissionValue((GDClaim) claim, GriefDefenderPlugin.DEFAULT_HOLDER, permission, contexts, PermissionDataType.PERSISTENT);
if (value != Tristate.UNDEFINED) {
return processResult(claim, permission, value, GriefDefenderPlugin.DEFAULT_HOLDER);
}
contexts.remove(ClaimContexts.USER_DEFAULT_CONTEXT);
} else {
contexts.add(ClaimContexts.GLOBAL_DEFAULT_CONTEXT);
value = PermissionUtil.getInstance().getPermissionValue((GDClaim) claim, GriefDefenderPlugin.DEFAULT_HOLDER, permission, contexts, PermissionDataType.ALL);
value = PermissionUtil.getInstance().getPermissionValue((GDClaim) claim, GriefDefenderPlugin.DEFAULT_HOLDER, permission, contexts, PermissionDataType.PERSISTENT);
if (value != Tristate.UNDEFINED) {
return processResult(claim, permission, value, GriefDefenderPlugin.DEFAULT_HOLDER);
}
}
contexts.remove(ClaimContexts.GLOBAL_DEFAULT_CONTEXT);
contexts.add(ClaimContexts.USER_DEFAULT_CONTEXT);
contexts.add(claim.getDefaultTypeContext());
value = PermissionUtil.getInstance().getPermissionValue((GDClaim) claim, GriefDefenderPlugin.DEFAULT_HOLDER, permission, contexts, PermissionDataType.TRANSIENT);
value = PermissionUtil.getInstance().getPermissionValue((GDClaim) claim, GriefDefenderPlugin.GD_DEFAULT_HOLDER, permission, contexts, PermissionDataType.TRANSIENT);
if (value != Tristate.UNDEFINED) {
return processResult(claim, permission, value, GriefDefenderPlugin.DEFAULT_HOLDER);
return processResult(claim, permission, value, GriefDefenderPlugin.GD_DEFAULT_HOLDER);
}
return processResult(claim, permission, Tristate.UNDEFINED, GriefDefenderPlugin.DEFAULT_HOLDER);
@ -488,7 +489,7 @@ public Tristate processResult(Claim claim, String permission, Tristate permissio
}
public Tristate processResult(Claim claim, String permission, String trust, Tristate permissionValue, GDPermissionHolder permissionHolder) {
if (GriefDefenderPlugin.debugActive) {
if (GriefDefenderPlugin.debugActive && this.currentEvent != null) {
// Use the event subject always if available
// This prevents debug showing 'default' for users
if (eventSubject != null) {
@ -502,7 +503,7 @@ public Tristate processResult(Claim claim, String permission, String trust, Tris
}
}
if (this.currentEvent != null && (this.currentEvent instanceof BlockPhysicsEvent)) {
if (this.currentEvent instanceof BlockPhysicsEvent) {
if (((GDClaim) claim).getWorld().getTime() % 100 != 0L) {
return permissionValue;
}
@ -580,10 +581,27 @@ public String getPermissionIdentifier(Object obj, boolean isSource) {
return populateEventSourceTarget(id, isSource);
} else if (obj instanceof Block) {
final String id = BlockTypeRegistryModule.getInstance().getNMSKey((Block) obj);
final Block block = (Block) obj;
if (GriefDefenderPlugin.getInstance().getSlimefunProvider() != null) {
final String customItemId = GriefDefenderPlugin.getInstance().getSlimefunProvider().getSlimeBlockId(block);
if (customItemId != null && !customItemId.isEmpty()) {
return populateEventSourceTarget(customItemId, isSource);
}
}
final String id = BlockTypeRegistryModule.getInstance().getNMSKey(block);
return populateEventSourceTarget(id, isSource);
} else if (obj instanceof BlockState) {
final BlockState blockstate = (BlockState) obj;
if (blockstate.getBlock().getType() != blockstate.getType()) {
return populateEventSourceTarget(blockstate.getType().name().toLowerCase(), isSource);
}
if (GriefDefenderPlugin.getInstance().getSlimefunProvider() != null) {
final String customItemId = GriefDefenderPlugin.getInstance().getSlimefunProvider().getSlimeBlockId(blockstate.getBlock());
if (customItemId != null && !customItemId.isEmpty()) {
return populateEventSourceTarget(customItemId, isSource);
}
}
final String id = BlockTypeRegistryModule.getInstance().getNMSKey(blockstate);
return populateEventSourceTarget(id, isSource);
} else if (obj instanceof Material) {
@ -604,6 +622,18 @@ public String getPermissionIdentifier(Object obj, boolean isSource) {
} else if (obj instanceof ItemStack) {
final ItemStack itemstack = (ItemStack) obj;
if (GriefDefenderPlugin.getInstance().isCustomItemsInstalled) {
final String customItemId = NMSUtil.getInstance().getItemStackNBTString(itemstack, "com.jojodmo.customitems.itemID");
if (customItemId != null && !customItemId.isEmpty()) {
return populateEventSourceTarget("customitems:" + customItemId, isSource);
}
}
if (GriefDefenderPlugin.getInstance().getSlimefunProvider() != null) {
final String customItemId = GriefDefenderPlugin.getInstance().getSlimefunProvider().getSlimeItemId(itemstack);
if (customItemId != null && !customItemId.isEmpty()) {
return populateEventSourceTarget(customItemId, isSource);
}
}
String id = ItemTypeRegistryModule.getInstance().getNMSKey(itemstack);
return populateEventSourceTarget(id, isSource);
} else if (obj instanceof DamageCause) {
@ -670,6 +700,12 @@ public Set<Context> getPermissionContexts(GDClaim claim, Object obj, boolean isS
return populateEventSourceTargetContext(contexts, id, isSource);
} else if (obj instanceof Block) {
final Block block = (Block) obj;
if (GriefDefenderPlugin.getInstance().getSlimefunProvider() != null) {
final String customItemId = GriefDefenderPlugin.getInstance().getSlimefunProvider().getSlimeBlockId(block, contexts);
if (customItemId != null && !customItemId.isEmpty()) {
return populateEventSourceTargetContext(contexts, customItemId, isSource);
}
}
final String id = BlockTypeRegistryModule.getInstance().getNMSKey(block);
this.addBlockContexts(contexts, block, isSource);
if (this.isObjectIdBanned(claim, id, BanType.BLOCK)) {
@ -679,6 +715,15 @@ public Set<Context> getPermissionContexts(GDClaim claim, Object obj, boolean isS
return populateEventSourceTargetContext(contexts, id, isSource);
} else if (obj instanceof BlockState) {
final BlockState blockstate = (BlockState) obj;
if (blockstate.getBlock().getType() != blockstate.getType()) {
return populateEventSourceTargetContext(contexts, blockstate.getType().name().toLowerCase(), isSource);
}
if (GriefDefenderPlugin.getInstance().getSlimefunProvider() != null) {
final String customItemId = GriefDefenderPlugin.getInstance().getSlimefunProvider().getSlimeBlockId(blockstate.getBlock(), contexts);
if (customItemId != null && !customItemId.isEmpty()) {
return populateEventSourceTargetContext(contexts, customItemId, isSource);
}
}
final String id = BlockTypeRegistryModule.getInstance().getNMSKey(blockstate);
this.addBlockContexts(contexts, blockstate.getBlock(), isSource);
if (this.isObjectIdBanned(claim, id, BanType.BLOCK)) {
@ -697,6 +742,18 @@ public Set<Context> getPermissionContexts(GDClaim claim, Object obj, boolean isS
return populateEventSourceTargetContext(contexts, id, isSource);
} else if (obj instanceof ItemStack) {
final ItemStack itemstack = (ItemStack) obj;
if (GriefDefenderPlugin.getInstance().isCustomItemsInstalled) {
final String customItemId = NMSUtil.getInstance().getItemStackNBTString(itemstack, "com.jojodmo.customitems.itemID");
if (customItemId != null && !customItemId.isEmpty()) {
return populateEventSourceTargetContext(contexts, "customitems:" + customItemId, isSource);
}
}
if (GriefDefenderPlugin.getInstance().getSlimefunProvider() != null) {
final String customItemId = GriefDefenderPlugin.getInstance().getSlimefunProvider().getSlimeItemId(itemstack, contexts);
if (customItemId != null && !customItemId.isEmpty()) {
return populateEventSourceTargetContext(contexts, customItemId, isSource);
}
}
if (NMSUtil.getInstance().isItemFood(itemstack)) {
if (isSource) {
contexts.add(ContextGroups.SOURCE_FOOD);
@ -1017,6 +1074,9 @@ private Set<Context> populateEventSourceTargetContext(Set<Context> contexts, Str
id = "minecraft:" + id;
}
contexts = this.populateTagContextsForId(contexts, id, isSource);
// always add source/target any contexts
contexts.add(ContextGroups.SOURCE_ANY);
contexts.add(ContextGroups.TARGET_ANY);
final String[] parts = id.split(":");
final String modId = parts[0];
if (isSource) {
@ -1595,22 +1655,43 @@ public <T> T getActiveOptionValue(TypeToken<T> type, Option<T> option, Subject s
@Override
public CompletableFuture<PermissionResult> setFlagDefinition(Subject subject, FlagDefinition flagDefinition, Tristate value) {
final Set<Context> contexts = new HashSet<>();
contexts.addAll(flagDefinition.getContexts());
PermissionResult result = new GDPermissionResult(ResultTypes.SUCCESS, TextComponent.builder().append("SUCCESS").build());
CompletableFuture<PermissionResult> future = new CompletableFuture<>();
for (FlagData flagData : flagDefinition.getFlagData()) {
final Set<Context> flagContexts = new HashSet<>(contexts);
flagContexts.addAll(flagData.getContexts());
// TODO - Add method that supports multiple permissions
PermissionUtil.getInstance().setPermissionValue((GDPermissionHolder) subject, flagData.getFlag(), value, flagContexts);
/*if (!result.successful()) {
future.complete(result);
return future;
}*/
Set<Context> contexts = new HashSet<>(flagDefinition.getContexts());
Set<Context> defaultContexts = new HashSet<>();
Set<Context> overrideContexts = new HashSet<>();
String groupStr = null;
final Iterator<Context> iterator = contexts.iterator();
while (iterator.hasNext()) {
final Context context = iterator.next();
if (context.getKey().equalsIgnoreCase("gd_claim_default")) {
defaultContexts.add(context);
} else if (context.getKey().equalsIgnoreCase("gd_claim_override")) {
if (context.getValue().equalsIgnoreCase("claim")) {
iterator.remove();
continue;
}
overrideContexts.add(context);
} else if (context.getKey().equalsIgnoreCase("group")) {
groupStr = context.getValue();
}
}
GDPermissionHolder holder = GriefDefenderPlugin.DEFAULT_HOLDER;
if (groupStr != null) {
if (PermissionUtil.getInstance().hasGroupSubject(groupStr)) {
holder = PermissionHolderCache.getInstance().getOrCreateGroup(groupStr);
if (holder == null) {
holder = GriefDefenderPlugin.DEFAULT_HOLDER;
}
}
}
future.complete(result);
return future;
CompletableFuture<PermissionResult> result = new CompletableFuture<>();
if (!defaultContexts.isEmpty()) {
result = PermissionUtil.getInstance().setFlagDefinition(holder, flagDefinition, flagDefinition.getDefaultValue(), defaultContexts, true);
}
if (!overrideContexts.isEmpty()) {
result = PermissionUtil.getInstance().setFlagDefinition(holder, flagDefinition, flagDefinition.getDefaultValue(), overrideContexts, false);
}
PermissionUtil.getInstance().save(holder);
return result;
}
}

View File

@ -45,10 +45,15 @@ public class GDPermissions {
public static final String COMMAND_CLAIM_BUY = "griefdefender.user.claim.command.buy";
public static final String COMMAND_CLAIM_CONTRACT = "griefdefender.user.claim.command.contract";
public static final String COMMAND_CLAIM_EXPAND = "griefdefender.user.claim.command.expand";
public static final String COMMAND_CLAIM_INFO_OTHERS = "griefdefender.user.claim.command.info.others";
public static final String COMMAND_CLAIM_INFO_BASE = "griefdefender.user.claim.command.info.base";
public static final String COMMAND_CLAIM_INFO_TELEPORT_OTHERS = "griefdefender.user.claim.command.info.teleport.others";
public static final String COMMAND_CLAIM_INFO_OTHERS = "griefdefender.user.claim.command.info.others";
public static final String COMMAND_CLAIM_INFO_OTHERS_CREATION_DATE = "griefdefender.user.claim.command.info.others.creation-date";
public static final String COMMAND_CLAIM_INFO_OTHERS_LAST_ACTIVE = "griefdefender.user.claim.command.info.others.last-active";
public static final String COMMAND_CLAIM_INFO_OTHERS_CLAIM_UUID = "griefdefender.user.claim.command.info.others.claim-uuid";
public static final String COMMAND_CLAIM_INFO_TELEPORT_BASE = "griefdefender.user.claim.command.info.teleport.base";
public static final String COMMAND_CLAIM_INFO_TELEPORT_OTHERS = "griefdefender.user.claim.command.info.teleport.others";
public static final String COMMAND_CLAIM_INFO_TELEPORT_INSIDE = "griefdefender.user.claim.command.info.teleport.inside";
public static final String COMMAND_CLAIM_INVESTIGATE = "griefdefender.user.claim.command.investigate";
public static final String COMMAND_CLAIM_MODE = "griefdefender.user.claim.command.claim-mode";
public static final String COMMAND_CLAIM_OPTIONS_BASE = "griefdefender.user.claim.option.base";
public static final String COMMAND_CLAIM_RENT = "griefdefender.user.claim.command.rent";
@ -56,6 +61,7 @@ public class GDPermissions {
public static final String COMMAND_CLAIM_SPAWN = "griefdefender.user.claim.command.spawn";
public static final String COMMAND_CLAIM_SET_SPAWN = "griefdefender.user.claim.command.set-spawn";
public static final String COMMAND_CLAIM_TAX = "griefdefender.user.claim.command.claim.tax";
public static final String COMMAND_CLAIM_TOOL = "griefdefender.user.claim.command.claim-tool";
public static final String COMMAND_CLAIM_WORLDEDIT = "griefdefender.user.claim.command.worldedit-claim";
public static final String COMMAND_SET_CLAIM_NAME = "griefdefender.user.claim.command.name";
public static final String COMMAND_SET_CLAIM_FAREWELL = "griefdefender.user.claim.command.farewell";
@ -134,6 +140,7 @@ public class GDPermissions {
public static final String BYPASS_CLAIM_LIMIT = "griefdefender.admin.bypass.override.limit";
public static final String BYPASS_OPTION = "griefdefender.admin.bypass.option";
public static final String BYPASS_PVP_CREATIVE = "griefdefender.admin.bypass.pvp-creative";
public static final String BYPASS_PVP_LOGOUT = "griefdefender.admin.bypass.pvp-logout";
public static final String CLAIM_CUBOID_ADMIN = "griefdefender.admin.claim.cuboid";
public static final String CLAIM_RESIZE_ALL = "griefdefender.admin.claim.resize";
public static final String CLAIM_RESIZE_ADMIN = "griefdefender.admin.claim.resize.admin";
@ -157,6 +164,7 @@ public class GDPermissions {
public static final String COMMAND_DELETE_ADMIN_CLAIMS = "griefdefender.admin.command.delete-admin-claims";
public static final String COMMAND_ECONOMY_BLOCK_TRANSFER = "griefdefender.admin.command.block-transfer";
public static final String COMMAND_SET_ACCRUED_CLAIM_BLOCKS = "griefdefender.admin.command.set-accrued-claim-blocks";
public static final String COMMAND_SET_ACCRUED_CLAIM_BLOCKS_ALL = "griefdefender.admin.command.set-accrued-claim-blocks-all";
public static final String COMMAND_RESTORE_CLAIM = "griefdefender.admin.command.restore-claim.base";
public static final String COMMAND_RESTORE_NATURE = "griefdefender.admin.command.restore-nature.base";
public static final String COMMAND_RESTORE_NATURE_AGGRESSIVE = "griefdefender.admin.command.restore-nature.aggressive";

View File

@ -30,12 +30,14 @@
public class FlagContexts {
public static final Context SOURCE_AIR = new Context(ContextKeys.SOURCE, "minecraft:air");
public static final Context SOURCE_ARROW = new Context(ContextKeys.SOURCE, "minecraft:arrow");
public static final Context SOURCE_CREEPER = new Context(ContextKeys.SOURCE, "minecraft:creeper");
public static final Context SOURCE_ENDERDRAGON = new Context(ContextKeys.SOURCE, "minecraft:enderdragon");
public static final Context SOURCE_ENDERMAN = new Context(ContextKeys.SOURCE, "minecraft:enderman");
public static final Context SOURCE_END_PORTAL = new Context(ContextKeys.SOURCE, "minecraft:end_portal");
public static final Context SOURCE_FALL = new Context(ContextKeys.SOURCE, "minecraft:fall");
public static final Context SOURCE_FALLING_BLOCK = new Context(ContextKeys.SOURCE, "minecraft:falling_block");
public static final Context SOURCE_FARMLAND = new Context(ContextKeys.SOURCE, "minecraft:farmland");
public static final Context SOURCE_FIRE = new Context(ContextKeys.SOURCE, "minecraft:fire");
public static final Context SOURCE_FIRE_TICK = new Context(ContextKeys.SOURCE, "minecraft:fire_tick");
public static final Context SOURCE_FIREWORKS = new Context(ContextKeys.SOURCE, "minecraft:fireworks");

View File

@ -65,7 +65,6 @@ public class DynmapProvider {
private DynmapCommonAPI dynmap;
private MarkerAPI markerapi;
private DynmapCategory cfg;
private DynmapOwnerStyleCategory defaultStyle = new DynmapOwnerStyleCategory();
private MarkerSet set;
private boolean disabled = false;
private boolean reload = false;
@ -178,7 +177,7 @@ private boolean isVisible(GDClaim claim, String owner, String worldname) {
return true;
}
private void addOwnerStyle(String owner, String worldid, AreaMarker marker, Claim claim) {
private void addClaimStyle(Claim claim, AreaMarker marker, String worldid, String owner) {
DynmapOwnerStyleCategory ownerStyle = null;
if (!this.cfg.ownerStyles.isEmpty()) {
@ -186,29 +185,36 @@ private void addOwnerStyle(String owner, String worldid, AreaMarker marker, Clai
}
if (ownerStyle == null) {
ownerStyle = this.defaultStyle;
ownerStyle = this.cfg.claimTypeStyles.get(claim.getType().getName().toLowerCase());
}
int sc = 0xFF0000;
int fc = 0xFF0000;
if (claim.getType().equals(ClaimTypes.ADMIN)) {
sc = 0xFF0000;
fc = 0xFF0000;
} else if (claim.getType().equals(ClaimTypes.BASIC)) {
sc = 0xFFFF00;
fc = 0xFFFF00;
} else if (claim.getType().equals(ClaimTypes.TOWN)) {
sc = 0x00FF00;
fc = 0x00FF00;
} else if (claim.getType().equals(ClaimTypes.SUBDIVISION)) {
sc = 0xFF9C00;
fc = 0xFF9C00;
int sc;
int fc;
try {
sc = Integer.parseInt(ownerStyle.strokeColor.replaceAll("#", ""), 16);
fc = Integer.parseInt(ownerStyle.fillColor.replaceAll("#", ""), 16);
} catch (NumberFormatException e) {
if (claim.getType().equals(ClaimTypes.ADMIN)) {
sc = 0xFF0000;
fc = 0xFF0000;
} else if (claim.getType().equals(ClaimTypes.BASIC)) {
sc = 0xFFFF00;
fc = 0xFFFF00;
} else if (claim.getType().equals(ClaimTypes.TOWN)) {
sc = 0x00FF00;
fc = 0x00FF00;
} else if (claim.getType().equals(ClaimTypes.SUBDIVISION)) {
sc = 0xFF9C00;
fc = 0xFF9C00;
} else {
sc = 0xFF0000;
fc = 0xFF0000;
}
}
marker.setLineStyle(ownerStyle.strokeWeight, ownerStyle.strokeOpacity, sc);
marker.setFillStyle(ownerStyle.fillOpacity, fc);
if (ownerStyle.label != null) {
if (ownerStyle.label != null && !ownerStyle.label.isEmpty() && !ownerStyle.label.equalsIgnoreCase("none")) {
marker.setLabel(ownerStyle.label);
}
}
@ -249,7 +255,7 @@ private void updateClaimMarker(Claim claim, Map<String, AreaMarker> markerMap) {
marker.setRangeY(greaterPos.getY() + 1.0, lesserPos.getY());
}
addOwnerStyle(owner, worldName, marker, claim);
addClaimStyle(claim, marker, worldName, owner);
String desc = getWindowInfo(claim, marker);
marker.setDescription(desc);
markerMap.put(markerid, marker);

View File

@ -30,8 +30,11 @@
import com.griefdefender.api.Tristate;
import com.griefdefender.api.claim.Claim;
import com.griefdefender.api.permission.Context;
import com.griefdefender.api.permission.ContextKeys;
import com.griefdefender.api.permission.PermissionResult;
import com.griefdefender.api.permission.ResultTypes;
import com.griefdefender.api.permission.flag.FlagData;
import com.griefdefender.api.permission.flag.FlagDefinition;
import com.griefdefender.api.permission.option.Option;
import com.griefdefender.cache.PermissionHolderCache;
import com.griefdefender.claim.ClaimContextCalculator;
@ -42,6 +45,8 @@
import com.griefdefender.permission.GDPermissionResult;
import com.griefdefender.permission.GDPermissionUser;
import com.griefdefender.registry.OptionRegistryModule;
import com.griefdefender.util.PermissionUtil;
import net.kyori.text.TextComponent;
import net.luckperms.api.LuckPerms;
import net.luckperms.api.cacheddata.CachedMetaData;
@ -67,6 +72,7 @@
import net.luckperms.api.query.dataorder.DataTypeFilterFunction;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Comparator;
import java.util.HashMap;
@ -77,10 +83,8 @@
import java.util.TreeMap;
import java.util.UUID;
import java.util.Map.Entry;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.function.Function;
import java.util.function.Predicate;
import org.bukkit.Bukkit;
@ -129,9 +133,6 @@ public boolean hasGroupSubject(String identifier) {
}
public PermissionHolder getLuckPermsHolder(GDPermissionHolder holder) {
if (holder.getIdentifier().equalsIgnoreCase("default")) {
return this.luckPermsApi.getGroupManager().getGroup("default");
}
if (holder instanceof GDPermissionUser) {
return this.getLuckPermsUser(holder.getIdentifier());
}
@ -165,11 +166,83 @@ public User getLuckPermsUser(String identifier) {
return user;
}
public Group getLuckPermsGroup(String identifier) {
if (identifier.equalsIgnoreCase("default")) {
return this.luckPermsApi.getGroupManager().getGroup("default");
public boolean createDefaultGroup(String identifier) {
Group group = this.luckPermsApi.getGroupManager().getGroup(identifier);
if (group == null) {
try {
GriefDefenderPlugin.getInstance().getLogger().info("Creating group '" + identifier + "' in LuckPerms...");
final String dataType = identifier.replaceAll("griefdefender_", "");
group = this.luckPermsApi.getGroupManager().createAndLoadGroup(identifier).get();
GriefDefenderPlugin.getInstance().getLogger().info("Group created successfully.");
if (group != null) {
final Group defaultGroup = this.luckPermsApi.getGroupManager().getGroup("default");
if (defaultGroup != null) {
GriefDefenderPlugin.getInstance().getLogger().info("Migrating legacy " + dataType + " permissions from 'default' to '" + identifier + "'...");
final Node node = this.luckPermsApi.getNodeBuilderRegistry().forInheritance().group(group).build();
// move all existing GD permissions to new group
List<Node> nodesToRemove = new ArrayList<>();
for (Node permNode : defaultGroup.data().toCollection()) {
if (!permNode.getKey().contains("griefdefender")) {
continue;
}
if (permNode.getType() == NodeType.META) {
if (permNode.getKey().contains("griefdefender") && identifier.equals(GriefDefenderPlugin.GD_OPTION_GROUP_NAME)) {
GriefDefenderPlugin.getInstance().getLogger().info("Found legacy option node [Key: " + permNode.getKey() + ", Value: " + permNode.getValue() + ", Contexts: " + permNode.getContexts() + "].\nAdding option node to group '" + identifier + "'...");
group.data().add(permNode);
nodesToRemove.add(permNode);
}
continue;
}
if (permNode.getType() != NodeType.PERMISSION) {
continue;
}
if (identifier.equals(GriefDefenderPlugin.GD_OVERRIDE_GROUP_NAME)) {
if (permNode.getContexts().containsKey(ContextKeys.CLAIM_OVERRIDE)) {
GriefDefenderPlugin.getInstance().getLogger().info("Found legacy override permission node [Key: " + permNode.getKey() + ", Value: " + permNode.getValue() + ", Contexts: " + permNode.getContexts() + "].\nAdding permission node to group '" + identifier + "'...");
group.data().add(permNode);
nodesToRemove.add(permNode);
}
continue;
} else if (identifier.equals(GriefDefenderPlugin.GD_CLAIM_GROUP_NAME)) {
if (permNode.getContexts().containsKey(ContextKeys.CLAIM)) {
GriefDefenderPlugin.getInstance().getLogger().info("Found legacy claim permission node [Key: " + permNode.getKey() + ", Value: " + permNode.getValue() + ", Contexts: " + permNode.getContexts() + "].\nAdding permission node to group '" + identifier + "'...");
group.data().add(permNode);
nodesToRemove.add(permNode);
}
continue;
} else if (identifier.equals(GriefDefenderPlugin.GD_DEFAULT_GROUP_NAME)) {
if (!permNode.getContexts().isEmpty()) {
GriefDefenderPlugin.getInstance().getLogger().info("Found legacy default permission node [Key: " + permNode.getKey() + ", Value: " + permNode.getValue() + ", Contexts: " + permNode.getContexts() + "].\nAdding permission node to group '" + identifier + "'...");
group.data().add(permNode);
nodesToRemove.add(permNode);
}
}
}
if (!nodesToRemove.isEmpty()) {
GriefDefenderPlugin.getInstance().getLogger().info("Removing legacy permission nodes from 'default' group...");
}
for (Node rem : nodesToRemove) {
defaultGroup.data().remove(rem);
}
if (!nodesToRemove.isEmpty()) {
GriefDefenderPlugin.getInstance().getLogger().info("Cleanup complete.");
}
final DataMutateResult result = defaultGroup.data().add(node);
GriefDefenderPlugin.getInstance().getLogger().info("Saving permission changes to 'default'...");
this.luckPermsApi.getGroupManager().saveGroup(defaultGroup).get();
GriefDefenderPlugin.getInstance().getLogger().info("Saving permission changes to '" + identifier + "'...");
this.luckPermsApi.getGroupManager().saveGroup(group).get();
GriefDefenderPlugin.getInstance().getLogger().info("Migration to group '" + identifier + "' complete.");
}
}
} catch (Throwable t) {
t.printStackTrace();
}
}
return group != null;
}
public Group getLuckPermsGroup(String identifier) {
return this.luckPermsApi.getGroupManager().getGroup(identifier);
}
@ -278,10 +351,10 @@ public void addActiveContexts(Set<Context> contexts, GDPermissionHolder permissi
public void clearPermissions(GDClaim claim) {
// check default holder
this.clearPermission(claim.getUniqueId(), GriefDefenderPlugin.DEFAULT_HOLDER);
this.clearPermission(claim.getUniqueId(), GriefDefenderPlugin.GD_CLAIM_HOLDER);
// check loaded groups
for (Group group : this.luckPermsApi.getGroupManager().getLoadedGroups()) {
if (group.getName().equalsIgnoreCase("default")) {
if (group.getName().equalsIgnoreCase(GriefDefenderPlugin.DEFAULT_GROUP_NAME) || group.getName().startsWith("griefdefender_")) {
continue;
}
final GDPermissionHolder holder = PermissionHolderCache.getInstance().getOrCreateGroup(group.getName());
@ -412,6 +485,37 @@ public Map<Set<Context>, Map<String, Boolean>> getPermanentPermissions(GDPermiss
return permanentPermissionMap;
}
public Map<Set<Context>, Map<String, Boolean>> getAllPermanentPermissions() {
Map<Set<Context>, Map<String, Boolean>> permanentPermissionMap = new TreeMap<Set<Context>, Map<String, Boolean>>(CONTEXT_COMPARATOR);
this.addAllPermanentPermissions(this.getLuckPermsHolder(GriefDefenderPlugin.GD_CLAIM_HOLDER), permanentPermissionMap);
this.addAllPermanentPermissions(this.getLuckPermsHolder(GriefDefenderPlugin.GD_DEFAULT_HOLDER), permanentPermissionMap);
this.addAllPermanentPermissions(this.getLuckPermsHolder(GriefDefenderPlugin.GD_DEFINITION_HOLDER), permanentPermissionMap);
this.addAllPermanentPermissions(this.getLuckPermsHolder(GriefDefenderPlugin.GD_OPTION_HOLDER), permanentPermissionMap);
this.addAllPermanentPermissions(this.getLuckPermsHolder(GriefDefenderPlugin.GD_OVERRIDE_HOLDER), permanentPermissionMap);
return permanentPermissionMap;
}
private Map<Set<Context>, Map<String, Boolean>> addAllPermanentPermissions(PermissionHolder holder, Map<Set<Context>, Map<String, Boolean>> permanentPermissionMap) {
final Collection<Node> nodes = holder.data().toCollection();
for (Node node : nodes) {
if (node.getType() != NodeType.PERMISSION) {
continue;
}
final PermissionNode permissionNode = (PermissionNode) node;
final Set<Context> contexts = getGPContexts(node.getContexts());
Map<String, Boolean> permissionEntry = permanentPermissionMap.get(contexts);
if (permissionEntry == null) {
permissionEntry = new HashMap<>();
permissionEntry.put(permissionNode.getPermission(), node.getValue());
permanentPermissionMap.put(contexts, permissionEntry);
} else {
permissionEntry.put(permissionNode.getPermission(), node.getValue());
}
}
return permanentPermissionMap;
}
public Map<Set<Context>, Map<String, Boolean>> getTransientPermissions(GDPermissionHolder holder) {
final PermissionHolder permissionHolder = this.getLuckPermsHolder(holder);
if (permissionHolder == null) {
@ -578,7 +682,7 @@ public Set<Context> getGPContexts(ContextSet contextSet) {
@Override
public Tristate getPermissionValue(GDPermissionHolder holder, String permission, Set<Context> contexts) {
return this.getPermissionValue(holder, permission, contexts, PermissionDataType.ALL);
return this.getPermissionValue(holder, permission, contexts, PermissionDataType.PERSISTENT);
}
@Override
@ -609,11 +713,11 @@ public Tristate getPermissionValue(GDPermissionHolder holder, String permission,
}
public Tristate getPermissionValue(GDPermissionHolder holder, String permission, ContextSet contexts) {
return this.getPermissionValue(holder, permission, contexts, PermissionDataType.ALL);
return this.getPermissionValue(holder, permission, contexts, PermissionDataType.PERSISTENT);
}
public Tristate getPermissionValue(GDPermissionHolder holder, String permission, ContextSet contexts, PermissionDataType type) {
final PermissionHolder permissionHolder = this.getLuckPermsHolder(holder);
final PermissionHolder permissionHolder = type == PermissionDataType.TRANSIENT ? this.getLuckPermsHolder(GriefDefenderPlugin.GD_DEFAULT_HOLDER) : this.getLuckPermsHolder(holder);
if (permissionHolder == null) {
return Tristate.UNDEFINED;
}
@ -672,26 +776,12 @@ public CompletableFuture<PermissionResult> setOptionValue(GDPermissionHolder hol
// If no server context exists, add global
this.checkServerContext(contexts);
}
if (holder == GriefDefenderPlugin.DEFAULT_HOLDER) {
holder = GriefDefenderPlugin.GD_OPTION_HOLDER;
}
ImmutableContextSet set = this.getLPContexts(contexts).immutableCopy();
final Option option = OptionRegistryModule.getInstance().getById(key).orElse(null);
if (option == null) {
new GDPermissionResult(ResultTypes.FAILURE);
}
final Node node = MetaNode.builder().key(key).value(value).context(set).build();
if (holder instanceof GDPermissionGroup) {
return this.luckPermsApi.getGroupManager().loadGroup(holder.getFriendlyName()).thenApplyAsync((Function<? super Optional<Group>, ? extends PermissionResult>) lpHolder -> {
final Group group = lpHolder.orElse(null);
if (group != null) {
return this.applyOptionNode(holder, group, node, option, value);
}
return new GDPermissionResult(ResultTypes.FAILURE, TextComponent.builder().append("COULD NOT LOAD GROUP " + holder.getFriendlyName()).build());
});
} else {
return this.luckPermsApi.getUserManager().loadUser(((GDPermissionUser) holder).getUniqueId()).thenApplyAsync((Function<? super User, ? extends PermissionResult>) lpHolder -> {
return this.applyOptionNode(holder, lpHolder, node, option, value);
});
}
return this.createOptionFuture(holder, node, key, value, false);
}
public CompletableFuture<PermissionResult> setPermissionValue(GDPermissionHolder holder, String permission, Tristate value, Set<Context> contexts, boolean check, boolean save) {
@ -701,71 +791,132 @@ public CompletableFuture<PermissionResult> setPermissionValue(GDPermissionHolder
}
ImmutableContextSet set = this.getLPContexts(contexts).immutableCopy();
final Node node = this.luckPermsApi.getNodeBuilderRegistry().forPermission().permission(permission).value(value.asBoolean()).context(set).build();
if (holder instanceof GDPermissionGroup) {
return this.luckPermsApi.getGroupManager().loadGroup(holder.getFriendlyName()).thenApplyAsync((Function<? super Optional<Group>, ? extends PermissionResult>) lpHolder -> {
final Group group = lpHolder.orElse(null);
if (group != null) {
return this.applyPermissionNode(holder, group, node, value, save);
}
return new GDPermissionResult(ResultTypes.FAILURE, TextComponent.builder().append("COULD NOT LOAD GROUP " + holder.getFriendlyName()).build());
});
} else {
return this.luckPermsApi.getUserManager().loadUser(((GDPermissionUser) holder).getUniqueId()).thenApplyAsync((Function<? super User, ? extends PermissionResult>) lpHolder -> {
return this.applyPermissionNode(holder, lpHolder, node, value, save);
});
}
return this.createPermissionFuture(PermissionUtil.getInstance().getGDPermissionHolder(holder, contexts), Arrays.asList(node), value, false);
}
public CompletableFuture<PermissionResult> setTransientOption(GDPermissionHolder holder, String permission, String value, Set<Context> contexts) {
@Override
public CompletableFuture<PermissionResult> setFlagDefinition(GDPermissionHolder holder, FlagDefinition definition, Tristate value, Set<Context> contexts, boolean isTransient) {
final List<Node> nodes = new ArrayList<>();
for (FlagData flagData : definition.getFlagData()) {
for (Context context : contexts) {
Set<Context> permissionContexts = new HashSet<>(flagData.getContexts());
permissionContexts.add(context);
// If no server context exists, add global
this.checkServerContext(permissionContexts);
ImmutableContextSet set = this.getLPContexts(permissionContexts).immutableCopy();
final Node node = this.luckPermsApi.getNodeBuilderRegistry().forPermission().permission(flagData.getFlag().getPermission()).value(value.asBoolean()).context(set).build();
nodes.add(node);
}
}
return this.createPermissionFuture(GriefDefenderPlugin.GD_DEFINITION_HOLDER, nodes, value, isTransient);
}
public CompletableFuture<PermissionResult> setTransientOption(GDPermissionHolder holder, String key, String value, Set<Context> contexts) {
// If no server context exists, add global
this.checkServerContext(contexts);
MutableContextSet contextSet = this.getLPContexts(contexts);
if (holder == GriefDefenderPlugin.DEFAULT_HOLDER) {
holder = GriefDefenderPlugin.GD_OPTION_HOLDER;
}
Node node = null;
if (value == null) {
node = this.luckPermsApi.getNodeBuilderRegistry().forMeta().key(permission).context(contextSet).build();
node = MetaNode.builder().key(key).context(contextSet).build();
} else {
node = this.luckPermsApi.getNodeBuilderRegistry().forMeta().key(permission).value(value).context(contextSet).build();
}
final Node permissionNode = node;
if (holder instanceof GDPermissionGroup) {
return this.luckPermsApi.getGroupManager().loadGroup(holder.getFriendlyName()).thenApplyAsync((Function<? super Optional<Group>, ? extends PermissionResult>) lpHolder -> {
final Group group = lpHolder.orElse(null);
if (group != null) {
return this.applyTransientOptionNode(holder, group, permissionNode, value);
}
return new GDPermissionResult(ResultTypes.FAILURE, TextComponent.builder().append("COULD NOT LOAD GROUP " + holder.getFriendlyName()).build());
});
} else {
return this.luckPermsApi.getUserManager().loadUser(((GDPermissionUser) holder).getUniqueId()).thenApplyAsync((Function<? super User, ? extends PermissionResult>) lpHolder -> {
return this.applyTransientOptionNode(holder, lpHolder, permissionNode, value);
});
node = MetaNode.builder().key(key).value(value).context(contextSet).build();
}
return this.createOptionFuture(holder, node, key, value, true);
}
public CompletableFuture<PermissionResult> setTransientPermission(GDPermissionHolder holder, String permission, Tristate value, Set<Context> contexts) {
// If no server context exists, add global
this.checkServerContext(contexts);
MutableContextSet contextSet = this.getLPContexts(contexts);
if (holder == GriefDefenderPlugin.DEFAULT_HOLDER) {
holder = GriefDefenderPlugin.GD_OPTION_HOLDER;
}
final Node node = this.luckPermsApi.getNodeBuilderRegistry().forPermission().permission(permission).value(value.asBoolean()).context(contextSet).build();
return this.createPermissionFuture(PermissionUtil.getInstance().getGDPermissionHolder(holder, contexts), Arrays.asList(node), value, true);
}
private CompletableFuture<PermissionResult> createOptionFuture(GDPermissionHolder holder, Node node, String key, String value, boolean isTransient) {
if (holder instanceof GDPermissionGroup) {
return this.luckPermsApi.getGroupManager().loadGroup(holder.getFriendlyName()).thenApplyAsync((Function<? super Optional<Group>, ? extends PermissionResult>) lpHolder -> {
final Group group = lpHolder.orElse(null);
return CompletableFuture.supplyAsync(() -> {
Group group = null;
try {
group = this.luckPermsApi.getGroupManager().loadGroup(holder.getFriendlyName()).get().orElse(null);
} catch (Throwable t) {
t.printStackTrace();
}
if (group != null) {
return this.applyTransientPermissionNode(holder, group, node, value);
if (isTransient) {
return this.applyTransientOptionNode(holder, group, node, value);
}
return this.applyOptionNode(holder, group, node, key, value);
}
return new GDPermissionResult(ResultTypes.FAILURE, TextComponent.builder().append("COULD NOT LOAD GROUP " + holder.getFriendlyName()).build());
});
}, GriefDefenderPlugin.getInstance().executor);
} else {
return this.luckPermsApi.getUserManager().loadUser(((GDPermissionUser) holder).getUniqueId()).thenApplyAsync((Function<? super User, ? extends PermissionResult>) lpHolder -> {
return this.applyTransientPermissionNode(holder, lpHolder, node, value);
});
return CompletableFuture.supplyAsync(() -> {
User user = null;
try {
user = this.luckPermsApi.getUserManager().loadUser(((GDPermissionUser) holder).getUniqueId()).get();
} catch (Throwable t) {
t.printStackTrace();
}
if (user != null) {
if (isTransient) {
return this.applyTransientOptionNode(holder, user, node, value);
}
return this.applyOptionNode(holder, user, node, key, value);
}
return new GDPermissionResult(ResultTypes.FAILURE, TextComponent.builder().append("COULD NOT LOAD USER " + holder.getFriendlyName()).build());
}, GriefDefenderPlugin.getInstance().executor);
}
}
public PermissionResult applyOptionNode(GDPermissionHolder holder, PermissionHolder lpHolder, Node node, Option option, String value) {
private CompletableFuture<PermissionResult> createPermissionFuture(GDPermissionHolder holder, List<Node> nodes, Tristate value, boolean isTransient) {
if (holder instanceof GDPermissionGroup) {
return CompletableFuture.supplyAsync(() -> {
Group group = null;
try {
group = this.luckPermsApi.getGroupManager().loadGroup(holder.getFriendlyName()).get().orElse(null);
} catch (Throwable t) {
t.printStackTrace();
}
if (group != null) {
if (isTransient) {
return this.applyTransientPermissionNodes(holder, group, nodes, value);
}
return this.applyPermissionNodes(holder, group, nodes, value, true);
}
return new GDPermissionResult(ResultTypes.FAILURE, TextComponent.builder().append("COULD NOT LOAD GROUP " + holder.getFriendlyName()).build());
}, GriefDefenderPlugin.getInstance().executor);
} else {
return CompletableFuture.supplyAsync(() -> {
User user = null;
try {
user = this.luckPermsApi.getUserManager().loadUser(((GDPermissionUser) holder).getUniqueId()).get();
} catch (Throwable t) {
t.printStackTrace();
}
if (user != null) {
if (isTransient) {
return this.applyTransientPermissionNodes(holder, user, nodes, value);
}
return this.applyPermissionNodes(holder, user, nodes, value, true);
}
return new GDPermissionResult(ResultTypes.FAILURE, TextComponent.builder().append("COULD NOT LOAD USER " + holder.getFriendlyName()).build());
}, GriefDefenderPlugin.getInstance().executor);
}
}
public PermissionResult applyOptionNode(GDPermissionHolder holder, PermissionHolder lpHolder, Node node, String key, String value) {
final Option option = OptionRegistryModule.getInstance().getById(key).orElse(null);
if (option == null) {
new GDPermissionResult(ResultTypes.FAILURE);
}
DataMutateResult result = null;
if (!value.equalsIgnoreCase("undefined")) {
if (!option.multiValued()) {
@ -782,6 +933,7 @@ public PermissionResult applyOptionNode(GDPermissionHolder holder, PermissionHol
this.savePermissionHolder(lpHolder);
return new GDPermissionResult(ResultTypes.SUCCESS, TextComponent.builder().append(result.name()).build());
}
return new GDPermissionResult(ResultTypes.FAILURE, TextComponent.builder().append(result.name()).build());
}
@ -806,23 +958,17 @@ public PermissionResult applyTransientOptionNode(GDPermissionHolder holder, Perm
return new GDPermissionResult(ResultTypes.FAILURE);
}
public PermissionResult applyPermissionNode(GDPermissionHolder holder, PermissionHolder lpHolder, Node node, Tristate value, boolean save) {
public PermissionResult applyPermissionNodes(GDPermissionHolder holder, PermissionHolder lpHolder, List<Node> nodes, Tristate value, boolean save) {
DataMutateResult result = null;
if (value == Tristate.UNDEFINED) {
result = lpHolder.data().remove(node);
} else {
result = lpHolder.data().add(node);
for (Node node : nodes) {
if (value == Tristate.UNDEFINED) {
result = lpHolder.data().remove(node);
} else {
result = lpHolder.data().add(node);
}
}
if (result.wasSuccessful()) {
if (holder instanceof Group) {
// If a group is changed, we invalidate all cache
PermissionHolderCache.getInstance().invalidateAllPermissionCache();
} else {
// We need to invalidate cache outside of LP listener so we can guarantee proper result returns
PermissionHolderCache.getInstance().getOrCreatePermissionCache(holder).invalidateAll();
}
if (save) {
this.savePermissionHolder(lpHolder);
}
@ -833,12 +979,14 @@ public PermissionResult applyPermissionNode(GDPermissionHolder holder, Permissio
return new GDPermissionResult(ResultTypes.FAILURE, TextComponent.builder().append(result.name()).build());
}
public PermissionResult applyTransientPermissionNode(GDPermissionHolder holder, PermissionHolder lpHolder, Node node, Tristate value) {
public PermissionResult applyTransientPermissionNodes(GDPermissionHolder holder, PermissionHolder lpHolder, List<Node> nodes, Tristate value) {
DataMutateResult result = null;
if (value == null || value == Tristate.UNDEFINED) {
result = lpHolder.transientData().remove(node);
} else {
result = lpHolder.transientData().add(node);
for (Node node : nodes) {
if (value == null || value == Tristate.UNDEFINED) {
result = lpHolder.transientData().remove(node);
} else {
result = lpHolder.transientData().add(node);
}
}
if (result.wasSuccessful()) {
@ -848,10 +996,23 @@ public PermissionResult applyTransientPermissionNode(GDPermissionHolder holder,
}
public void savePermissionHolder(PermissionHolder holder) {
// Always wait for completion to avoid save race conditions
if (holder instanceof User) {
this.luckPermsApi.getUserManager().saveUser((User) holder);
try {
this.luckPermsApi.getUserManager().saveUser((User) holder).get();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
} else {
this.luckPermsApi.getGroupManager().saveGroup((Group) holder);
try {
this.luckPermsApi.getGroupManager().saveGroup((Group) holder).get();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
}
}
@ -934,7 +1095,7 @@ private static class DefaultDataQueryOrderFunction implements DataQueryOrderFunc
@Override
public Comparator<DataType> getOrderComparator(Identifier identifier) {
if (identifier.getType() == Identifier.GROUP_TYPE && identifier.getName().equalsIgnoreCase("default")) {
if (identifier.getType() == Identifier.GROUP_TYPE && (identifier.getName().equalsIgnoreCase(GriefDefenderPlugin.DEFAULT_GROUP_NAME) || identifier.getName().startsWith("griefdefender_"))) {
return DataQueryOrder.TRANSIENT_LAST;
}
@ -946,7 +1107,7 @@ private static class DefaultTransientOnlyDataFilter implements DataTypeFilterFun
@Override
public @NonNull Predicate<DataType> getTypeFilter(@NonNull Identifier identifier) {
if (identifier.getType() == Identifier.GROUP_TYPE && identifier.getName().equalsIgnoreCase("default")) {
if (identifier.getType() == Identifier.GROUP_TYPE && (identifier.getName().equalsIgnoreCase(GriefDefenderPlugin.DEFAULT_GROUP_NAME) || identifier.getName().startsWith("griefdefender_"))) {
return DataTypeFilter.TRANSIENT_ONLY;
}
return DataTypeFilter.ALL;
@ -958,7 +1119,7 @@ private static class DefaultPersistentOnlyDataFilter implements DataTypeFilterFu
@Override
public @NonNull Predicate<DataType> getTypeFilter(@NonNull Identifier identifier) {
if (identifier.getType() == Identifier.GROUP_TYPE && identifier.getName().equalsIgnoreCase("default")) {
if (identifier.getType() == Identifier.GROUP_TYPE && (identifier.getName().equalsIgnoreCase(GriefDefenderPlugin.DEFAULT_GROUP_NAME) || identifier.getName().startsWith("griefdefender_"))) {
return DataTypeFilter.NORMAL_ONLY;
}
return DataTypeFilter.ALL;
@ -969,7 +1130,7 @@ private static class UserPersistentOnlyDataFilter implements DataTypeFilterFunct
@Override
public @NonNull Predicate<DataType> getTypeFilter(@NonNull Identifier identifier) {
if (identifier.getType() == Identifier.GROUP_TYPE && identifier.getName().equalsIgnoreCase("default")) {
if (identifier.getType() == Identifier.GROUP_TYPE && (identifier.getName().equalsIgnoreCase(GriefDefenderPlugin.DEFAULT_GROUP_NAME) || identifier.getName().startsWith("griefdefender_"))) {
return DataTypeFilter.NONE;
}
return DataTypeFilter.NORMAL_ONLY;

View File

@ -38,6 +38,7 @@
import com.griefdefender.api.permission.Context;
import com.griefdefender.api.permission.PermissionResult;
import com.griefdefender.api.permission.flag.Flag;
import com.griefdefender.api.permission.flag.FlagDefinition;
import com.griefdefender.api.permission.option.Option;
import com.griefdefender.claim.GDClaim;
import com.griefdefender.permission.GDPermissionHolder;
@ -72,6 +73,14 @@ public enum PermissionDataType {
*/
boolean hasGroupSubject(String identifier);
/**
* Creates the default group used by GriefDefender.
*
* @param identifier
* @return whether the group was created
*/
boolean createDefaultGroup(String identifier);
/**
* Performs a lookup for a UUID with matching
* username.
@ -167,6 +176,13 @@ public enum PermissionDataType {
*/
Map<String, String> getOptions(GDPermissionHolder holder, Set<Context> contexts);
/**
* Gets all persisted permissions.
*
* @return An immutable map of persisted permissions or empty if none.
*/
Map<Set<Context>, Map<String, Boolean>> getAllPermanentPermissions();
/**
* Gets all persisted permissions with associated contexts of holder.
*
@ -287,6 +303,18 @@ public enum PermissionDataType {
*/
List<String> getOptionValueList(GDPermissionHolder holder, Option option, Set<Context> contexts);
/**
* Sets a flag definition with contexts to a holder.
*
* @param holder The holder
* @param definition The flag definition
* @param value The value
* @param contexts The contexts
* @param isTransient Whether the definition should be applied as transient
* @return Whether the set flag definition operation was successful
*/
CompletableFuture<PermissionResult> setFlagDefinition(GDPermissionHolder holder, FlagDefinition definition, Tristate value, Set<Context> contexts, boolean isTransient);
/**
* Sets an option and value with contexts to a holder.
*

View File

@ -0,0 +1,95 @@
/*
* 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.provider;
import java.util.Set;
import org.bukkit.block.Block;
import org.bukkit.inventory.ItemStack;
import com.griefdefender.api.permission.Context;
import com.griefdefender.internal.util.NMSUtil;
public class SlimefunProvider {
private static final String SLIME_COMPOUND_KEY = "PublicBukkitValues";
private static final String SLIME_BLOCK_KEY = "slimefun:slimefun_block";
private static final String SLIME_ITEM_KEY = "slimefun:slimefun_item";
public SlimefunProvider() {
}
public String getSlimeItemId(ItemStack stack) {
return this.getSlimeItemId(stack, null);
}
public String getSlimeItemId(ItemStack stack, Set<Context> contexts) {
// check item
String customItemId = NMSUtil.getInstance().getItemStackNBTString(stack, SLIME_COMPOUND_KEY, SLIME_ITEM_KEY);
if (customItemId != null && !customItemId.isEmpty()) {
String level = null;
if (contexts != null && customItemId.length() > 2 && customItemId.matches("^.*\\_\\d$")) {
level = customItemId.substring(customItemId.length() - 1, customItemId.length());
customItemId = customItemId.substring(0, customItemId.length() - 2);
if (contexts != null) {
contexts.add(new Context("slimefun_level", level));
}
}
return "slimefun:" + customItemId.toLowerCase();
}
// check block
String customItemBlockId = NMSUtil.getInstance().getItemStackNBTString(stack, SLIME_COMPOUND_KEY, SLIME_BLOCK_KEY);
if (customItemBlockId != null && !customItemBlockId.isEmpty()) {
String level = null;
if (contexts != null && customItemBlockId.length() > 2 && customItemBlockId.matches("^.*\\_\\d$")) {
level = customItemBlockId.substring(customItemBlockId.length() - 1, customItemBlockId.length());
customItemBlockId = customItemBlockId.substring(0, customItemBlockId.length() - 2);
contexts.add(new Context("slimefun_level", level));
}
return "slimefun:" + customItemBlockId.toLowerCase();
}
return "";
}
public String getSlimeBlockId(Block block) {
return this.getSlimeBlockId(block, null);
}
public String getSlimeBlockId(Block block, Set<Context> contexts) {
String customItemBlockId = NMSUtil.getInstance().getTileEntityNBTString(block, "PublicBukkitValues", "slimefun:slimefun_block");
if (customItemBlockId != null && !customItemBlockId.isEmpty()) {
String level = null;
if (contexts != null && customItemBlockId.length() > 2 && customItemBlockId.matches("^.*\\_\\d$")) {
level = customItemBlockId.substring(customItemBlockId.length() - 1, customItemBlockId.length());
customItemBlockId = customItemBlockId.substring(0, customItemBlockId.length() - 2);
contexts.add(new Context("slimefun_level", level));
}
return "slimefun:" + customItemBlockId.toLowerCase();
}
return "";
}
}

View File

@ -21,6 +21,7 @@
import com.griefdefender.api.permission.PermissionResult;
import com.griefdefender.api.permission.ResultTypes;
import com.griefdefender.api.permission.flag.Flag;
import com.griefdefender.api.permission.flag.FlagDefinition;
import com.griefdefender.api.permission.option.Option;
import com.griefdefender.claim.GDClaim;
import com.griefdefender.internal.registry.BlockTypeRegistryModule;
@ -220,6 +221,14 @@ private boolean pValIntegerToBool(@Nullable Integer value) {
// - Implement API
@Override
public boolean createDefaultGroup(String identifier) {
if (!this.hasGroupSubject(identifier)) {
pex.createSubjectIdentifier(PermissionsEx.SUBJECTS_GROUP, identifier);
}
return true;
}
@Override
public String getServerName() {
return pex.getConfig().getServerTags().get(0);
@ -315,6 +324,12 @@ public Map<String, String> getOptions(GDPermissionHolder holder, Set<Context> co
return holderToPEXSubject(holder).getOptions(contextsGDToPEX(contexts));
}
@Override
public Map<Set<Context>, Map<String, Boolean>> getAllPermanentPermissions() {
// TODO
return new HashMap<>();
}
@Override
public Map<Set<Context>, Map<String, Boolean>> getPermanentPermissions(GDPermissionHolder holder) {
return tKeys(holderToPEXSubject(holder).data().get().getAllPermissions(), map -> Maps.transformValues(map, this::pValIntegerToBool));
@ -426,5 +441,11 @@ public CompletableFuture<Void> save(GDPermissionHolder holder) {
// TODO
return new CompletableFuture<>();
}
@Override
public CompletableFuture<PermissionResult> setFlagDefinition(GDPermissionHolder holder, FlagDefinition definition, Tristate value, Set<Context> contexts, boolean isTransient) {
// TODO
return new CompletableFuture<>();
}
}

View File

@ -44,7 +44,6 @@
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
@ -87,6 +86,7 @@ public void registerDefaults() {
FlagData.Builder flagDataBuilder = GriefDefender.getRegistry().createBuilder(FlagData.Builder.class);
// ADMIN
flagContexts.add(FlagContexts.TARGET_TYPE_AMBIENT);
this.registerCustomType(
definitionBuilder
.reset()
@ -99,10 +99,12 @@ public void registerDefaults() {
.flagData(flagDataBuilder
.reset()
.flag(Flags.ENTITY_SPAWN)
.context(FlagContexts.TARGET_TYPE_AMBIENT)
.contexts(flagContexts)
.build())
.build());
flagContexts = new HashSet<>();
flagContexts.add(FlagContexts.TARGET_TYPE_ANIMAL);
this.registerCustomType(
definitionBuilder
.reset()
@ -115,10 +117,12 @@ public void registerDefaults() {
.flagData(flagDataBuilder
.reset()
.flag(Flags.ENTITY_SPAWN)
.context(FlagContexts.TARGET_TYPE_ANIMAL)
.contexts(flagContexts)
.build())
.build());
flagContexts = new HashSet<>();
flagContexts.add(FlagContexts.TARGET_TYPE_AQUATIC);
this.registerCustomType(
definitionBuilder
.reset()
@ -131,7 +135,7 @@ public void registerDefaults() {
.flagData(flagDataBuilder
.reset()
.flag(Flags.ENTITY_SPAWN)
.context(FlagContexts.TARGET_TYPE_AQUATIC)
.contexts(flagContexts)
.build())
.build());
@ -169,6 +173,9 @@ public void registerDefaults() {
.flagData(flagData)
.build());
flagContexts = new HashSet<>();
flagContexts.add(FlagContexts.SOURCE_PLAYER);
flagContexts.add(FlagContexts.TARGET_CHORUS_FRUIT);
this.registerCustomType(
definitionBuilder
.reset()
@ -181,10 +188,12 @@ public void registerDefaults() {
.flagData(flagDataBuilder
.reset()
.flag(Flags.INTERACT_ITEM_SECONDARY)
.context(FlagContexts.TARGET_CHORUS_FRUIT)
.contexts(flagContexts)
.build())
.build());
flagContexts = new HashSet<>();
flagContexts.add(FlagContexts.SOURCE_CREEPER);
this.registerCustomType(
definitionBuilder
.reset()
@ -197,10 +206,12 @@ public void registerDefaults() {
.flagData(flagDataBuilder
.reset()
.flag(Flags.EXPLOSION_BLOCK)
.context(FlagContexts.SOURCE_CREEPER)
.contexts(flagContexts)
.build())
.build());
flagContexts = new HashSet<>();
flagContexts.add(FlagContexts.SOURCE_CREEPER);
this.registerCustomType(
definitionBuilder
.reset()
@ -213,11 +224,19 @@ public void registerDefaults() {
.flagData(flagDataBuilder
.reset()
.flag(Flags.EXPLOSION_ENTITY)
.context(FlagContexts.SOURCE_CREEPER)
.contexts(flagContexts)
.build())
.build());
flagContexts = new HashSet<>();
flagContexts.add(FlagContexts.SOURCE_ARROW);
flagContexts.add(FlagContexts.TARGET_END_CRYSTAL);
flagData.add(flagDataBuilder
.reset()
.flag(Flags.PROJECTILE_IMPACT_ENTITY)
.contexts(flagContexts)
.build());
flagContexts = new HashSet<>();
flagContexts.add(FlagContexts.SOURCE_PLAYER);
flagContexts.add(FlagContexts.TARGET_END_CRYSTAL);
flagData = new ArrayList<>();
@ -301,6 +320,8 @@ public void registerDefaults() {
.flagData(flagData)
.build());
flagContexts = new HashSet<>();
flagContexts.add(FlagContexts.TARGET_XP_ORB);
this.registerCustomType(
definitionBuilder
.reset()
@ -313,10 +334,12 @@ public void registerDefaults() {
.flagData(flagDataBuilder
.reset()
.flag(Flags.ENTITY_SPAWN)
.context(FlagContexts.TARGET_XP_ORB)
.contexts(flagContexts)
.build())
.build());
flagContexts = new HashSet<>();
flagContexts.add(FlagContexts.SOURCE_FALL);
this.registerCustomType(
definitionBuilder
.reset()
@ -329,7 +352,7 @@ public void registerDefaults() {
.flagData(flagDataBuilder
.reset()
.flag(Flags.ENTITY_DAMAGE)
.context(FlagContexts.SOURCE_FALL)
.contexts(flagContexts)
.build())
.build());
@ -352,6 +375,8 @@ public void registerDefaults() {
.build())
.build());
flagContexts = new HashSet<>();
flagContexts.add(FlagContexts.SOURCE_FALL);
this.registerCustomType(
definitionBuilder
.reset()
@ -364,10 +389,12 @@ public void registerDefaults() {
.flagData(flagDataBuilder
.reset()
.flag(Flags.BLOCK_BREAK)
.context(FlagContexts.SOURCE_FALLING_BLOCK)
.contexts(flagContexts)
.build())
.build());
flagContexts = new HashSet<>();
flagContexts.add(FlagContexts.SOURCE_FIRE);
this.registerCustomType(
definitionBuilder
.reset()
@ -380,37 +407,47 @@ public void registerDefaults() {
.flagData(flagDataBuilder
.reset()
.flag(Flags.BLOCK_BREAK)
.context(FlagContexts.SOURCE_FIRE)
.contexts(flagContexts)
.build())
.build());
flagData = new ArrayList<>();
flagContexts = new HashSet<>();
flagContexts.add(FlagContexts.SOURCE_FIRE);
flagData.add(flagDataBuilder
.reset()
.flag(Flags.ENTITY_DAMAGE)
.context(FlagContexts.SOURCE_FIRE)
.contexts(flagContexts)
.build());
flagContexts = new HashSet<>();
flagContexts.add(FlagContexts.SOURCE_FIRE_TICK);
flagData.add(flagDataBuilder
.reset()
.flag(Flags.ENTITY_DAMAGE)
.context(FlagContexts.SOURCE_FIRE_TICK)
.contexts(flagContexts)
.build());
flagContexts = new HashSet<>();
flagContexts.add(FlagContexts.SOURCE_MAGMA_BLOCK);
flagData.add(flagDataBuilder
.reset()
.flag(Flags.ENTITY_DAMAGE)
.context(FlagContexts.SOURCE_MAGMA_BLOCK)
.contexts(flagContexts)
.build());
if (GriefDefenderPlugin.getMajorMinecraftVersion() > 12) {
flagContexts = new HashSet<>();
flagContexts.add(FlagContexts.SOURCE_LAVA);
flagData.add(flagDataBuilder
.reset()
.flag(Flags.ENTITY_DAMAGE)
.context(FlagContexts.SOURCE_LAVA)
.contexts(flagContexts)
.build());
} else {
flagContexts = new HashSet<>();
flagContexts.add(FlagContexts.SOURCE_LAVA_1_12);
flagData.add(flagDataBuilder
.reset()
.flag(Flags.ENTITY_DAMAGE)
.context(FlagContexts.SOURCE_LAVA_1_12)
.contexts(flagContexts)
.build());
}
this.registerCustomType(
@ -425,6 +462,8 @@ public void registerDefaults() {
.flagData(flagData)
.build());
flagContexts = new HashSet<>();
flagContexts.add(FlagContexts.SOURCE_LIGHTNING_BOLT);
this.registerCustomType(
definitionBuilder
.reset()
@ -437,7 +476,7 @@ public void registerDefaults() {
.flagData(flagDataBuilder
.reset()
.flag(Flags.ENTITY_DAMAGE)
.context(FlagContexts.SOURCE_LIGHTNING_BOLT)
.contexts(flagContexts)
.build())
.build());
@ -445,6 +484,14 @@ public void registerDefaults() {
flagContexts.add(FlagContexts.SOURCE_TYPE_MONSTER);
flagContexts.add(FlagContexts.TARGET_TYPE_ANIMAL);
flagData = new ArrayList<>();
flagData.add(flagDataBuilder
.reset()
.flag(Flags.ENTITY_DAMAGE)
.contexts(flagContexts)
.build());
flagContexts = new HashSet<>();
flagContexts.add(FlagContexts.SOURCE_TYPE_MONSTER);
flagContexts.add(FlagContexts.TARGET_TYPE_AQUATIC);
flagData.add(flagDataBuilder
.reset()
.flag(Flags.ENTITY_DAMAGE)
@ -493,6 +540,8 @@ public void registerDefaults() {
.flagData(flagData)
.build());
flagContexts = new HashSet<>();
flagContexts.add(FlagContexts.TARGET_TYPE_MONSTER);
this.registerCustomType(
definitionBuilder
.reset()
@ -505,20 +554,24 @@ public void registerDefaults() {
.flagData(flagDataBuilder
.reset()
.flag(Flags.ENTITY_SPAWN)
.context(FlagContexts.TARGET_TYPE_MONSTER)
.contexts(flagContexts)
.build())
.build());
flagData = new ArrayList<>();
flagContexts = new HashSet<>();
flagContexts.add(FlagContexts.SOURCE_PISTON);
flagData.add(flagDataBuilder
.reset()
.flag(Flags.ITEM_SPAWN)
.context(FlagContexts.SOURCE_PISTON)
.contexts(flagContexts)
.build());
flagContexts = new HashSet<>();
flagContexts.add(FlagContexts.SOURCE_PISTON_STICKY);
flagData.add(flagDataBuilder
.reset()
.flag(Flags.ITEM_SPAWN)
.context(FlagContexts.SOURCE_PISTON_STICKY)
.contexts(flagContexts)
.build());
this.registerCustomType(
definitionBuilder
@ -533,25 +586,29 @@ public void registerDefaults() {
.build());
flagData = new ArrayList<>();
flagContexts = new HashSet<>();
flagContexts.add(FlagContexts.SOURCE_PISTON);
flagData.add(flagDataBuilder
.reset()
.flag(Flags.BLOCK_BREAK)
.context(FlagContexts.SOURCE_PISTON)
.contexts(flagContexts)
.build());
flagData.add(flagDataBuilder
.reset()
.flag(Flags.BLOCK_PLACE)
.context(FlagContexts.SOURCE_PISTON)
.contexts(flagContexts)
.build());
flagContexts = new HashSet<>();
flagContexts.add(FlagContexts.SOURCE_PISTON_STICKY);
flagData.add(flagDataBuilder
.reset()
.flag(Flags.BLOCK_BREAK)
.context(FlagContexts.SOURCE_PISTON_STICKY)
.contexts(flagContexts)
.build());
flagData.add(flagDataBuilder
.reset()
.flag(Flags.BLOCK_PLACE)
.context(FlagContexts.SOURCE_PISTON_STICKY)
.contexts(flagContexts)
.build());
this.registerCustomType(
definitionBuilder
@ -565,6 +622,8 @@ public void registerDefaults() {
.flagData(flagData)
.build());
flagContexts = new HashSet<>();
flagContexts.add(FlagContexts.SOURCE_PLAYER);
this.registerCustomType(
definitionBuilder
.reset()
@ -577,10 +636,12 @@ public void registerDefaults() {
.flagData(flagDataBuilder
.reset()
.flag(Flags.BLOCK_BREAK)
.context(FlagContexts.SOURCE_PLAYER)
.contexts(flagContexts)
.build())
.build());
flagContexts = new HashSet<>();
flagContexts.add(FlagContexts.SOURCE_PLAYER);
this.registerCustomType(
definitionBuilder
.reset()
@ -593,10 +654,12 @@ public void registerDefaults() {
.flagData(flagDataBuilder
.reset()
.flag(Flags.INTERACT_BLOCK_SECONDARY)
.context(FlagContexts.SOURCE_PLAYER)
.contexts(flagContexts)
.build())
.build());
flagContexts = new HashSet<>();
flagContexts.add(FlagContexts.SOURCE_PLAYER);
this.registerCustomType(
definitionBuilder
.reset()
@ -609,7 +672,7 @@ public void registerDefaults() {
.flagData(flagDataBuilder
.reset()
.flag(Flags.BLOCK_PLACE)
.context(FlagContexts.SOURCE_PLAYER)
.contexts(flagContexts)
.build())
.build());
@ -657,6 +720,8 @@ public void registerDefaults() {
.build())
.build());
flagContexts = new HashSet<>();
flagContexts.add(FlagContexts.SOURCE_PLAYER);
this.registerCustomType(
definitionBuilder
.reset()
@ -669,10 +734,12 @@ public void registerDefaults() {
.flagData(flagDataBuilder
.reset()
.flag(Flags.ENTER_CLAIM)
.context(FlagContexts.SOURCE_PLAYER)
.contexts(flagContexts)
.build())
.build());
flagContexts = new HashSet<>();
flagContexts.add(FlagContexts.SOURCE_PLAYER);
this.registerCustomType(
definitionBuilder
.reset()
@ -685,10 +752,12 @@ public void registerDefaults() {
.flagData(flagDataBuilder
.reset()
.flag(Flags.INTERACT_ENTITY_SECONDARY)
.context(FlagContexts.SOURCE_PLAYER)
.contexts(flagContexts)
.build())
.build());
flagContexts = new HashSet<>();
flagContexts.add(FlagContexts.SOURCE_PLAYER);
this.registerCustomType(
definitionBuilder
.reset()
@ -701,7 +770,7 @@ public void registerDefaults() {
.flagData(flagDataBuilder
.reset()
.flag(Flags.EXIT_CLAIM)
.context(FlagContexts.SOURCE_PLAYER)
.contexts(flagContexts)
.build())
.build());
@ -743,6 +812,8 @@ public void registerDefaults() {
.build())
.build());
flagContexts = new HashSet<>();
flagContexts.add(FlagContexts.SOURCE_PLAYER);
this.registerCustomType(
definitionBuilder
.reset()
@ -755,10 +826,12 @@ public void registerDefaults() {
.flagData(flagDataBuilder
.reset()
.flag(Flags.ITEM_DROP)
.context(FlagContexts.SOURCE_PLAYER)
.contexts(flagContexts)
.build())
.build());
flagContexts = new HashSet<>();
flagContexts.add(FlagContexts.SOURCE_PLAYER);
this.registerCustomType(
definitionBuilder
.reset()
@ -771,7 +844,7 @@ public void registerDefaults() {
.flagData(flagDataBuilder
.reset()
.flag(Flags.ITEM_PICKUP)
.context(FlagContexts.SOURCE_PLAYER)
.contexts(flagContexts)
.build())
.build());
@ -813,6 +886,8 @@ public void registerDefaults() {
.build())
.build());
flagContexts = new HashSet<>();
flagContexts.add(FlagContexts.TARGET_PLAYER);
this.registerCustomType(
definitionBuilder
.reset()
@ -825,10 +900,12 @@ public void registerDefaults() {
.flagData(flagDataBuilder
.reset()
.flag(Flags.ENTITY_TELEPORT_FROM)
.context(FlagContexts.TARGET_PLAYER)
.contexts(flagContexts)
.build())
.build());
flagContexts = new HashSet<>();
flagContexts.add(FlagContexts.TARGET_PLAYER);
this.registerCustomType(
definitionBuilder
.reset()
@ -841,7 +918,7 @@ public void registerDefaults() {
.flagData(flagDataBuilder
.reset()
.flag(Flags.ENTITY_TELEPORT_TO)
.context(FlagContexts.TARGET_PLAYER)
.contexts(flagContexts)
.build())
.build());
@ -897,6 +974,8 @@ public void registerDefaults() {
.flagData(flagData)
.build());
flagContexts = new HashSet<>();
flagContexts.add(FlagContexts.SOURCE_TNT);
this.registerCustomType(
definitionBuilder
.reset()
@ -909,10 +988,12 @@ public void registerDefaults() {
.flagData(flagDataBuilder
.reset()
.flag(Flags.EXPLOSION_BLOCK)
.context(FlagContexts.SOURCE_TNT)
.contexts(flagContexts)
.build())
.build());
flagContexts = new HashSet<>();
flagContexts.add(FlagContexts.SOURCE_TNT);
this.registerCustomType(
definitionBuilder
.reset()
@ -925,13 +1006,13 @@ public void registerDefaults() {
.flagData(flagDataBuilder
.reset()
.flag(Flags.EXPLOSION_ENTITY)
.context(FlagContexts.SOURCE_TNT)
.contexts(flagContexts)
.build())
.build());
flagContexts = new HashSet<>();
flagContexts.add(FlagContexts.SOURCE_TURTLE_EGG);
flagContexts.add(FlagContexts.TARGET_AIR);
flagContexts.add(FlagContexts.TARGET_TURTLE_EGG);
flagData = new ArrayList<>();
flagData.add(flagDataBuilder
.reset()
@ -971,6 +1052,8 @@ public void registerDefaults() {
.flagData(flagData)
.build());
flagContexts = new HashSet<>();
flagContexts.add(FlagContexts.SOURCE_WITHER);
this.registerCustomType(
definitionBuilder
.reset()
@ -983,10 +1066,12 @@ public void registerDefaults() {
.flagData(flagDataBuilder
.reset()
.flag(Flags.BLOCK_BREAK)
.context(FlagContexts.SOURCE_WITHER)
.contexts(flagContexts)
.build())
.build());
flagContexts = new HashSet<>();
flagContexts.add(FlagContexts.SOURCE_WITHER);
this.registerCustomType(
definitionBuilder
.reset()
@ -999,7 +1084,7 @@ public void registerDefaults() {
.flagData(flagDataBuilder
.reset()
.flag(Flags.ENTITY_DAMAGE)
.context(FlagContexts.SOURCE_WITHER)
.contexts(flagContexts)
.build())
.build());
@ -1073,6 +1158,8 @@ public void registerDefaults() {
.flagData(flagData)
.build());
flagContexts = new HashSet<>();
flagContexts.add(FlagContexts.TARGET_TYPE_CROP);
this.registerCustomType(
definitionBuilder
.reset()
@ -1085,7 +1172,7 @@ public void registerDefaults() {
.flagData(flagDataBuilder
.reset()
.flag(Flags.BLOCK_GROW)
.context(FlagContexts.TARGET_TYPE_CROP)
.contexts(flagContexts)
.build())
.build());
@ -1114,6 +1201,8 @@ public void registerDefaults() {
.flagData(flagData)
.build());
flagContexts = new HashSet<>();
flagContexts.add(FlagContexts.SOURCE_ENDERMAN);
this.registerCustomType(
definitionBuilder
.reset()
@ -1126,23 +1215,31 @@ public void registerDefaults() {
.flagData(flagDataBuilder
.reset()
.flag(Flags.BLOCK_BREAK)
.context(FlagContexts.SOURCE_ENDERMAN)
.contexts(flagContexts)
.build())
.build());
flagContexts = new HashSet<>();
flagContexts.add(FlagContexts.SOURCE_FIRE);
definitionContexts = new HashSet<>();
definitionContexts.add(ClaimContexts.GLOBAL_OVERRIDE_CONTEXT);
definitionContexts.add(OWNER_OVERRIDE_CONTEXT);
//definitionContexts.add(OWNER_OVERRIDE_CONTEXT);
flagData = new ArrayList<>();
flagData.add(flagDataBuilder
.reset()
.flag(Flags.BLOCK_SPREAD)
.context(FlagContexts.SOURCE_FIRE)
.contexts(flagContexts)
.build());
flagContexts = new HashSet<>();
if (GriefDefenderPlugin.getMajorMinecraftVersion() > 12) {
flagContexts.add(FlagContexts.SOURCE_LAVA);
} else {
flagContexts.add(FlagContexts.SOURCE_LAVA_1_12);
}
flagData.add(flagDataBuilder
.reset()
.flag(Flags.BLOCK_SPREAD)
.context(FlagContexts.SOURCE_LAVA)
.contexts(flagContexts)
.build());
this.registerCustomType(
definitionBuilder
@ -1156,6 +1253,8 @@ public void registerDefaults() {
.flagData(flagData)
.build());
flagContexts = new HashSet<>();
flagContexts.add(FlagContexts.TARGET_GRASS);
this.registerCustomType(
definitionBuilder
.reset()
@ -1168,10 +1267,12 @@ public void registerDefaults() {
.flagData(flagDataBuilder
.reset()
.flag(Flags.BLOCK_GROW)
.context(FlagContexts.TARGET_GRASS)
.contexts(flagContexts)
.build())
.build());
flagContexts = new HashSet<>();
flagContexts.add(FlagContexts.TARGET_ICE_FORM);
this.registerCustomType(
definitionBuilder
.reset()
@ -1184,7 +1285,7 @@ public void registerDefaults() {
.flagData(flagDataBuilder
.reset()
.flag(Flags.BLOCK_MODIFY)
.context(FlagContexts.TARGET_ICE_FORM)
.contexts(flagContexts)
.build())
.build());
@ -1247,6 +1348,9 @@ public void registerDefaults() {
.build())
.build());
flagContexts = new HashSet<>();
flagContexts.add(FlagContexts.SOURCE_PLAYER);
flagContexts.add(FlagContexts.TARGET_FLINTANDSTEEL);
this.registerCustomType(
definitionBuilder
.reset()
@ -1259,10 +1363,12 @@ public void registerDefaults() {
.flagData(flagDataBuilder
.reset()
.flag(Flags.INTERACT_ITEM_SECONDARY)
.context(FlagContexts.TARGET_FLINTANDSTEEL)
.contexts(flagContexts)
.build())
.build());
flagContexts = new HashSet<>();
flagContexts.add(FlagContexts.TARGET_TYPE_MUSHROOM);
this.registerCustomType(
definitionBuilder
.reset()
@ -1279,6 +1385,8 @@ public void registerDefaults() {
.build())
.build());
flagContexts = new HashSet<>();
flagContexts.add(FlagContexts.TARGET_MYCELIUM);
this.registerCustomType(
definitionBuilder
.reset()
@ -1380,10 +1488,8 @@ public void registerDefaults() {
flagContexts = new HashSet<>();
if (GriefDefenderPlugin.getMajorMinecraftVersion() > 12) {
flagContexts.add(FlagContexts.SOURCE_SNOW);
flagContexts.add(FlagContexts.TARGET_AIR);
} else {
flagContexts.add(FlagContexts.SOURCE_SNOW_1_12);
flagContexts.add(FlagContexts.TARGET_AIR);
}
this.registerCustomType(
definitionBuilder
@ -1425,6 +1531,9 @@ public void registerDefaults() {
.build())
.build());
flagContexts = new HashSet<>();
flagContexts.add(FlagContexts.SOURCE_FARMLAND);
flagContexts.add(FlagContexts.STATE_FARMLAND_DRY);
this.registerCustomType(
definitionBuilder
.reset()
@ -1437,7 +1546,7 @@ public void registerDefaults() {
.flagData(flagDataBuilder
.reset()
.flag(Flags.BLOCK_MODIFY)
.context(FlagContexts.STATE_FARMLAND_DRY)
.contexts(flagContexts)
.build())
.build());
@ -1500,6 +1609,9 @@ public void registerDefaults() {
.flagData(flagData)
.build());
flagContexts = new HashSet<>();
flagContexts.add(FlagContexts.SOURCE_PLAYER);
flagContexts.add(FlagContexts.TARGET_VILLAGER);
this.registerCustomType(
definitionBuilder
.reset()

View File

@ -57,6 +57,7 @@
import com.griefdefender.event.GDRemoveClaimEvent.Delete;
import com.griefdefender.internal.util.VecHelper;
import com.griefdefender.migrator.PlayerDataMigrator;
import com.griefdefender.permission.ContextGroups;
import com.griefdefender.permission.GDPermissionUser;
import com.griefdefender.permission.flag.FlagContexts;
import com.griefdefender.permission.option.GDOption;
@ -393,7 +394,7 @@ public void setDefaultGlobalPermissions() {
contexts.add(ClaimContexts.GLOBAL_DEFAULT_CONTEXT);
final Map<String, String> globalDefaultOptions = optionConfig.getConfig().defaultOptionCategory.getUserOptionDefaults();
this.setDefaultOptions(contexts, new HashMap<>(globalDefaultOptions));
GriefDefenderPlugin.getInstance().getPermissionProvider().setTransientPermission(GriefDefenderPlugin.DEFAULT_HOLDER, "griefdefender", Tristate.FALSE, new HashSet<>());
GriefDefenderPlugin.getInstance().getPermissionProvider().setTransientPermission(GriefDefenderPlugin.GD_DEFAULT_HOLDER, "griefdefender", Tristate.FALSE, new HashSet<>());
flagConfig.save();
optionConfig.save();
}
@ -409,9 +410,9 @@ private void setDefaultFlags(Set<Context> contexts, Map<String, Boolean> default
if (flag == null) {
continue;
}
PermissionUtil.getInstance().setTransientPermission(GriefDefenderPlugin.DEFAULT_HOLDER, flag.getPermission(), Tristate.fromBoolean(mapEntry.getValue()), contexts);
PermissionUtil.getInstance().setTransientPermission(GriefDefenderPlugin.GD_DEFAULT_HOLDER, flag.getPermission(), Tristate.fromBoolean(mapEntry.getValue()), contexts);
}
PermissionUtil.getInstance().refreshCachedData(GriefDefenderPlugin.DEFAULT_HOLDER);
PermissionUtil.getInstance().refreshCachedData(GriefDefenderPlugin.GD_DEFAULT_HOLDER);
});
}
@ -441,9 +442,9 @@ private void setDefaultOptions(Set<Context> contexts, Map<String, String> defaul
continue;
}
}
PermissionUtil.getInstance().setTransientOption(GriefDefenderPlugin.DEFAULT_HOLDER, option.getPermission(), optionEntry.getValue(), contexts);
PermissionUtil.getInstance().setTransientOption(GriefDefenderPlugin.GD_OPTION_HOLDER, option.getPermission(), optionEntry.getValue(), contexts);
}
PermissionUtil.getInstance().refreshCachedData(GriefDefenderPlugin.DEFAULT_HOLDER);
PermissionUtil.getInstance().refreshCachedData(GriefDefenderPlugin.GD_OPTION_HOLDER);
});
}

View File

@ -150,80 +150,88 @@ private void handleClaimRent(GDClaim claim, GDPermissionUser renter) {
}
}
final Player player = renter.getOnlinePlayer();
final EconomyResponse response = EconomyUtil.getInstance().withdrawFunds(renter.getOfflinePlayer(), totalrentOwed);
if (!response.transactionSuccess()) {
Instant rentPastDue = claim.getEconomyData().getRentPastDueDate();
if (rentPastDue == null) {
claim.getEconomyData().setRentPastDueDate(localNow);
rentPastDue = localNow;
}
final Duration pastDueDuration = Duration.between(rentPastDue, localNow);
final int rentExpirationDays = GDPermissionManager.getInstance().getInternalOptionValue(TypeToken.of(Integer.class), ownerPlayerData.getSubject(), Options.RENT_EXPIRATION, claim).intValue();
final int expireDaysToKeep = GDPermissionManager.getInstance().getInternalOptionValue(TypeToken.of(Integer.class), ownerPlayerData.getSubject(), Options.RENT_EXPIRATION_DAYS_KEEP, claim).intValue();
if (pastDueDuration.toDays() > rentExpirationDays) {
claim.getInternalClaimData().setExpired(false);
final int keepDays = (int) (expireDaysToKeep - pastDueDuration.toDays());
if (player != null) {
final Component message = GriefDefenderPlugin.getInstance().messageData.getMessage(MessageStorage.ECONOMY_CLAIM_RENTED_EXPIRED, ImmutableMap.of(
"balance", totalrentOwed,
"time", keepDays
));
GriefDefenderPlugin.sendMessage(player, message);
if (totalrentOwed > 0) {
final EconomyResponse response = EconomyUtil.getInstance().withdrawFunds(renter.getOfflinePlayer(), totalrentOwed);
if (!response.transactionSuccess()) {
Instant rentPastDue = claim.getEconomyData().getRentPastDueDate();
if (rentPastDue == null) {
claim.getEconomyData().setRentPastDueDate(localNow);
rentPastDue = localNow;
}
claim.getData().save();
if (rentRestore && rentPastDue.plus(Duration.ofDays(rentExpirationDays + expireDaysToKeep)).isBefore(localNow)) {
// expiration days keep is up
// restore schematic and remove renter rights
final ClaimSchematic schematic = claim.getSchematics().get("__rent__");
if (schematic != null) {
if (schematic.apply()) {
if (ownerPlayerData.getSubject().getOnlinePlayer() != null) {
ownerPlayerData.getSubject().getOnlinePlayer().sendMessage("Claim '" + claim.getFriendlyName() + "' has been restored.");
final Duration pastDueDuration = Duration.between(rentPastDue, localNow);
final int rentExpirationDays = GDPermissionManager.getInstance().getInternalOptionValue(TypeToken.of(Integer.class), ownerPlayerData.getSubject(), Options.RENT_EXPIRATION, claim).intValue();
final int expireDaysToKeep = GDPermissionManager.getInstance().getInternalOptionValue(TypeToken.of(Integer.class), ownerPlayerData.getSubject(), Options.RENT_EXPIRATION_DAYS_KEEP, claim).intValue();
if (pastDueDuration.toDays() > rentExpirationDays) {
claim.getInternalClaimData().setExpired(false);
final int keepDays = (int) (expireDaysToKeep - pastDueDuration.toDays());
if (player != null) {
final Component message = GriefDefenderPlugin.getInstance().messageData.getMessage(MessageStorage.ECONOMY_CLAIM_RENTED_EXPIRED, ImmutableMap.of(
"balance", totalrentOwed,
"time", keepDays
));
GriefDefenderPlugin.sendMessage(player, message);
}
claim.getData().save();
if (rentRestore && rentPastDue.plus(Duration.ofDays(rentExpirationDays + expireDaysToKeep)).isBefore(localNow)) {
// expiration days keep is up
// restore schematic and remove renter rights
final ClaimSchematic schematic = claim.getSchematics().get("__rent__");
if (schematic != null) {
if (schematic.apply()) {
if (ownerPlayerData.getSubject().getOnlinePlayer() != null) {
final Component message = GriefDefenderPlugin.getInstance().messageData.getMessage(MessageStorage.ECONOMY_CLAIM_RENT_END_RESTORE, ImmutableMap.of(
"claim", claim.getFriendlyName()));
GriefDefenderPlugin.sendMessage(ownerPlayerData.getSubject().getOnlinePlayer(), message);
}
// end rent
claim.getEconomyData().setForRent(false);
claim.getEconomyData().getDelinquentRenters().add(renter.getUniqueId());
claim.removeAllTrustsFromUser(renter.getUniqueId());
final Sign rentSign = SignUtil.getSign(claim.getWorld(), claim.getEconomyData().getRentSignPosition());
if (rentSign != null) {
rentSign.getBlock().setType(Material.AIR);
}
SignUtil.resetRentData(claim);
if (player != null) {
GriefDefenderPlugin.sendMessage(player, MessageCache.getInstance().ECONOMY_CLAIM_RENT_CANCELLED);
}
claim.getEconomyData().getRenters().clear();
claim.getData().save();
return;
}
// end rent
claim.getEconomyData().setForRent(false);
claim.getEconomyData().getDelinquentRenters().add(renter.getUniqueId());
claim.removeAllTrustsFromUser(renter.getUniqueId());
final Sign rentSign = SignUtil.getSign(claim.getWorld(), claim.getEconomyData().getRentSignPosition());
if (rentSign != null) {
rentSign.getBlock().setType(Material.AIR);
}
SignUtil.resetRentData(claim);
if (player != null) {
GriefDefenderPlugin.sendMessage(player, MessageCache.getInstance().ECONOMY_CLAIM_RENT_CANCELLED);
}
claim.getEconomyData().getRenters().clear();
claim.getData().save();
return;
}
}
}
}
claim.getEconomyData().setRentBalance(playerData.playerID, totalrentOwed);
claim.getEconomyData().addPaymentTransaction(new GDPaymentTransaction(TransactionType.RENT, TransactionResultType.FAIL, Instant.now(), rentOwed));
if (player != null) {
final Component message = GriefDefenderPlugin.getInstance().messageData.getMessage(MessageStorage.ECONOMY_CLAIM_RENT_PAYMENT_FAILURE, ImmutableMap.of(
"total-funds", this.economy.getBalance(player),
"amount", rentBalance,
"balance", totalrentOwed,
"days-remaining", 5
));
GriefDefenderPlugin.sendMessage(player, message);
claim.getEconomyData().setRentBalance(playerData.playerID, totalrentOwed);
claim.getEconomyData().addPaymentTransaction(new GDPaymentTransaction(TransactionType.RENT, TransactionResultType.FAIL, Instant.now(), rentOwed));
if (player != null) {
final Component message = GriefDefenderPlugin.getInstance().messageData.getMessage(MessageStorage.ECONOMY_CLAIM_RENT_PAYMENT_FAILURE, ImmutableMap.of(
"total-funds", this.economy.getBalance(player),
"amount", rentBalance,
"balance", totalrentOwed,
"days-remaining", 5
));
GriefDefenderPlugin.sendMessage(player, message);
}
} else {
claim.getEconomyData().addPaymentTransaction(new GDPaymentTransaction(TransactionType.RENT, TransactionResultType.SUCCESS, Instant.now(), totalrentOwed));
claim.getEconomyData().setRentPastDueDate(null);
claim.getEconomyData().setRentBalance(playerData.playerID, 0);
claim.getInternalClaimData().setExpired(false);
claim.getData().save();
if (player != null) {
final Component message = GriefDefenderPlugin.getInstance().messageData.getMessage(MessageStorage.ECONOMY_CLAIM_RENT_PAYMENT_SUCCESS, ImmutableMap.of(
"balance", totalrentOwed));
GriefDefenderPlugin.sendMessage(player, message);
}
}
} else {
claim.getEconomyData().addPaymentTransaction(new GDPaymentTransaction(TransactionType.RENT, TransactionResultType.SUCCESS, Instant.now(), totalrentOwed));
claim.getEconomyData().setRentPastDueDate(null);
claim.getEconomyData().setRentBalance(playerData.playerID, 0);
claim.getInternalClaimData().setExpired(false);
claim.getEconomyData().setRentBalance(playerData.playerID, totalrentOwed); // new balance
claim.getData().save();
if (player != null) {
final Component message = GriefDefenderPlugin.getInstance().messageData.getMessage(MessageStorage.ECONOMY_CLAIM_RENT_PAYMENT_SUCCESS, ImmutableMap.of(
"balance", totalrentOwed));
GriefDefenderPlugin.sendMessage(player, message);
}
}
// check max days
@ -247,6 +255,24 @@ private void handleClaimRent(GDClaim claim, GDPermissionUser renter) {
if (renter != null && renter.getOnlinePlayer() != null) {
GriefDefenderPlugin.sendMessage(renter.getOnlinePlayer(), MessageCache.getInstance().ECONOMY_CLAIM_RENT_CANCELLED);
}
if (rentRestore) {
final ClaimSchematic schematic = claim.getSchematics().get("__rent__");
if (schematic != null) {
if (schematic.apply()) {
if (ownerPlayerData.getSubject().getOnlinePlayer() != null) {
final Component message = GriefDefenderPlugin.getInstance().messageData.getMessage(MessageStorage.ECONOMY_CLAIM_RENT_END_RESTORE, ImmutableMap.of(
"claim", claim.getFriendlyName()));
GriefDefenderPlugin.sendMessage(ownerPlayerData.getSubject().getOnlinePlayer(), message);
}
}
}
} else {
if (ownerPlayerData.getSubject().getOnlinePlayer() != null) {
final Component message = GriefDefenderPlugin.getInstance().messageData.getMessage(MessageStorage.ECONOMY_CLAIM_RENT_END, ImmutableMap.of(
"claim", claim.getFriendlyName()));
GriefDefenderPlugin.sendMessage(ownerPlayerData.getSubject().getOnlinePlayer(), message);
}
}
claim.getEconomyData().getRenters().clear();
claim.getData().save();
} else {

View File

@ -441,7 +441,7 @@ public void rentClaimConsumerConfirmation(CommandSender src, Claim claim, Sign s
minTime = TextComponent.builder()
.append(String.valueOf(min))
.append(" ")
.append(claim.getEconomyData().getPaymentType() == PaymentType.DAILY ?
.append(paymentType == PaymentType.DAILY ?
(min > 1 ? MessageCache.getInstance().LABEL_DAYS : MessageCache.getInstance().LABEL_DAY) :
(min > 1 ? MessageCache.getInstance().LABEL_HOURS : MessageCache.getInstance().LABEL_HOUR))
.build();
@ -523,6 +523,11 @@ private Consumer<CommandSender> createRentConsumerConfirmed(CommandSender src, C
}
claim.getEconomyData().addPaymentTransaction(new GDPaymentTransaction(TransactionType.RENT, TransactionResultType.SUCCESS, player.getUniqueId(), Instant.now(), rate));
if (claim.getEconomyData().getRentMinTime() > 0) {
final double minDeposit = rate * claim.getEconomyData().getRentMinTime();
final double currentBalance = claim.getEconomyData().getRentBalance(player.getUniqueId());
claim.getEconomyData().setRentBalance(player.getUniqueId(), currentBalance - minDeposit);
}
if (claim.isAdminClaim()) {
final UUID bankAccount = claim.getEconomyAccountId().orElse(null);
if (bankAccount != null) {

View File

@ -31,12 +31,17 @@
import com.griefdefender.api.claim.Claim;
import com.griefdefender.api.claim.TrustTypes;
import com.griefdefender.api.permission.Context;
import com.griefdefender.api.permission.ContextKeys;
import com.griefdefender.api.permission.PermissionResult;
import com.griefdefender.api.permission.flag.Flag;
import com.griefdefender.api.permission.flag.FlagDefinition;
import com.griefdefender.api.permission.flag.Flags;
import com.griefdefender.api.permission.option.Option;
import com.griefdefender.cache.PermissionHolderCache;
import com.griefdefender.claim.GDClaim;
import com.griefdefender.internal.util.VecHelper;
import com.griefdefender.permission.GDPermissionHolder;
import com.griefdefender.permission.GDPermissionManager;
import com.griefdefender.permission.GDPermissions;
import com.griefdefender.provider.PermissionProvider;
import com.griefdefender.provider.PermissionProvider.PermissionDataType;
@ -144,6 +149,10 @@ public Map<String, String> getOptions(GDPermissionHolder holder, Set<Context> co
return PERMISSION_PROVIDER.getOptions(holder, contexts);
}
public Map<Set<Context>, Map<String, Boolean>> getAllPermanentPermissions() {
return PERMISSION_PROVIDER.getAllPermanentPermissions();
}
public Map<Set<Context>, Map<String, Boolean>> getPermanentPermissions(GDPermissionHolder holder) {
return PERMISSION_PROVIDER.getPermanentPermissions(holder);
}
@ -196,6 +205,10 @@ public List<String> getOptionValueList(GDPermissionHolder holder, Option option,
return PERMISSION_PROVIDER.getOptionValueList(holder, option, contexts);
}
public CompletableFuture<PermissionResult> setFlagDefinition(GDPermissionHolder holder, FlagDefinition definition, Tristate value, Set<Context> contexts, boolean isTransient) {
return PERMISSION_PROVIDER.setFlagDefinition(holder, definition, value, contexts, isTransient);
}
public CompletableFuture<PermissionResult> setOptionValue(GDPermissionHolder holder, String permission, String value, Set<Context> contexts) {
return PERMISSION_PROVIDER.setOptionValue(holder, permission, value, contexts, true);
}
@ -274,27 +287,57 @@ public Tristate getTristateFromString(String value) {
public boolean canPlayerTeleport(Player player, GDClaim claim) {
final GDPlayerData playerData = GriefDefenderPlugin.getInstance().dataStore.getPlayerData(player.getWorld(), player.getUniqueId());
boolean allowTeleport = true;
if (!playerData.canIgnoreClaim(claim) && !playerData.canManageAdminClaims) {
// if not owner of claim, validate perms
if (!player.getUniqueId().equals(claim.getOwnerUniqueId())) {
if (!player.hasPermission(GDPermissions.COMMAND_CLAIM_INFO_TELEPORT_OTHERS)) {
return false;
}
if (!claim.isUserTrusted(player, TrustTypes.ACCESSOR)) {
if (GriefDefenderPlugin.getInstance().getVaultProvider() != null) {
// Allow non-trusted to TP to claims for sale
if (!claim.getEconomyData().isForSale() && !claim.getEconomyData().isForRent()) {
return false;
allowTeleport = false;
} else {
if (!claim.isUserTrusted(player, TrustTypes.ACCESSOR)) {
if (GriefDefenderPlugin.getInstance().getVaultProvider() != null) {
// Allow non-trusted to TP to claims for sale
if (!claim.getEconomyData().isForSale() && !claim.getEconomyData().isForRent()) {
allowTeleport = false;
}
} else {
allowTeleport = false;
}
} else {
return false;
}
}
} else if (!player.hasPermission(GDPermissions.COMMAND_CLAIM_INFO_TELEPORT_BASE)) {
return false;
allowTeleport = false;
}
}
if (!claim.isWilderness() && !allowTeleport && player.hasPermission(GDPermissions.COMMAND_CLAIM_INFO_TELEPORT_INSIDE)) {
// check if player is in claim
if (!player.getUniqueId().equals(claim.getOwnerUniqueId()) && !claim.isUserTrusted(player, TrustTypes.BUILDER)) {
if (claim.contains(VecHelper.toVector3i(player.getLocation()))) {
// check place
final Tristate placeResult = GDPermissionManager.getInstance().getFinalPermission(null, player.getLocation(), claim, Flags.BLOCK_PLACE, player, player.getLocation(), player, TrustTypes.BUILDER, true);
if (placeResult == Tristate.FALSE) {
allowTeleport = true;
}
}
}
}
return true;
return allowTeleport;
}
public GDPermissionHolder getGDPermissionHolder(GDPermissionHolder holder, Set<Context> contexts) {
if (holder != GriefDefenderPlugin.DEFAULT_HOLDER && holder != GriefDefenderPlugin.GD_DEFAULT_HOLDER) {
return holder;
}
for (Context context : contexts) {
if (context.getKey().equals(ContextKeys.CLAIM_OVERRIDE)) {
return GriefDefenderPlugin.GD_OVERRIDE_HOLDER;
}
if (context.getKey().equals(ContextKeys.CLAIM)) {
return GriefDefenderPlugin.GD_CLAIM_HOLDER;
}
}
return GriefDefenderPlugin.GD_DEFAULT_HOLDER;
}
}

View File

@ -66,9 +66,12 @@
import org.bukkit.block.BlockFace;
import org.bukkit.entity.Entity;
import org.bukkit.entity.Player;
import org.bukkit.event.block.Action;
import org.bukkit.inventory.ItemStack;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.UUID;
@ -323,4 +326,51 @@ public boolean isFakePlayer(Player player) {
return GriefDefenderPlugin.getGlobalConfig().getConfig().mod.isFakePlayer(player);
}
public GDClaim findNearbyClaim(Player player, GDPlayerData playerData, int maxDistance, boolean hidingVisuals) {
if (maxDistance <= 20) {
maxDistance = 100;
}
BlockRay blockRay = BlockRay.from(player).distanceLimit(maxDistance).build();
GDClaim playerClaim = GriefDefenderPlugin.getInstance().dataStore.getClaimAtPlayer(playerData, player.getLocation());
GDClaim firstClaim = null;
GDClaim claim = null;
playerData.lastNonAirInspectLocation = null;
playerData.lastValidInspectLocation = null;
while (blockRay.hasNext()) {
BlockRayHit blockRayHit = blockRay.next();
Location location = blockRayHit.getLocation();
claim = GriefDefenderPlugin.getInstance().dataStore.getClaimAt(location);
if (firstClaim == null && !claim.isWilderness()) {
if (hidingVisuals) {
if (claim.hasActiveVisual(player)) {
firstClaim = claim;
}
} else {
firstClaim = claim;
}
}
if (playerData.lastNonAirInspectLocation == null && !location.getBlock().isEmpty()) {
playerData.lastNonAirInspectLocation = location;
}
if (claim != null && !claim.isWilderness() && !playerClaim.getUniqueId().equals(claim.getUniqueId())) {
playerData.lastValidInspectLocation = location;
}
final Block block = location.getBlock();
if (!block.isEmpty() && !NMSUtil.getInstance().isBlockTransparent(block)) {
break;
}
}
if (claim == null || claim.isWilderness()) {
if (firstClaim == null) {
return GriefDefenderPlugin.getInstance().dataStore.getClaimWorldManager(player.getWorld().getUID()).getWildernessClaim();
}
return firstClaim;
}
return claim;
}
}

View File

@ -254,7 +254,7 @@ public static void setClaimForRent(Claim claim, Player player, Sign sign, double
minTime = TextComponent.builder()
.append(String.valueOf(min))
.append(" ")
.append(claim.getEconomyData().getPaymentType() == PaymentType.DAILY ?
.append(paymentType == PaymentType.DAILY ?
(min > 1 ? MessageCache.getInstance().LABEL_DAYS : MessageCache.getInstance().LABEL_DAY) :
(min > 1 ? MessageCache.getInstance().LABEL_HOURS : MessageCache.getInstance().LABEL_HOUR))
.build();
@ -349,8 +349,6 @@ public static void updateSignRentable(Claim claim, Sign sign) {
return;
}
final PaymentType paymentType = claim.getEconomyData().getPaymentType();
List<String> colorLines = new ArrayList<>(4);
colorLines.add(ChatColor.translateAlternateColorCodes('&', "&7[&bGD&7-&1rent&7]"));
colorLines.add(ChatColor.translateAlternateColorCodes('&', LegacyComponentSerializer.legacy().serialize(MessageCache.getInstance().ECONOMY_SIGN_RENT_DESCRIPTION)));

View File

@ -3,9 +3,9 @@
"libraries": [
{
"name": "com.griefdefender:adapter:1.12.2",
"sha1": "7bb52199ac2ba62ee6ab92fcc16b19ba5a8c0280",
"path": "com/griefdefender/adapter/1.12.2-SNAPSHOT/adapter-1.12.2-20200703.183356-45.jar",
"url": "https://repo.glaremasters.me/repository/bloodshot/com/griefdefender/adapter/1.12.2-SNAPSHOT/adapter-1.12.2-20200703.183356-45.jar"
"sha1": "ec24281ca279a99a7ae26e55e8a0a8877632fbc5",
"path": "com/griefdefender/adapter/1.12.2-SNAPSHOT/adapter-1.12.2-20200815.181857-48.jar",
"url": "https://repo.glaremasters.me/repository/bloodshot/com/griefdefender/adapter/1.12.2-SNAPSHOT/adapter-1.12.2-20200815.181857-48.jar"
},
{
"name": "com.griefdefender:api:1.0.0",

View File

@ -3,9 +3,9 @@
"libraries": [
{
"name": "com.griefdefender:adapter:1.13.2",
"sha1": "0b655bd8f4c3a2839dcae0d68c26817ee2043e79",
"path": "com/griefdefender/adapter/1.13.2-SNAPSHOT/adapter-1.13.2-20200703.183307-43.jar",
"url": "https://repo.glaremasters.me/repository/bloodshot/com/griefdefender/adapter/1.13.2-SNAPSHOT/adapter-1.13.2-20200703.183307-43.jar"
"sha1": "b0d4103d5163e36729e61c6ce31a614dcd5e479d",
"path": "com/griefdefender/adapter/1.13.2-SNAPSHOT/adapter-1.13.2-20200815.181639-46.jar",
"url": "https://repo.glaremasters.me/repository/bloodshot/com/griefdefender/adapter/1.13.2-SNAPSHOT/adapter-1.13.2-20200815.181639-46.jar"
},
{
"name": "com.griefdefender:api:1.0.0",

View File

@ -3,9 +3,9 @@
"libraries": [
{
"name": "com.griefdefender:adapter:1.14.2",
"sha1": "fd7308666a4538c5f08bd6bdf37fe852ffd9c0d0",
"path": "com/griefdefender/adapter/1.14.2-SNAPSHOT/adapter-1.14.2-20200703.183227-43.jar",
"url": "https://repo.glaremasters.me/repository/bloodshot/com/griefdefender/adapter/1.14.2-SNAPSHOT/adapter-1.14.2-20200703.183227-43.jar"
"sha1": "66194045c0dc7dba2451220a5ae0b81d0657f6f8",
"path": "com/griefdefender/adapter/1.14.2-SNAPSHOT/adapter-1.14.2-20200815.181604-46.jar",
"url": "https://repo.glaremasters.me/repository/bloodshot/com/griefdefender/adapter/1.14.2-SNAPSHOT/adapter-1.14.2-20200815.181604-46.jar"
},
{
"name": "com.griefdefender:api:1.0.0",

View File

@ -3,9 +3,9 @@
"libraries": [
{
"name": "com.griefdefender:adapter:1.14.3",
"sha1": "700f476c968c0b2dca09ae5d1a0fc7ba1195a5c1",
"path": "com/griefdefender/adapter/1.14.3-SNAPSHOT/adapter-1.14.3-20200703.183150-45.jar",
"url": "https://repo.glaremasters.me/repository/bloodshot/com/griefdefender/adapter/1.14.3-SNAPSHOT/adapter-1.14.3-20200703.183150-45.jar"
"sha1": "f76f3af9978ec81abf65d48bd3852a04d5fbe5fe",
"path": "com/griefdefender/adapter/1.14.3-SNAPSHOT/adapter-1.14.3-20200815.181527-48.jar",
"url": "https://repo.glaremasters.me/repository/bloodshot/com/griefdefender/adapter/1.14.3-SNAPSHOT/adapter-1.14.3-20200815.181527-48.jar"
},
{
"name": "com.griefdefender:api:1.0.0",

View File

@ -3,9 +3,9 @@
"libraries": [
{
"name": "com.griefdefender:adapter:1.14.4",
"sha1": "da17aa7a08dbf7012fc731e77a56f1ef560f082d",
"path": "com/griefdefender/adapter/1.14.4-SNAPSHOT/adapter-1.14.4-20200703.183119-43.jar",
"url": "https://repo.glaremasters.me/repository/bloodshot/com/griefdefender/adapter/1.14.4-SNAPSHOT/adapter-1.14.4-20200703.183119-43.jar"
"sha1": "c2290d6f4cec30b2fd3d7ae95e4186f7c5493bf4",
"path": "com/griefdefender/adapter/1.14.4-SNAPSHOT/adapter-1.14.4-20200815.181454-46.jar",
"url": "https://repo.glaremasters.me/repository/bloodshot/com/griefdefender/adapter/1.14.4-SNAPSHOT/adapter-1.14.4-20200815.181454-46.jar"
},
{
"name": "com.griefdefender:api:1.0.0",

View File

@ -3,9 +3,9 @@
"libraries": [
{
"name": "com.griefdefender:adapter:1.15.2",
"sha1": "a7c58074cf314d67de4fa49675681965f3cb7d48",
"path": "com/griefdefender/adapter/1.15.2-SNAPSHOT/adapter-1.15.2-20200703.183009-26.jar",
"url": "https://repo.glaremasters.me/repository/bloodshot/com/griefdefender/adapter/1.15.2-SNAPSHOT/adapter-1.15.2-20200703.183009-26.jar"
"sha1": "464541f3ea442ed7f272c12965b0be0107166e8a",
"path": "com/griefdefender/adapter/1.15.2-SNAPSHOT/adapter-1.15.2-20200815.181347-29.jar",
"url": "https://repo.glaremasters.me/repository/bloodshot/com/griefdefender/adapter/1.15.2-SNAPSHOT/adapter-1.15.2-20200815.181347-29.jar"
},
{
"name": "com.griefdefender:api:1.0.0",

View File

@ -3,9 +3,9 @@
"libraries": [
{
"name": "com.griefdefender:adapter:1.15",
"sha1": "0e0eba8652e6a2b88bb462fc775ba70dccb93d8e",
"path": "com/griefdefender/adapter/1.15-SNAPSHOT/adapter-1.15-20200703.183045-26.jar",
"url": "https://repo.glaremasters.me/repository/bloodshot/com/griefdefender/adapter/1.15-SNAPSHOT/adapter-1.15-20200703.183045-26.jar"
"sha1": "f689a443852fefa7462d3154999ea624a8756046",
"path": "com/griefdefender/adapter/1.15-SNAPSHOT/adapter-1.15-20200815.181416-29.jar",
"url": "https://repo.glaremasters.me/repository/bloodshot/com/griefdefender/adapter/1.15-SNAPSHOT/adapter-1.15-20200815.181416-29.jar"
},
{
"name": "com.griefdefender:api:1.0.0",

View File

@ -3,9 +3,9 @@
"libraries": [
{
"name": "com.griefdefender:adapter:1.16.1",
"sha1": "29795458f87a4aa2c6b6d0d753fda369c8207195",
"path": "com/griefdefender/adapter/1.16.1-SNAPSHOT/adapter-1.16.1-20200703.182855-6.jar",
"url": "https://repo.glaremasters.me/repository/bloodshot/com/griefdefender/adapter/1.16.1-SNAPSHOT/adapter-1.16.1-20200703.182855-6.jar"
"sha1": "da96fb3001c4a0d866e9b3715aaee6335a881bb0",
"path": "com/griefdefender/adapter/1.16.1-SNAPSHOT/adapter-1.16.1-20200815.181259-9.jar",
"url": "https://repo.glaremasters.me/repository/bloodshot/com/griefdefender/adapter/1.16.1-SNAPSHOT/adapter-1.16.1-20200815.181259-9.jar"
},
{
"name": "com.griefdefender:api:1.0.0",

View File

@ -0,0 +1,264 @@
{
"version": "1.16.2",
"libraries": [
{
"name": "com.griefdefender:adapter:1.16.2",
"sha1": "01a80ffbcd5b7dec1948faf82f1270abfff5c1e8",
"path": "com/griefdefender/adapter/1.16.2-SNAPSHOT/adapter-1.16.2-20200815.181223-2.jar",
"url": "https://repo.glaremasters.me/repository/bloodshot/com/griefdefender/adapter/1.16.2-SNAPSHOT/adapter-1.16.2-20200815.181223-2.jar"
},
{
"name": "com.griefdefender:api:1.0.0",
"sha1": "2a3f820d12a3bd4c03932018567ab3732517aee5",
"path": "com/griefdefender/api/1.0.0-SNAPSHOT/api-1.0.0-20200528.202302-24.jar",
"url": "https://repo.glaremasters.me/repository/bloodshot/com/griefdefender/api/1.0.0-SNAPSHOT/api-1.0.0-20200528.202302-24.jar"
},
{
"name": "com.griefdefender:reflect-helper:1.0",
"sha1": "7a50bffa9f0062ac4ca376d95a0e6599aa5f3257",
"path": "com/griefdefender/reflect-helper/1.0/reflect-helper-1.0.jar",
"url": "https://repo.glaremasters.me/repository/bloodshot/com/griefdefender/reflect-helper/1.0/reflect-helper-1.0.jar"
},
{
"name": "com.griefdefender:reflect-helper:2.0",
"sha1": "ee45d077344ae67e155e37eb61025401944ffabc",
"path": "com/griefdefender/reflect-helper/2.0/reflect-helper-2.0.jar",
"url": "https://repo.glaremasters.me/repository/bloodshot/com/griefdefender/reflect-helper/2.0/reflect-helper-2.0.jar"
},
{
"name": "org.checkerframework:checker-qual:2.10.0",
"sha1": "5786699a0cb71f9dc32e6cca1d665eef07a0882f",
"path": "org/checkerframework/checker-qual/2.10.0/checker-qual-2.10.0.jar",
"relocate": "javax.inject:javaxinject",
"url": "https://repo1.maven.org/maven2/org/checkerframework/checker-qual/2.10.0/checker-qual-2.10.0.jar"
},
{
"name": "org.ow2.asm:asm-debug-all:5.2",
"sha1": "3354e11e2b34215f06dab629ab88e06aca477c19",
"path": "org/ow2/asm/asm-debug-all/5.2/asm-debug-all-5.2.jar",
"relocate": "org.ow2.asm:asm",
"url": "https://repo1.maven.org/maven2/org/ow2/asm/asm-debug-all/5.2/asm-debug-all-5.2.jar"
},
{
"name": "me.lucko:jar-relocator:1.3",
"sha1": "90c6b66b8535f2f5eefc108e34e50f3e02e1f4cf",
"path": "me/lucko/jar-relocator/1.3/jar-relocator-1.3.jar",
"relocate": "me.lucko:lucko",
"url": "https://repo1.maven.org/maven2/me/lucko/jar-relocator/1.3/jar-relocator-1.3.jar"
},
{
"name": "co.aikar:acf-core:0.5.0-SNAPSHOT",
"sha1": "d640d058f08da1be6b4483ac7a665d0b4bb22044",
"path": "co/aikar/acf-core/0.5.0-SNAPSHOT/acf-core-0.5.0-20190617.211117-148.jar",
"url": "https://repo.glaremasters.me/repository/public/co/aikar/acf-core/0.5.0-SNAPSHOT/acf-core-0.5.0-20190617.211117-148.jar"
},
{
"name": "co.aikar:acf-bukkit:0.5.0-SNAPSHOT",
"sha1": "0af5d53de31ebf4e19100cc0654b88cc9c9c07fb",
"path": "co/aikar/acf-bukkit/0.5.0-SNAPSHOT/acf-bukkit-0.5.0-20190607.112608-152.jar",
"url": "https://repo.glaremasters.me/repository/public/co/aikar/acf-bukkit/0.5.0-SNAPSHOT/acf-bukkit-0.5.0-20190607.112608-152.jar"
},
{
"name": "co.aikar:acf-paper:0.5.0-SNAPSHOT",
"sha1": "5df2f2f0c7190f4b867af20ff57f9fde012a4e2c",
"path": "co/aikar/acf-paper/0.5.0-SNAPSHOT/acf-paper-0.5.0-20190607.112622-147.jar",
"url": "https://repo.glaremasters.me/repository/public/co/aikar/acf-paper/0.5.0-SNAPSHOT/acf-paper-0.5.0-20190607.112622-147.jar"
},
{
"name": "co.aikar:locales:1.0-SNAPSHOT",
"sha1": "09c89ff1a611600186edf8482d1059544875582b",
"path": "co/aikar/locales/1.0-SNAPSHOT/locales-1.0-20181221.115311-17.jar",
"url": "https://repo.glaremasters.me/repository/public/co/aikar/locales/1.0-SNAPSHOT/locales-1.0-20181221.115311-17.jar"
},
{
"name": "co.aikar:minecraft-timings:1.0.4",
"sha1": "7ed9d44840cd2c0f77b7c5276d60ca901b146332",
"path": "co/aikar/minecraft-timings/1.0.4/minecraft-timings-1.0.4.jar",
"url": "https://repo.glaremasters.me/repository/public/co/aikar/minecraft-timings/1.0.4/minecraft-timings-1.0.4.jar"
},
{
"name": "co.aikar:Table:1.0.0-SNAPSHOT",
"sha1": "ccbfaea11c65e6d7173226d318c577c439673b3a",
"path": "co/aikar/Table/1.0.0-SNAPSHOT/Table-1.0.0-20180331.054128-7.jar",
"url": "https://repo.glaremasters.me/repository/public/co/aikar/Table/1.0.0-SNAPSHOT/Table-1.0.0-20180331.054128-7.jar"
},
{
"name": "net.jodah:expiringmap:0.5.9",
"sha1": "b93ac8a915e38beadc20c3cc284506e15478fd7b",
"path": "net/jodah/expiringmap/0.5.9/expiringmap-0.5.9.jar",
"relocate": "net.jodah:jodah",
"url": "https://repo1.maven.org/maven2/net/jodah/expiringmap/0.5.9/expiringmap-0.5.9.jar"
},
{
"name": "aopalliance:aopalliance:1.0",
"sha1": "0235ba8b489512805ac13a8f9ea77a1ca5ebe3e8",
"path": "aopalliance/aopalliance/1.0/aopalliance-1.0.jar",
"relocate": "org.aopalliance:aopalliance",
"url": "https://repo1.maven.org/maven2/aopalliance/aopalliance/1.0/aopalliance-1.0.jar"
},
{
"name": "com.flowpowered:flow-math:1.0.3",
"sha1": "d98020239e5015091ad3be927cef9dea0d61a234",
"path": "com/flowpowered/flow-math/1.0.3/flow-math-1.0.3.jar",
"url": "https://repo1.maven.org/maven2/com/flowpowered/flow-math/1.0.3/flow-math-1.0.3.jar"
},
{
"name": "com.google.inject:guice:4.1.0",
"sha1": "eeb69005da379a10071aa4948c48d89250febb07",
"path": "com/google/inject/guice/4.1.0/guice-4.1.0.jar",
"relocate": "com.google.inject:googleinject",
"url": "https://repo1.maven.org/maven2/com/google/inject/guice/4.1.0/guice-4.1.0.jar"
},
{
"name": "javax.inject:javax.inject:1",
"sha1": "6975da39a7040257bd51d21a231b76c915872d38",
"path": "javax/inject/javax.inject/1/javax.inject-1.jar",
"relocate": "javax.inject:javaxinject",
"url": "https://repo1.maven.org/maven2/javax/inject/javax.inject/1/javax.inject-1.jar"
},
{
"name": "com.squareup.okhttp3:okhttp:4.7.2",
"sha1": "c9acfd63537db1d7d21d98a7405e22449bb881d6",
"path": "com/squareup/okhttp3/okhttp/4.7.2/okhttp-4.7.2.jar",
"relocate": "okhttp3:okhttp3",
"url": "https://repo1.maven.org/maven2/com/squareup/okhttp3/okhttp/4.7.2/okhttp-4.7.2.jar"
},
{
"name": "com.squareup.okio:okio:2.6.0",
"sha1": "0f06923d428f3c8e6f571043ec29a45d0cd9d2bf",
"path": "com/squareup/okio/okio/2.6.0/okio-2.6.0.jar",
"relocate": "okio:okio",
"url": "https://repo1.maven.org/maven2/com/squareup/okio/okio/2.6.0/okio-2.6.0.jar"
},
{
"name": "com.github.ben-manes.caffeine:caffeine:2.7.0",
"sha1": "c3af06be4a7d4e769fce2cef5e77d3becad9818a",
"path": "com/github/ben-manes/caffeine/caffeine/2.7.0/caffeine-2.7.0.jar",
"relocate": "com.github.benmanes.caffeine:caffeine",
"url": "https://repo1.maven.org/maven2/com/github/ben-manes/caffeine/caffeine/2.7.0/caffeine-2.7.0.jar"
},
{
"name": "commons-io:commons-io:2.6",
"sha1": "815893df5f31da2ece4040fe0a12fd44b577afaf",
"path": "org/apache/commons/commons-io/2.6/commons-io-2.6.jar",
"relocate": "org.apache.commons.io:commonsio",
"url": "https://repo1.maven.org/maven2/commons-io/commons-io/2.6/commons-io-2.6.jar"
},
{
"name": "org.apache.commons:commons-lang3:3.9",
"sha1": "0122c7cee69b53ed4a7681c03d4ee4c0e2765da5",
"path": "org/apache/commons/commons-lang3/3.9/commons-lang3-3.9.jar",
"relocate": "org.apache.commons.lang3:commonslang3",
"url": "https://repo1.maven.org/maven2/org/apache/commons/commons-lang3/3.9/commons-lang3-3.9.jar"
},
{
"name": "org.spongepowered:configurate-core:3.7-SNAPSHOT",
"sha1": "e596c439ac71fa2ea5c48f8ba97a7dc6f4c77b16",
"path": "org/spongepowered/configurate-core/3.7-SNAPSHOT/configurate-core-3.7-20190531.182437-11.jar",
"relocate": "ninja.leaping.configurate:configurate",
"url": "https://repo.spongepowered.org/maven/org/spongepowered/configurate-core/3.7-SNAPSHOT/configurate-core-3.7-20190531.182437-11.jar"
},
{
"name": "org.spongepowered:configurate-gson:3.7-SNAPSHOT",
"sha1": "265a94f16583621f497eeecc356f35f983484dde",
"path": "org/spongepowered/configurate-gson/3.7-SNAPSHOT/configurate-gson-3.7-20190531.182438-11.jar",
"relocate": "ninja.leaping.configurate:configurate",
"url": "https://repo.spongepowered.org/maven/org/spongepowered/configurate-gson/3.7-SNAPSHOT/configurate-gson-3.7-20190531.182438-11.jar"
},
{
"name": "org.spongepowered:configurate-hocon:3.7-SNAPSHOT",
"sha1": "af48dcb9e7456f2f81a633f62ae5c55e5215c4af",
"path": "org/spongepowered/configurate-hocon/3.7-SNAPSHOT/configurate-hocon-3.7-20190531.182439-11.jar",
"relocate": "ninja.leaping.configurate:configurate",
"url": "https://repo.spongepowered.org/maven/org/spongepowered/configurate-hocon/3.7-SNAPSHOT/configurate-hocon-3.7-20190531.182439-11.jar"
},
{
"name": "org.spongepowered:configurate-yaml:3.7-SNAPSHOT",
"sha1": "c66110f5ae0098c450e048f78b322590d2e24d06",
"path": "org/spongepowered/configurate-yaml/3.7-SNAPSHOT/configurate-yaml-3.7-20190531.182442-11.jar",
"relocate": "ninja.leaping.configurate:configurate",
"url": "https://repo.spongepowered.org/maven/org/spongepowered/configurate-yaml/3.7-SNAPSHOT/configurate-yaml-3.7-20190531.182442-11.jar"
},
{
"name": "com.typesafe:config:1.3.1",
"sha1": "2cf7a6cc79732e3bdf1647d7404279900ca63eb0",
"path": "com/typesafe/config/1.3.1/config-1.3.1.jar",
"relocate": "com.typesafe:typesafe",
"url": "https://repo1.maven.org/maven2/com/typesafe/config/1.3.1/config-1.3.1.jar"
},
{
"name": "it.unimi.dsi:fastutil:8.2.3",
"sha1": "f3a26db2204f1779c9958a914422f84284e53a84",
"path": "it/unimi/dsi/fastutil/8.2.3/fastutil-8.2.3.jar",
"relocate": "it.unimi.dsi:fastutil",
"url": "https://repo1.maven.org/maven2/it/unimi/dsi/fastutil/8.2.3/fastutil-8.2.3.jar"
},
{
"name": "org.jetbrains.kotlin:kotlin-stdlib:1.3.72",
"sha1": "8032138f12c0180bc4e51fe139d4c52b46db6109",
"path": "org/jetbrains/kotlin/kotlin-stdlib/1.3.72/kotlin-stdlib-1.3.72.jar",
"relocate": "kotlin:kotlin",
"url": "https://repo1.maven.org/maven2/org/jetbrains/kotlin/kotlin-stdlib/1.3.72/kotlin-stdlib-1.3.72.jar"
},
{
"name": "net.kyori:event-api:3.0.0",
"sha1": "4e207f07d2adaa15e174a085f65bc6ae5a81029e",
"path": "net/kyori/event-api/3.0.0/event-api-3.0.0.jar",
"url": "https://repo1.maven.org/maven2/net/kyori/event-api/3.0.0/event-api-3.0.0.jar"
},
{
"name": "net.kyori:event-method:3.0.0",
"sha1": "85fe9bbf8ebadde4c82602af29352ba5db06e8e5",
"path": "net/kyori/event-method/3.0.0/event-method-3.0.0.jar",
"url": "https://repo1.maven.org/maven2/net/kyori/event-method/3.0.0/event-method-3.0.0.jar"
},
{
"name": "net.kyori:event-method-asm:3.0.0",
"sha1": "69113430c1ba05c9d9fa6e48028edd53e3e16723",
"path": "net/kyori/event-method-asm/3.0.0/event-method-asm-3.0.0.jar",
"url": "https://repo1.maven.org/maven2/net/kyori/event-method-asm/3.0.0/event-method-asm-3.0.0.jar"
},
{
"name": "net.kyori:text-adapter-bukkit:3.0.5",
"sha1": "00f1b0dcf5a92da9172ea911695c0021eed445cb",
"path": "net/kyori/text-adapter-bukkit/3.0.5/text-adapter-bukkit-3.0.5.jar",
"url": "https://repo1.maven.org/maven2/net/kyori/text-adapter-bukkit/3.0.5/text-adapter-bukkit-3.0.5.jar"
},
{
"name": "net.kyori:text-adapter-bungeecord:3.0.5",
"sha1": "3d4d18e691d8319cb3f2e42cedaaa18c7b1b324c",
"path": "net/kyori/text-adapter-bungeecord/3.0.5/text-adapter-bungeecord-3.0.5.jar",
"url": "https://repo1.maven.org/maven2/net/kyori/text-adapter-bungeecord/3.0.5/text-adapter-bungeecord-3.0.5.jar"
},
{
"name": "net.kyori:text-adapter-spongeapi:3.0.5",
"sha1": "ce0217b7ac94d464074a916de58d86c1bac4f4b0",
"path": "net/kyori/text-adapter-spongeapi/3.0.5/text-adapter-spongeapi-3.0.5.jar",
"url": "https://repo1.maven.org/maven2/net/kyori/text-adapter-spongeapi/3.0.5/text-adapter-spongeapi-3.0.5.jar"
},
{
"name": "net.kyori:text-api:3.0.4",
"sha1": "3f6844794af6769053337f21e6ac544d88181fd9",
"path": "net/kyori/text-api/3.0.4/text-api-3.0.4.jar",
"url": "https://repo1.maven.org/maven2/net/kyori/text-api/3.0.4/text-api-3.0.4.jar"
},
{
"name": "net.kyori:text-serializer-gson:3.0.4",
"sha1": "d9e3e97a60bf64690f633f16278117b1c0702c27",
"path": "net/kyori/text-serializer-gson/3.0.4/text-serializer-gson-3.0.4.jar",
"url": "https://repo1.maven.org/maven2/net/kyori/text-serializer-gson/3.0.4/text-serializer-gson-3.0.4.jar"
},
{
"name": "net.kyori:text-serializer-legacy:3.0.4",
"sha1": "925bad50c7221713fe6ada7a42686df584969017",
"path": "net/kyori/text-serializer-legacy/3.0.4/text-serializer-legacy-3.0.4.jar",
"url": "https://repo1.maven.org/maven2/net/kyori/text-serializer-legacy/3.0.4/text-serializer-legacy-3.0.4.jar"
},
{
"name": "net.kyori:text-serializer-plain:3.0.4",
"sha1": "b5b9ca6a4be956542934ca699091a3b8ea169c19",
"path": "net/kyori/text-serializer-plain/3.0.4/text-serializer-plain-3.0.4.jar",
"url": "https://repo1.maven.org/maven2/net/kyori/text-serializer-plain/3.0.4/text-serializer-plain-3.0.4.jar"
}
]
}

View File

@ -3,9 +3,9 @@
"libraries": [
{
"name": "com.griefdefender:adapter:1.8.8",
"sha1": "263b5c05c6bffb979742e67eeb29fa2ecf5bb0e3",
"path": "com/griefdefender/adapter/1.8.8-SNAPSHOT/adapter-1.8.8-20200703.183440-43.jar",
"url": "https://repo.glaremasters.me/repository/bloodshot/com/griefdefender/adapter/1.8.8-SNAPSHOT/adapter-1.8.8-20200703.183440-43.jar"
"sha1": "afbe175884a0703974df792de5452287e9f48cb8",
"path": "com/griefdefender/adapter/1.8.8-SNAPSHOT/adapter-1.8.8-20200815.181931-46.jar",
"url": "https://repo.glaremasters.me/repository/bloodshot/com/griefdefender/adapter/1.8.8-SNAPSHOT/adapter-1.8.8-20200815.181931-46.jar"
},
{
"name": "com.griefdefender:api:1.0.0",

View File

@ -3,5 +3,5 @@ main: com.griefdefender.GDBootstrap
softdepend: [dynmap, PlaceholderAPI, WorldEdit, WorldGuard, Vault]
depend: [LuckPerms]
load: STARTUP
version: '1.4.7'
version: '1.5.0'
api-version: 1.13

View File

@ -74,6 +74,8 @@ GriefDefender {
abandon-world-success="&aAlle SpielerGrundstücke in &6{world}&a gelöscht."
abandon-world-warning="&6Bist du dir sicher, dass du &cALLE&6 SpielerGrundstücke in &a{world}&6 löschen möchtest?"
adjust-accrued-blocks-success="&6{player}&a's angesammelte Blöcke wurden auf &6{amount}&a angepasst. Neue Anzahl: &6{total}&a."
adjust-bonus-blocks-all-success="&aAdjusted &6{count} &aonline players' bonus claim blocks by &6{amount}&a."
adjust-bonus-blocks-all-warning="&6Are you sure you want to adjust &cALL&6 online players' bonus claim blocks by &b{amount}&6?"
adjust-bonus-blocks-success="&6{player}&a's Bonusblöcke wurden auf &6{amount}&a angepasst. Neue Anzahl: &6{total}&a."
bank-click-view-transactions="Klicken, um Banktransaktionen anzuzeigen."
bank-deposit="&aErfolgreich &6{amount}&a in die Bank eingezahlt."
@ -171,6 +173,7 @@ GriefDefender {
claimlist-ui-return-claimlist="Zurück zur Grundstücksliste"
claimlist-ui-title=Grundstücksliste
claimlist-ui-title-child-claims=Teilgrundstücke
claimtool-not-enabled="&6The claim tool is not enabled. Use &f/claimtool&6 to re-enable for claiming."
command-blocked="&cDer Befehl &f{command}&c wurde vom Grundstücksbesitzer &6{player}&c deaktiviert."
command-claimban-success-block="&aErfolgreich folgenden Block &cgeblockt&a: {id}."
command-claimban-success-entity="&aErfolgreich folgendes Objekt &cgeblock&at: {id}."
@ -188,6 +191,8 @@ GriefDefender {
command-claimmode-disabled="Grundstücksmodus: &cAUS"
command-claimmode-enabled="Grundstücksmodus &aAN&f\n&aLinksklick zum Inspizieren.\n&aRechtsklick, um Grundstücke zu erstellen und anzupassen.&b\nTipp&f: &aZum Verlassen des Modus: &f/claim&a."
command-claimspawn-not-found="&aKein Grundstück {name}&a gefunden."
command-claimtool-disabled="&cClaim tool disabled."
command-claimtool-enabled="&aClaim tool enabled."
command-claimunban-success-block="&aErfolgreich folgenden Block &centblockt&a: {id}."
command-claimunban-success-entity="&aErfolgreich folgendes Objekt &centblockt&a: {id}."
command-claimunban-success-item="&aErfolgreich folgendes Item &centblockt&a: {id}."
@ -282,6 +287,8 @@ GriefDefender {
economy-claim-rent-confirmation-min="&6Bist du dir sicher, dass du dein Grundstück vermieten möchtest?\n\n&bPreis: &a{amount} pro &a{type}\n&bMindestzeit: &a{min-time}&6\n\nSobald es vermietet ist, kannst du nicht darauf zugreifen.\nKlicke auf Bestätigen um fortzufahren."
economy-claim-rent-confirmation-min-max="&6ist du dir sicher, dass du dein Grundstück vermieten möchtest?\n\n&bPreis: &a{amount} pro &a{type}\n&bMindestzeit: &a{min-time}\n&bVermietung endet in: &a{max-time}&6\n\nSobald es vermietet ist, kannst du nicht darauf zugreifen.\nKlicke auf Bestätigen um fortzufahren."
economy-claim-rent-confirmed="&aDu hast dein Grundstück erfolgreich zur Anmietung freigegeben. Nutze '/claimrent info' auf dem Grundstück, um Details einzusehen."
economy-claim-rent-end="&aYour claim rental '{claim}&a' has ended."
economy-claim-rent-end-restore="&aYour claim rental '{claim}&a' has ended. It has been restored to its original state."
economy-claim-rent-invalid-price="&cDer Mietzins &a{amount}&c muss größer oder gleich &a0&c sein."
economy-claim-rent-not-enough-funds="&cDu hast nicht genug Geld, um das Grundstück für &a{amount}&c zu mieten. Du hast &a{balance}&c und benötigst noch &a{amount_required}&c."
economy-claim-rent-not-renting="&aDu bist nicht der Mietes dieses Grundstückes."

View File

@ -74,6 +74,8 @@ GriefDefender {
abandon-world-success="&aAbandoned all player claims in &6{world}&a."
abandon-world-warning="&6Are you sure you want to abandon &cALL&6 user claims in &a{world}&6?"
adjust-accrued-blocks-success="&aAdjusted &6{player}&a's accrued claim blocks by &6{amount}&a. New total accrued blocks: &6{total}&a."
adjust-bonus-blocks-all-success="&aAdjusted &6{count} &aonline players' bonus claim blocks by &6{amount}&a."
adjust-bonus-blocks-all-warning="&6Are you sure you want to adjust &cALL&6 online players' bonus claim blocks by &b{amount}&6?"
adjust-bonus-blocks-success="&aAdjusted &6{player}&a's bonus claim blocks by &6{amount}&a. New total bonus blocks: &6{total}&a."
bank-click-view-transactions="Click here to view bank transactions"
bank-deposit="&aSuccessful deposit of &6{amount}&a into bank."
@ -171,6 +173,7 @@ GriefDefender {
claimlist-ui-return-claimlist="Return to claims list"
claimlist-ui-title="Claim list"
claimlist-ui-title-child-claims="Child Claims"
claimtool-not-enabled="&6The claim tool is not enabled. Use &f/claimtool&6 to re-enable for claiming."
command-blocked="&cThe command &f{command}&c has been blocked by claim owner &6{player}&c."
command-claimban-success-block="&aSuccessfully &cBANNED&a block with id {id}&a."
command-claimban-success-entity="&aSuccessfully &cBANNED&a entity with id {id}&a."
@ -188,6 +191,8 @@ GriefDefender {
command-claimmode-disabled="Claim mode &cOFF"
command-claimmode-enabled="Claim mode &aON&f\n&aLeft-click to inspect.\n&aRight-click to claim.&b\nNote&f: &aUse &f/claim&a to exit mode."
command-claimspawn-not-found="&aCould not locate a claim with name {name}&a."
command-claimtool-disabled="&cClaim tool disabled."
command-claimtool-enabled="&aClaim tool enabled."
command-claimunban-success-block="&aSuccessfully &6UNBANNED&a block with id {id}&a."
command-claimunban-success-entity="&aSuccessfully &6UNBANNED&a entity with id {id}&a."
command-claimunban-success-item="&aSuccessfully &6UNBANNED&a item with id {id}&a."
@ -282,6 +287,8 @@ GriefDefender {
economy-claim-rent-confirmation-min="&6Are you sure you want to rent out your claim?\n\n&bPrice: &a{amount} per &a{type}\n&bMinimum Time: &a{min-time}&6\n\nOnce your claim is rented, you will lose access to it.\nClick confirm if this is OK."
economy-claim-rent-confirmation-min-max="&6Are you sure you want to rent out your claim?\n\n&bPrice: &a{amount} per &a{type}\n&bMinimum Time: &a{min-time}\n&bRental will end in: &a{max-time}&6\n\nOnce your claim is rented, you will lose access to it.\nClick confirm if this is OK."
economy-claim-rent-confirmed="&aYou have successfully set your claim up for rent. Type '/claimrent info' inside this claim for details."
economy-claim-rent-end="&aYour claim rental '{claim}&a' has ended."
economy-claim-rent-end-restore="&aYour claim rental '{claim}&a' has ended. It has been restored to its original state."
economy-claim-rent-invalid-price="&cThe rent price of &a{amount}&c must be greater than or equal to &a0&c."
economy-claim-rent-not-enough-funds="&cYou do not have enough funds to rent this claim for &a{amount}&c. You currently have a balance of &a{balance}&c and need &a{amount_required}&c more for rent."
economy-claim-rent-not-renting="&aYou are not renting this claim."

View File

@ -74,6 +74,8 @@ GriefDefender {
abandon-world-success="&aTodas las claims del mundo &6{world}&a han sido abandonadas."
abandon-world-warning="&4&l[ATENCION] &6¿Estás seguro que deseas abandonar &cTODAS&6 las claims de los usuarios en el mundo &a{world}&6?"
adjust-accrued-blocks-success="&2&l[MODIFICADO] &ala cantidad de bloques acumulados a &6&o{amount} &aal jugador &6&o{player}&a. &aTOTAL BLOQUES ACUMULADOS: &6&o{total}&a."
adjust-bonus-blocks-all-success="&aHas ajustado el bonus de claimblocks de &6{count} &ajugadores en línea por &6{amount}&a."
adjust-bonus-blocks-all-warning="&6¿Estás seguro que deseas ajustar los bonus de claimblocks de &cTODOS&6 los jugadores en línea por &b{amount}&6?."
adjust-bonus-blocks-success="&2&l[MODIFICADO] &ael bonus de ClaimBlocks a &6&o{amount} &aal jugador &6&o{player}&a. &aTOTAL DE BONOS ACUMULADOS: &6&o{total}&a."
bank-click-view-transactions="&aClick aqui para ver las transacciones del Banco."
bank-deposit="&a&l+{amount} &7&ohan sido depositados del Banco."
@ -171,6 +173,7 @@ GriefDefender {
claimlist-ui-return-claimlist="Retroceder a la Lista de Terrenos"
claimlist-ui-title="&6&lLISTA DE TERRENOS"
claimlist-ui-title-child-claims="Subclaims"
claimtool-not-enabled="&6La herramienta de claim no está habilitada. Utiliza &f/claimtool&6 para re-habilitarla y crear protecciones con ella."
command-blocked="&4&l[COMANDO DENEGADO] &6&o'{command}' &cha sido bloqueado en este terreno por el dueño &6&o{player}&c."
command-claimban-success-block="&4&l[BANEADO]&a el &6bloque &acon ID: &6&l{id}&a."
command-claimban-success-entity="&4&l[BANEADO]&a la &6entidad &acon ID: &6&l{id}&a."
@ -188,6 +191,8 @@ GriefDefender {
command-claimmode-disabled="&f&lMODO CLAIM ► &4&l&oDESACTIVADO"
command-claimmode-enabled="&3&l---------------------------------------------\n&f&lMODO CLAIM ► &2&l&oACTIVADO&f\n\n&aHaz &6&lCLICK-IZQUIERDO&a para &d&ninspeccionar el terreno&a y comprobar si está libre para reclamar o ya ha sido reclamado por alguien&a. \n\n Haz &6&lCLICK-DERECHO&a para &d&nreclamar el terreno&a.\n\n&4&l[NOTA]&c Si quieres cancelar el Claimeo, usa &6&l&o'/claim'&c para salir del modo de reclamo."
command-claimspawn-not-found="&4&l[ERROR] &cNo puedes localizar el terreno con el nombre &6&o'{name}'&c."
command-claimtool-disabled="&cHerramienta de claim deshabilitada."
command-claimtool-enabled="&aHerramienta de claim habilitada."
command-claimunban-success-block="&2&l[DES-BANEADO]&a el &6bloque &acon ID: &6&l{id}&a."
command-claimunban-success-entity="&2&l[DES-BANEADO]&a la &6entidad &acon ID: &6&l{id}&a."
command-claimunban-success-item="&2&l[DES-BANEADO]&a el &6objeto &acon ID: &6&l{id}&a."
@ -282,6 +287,8 @@ GriefDefender {
economy-claim-rent-confirmation-min="&2&l[CONFIRMAR ACCIÓN] &6¿Estás seguro que deseas dar a rentar esta claim?\n\n&bPrecio: &a{amount} por &a{type}&6\n&bTiempo mínimo: &a{min-time}&6\n\n&6Cuando tu claim sea rentada, perderás acceso a ella.\n&6Click a CONFIRMAR si estás de acuerdo."
economy-claim-rent-confirmation-min-max="&2&l[CONFIRMAR ACCIÓN] &6¿Estás seguro que deseas dar a rentar esta claim?\n\n&bPrecio: &a{amount} por &a{type}&6\n&bTiempo mínimo: &a{min-time}\n&bLa renta termina en: &a{max-time}&6\n\n&6Cuando tu claim sea rentada, perderás acceso a ella.\n&6Click a CONFIRMAR si estás de acuerdo."
economy-claim-rent-confirmed="&2&l[RENTA ACTIVADA] &aHas puesto tu claim en renta a &6{amount}&a &apor &6{type}&a."
economy-claim-rent-end="&aLa renta de tu claim '{claim}&a' ha terminado."
economy-claim-rent-end-restore="&aLa renta de tu claim '{claim}&a' ha terminado. La claim ha sido restaurada a su estado original."
economy-claim-rent-invalid-price="&4&l[ERROR] &cEl precio de renta &a{amount}&c debe ser mayor o igual a &a0&c."
economy-claim-rent-not-enough-funds="&4&l[ERROR] &cNo tienes el suficiente dinero para rentar esta claim por &a{amount}&c. Tu balance actual es de &a{balance}&c y necesitas &a{amount_required}&c más para rentarla."
economy-claim-rent-not-renting="&2&l[INFORMACIÓN] &aNo estás rentando esta claim."

View File

@ -74,6 +74,8 @@ GriefDefender {
abandon-world-success="&aToutes les protections de l'ensemble des joueurs dans le monde &6{world}&a ont été abandonné."
abandon-world-warning="&6Es-tu sûr de vouloir abandonner &cTOUTES&6 les protections des joueurs dans le monde &a{world}&6 ?"
adjust-accrued-blocks-success="&aAjustement du nombre de blocs de terrain gagnés par &6{player}&a de &6{amount}&a. Nouveau total de blocs de terrain gagnés: &6{total}&a."
adjust-bonus-blocks-all-success="&aAdjusted &6{count} &aonline players' bonus claim blocks by &6{amount}&a."
adjust-bonus-blocks-all-warning="&6Are you sure you want to adjust &cALL&6 online players' bonus claim blocks by &b{amount}&6?"
adjust-bonus-blocks-success="&aAjustement du nombre de blocs de terrain, bonus &6{player}&a de &6{amount}&a. Nouveau total de blocs de terrain bonus: &6{total}&a."
bank-click-view-transactions="Clique ici pour voir les transactions bancaires"
bank-deposit="&aDépôt de &6{amount}&a avec succès dans la banque."
@ -171,6 +173,7 @@ GriefDefender {
claimlist-ui-return-claimlist="Retourne à la liste des terrains"
claimlist-ui-title="Liste les terrains"
claimlist-ui-title-child-claims="Terrains enfants"
claimtool-not-enabled="&6The claim tool is not enabled. Use &f/claimtool&6 to re-enable for claiming."
command-blocked="&cLa commande &f{command}&c a été bloquée par le propriétaire du terrain &6{player}&c."
command-claimban-success-block="&cBANNISSEMENT&a du bloc avec l'id {id}&a avec succès."
command-claimban-success-entity="&cBANNISSEMENT&a de l'entité avec l'id {id}&a avec succès."
@ -188,6 +191,8 @@ GriefDefender {
command-claimmode-disabled="Mode terrain &cOFF"
command-claimmode-enabled="Mode terrain &aON&f\n&aClique gauche pour inspecter.\n&aClique droit pour réclamer.&b\nNote&f: &aUtilise &f/claim&a pour sortir du mode."
command-claimspawn-not-found="&aNe peut pas localiser un terrain avec le nom {name}&a."
command-claimtool-disabled="&cClaim tool disabled."
command-claimtool-enabled="&aClaim tool enabled."
command-claimunban-success-block="&cDÉBANISSEMENT&a du bloc avec l'id {id}&a avec succès."
command-claimunban-success-entity="&cDÉBANISSEMENT&a de l'entité avec l'id {id}&a avec succès."
command-claimunban-success-item="&cDÉBANISSEMENT&a de l'objet avec l'id {id}&a avec succès."
@ -282,6 +287,8 @@ GriefDefender {
economy-claim-rent-confirmation-min="&6Are you sure you want to rent out your claim?\n\n&bPrice: &a{amount} per &a{type}\n&bMinimum Time: &a{min-time}&6\n\nOnce your claim is rented, you will lose access to it.\nClick confirm if this is OK."
economy-claim-rent-confirmation-min-max="&6Are you sure you want to rent out your claim?\n\n&bPrice: &a{amount} per &a{type}\n&bMinimum Time: &a{min-time}\n&bRental will end in: &a{max-time}&6\n\nOnce your claim is rented, you will lose access to it.\nClick confirm if this is OK."
economy-claim-rent-confirmed="&aYou have successfully set your claim up for rent. Type '/claimrent info' inside this claim for details."
economy-claim-rent-end="&aYour claim rental '{claim}&a' has ended."
economy-claim-rent-end-restore="&aYour claim rental '{claim}&a' has ended. It has been restored to its original state."
economy-claim-rent-invalid-price="&cLe prix de la location de &a{amount}&c doit être supérieur ou égal à &a0&c."
economy-claim-rent-not-enough-funds="&cTu n'as pas suffisamment de fonds pour louer ce terrain pour &a{amount}&c. Tu as actuellement un solde de &a{balance}&c et a besoin de &a{amount_required}&c de plus pour louer."
economy-claim-rent-not-renting="&aTu ne loue pas ce terrain."

View File

@ -74,6 +74,8 @@ GriefDefender {
abandon-world-success="&aAbandoned all player claims in &6{world}&a."
abandon-world-warning="&6Are you sure you want to abandon &cALL&6 user claims in &a{world}&6?"
adjust-accrued-blocks-success="&aZmieniono ilość bloków metrażu gracza &6{player} &ao &6{amount}&a. Nowy metraż: &6{total} &abloków."
adjust-bonus-blocks-all-success="&aAdjusted &6{count} &aonline players' bonus claim blocks by &6{amount}&a."
adjust-bonus-blocks-all-warning="&6Are you sure you want to adjust &cALL&6 online players' bonus claim blocks by &b{amount}&6?"
adjust-bonus-blocks-success="&aZmieniono ilość bonusowych bloków metrażu gracza &6{player} &ao &6{amount}&a. Nowy bonus: &6{total} &abloków."
bank-click-view-transactions="Kliknij aby sprawdzić transakcje bankowe"
bank-deposit="&aOperacja wpłaty kwoty &6{amount} &a do banku powiodła się."
@ -171,6 +173,7 @@ GriefDefender {
claimlist-ui-return-claimlist="Powrót do listy działek"
claimlist-ui-title="Lista Działek"
claimlist-ui-title-child-claims="Działki dziedziczące"
claimtool-not-enabled="&6The claim tool is not enabled. Use &f/claimtool&6 to re-enable for claiming."
command-blocked="&cKomenda &f{command}&c została wyłączona przez właściciela: &6{player}&c."
command-claimban-success-block="&aPomyślnie &cZBANOWANO&a blok o id {id}&a."
command-claimban-success-entity="&aPomyślnie &cZBANOWANO&a obiekt o id {id}&a."
@ -191,6 +194,8 @@ GriefDefender {
command-claimunban-success-block="&aPomyślnie &6ODBANOWANO&a blok o id {id}&a."
command-claimunban-success-entity="&aPomyślnie &6ODBANOWANO&a obiekt o id {id}&a."
command-claimunban-success-item="&aPomyślnie &6Odbanowano&a przedmiot o id {id}&a."
command-claimtool-disabled="&cClaim tool disabled."
command-claimtool-enabled="&aClaim tool enabled."
command-cuboid-disabled="&aTryb tworzenia: &d2D&a."
command-cuboid-enabled="&aTryb tworzenia &d3D&a."
command-execute-failed="&cNie udało się wykonać polecenia '{command} {args}'"
@ -282,6 +287,8 @@ GriefDefender {
economy-claim-rent-confirmation-min="&6Are you sure you want to rent out your claim?\n\n&bPrice: &a{amount} per &a{type}\n&bMinimum Time: &a{min-time}&6\n\nOnce your claim is rented, you will lose access to it.\nClick confirm if this is OK."
economy-claim-rent-confirmation-min-max="&6Are you sure you want to rent out your claim?\n\n&bPrice: &a{amount} per &a{type}\n&bMinimum Time: &a{min-time}\n&bRental will end in: &a{max-time}&6\n\nOnce your claim is rented, you will lose access to it.\nClick confirm if this is OK."
economy-claim-rent-confirmed="&aYou have successfully set your claim up for rent. Type '/claimrent info' inside this claim for details."
economy-claim-rent-end="&aYour claim rental '{claim}&a' has ended."
economy-claim-rent-end-restore="&aYour claim rental '{claim}&a' has ended. It has been restored to its original state."
economy-claim-rent-invalid-price="&cCena najmu &a{amount}&c musi być większa niż lub równa &a0&c."
economy-claim-rent-not-enough-funds="&cNie stać cię na wynajem działki za &a{amount}&c. Obecnie dysponujesz kwotą &a{balance}&c i brakuje Ci &a{amount_required}&c."
economy-claim-rent-not-renting="&aNie wynajmujesz tej działki."

View File

@ -74,6 +74,8 @@ GriefDefender {
abandon-world-success="&aAbandoned all player claims in &6{world}&a."
abandon-world-warning="&6Are you sure you want to abandon &cALL&6 user claims in &a{world}&6?"
adjust-accrued-blocks-success="&aКоличество накопленных блоков региона для &6{player}&a изменено на &6{amount}&a. Новое количество накопленных блоков: &6{total}&a."
adjust-bonus-blocks-all-success="&aAdjusted &6{count} &aonline players' bonus claim blocks by &6{amount}&a."
adjust-bonus-blocks-all-warning="&6Are you sure you want to adjust &cALL&6 online players' bonus claim blocks by &b{amount}&6?"
adjust-bonus-blocks-success="&aКоличество бонусных блоков региона для &6{player}&a изменено на &6{amount}&a. Новое количество бонусных блоков: &6{total}&a."
bank-click-view-transactions="Нажмите здесь, чтобы просмотреть историю банковских переводов"
bank-deposit="&aУспешно передано &6{amount}&a в банк."
@ -171,6 +173,7 @@ GriefDefender {
claimlist-ui-return-claimlist="Вернуться к списку регионов"
claimlist-ui-title="Список регионов"
claimlist-ui-title-child-claims=Суб-регионы
claimtool-not-enabled="&6The claim tool is not enabled. Use &f/claimtool&6 to re-enable for claiming."
command-blocked="&cИспользование команды &f{command}&c заблокировано игроком &6{player}&c, владельцем региона."
command-claimban-success-block="&aБлок с id &c{id}&a успешно &cЗАБАНЕН&a."
command-claimban-success-entity="&aСущность с id &c{id}&a успешно &cЗАБАНЕНА&a."
@ -188,6 +191,8 @@ GriefDefender {
command-claimmode-disabled="Claim mode &cOFF"
command-claimmode-enabled="Claim mode &aON&f\n&aLeft-click to inspect.\n&aRight-click to claim.&b\nNote&f: &aUse &f/claim&a to exit mode."
command-claimspawn-not-found="&aНе удалось найти регион с именем {name}&a."
command-claimtool-disabled="&cClaim tool disabled."
command-claimtool-enabled="&aClaim tool enabled."
command-claimunban-success-block="&aБлок с id &6{id}&a успешно &6РАЗБАНЕН&a."
command-claimunban-success-entity="&aСущность с id &6{id}&a успешно &6РАЗБАНЕНА&a."
command-claimunban-success-item="&aПредмет с id &6{id}&a успешно &6РАЗБАНЕН&a."
@ -282,6 +287,8 @@ GriefDefender {
economy-claim-rent-confirmation-min="&6Are you sure you want to rent out your claim?\n\n&bPrice: &a{amount} per &a{type}\n&bMinimum Time: &a{min-time}&6\n\nOnce your claim is rented, you will lose access to it.\nClick confirm if this is OK."
economy-claim-rent-confirmation-min-max="&6Are you sure you want to rent out your claim?\n\n&bPrice: &a{amount} per &a{type}\n&bMinimum Time: &a{min-time}\n&bRental will end in: &a{max-time}&6\n\nOnce your claim is rented, you will lose access to it.\nClick confirm if this is OK."
economy-claim-rent-confirmed="&aYou have successfully set your claim up for rent. Type '/claimrent info' inside this claim for details."
economy-claim-rent-end="&aYour claim rental '{claim}&a' has ended."
economy-claim-rent-end-restore="&aYour claim rental '{claim}&a' has ended. It has been restored to its original state."
economy-claim-rent-invalid-price="&cThe rent price of &a{amount}&c must be greater than or equal to &a0&c."
economy-claim-rent-not-enough-funds="&cYou do not have enough funds to rent this claim for &a{amount}&c. You currently have a balance of &a{balance}&c and need &a{amount_required}&c more for rent."
economy-claim-rent-not-renting="&aYou are not renting this claim."

View File

@ -2,11 +2,11 @@
name=GriefDefender
group=com.griefdefender
url=https://github.com/bloodmc/GriefDefender
version=1.4.7
version=1.5.0
apiVersion=1.0.0-20200528.202302-24
# Bukkit
adapterVersion=1.16.1-20200628.024544-5
spigotVersion=1.16.1-R0.1-SNAPSHOT
adapterVersion=1.16.2-20200815.181223-2
spigotVersion=1.16.2-R0.1-SNAPSHOT
# Sponge
adapterSpongeVersion=1.12.2-20200627.042712-12
commonVersion=1.12.2-7.1.7-SNAPSHOT

View File

@ -183,6 +183,7 @@ public void pasteRecords() {
final String SOURCE = PlainComponentSerializer.INSTANCE.serialize(MessageCache.getInstance().LABEL_SOURCE);
final String TARGET = PlainComponentSerializer.INSTANCE.serialize(MessageCache.getInstance().LABEL_TARGET);
final String USER = PlainComponentSerializer.INSTANCE.serialize(MessageCache.getInstance().LABEL_USER);
final String GROUP = PlainComponentSerializer.INSTANCE.serialize(MessageCache.getInstance().LABEL_GROUP);
final String CONTEXT = PlainComponentSerializer.INSTANCE.serialize(MessageCache.getInstance().LABEL_CONTEXT);
final String RESULT = PlainComponentSerializer.INSTANCE.serialize(MessageCache.getInstance().LABEL_RESULT);
debugOutput.add("| " + RECORD_END + " | " + DATE_FORMAT.format(new Date(endTime)) + "|");
@ -190,7 +191,7 @@ public void pasteRecords() {
debugOutput.add("| " + TIME_ELAPSED + " | " + elapsed + " seconds" + "|");
debugOutput.add("");
debugOutput.add("### " + OUTPUT) ;
debugOutput.add("| " + FLAG + " | " + TRUST + " | " + SOURCE + " | " + TARGET + " | " + LOCATION + " | " + USER + " | " + CONTEXT + " | " + RESULT + " |");
debugOutput.add("| " + FLAG + " | " + TRUST + " | " + SOURCE + " | " + TARGET + " | " + LOCATION + " | " + USER + "/" + GROUP + " | " + CONTEXT + " | " + RESULT + " |");
debugOutput.add("|------|-------|--------|--------|----------|------|----------|--------|");
debugOutput.addAll(this.records);

View File

@ -94,6 +94,7 @@ public class GDPlayerData implements PlayerData {
public Location<World> lastValidInspectLocation;
public Location<World> lastNonAirInspectLocation;
public boolean claimMode = false;
public boolean claimTool = true;
public ShovelType shovelMode = ShovelTypes.BASIC;
public GDClaim claimResizing;
@ -181,7 +182,7 @@ public class GDPlayerData implements PlayerData {
public boolean dataInitialized = false;
public boolean showNoClaimsFoundMessage = true;
public boolean useRestoreSchematic = false;
private boolean checkedDimensionHeight = false;
private final int worldMaxHeight;
public GDPlayerData(UUID worldUniqueId, String worldName, UUID playerUniqueId, Set<Claim> claims) {
this.worldUniqueId = worldUniqueId;
@ -202,6 +203,7 @@ public GDPlayerData(UUID worldUniqueId, String worldName, UUID playerUniqueId, S
contexts.add(new Context("server", PermissionUtil.getInstance().getServerName()));
}
}
this.worldMaxHeight = GriefDefenderPlugin.getInstance().dataStore.getClaimWorldManager(this.worldUniqueId).getWorldMaxHeight();
this.optionContexts = contexts;
this.refreshPlayerOptions();
}
@ -240,7 +242,6 @@ public void refreshPlayerOptions() {
this.userOptionBypassPlayerGamemode = PermissionUtil.getInstance().getPermissionValue(subject, GDPermissions.BYPASS_OPTION + "." + Options.PLAYER_GAMEMODE.getName().toLowerCase(), activeContexts).asBoolean();
this.playerID = subject.getUniqueId();
this.dataInitialized = true;
this.checkedDimensionHeight = false;
});
}
@ -704,15 +705,8 @@ public int getMinClaimZ(ClaimType type) {
@Override
public int getMaxClaimLevel() {
int maxClaimLevel = GDPermissionManager.getInstance().getInternalOptionValue(TypeToken.of(Integer.class), this.getSubject(), Options.MAX_LEVEL);
if (!this.checkedDimensionHeight) {
final World world = Sponge.getServer().getWorld(this.worldUniqueId).orElse(null);
if (world != null) {
final int buildHeight = world.getDimension().getBuildHeight() - 1;
if (buildHeight < maxClaimLevel) {
maxClaimLevel = buildHeight;
}
}
this.checkedDimensionHeight = true;
if (this.worldMaxHeight > -1 && this.worldMaxHeight < maxClaimLevel) {
maxClaimLevel = this.worldMaxHeight;
}
return maxClaimLevel;
}
@ -881,6 +875,7 @@ public void onDisconnect() {
this.createBlockVisualRevertRunnables.clear();
this.queuedVisuals.clear();
this.claimMode = false;
this.claimTool = true;
this.debugClaimPermissions = false;
this.ignoreClaims = false;
this.lastShovelLocation = null;

View File

@ -55,6 +55,7 @@
import com.griefdefender.claim.GDClaimManager;
import com.griefdefender.claim.GDSpongeClaimSchematic;
import com.griefdefender.command.CommandAdjustBonusClaimBlocks;
import com.griefdefender.command.CommandAdjustBonusClaimBlocksAll;
import com.griefdefender.command.CommandCallback;
import com.griefdefender.command.CommandClaimAbandon;
import com.griefdefender.command.CommandClaimAbandonAll;
@ -85,6 +86,7 @@
import com.griefdefender.command.CommandClaimIgnore;
import com.griefdefender.command.CommandClaimInfo;
import com.griefdefender.command.CommandClaimInherit;
import com.griefdefender.command.CommandClaimInvestigate;
import com.griefdefender.command.CommandClaimList;
import com.griefdefender.command.CommandClaimMode;
import com.griefdefender.command.CommandClaimName;
@ -102,6 +104,7 @@
import com.griefdefender.command.CommandClaimSpawn;
import com.griefdefender.command.CommandClaimSubdivision;
import com.griefdefender.command.CommandClaimTax;
import com.griefdefender.command.CommandClaimTool;
import com.griefdefender.command.CommandClaimTown;
import com.griefdefender.command.CommandClaimTransfer;
import com.griefdefender.command.CommandClaimUnban;
@ -233,6 +236,7 @@
import org.spongepowered.api.world.Location;
import org.spongepowered.api.world.World;
import org.spongepowered.api.world.storage.WorldProperties;
import org.spongepowered.common.SpongeImplHooks;
import java.io.IOException;
import java.io.InputStream;
@ -289,7 +293,18 @@ public class GriefDefenderPlugin {
public static final String PUBLIC_NAME = "[GDPublic]";
public static final String WORLD_USER_NAME = "[GDWorld]";
public static GDPermissionHolder DEFAULT_HOLDER;
public static final String DEFAULT_GROUP_NAME = "default";
public static final String GD_CLAIM_GROUP_NAME = "griefdefender_claim";
public static final String GD_DEFAULT_GROUP_NAME = "griefdefender_default";
public static final String GD_DEFINITION_GROUP_NAME = "griefdefender_definition";
public static final String GD_OPTION_GROUP_NAME = "griefdefender_option";
public static final String GD_OVERRIDE_GROUP_NAME = "griefdefender_override";
public static GDPermissionGroup DEFAULT_HOLDER;
public static GDPermissionGroup GD_DEFAULT_HOLDER;
public static GDPermissionGroup GD_CLAIM_HOLDER;
public static GDPermissionGroup GD_DEFINITION_HOLDER;
public static GDPermissionGroup GD_OPTION_HOLDER;
public static GDPermissionGroup GD_OVERRIDE_HOLDER;
private SpongeCommandManager commandManager;
public BaseStorage dataStore;
@ -335,15 +350,16 @@ public Logger getLogger() {
public static void addEventLogEntry(Event event, Claim claim, Location<World> location, String sourceId, String targetId, GDPermissionHolder permissionSubject, String permission, String trust, Tristate result, Set<Context> contexts) {
final String eventName = event.getClass().getSimpleName().replace('$', '.').replace(".Impl", "");
final String eventLocation = location == null ? "none" : location.getBlockPosition().toString();
final GDPermissionHolder debugHolder = PermissionUtil.getInstance().getGDPermissionHolder(permissionSubject, contexts);
for (GDDebugData debugEntry : GriefDefenderPlugin.getInstance().getDebugUserMap().values()) {
final CommandSource debugSource = debugEntry.getSource();
final GDPermissionUser debugUser = debugEntry.getUser();
if (debugUser != null) {
if (permissionSubject == null) {
if (debugHolder == null) {
continue;
}
// Check event source user
if (!permissionSubject.getIdentifier().equals(debugUser.getUniqueId().toString())) {
if (!debugHolder.getIdentifier().equals(debugUser.getUniqueId().toString())) {
continue;
}
} else if (debugEntry.getClaimUniqueId() != null) {
@ -378,9 +394,9 @@ public static void addEventLogEntry(Event event, Claim claim, Location<World> lo
}
}
String messageUser = permissionSubject.getFriendlyName();
if (permissionSubject instanceof GDPermissionUser) {
messageUser = ((GDPermissionUser) permissionSubject).getName();
String messageUser = debugHolder.getFriendlyName().replaceAll("griefdefender_", "");
if (debugHolder instanceof GDPermissionUser) {
messageUser = ((GDPermissionUser) debugHolder).getName();
}
// record
@ -509,6 +525,10 @@ public void onChangeServiceProvider(ChangeServiceProviderEvent event) {
}
private boolean validateSpongeVersion() {
if (SpongeImplHooks.isDeobfuscatedEnvironment()) {
this.logger.info("De-obfuscated environment detected! Use at your own risk!");
return true;
}
if (Sponge.getPlatform().getContainer(org.spongepowered.api.Platform.Component.IMPLEMENTATION).getName().equals("SpongeForge")) {
if (Sponge.getPlatform().getContainer(org.spongepowered.api.Platform.Component.IMPLEMENTATION).getVersion().isPresent()) {
try {
@ -556,7 +576,28 @@ public void onPreInit(GamePreInitializationEvent event, Logger logger, Path path
instance = this;
this.getLogger().info("GriefDefender boot start.");
this.getLogger().info("Finished loading configuration.");
DEFAULT_HOLDER = new GDPermissionGroup("default");
DEFAULT_HOLDER = new GDPermissionGroup(DEFAULT_GROUP_NAME);
GD_DEFAULT_HOLDER = new GDPermissionGroup(GD_DEFAULT_GROUP_NAME);
GD_CLAIM_HOLDER = new GDPermissionGroup(GD_CLAIM_GROUP_NAME);
GD_DEFINITION_HOLDER = new GDPermissionGroup(GD_DEFINITION_GROUP_NAME);
GD_OPTION_HOLDER = new GDPermissionGroup(GD_OPTION_GROUP_NAME);
GD_OVERRIDE_HOLDER = new GDPermissionGroup(GD_OVERRIDE_GROUP_NAME);
if (!this.permissionProvider.hasGroupSubject(GD_OPTION_GROUP_NAME)) {
this.permissionProvider.createDefaultGroup(GD_OPTION_GROUP_NAME);
}
if (!this.permissionProvider.hasGroupSubject(GD_CLAIM_GROUP_NAME)) {
this.permissionProvider.createDefaultGroup(GD_CLAIM_GROUP_NAME);
}
if (!this.permissionProvider.hasGroupSubject(GD_OVERRIDE_GROUP_NAME)) {
this.permissionProvider.createDefaultGroup(GD_OVERRIDE_GROUP_NAME);
}
if (!this.permissionProvider.hasGroupSubject(GD_DEFAULT_GROUP_NAME)) {
this.permissionProvider.createDefaultGroup(GD_DEFAULT_GROUP_NAME);
}
if (!this.permissionProvider.hasGroupSubject(GD_DEFINITION_GROUP_NAME)) {
this.permissionProvider.createDefaultGroup(GD_DEFINITION_GROUP_NAME);
}
this.permissionProvider.refreshCachedData(DEFAULT_HOLDER);
PUBLIC_USER = new GDPermissionUser(PUBLIC_UUID, PUBLIC_NAME);
WORLD_USER = new GDPermissionUser(WORLD_USER_UUID, WORLD_USER_NAME);
this.getLogger().info("Registering GriefDefender API...");
@ -592,7 +633,6 @@ public void onServerAboutToStart(GameAboutToStartServerEvent event) {
ItemTypeRegistryModule.getInstance().registerDefaults();
this.loadConfig();
this.registerBaseCommands();
this.executor = Executors.newFixedThreadPool(GriefDefenderPlugin.getGlobalConfig().getConfig().thread.numExecutorThreads);
final Path migratedPath = this.configPath.resolve("_gpSpongeMigrated");
if (GriefDefenderPlugin.getGlobalConfig().getConfig().migrator.gpSpongeMigrator && !Files.exists(migratedPath)) {
GPSpongeMigrator.getInstance().migrateData();
@ -780,6 +820,7 @@ public void registerBaseCommands() {
manager.getCommandReplacements().addReplacement("griefdefender", "gd|griefdefender");
manager.registerCommand(new CommandAccessTrust());
manager.registerCommand(new CommandAdjustBonusClaimBlocks());
manager.registerCommand(new CommandAdjustBonusClaimBlocksAll());
manager.registerCommand(new CommandCallback());
manager.registerCommand(new CommandClaimAbandon());
manager.registerCommand(new CommandClaimAbandonAll());
@ -810,6 +851,7 @@ public void registerBaseCommands() {
manager.registerCommand(new CommandClaimIgnore());
manager.registerCommand(new CommandClaimInfo());
manager.registerCommand(new CommandClaimInherit());
manager.registerCommand(new CommandClaimInvestigate());
manager.registerCommand(new CommandClaimList());
manager.registerCommand(new CommandClaimMode());
manager.registerCommand(new CommandClaimName());
@ -827,6 +869,7 @@ public void registerBaseCommands() {
manager.registerCommand(new CommandClaimSpawn());
manager.registerCommand(new CommandClaimSubdivision());
manager.registerCommand(new CommandClaimTax());
manager.registerCommand(new CommandClaimTool());
manager.registerCommand(new CommandClaimTown());
manager.registerCommand(new CommandClaimTransfer());
manager.registerCommand(new CommandClaimUnban());
@ -1076,6 +1119,9 @@ public void loadConfig() {
messageStorage = new MessageStorage(localePath);
messageData = messageStorage.getConfig();
MessageCache.getInstance().loadCache();
if (this.executor == null) {
this.executor = Executors.newFixedThreadPool(GriefDefenderPlugin.getGlobalConfig().getConfig().thread.numExecutorThreads);
}
flagConfig = new FlagConfig(this.getConfigPath().resolve("flags.conf"));
// FlagDefinition registry needs to init after config load
FlagDefinitionRegistryModule.getInstance().registerDefaults();
@ -1089,7 +1135,6 @@ public void loadConfig() {
BaseStorage.globalConfig.save();
BaseStorage.USE_GLOBAL_PLAYER_STORAGE = !BaseStorage.globalConfig.getConfig().playerdata.useWorldPlayerData();
GDFlags.populateFlagStatus();
PermissionHolderCache.getInstance().getOrCreatePermissionCache(GriefDefenderPlugin.DEFAULT_HOLDER).invalidateAll();
CLAIM_BLOCK_SYSTEM = BaseStorage.globalConfig.getConfig().playerdata.claimBlockSystem;
final GDItemType defaultModTool = ItemTypeRegistryModule.getInstance().getById("minecraft:golden_shovel").orElse(null);
final GDBlockType defaultCreateVisualBlock = BlockTypeRegistryModule.getInstance().getById("minecraft:diamond_block").orElse(null);

View File

@ -112,6 +112,7 @@ public static MessageCache getInstance() {
public Component CLAIMLIST_UI_RETURN_CLAIMSLIST;
public Component CLAIMLIST_UI_TITLE;
public Component CLAIMLIST_UI_TITLE_CHILD_CLAIMS;
public Component CLAIMTOOL_NOT_ENABLED;
public Component COMMAND_CLAIMBUY_TITLE;
public Component COMMAND_CLAIMCLEAR_UUID_DENY;
public Component COMMAND_CLAIMFLAGDEBUG_DISABLED;
@ -122,6 +123,8 @@ public static MessageCache getInstance() {
public Component COMMAND_CLAIMINHERIT_ENABLED;
public Component COMMAND_CLAIMMODE_DISABLED;
public Component COMMAND_CLAIMMODE_ENABLED;
public Component COMMAND_CLAIMTOOL_DISABLED;
public Component COMMAND_CLAIMTOOL_ENABLED;
public Component COMMAND_CUBOID_DISABLED;
public Component COMMAND_CUBOID_ENABLED;
public Component COMMAND_INHERIT_ONLY_CHILD;
@ -574,6 +577,7 @@ public void loadCache() {
CLAIMLIST_UI_RETURN_CLAIMSLIST = MessageStorage.MESSAGE_DATA.getMessage("claimlist-ui-return-claimlist");
CLAIMLIST_UI_TITLE = MessageStorage.MESSAGE_DATA.getMessage("claimlist-ui-title");
CLAIMLIST_UI_TITLE_CHILD_CLAIMS = MessageStorage.MESSAGE_DATA.getMessage("claimlist-ui-title-child-claims");
CLAIMTOOL_NOT_ENABLED = MessageStorage.MESSAGE_DATA.getMessage("claimtool-not-enabled");
COMMAND_CLAIMBUY_TITLE = MessageStorage.MESSAGE_DATA.getMessage("command-claimbuy-title");
COMMAND_CLAIMCLEAR_UUID_DENY = MessageStorage.MESSAGE_DATA.getMessage("command-claimclear-uuid-deny");
COMMAND_CLAIMFLAGDEBUG_DISABLED = MessageStorage.MESSAGE_DATA.getMessage("command-claimflagdebug-disabled");
@ -584,6 +588,8 @@ public void loadCache() {
COMMAND_CLAIMINHERIT_ENABLED = MessageStorage.MESSAGE_DATA.getMessage("command-claiminherit-enabled");
COMMAND_CLAIMMODE_DISABLED = MessageStorage.MESSAGE_DATA.getMessage("command-claimmode-disabled");
COMMAND_CLAIMMODE_ENABLED = MessageStorage.MESSAGE_DATA.getMessage("command-claimmode-enabled");
COMMAND_CLAIMTOOL_DISABLED = MessageStorage.MESSAGE_DATA.getMessage("command-claimtool-disabled");
COMMAND_CLAIMTOOL_ENABLED = MessageStorage.MESSAGE_DATA.getMessage("command-claimtool-enabled");
COMMAND_CUBOID_DISABLED = MessageStorage.MESSAGE_DATA.getMessage("command-cuboid-disabled");
COMMAND_CUBOID_ENABLED = MessageStorage.MESSAGE_DATA.getMessage("command-cuboid-enabled");
COMMAND_INHERIT_ONLY_CHILD = MessageStorage.MESSAGE_DATA.getMessage("command-inherit-only-child");

View File

@ -40,7 +40,6 @@
import org.spongepowered.api.service.user.UserStorageService;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.TimeUnit;
public class PermissionHolderCache {
@ -50,7 +49,6 @@ public class PermissionHolderCache {
.build();
private final Cache<String, GDPermissionGroup> groupCache = Caffeine.newBuilder().expireAfterAccess(10, TimeUnit.MINUTES)
.build();
private final ConcurrentHashMap<GDPermissionHolder, Cache<Integer, Tristate>> permissionCache = new ConcurrentHashMap<>();
public GDPermissionUser getOrCreateUser(User user) {
if (user == null) {
@ -129,21 +127,6 @@ public GDPermissionHolder getOrCreateHolder(String identifier) {
return this.getOrCreateUser(uuid);
}
public Cache<Integer, Tristate> getOrCreatePermissionCache(GDPermissionHolder holder) {
Cache<Integer, Tristate> cache = this.permissionCache.get(holder);
if (cache == null) {
cache = Caffeine.newBuilder().expireAfterAccess(10, TimeUnit.MINUTES).build();
this.permissionCache.put(holder, cache);
}
return cache;
}
public void invalidateAllPermissionCache() {
for (Cache<Integer, Tristate> cache : this.permissionCache.values()) {
cache.invalidateAll();
}
}
static {
instance = new PermissionHolderCache();
}

View File

@ -1132,6 +1132,18 @@ public ClaimResult checkArea(boolean resize) {
continue;
}
// validate this claim exists
boolean claimExists = false;
for (Claim claim : this.worldClaimManager.getWorldClaims()) {
if (claim.getUniqueId().equals(chunkClaim.getUniqueId())) {
claimExists = true;
break;
}
}
if (!claimExists) {
//GriefDefenderPlugin.getInstance().getLogger().warn("Detected Ghost chunk claim with the following data [UUID: " + chunkClaim.getUniqueId() + ", Owner: " + chunkClaim.getOwnerName() + ", Type: " + chunkClaim.getType().getName() + "]. Ignoring...");
continue;
}
// First check if new claim is crossing another
if (this.isBandingAcross(gpChunkClaim) || gpChunkClaim.isBandingAcross(this)) {
return new GDClaimResult(gpChunkClaim, ClaimResultType.OVERLAPPING_CLAIM);

View File

@ -48,7 +48,6 @@
import com.griefdefender.permission.GDPermissionManager;
import com.griefdefender.permission.GDPermissionUser;
import com.griefdefender.storage.BaseStorage;
import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap;
import net.kyori.text.Component;
import net.kyori.text.TextComponent;
import net.kyori.text.serializer.plain.PlainComponentSerializer;
@ -69,6 +68,7 @@
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
@ -81,6 +81,7 @@ public class GDClaimManager implements ClaimManager {
private static final BaseStorage DATASTORE = GriefDefenderPlugin.getInstance().dataStore;
private UUID worldUniqueId;
private String worldName;
private final int worldMaxHeight;
// Player UUID -> player data
private Map<UUID, GDPlayerData> playerDataList = Maps.newHashMap();
@ -89,13 +90,18 @@ public class GDClaimManager implements ClaimManager {
// Claim UUID -> Claim
private Map<UUID, Claim> claimUniqueIdMap = Maps.newHashMap();
// String -> Claim
private Map<Long, Set<Claim>> chunksToClaimsMap = new Long2ObjectOpenHashMap<>(4096);
private Map<Long, GDChunk> chunksToGDChunks = new Long2ObjectOpenHashMap<>(4096);
private Map<Long, Set<Claim>> chunksToClaimsMap = new HashMap<>();
private Map<Long, GDChunk> chunksToGDChunks = new HashMap<>();
private GDClaim theWildernessClaim;
public GDClaimManager(World world) {
this.worldUniqueId = world.getUniqueId();
this.worldName = world.getName();
if (GriefDefenderPlugin.getActiveConfig(this.worldUniqueId).getConfig().claim.restrictWorldMaxHeight) {
this.worldMaxHeight = world.getDimension().getBuildHeight() - 1;
} else {
this.worldMaxHeight = -1;
}
}
public GDPlayerData getOrCreatePlayerData(UUID playerUniqueId) {
@ -648,6 +654,10 @@ public UUID getWorldId() {
return this.worldUniqueId;
}
public int getWorldMaxHeight() {
return this.worldMaxHeight;
}
public GDChunk getChunk(Chunk chunk) {
return this.getChunk(chunk, true);
}

View File

@ -42,6 +42,7 @@
import com.griefdefender.api.permission.ResultTypes;
import com.griefdefender.api.permission.flag.Flag;
import com.griefdefender.api.permission.flag.FlagData;
import com.griefdefender.api.permission.flag.Flags;
import com.griefdefender.cache.MessageCache;
import com.griefdefender.cache.PermissionHolderCache;
import com.griefdefender.claim.GDClaim;
@ -425,7 +426,7 @@ protected void showFlagPermissions(GDPermissionUser src, GDClaim claim, MenuType
overrideContexts.add(claim.getOverrideClaimContext());
Map<String, UIFlagData> filteredContextMap = new HashMap<>();
for (Map.Entry<Set<Context>, Map<String, Boolean>> mapEntry : PermissionUtil.getInstance().getTransientPermissions(this.subject).entrySet()) {
for (Map.Entry<Set<Context>, Map<String, Boolean>> mapEntry : PermissionUtil.getInstance().getTransientPermissions(GriefDefenderPlugin.GD_DEFAULT_HOLDER).entrySet()) {
final Set<Context> contextSet = mapEntry.getKey();
if (contextSet.contains(claim.getDefaultTypeContext())) {
this.addFilteredContexts(filteredContextMap, contextSet, MenuType.DEFAULT, mapEntry.getValue());
@ -435,7 +436,7 @@ protected void showFlagPermissions(GDPermissionUser src, GDClaim claim, MenuType
}
final List<Claim> inheritParents = claim.getInheritedParents();
for (Map.Entry<Set<Context>, Map<String, Boolean>> mapEntry : PermissionUtil.getInstance().getPermanentPermissions(this.subject).entrySet()) {
for (Map.Entry<Set<Context>, Map<String, Boolean>> mapEntry : PermissionUtil.getInstance().getAllPermanentPermissions().entrySet()) {
final Set<Context> contextSet = mapEntry.getKey();
if (contextSet.contains(claim.getDefaultTypeContext())) {
this.addFilteredContexts(filteredContextMap, contextSet, MenuType.DEFAULT, mapEntry.getValue());
@ -626,17 +627,21 @@ private Component getCustomClickableText(GDPermissionUser src, GDClaim claim, GD
boolean hasHover = false;
TextComponent.Builder hoverBuilder = TextComponent.builder();
final Player player = src.getOnlinePlayer();
final boolean canIgnoreClaim = src.getInternalPlayerData().canIgnoreClaim(claim);
boolean hasEditPermission = true;
Component denyReason = claim.allowEdit(player);
if (denyReason != null) {
hasEditPermission = false;
hasHover = true;
Component denyReason = null;
if (!canIgnoreClaim) {
denyReason = claim.allowEdit(player);
if (denyReason != null) {
hasEditPermission = false;
hasHover = true;
}
}
final boolean isAdminGroup = GriefDefenderPlugin.getFlagConfig().getConfig().customFlags.getGroups().get(flagGroup).isAdminGroup();
final String permission = isAdminGroup ? GDPermissions.FLAG_CUSTOM_ADMIN_BASE : GDPermissions.FLAG_CUSTOM_USER_BASE;
// check flag perm
if (!player.hasPermission(permission + "." + flagGroup + "." + customFlag.getName())) {
if (!canIgnoreClaim && !player.hasPermission(permission + "." + flagGroup + "." + customFlag.getName())) {
hoverBuilder.append(MessageCache.getInstance().PERMISSION_FLAG_USE).append("\n");
hasEditPermission = false;
hasHover = true;
@ -653,8 +658,7 @@ private Component getCustomClickableText(GDPermissionUser src, GDClaim claim, GD
hasOverride = true;
hasEditPermission = false;
} else if (activeData.getType() == GDActiveFlagData.Type.OWNER_OVERRIDE_PARENT_INHERIT || activeData.getType() == GDActiveFlagData.Type.CLAIM_PARENT_INHERIT) {
if (claim.allowEdit(src) != null) {
hasEditPermission = false;
if (!hasEditPermission) {
parentInheritUniqueId = activeData.getInheritParentUniqueId();
parentInheritFriendlyType = activeData.getInheritParentFriendlyType();
}
@ -912,14 +916,14 @@ public GDActiveFlagData getActiveDefinitionResult(GDClaim claim, GDFlagDefinitio
if (!claim.isWilderness()) {
permissionContexts.add(ClaimContexts.GLOBAL_DEFAULT_CONTEXT);
permissionContexts.add(ClaimContexts.USER_DEFAULT_CONTEXT);
result = PermissionUtil.getInstance().getPermissionValue(claim, (GDPermissionHolder) flagDefinition.getSubject(), flagData.getFlag().getPermission(), permissionContexts, PermissionDataType.ALL);
result = PermissionUtil.getInstance().getPermissionValue(claim, (GDPermissionHolder) flagDefinition.getSubject(), flagData.getFlag().getPermission(), permissionContexts, PermissionDataType.PERSISTENT);
if (result != Tristate.UNDEFINED) {
return new GDActiveFlagData(flagDefinition, flagData, result, permissionContexts, GDActiveFlagData.Type.DEFAULT);
}
permissionContexts.remove(ClaimContexts.USER_DEFAULT_CONTEXT);
} else {
permissionContexts.add(ClaimContexts.GLOBAL_DEFAULT_CONTEXT);
result = PermissionUtil.getInstance().getPermissionValue(claim, (GDPermissionHolder) flagDefinition.getSubject(), flagData.getFlag().getPermission(), permissionContexts, PermissionDataType.ALL);
result = PermissionUtil.getInstance().getPermissionValue(claim, (GDPermissionHolder) flagDefinition.getSubject(), flagData.getFlag().getPermission(), permissionContexts, PermissionDataType.PERSISTENT);
if (result != Tristate.UNDEFINED) {
return new GDActiveFlagData(flagDefinition, flagData, result, permissionContexts, GDActiveFlagData.Type.DEFAULT);
}
@ -1083,11 +1087,11 @@ public int compare(Context o1, Context o2) {
return textBuilder.build();
}
private Consumer<CommandSource> createCustomFlagConsumer(GDPermissionUser src, GDClaim claim, GDFlagDefinition customFlag, Tristate currentValue, String flagGroup) {
private Consumer<CommandSource> createCustomFlagConsumer(GDPermissionUser src, GDClaim claim, GDFlagDefinition flagDefinition, Tristate currentValue, String flagGroup) {
final Player player = src.getOnlinePlayer();
return consumer -> {
GDCauseStackManager.getInstance().pushCause(player);
Set<Context> definitionContexts = new HashSet<>(customFlag.getContexts());
Set<Context> definitionContexts = new HashSet<>(flagDefinition.getContexts());
boolean addClaimContext = false;
boolean addClaimOverrideContext = false;
final Iterator<Context> iterator = definitionContexts.iterator();
@ -1106,28 +1110,15 @@ private Consumer<CommandSource> createCustomFlagConsumer(GDPermissionUser src, G
} else if (addClaimContext) {
definitionContexts.add(claim.getContext());
}
CompletableFuture<PermissionResult> result = null;
for (FlagData flagData : customFlag.getFlagData()) {
final Set<Context> newContexts = new HashSet<>(definitionContexts);
newContexts.addAll(flagData.getContexts());
Tristate newValue = Tristate.UNDEFINED;
if (currentValue == Tristate.TRUE) {
newValue = Tristate.FALSE;
} else {
newValue = Tristate.TRUE;
}
final Flag flag = flagData.getFlag();
GDFlagPermissionEvent.Set event = new GDFlagPermissionEvent.Set(this.subject, flagData.getFlag(), newValue, newContexts);
GriefDefender.getEventManager().post(event);
if (event.cancelled()) {
return;
}
result = GriefDefenderPlugin.getInstance().getPermissionProvider().setPermissionValue(GriefDefenderPlugin.DEFAULT_HOLDER, flag, newValue, newContexts);
Tristate newValue = Tristate.UNDEFINED;
if (currentValue == Tristate.TRUE) {
newValue = Tristate.FALSE;
} else {
newValue = Tristate.TRUE;
}
result.thenAccept(r -> {
PermissionUtil.getInstance().setFlagDefinition(GriefDefenderPlugin.GD_DEFINITION_HOLDER, flagDefinition, newValue, definitionContexts, false).thenAccept(r -> {
Sponge.getScheduler().createSyncExecutor(GDBootstrap.getInstance()).execute(() -> {
GDCauseStackManager.getInstance().popCause();
showCustomFlags(src, claim, flagGroup);

View File

@ -384,7 +384,7 @@ protected void showOptionPermissions(GDPermissionUser src, GDClaim claim, MenuTy
overrideContexts.add(claim.getOverrideClaimContext());
Map<String, OptionData> filteredContextMap = new HashMap<>();
for (Map.Entry<Set<Context>, Map<String, String>> mapEntry : PermissionUtil.getInstance().getTransientOptions(this.subject).entrySet()) {
for (Map.Entry<Set<Context>, Map<String, String>> mapEntry : PermissionUtil.getInstance().getTransientOptions(GriefDefenderPlugin.GD_OPTION_HOLDER).entrySet()) {
final Set<Context> contextSet = mapEntry.getKey();
if (contextSet.contains(claim.getDefaultTypeContext()) || (contextSet.contains(ClaimContexts.GLOBAL_DEFAULT_CONTEXT) || (!claim.isWilderness() && contextSet.contains(ClaimContexts.USER_DEFAULT_CONTEXT)))) {
this.addFilteredContexts(src, filteredContextMap, contextSet, MenuType.DEFAULT, mapEntry.getValue());

View File

@ -71,19 +71,14 @@ public void execute(CommandSource src, User user, int amount, @Optional String w
return;
}
// parse the adjustment amount
int adjustment = amount;
//User user = args.<User>getOne("user").get();
// give blocks to player
GDPlayerData playerData = GriefDefenderPlugin.getInstance().dataStore.getOrCreatePlayerData(worldProperties.getUniqueId(), user.getUniqueId());
playerData.setBonusClaimBlocks(playerData.getBonusClaimBlocks() + adjustment);
playerData.setBonusClaimBlocks(playerData.getBonusClaimBlocks() + amount);
final Component message = GriefDefenderPlugin.getInstance().messageData.getMessage(MessageStorage.ADJUST_BONUS_BLOCKS_SUCCESS, ImmutableMap.of(
"player", user.getName(),
"amount", adjustment,
"total", playerData.getBonusClaimBlocks()));
"amount", amount,
"total", playerData.getBonusClaimBlocks() + amount));
TextAdapter.sendComponent(src, message);
GriefDefenderPlugin.getInstance().getLogger().info(
src.getName() + " adjusted " + user.getName() + "'s bonus claim blocks by " + adjustment + ".");
src.getName() + " adjusted " + user.getName() + "'s bonus claim blocks by " + amount + ".");
}
}

View File

@ -0,0 +1,106 @@
/*
* 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;
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 co.aikar.commands.annotation.Syntax;
import com.google.common.collect.ImmutableMap;
import com.griefdefender.GDPlayerData;
import com.griefdefender.GriefDefenderPlugin;
import com.griefdefender.cache.MessageCache;
import com.griefdefender.configuration.MessageStorage;
import com.griefdefender.permission.GDPermissions;
import com.griefdefender.text.action.GDCallbackHolder;
import net.kyori.text.Component;
import net.kyori.text.TextComponent;
import net.kyori.text.adapter.spongeapi.TextAdapter;
import net.kyori.text.event.ClickEvent;
import net.kyori.text.event.HoverEvent;
import net.kyori.text.format.TextColor;
import java.util.function.Consumer;
import org.spongepowered.api.Sponge;
import org.spongepowered.api.command.CommandSource;
import org.spongepowered.api.entity.living.player.Player;
@CommandAlias("%griefdefender")
@CommandPermission(GDPermissions.COMMAND_SET_ACCRUED_CLAIM_BLOCKS_ALL)
public class CommandAdjustBonusClaimBlocksAll extends BaseCommand {
@CommandAlias("acball|adjustclaimblocksall")
@Description("Adjusts bonus claim block total for all online players by amount specified")
@Syntax("<amount>")
@Subcommand("player adjustbonusblocksall")
public void execute(CommandSource src, int amount) {
if (!(src instanceof Player)) {
updateOnlinePlayerBonusBlocks(src, amount);
return;
}
final Component message = GriefDefenderPlugin.getInstance().messageData.getMessage(MessageStorage.ADJUST_BONUS_BLOCKS_ALL_WARNING, ImmutableMap.of(
"amount", amount));
final Component confirmationText = TextComponent.builder()
.append(message)
.append(TextComponent.builder()
.append("\n[")
.append(MessageCache.getInstance().LABEL_CONFIRM.color(TextColor.GREEN))
.append("]\n")
.clickEvent(ClickEvent.runCommand(GDCallbackHolder.getInstance().createCallbackRunCommand(src, createConfirmationConsumer(src, amount), true)))
.hoverEvent(HoverEvent.showText(MessageCache.getInstance().UI_CLICK_CONFIRM)).build())
.build();
TextAdapter.sendComponent(src, confirmationText);
}
private static Consumer<CommandSource> createConfirmationConsumer(CommandSource src, int amount) {
return confirm -> {
updateOnlinePlayerBonusBlocks(src, amount);
};
}
private static void updateOnlinePlayerBonusBlocks(CommandSource src, int amount) {
int count = 0;
for (Player player : Sponge.getServer().getOnlinePlayers()) {
// give blocks to player
GDPlayerData playerData = GriefDefenderPlugin.getInstance().dataStore.getOrCreateGlobalPlayerData(player.getUniqueId());
playerData.setBonusClaimBlocks(playerData.getBonusClaimBlocks() + amount);
count++;
}
final Component message = GriefDefenderPlugin.getInstance().messageData.getMessage(MessageStorage.ADJUST_BONUS_BLOCKS_ALL_SUCCESS, ImmutableMap.of(
"count", count,
"amount", amount));
TextAdapter.sendComponent(src, message);
GriefDefenderPlugin.getInstance().getLogger().info(
src.getName() + " adjusted " + count + " online player's bonus claim blocks by " + amount + ".");
}
}

View File

@ -191,7 +191,15 @@ private static Consumer<CommandSource> createConfirmationConsumer(Player source,
playerData.townChat = false;
}
if (!claim.isSubdivision() && !claim.isAdminClaim()) {
if (claim.isSubdivision()) {
int remainingBlocks = playerData.getRemainingClaimBlocks();
final Component message = GriefDefenderPlugin.getInstance().messageData.getMessage(MessageStorage.ABANDON_SUCCESS, ImmutableMap.of(
"amount", remainingBlocks));
GriefDefenderPlugin.sendMessage(source, message);
return;
}
if (!claim.isAdminClaim()) {
final double abandonReturnRatio = GDPermissionManager.getInstance().getInternalOptionValue(TypeToken.of(Double.class), user, Options.ABANDON_RETURN_RATIO, claim);
if (GriefDefenderPlugin.getInstance().isEconomyModeEnabled()) {
final Account playerAccount = GriefDefenderPlugin.getInstance().economyService.get().getOrCreateAccount(user.getUniqueId()).orElse(null);

View File

@ -187,7 +187,8 @@ private static Consumer<CommandSource> createConfirmationConsumer(GDPermissionUs
}
final double abandonReturnRatio = GDPermissionManager.getInstance().getInternalOptionValue(TypeToken.of(Double.class), user, Options.ABANDON_RETURN_RATIO, claim);
if (GriefDefenderPlugin.getInstance().isEconomyModeEnabled()) {
refund += claim.getClaimBlocks() * abandonReturnRatio;
final double requiredClaimBlocks = claim.getClaimBlocks() * abandonReturnRatio;
refund += requiredClaimBlocks * ((GDClaim) claim).getOwnerEconomyBlockCost();
} else {
playerData.setAccruedClaimBlocks(playerData.getAccruedClaimBlocks() - ((int) Math.ceil(claim.getClaimBlocks() * (1 - abandonReturnRatio))));
}

View File

@ -177,6 +177,7 @@ public void execute(CommandSource src, String[] args) {
final GDPermissionUser owner = PermissionHolderCache.getInstance().getOrCreateUser(claim.getOwnerUniqueId());
final UUID ownerUniqueId = claim.getOwnerUniqueId();
final boolean isAdmin = playerData.canManageAdminClaims;
final boolean canPlayerTeleport = (player != null && PermissionUtil.getInstance().canPlayerTeleport(player, gdClaim)) ? true : false;
// if not owner of claim, validate perms
if (!isAdmin && !player.getUniqueId().equals(claim.getOwnerUniqueId())) {
if (!gdClaim.getInternalClaimData().getContainers().contains(player.getUniqueId())
@ -513,66 +514,72 @@ public void execute(CommandSource src, String[] args) {
.append(getClickableInfoText(src, claim, RAID_OVERRIDE, GDPermissionManager.getInstance().getInternalOptionValue(TypeToken.of(Boolean.class), owner, Options.RAID, gdClaim) == true ? TextComponent.of("ON", TextColor.GREEN) : TextComponent.of("OFF", TextColor.RED))).build();
*/
Component claimSpawn = null;
if (claim.getData().getSpawnPos().isPresent() && player != null && PermissionUtil.getInstance().canPlayerTeleport(player, gdClaim)) {
if (claim.getData().getSpawnPos().isPresent() && player != null) {
Vector3i spawnPos = claim.getData().getSpawnPos().get();
Location<World> spawnLoc = new Location<>(gdClaim.getWorld(), spawnPos.getX(), spawnPos.getY(), spawnPos.getZ());
claimSpawn = TextComponent.builder()
TextComponent.Builder spawnBuilder = TextComponent.builder()
.append(MessageCache.getInstance().LABEL_SPAWN.color(TextColor.GREEN))
.append(" : ")
.append(spawnPos.toString(), TextColor.GRAY)
.clickEvent(ClickEvent.runCommand(GDCallbackHolder.getInstance().createCallbackRunCommand(CommandHelper.createTeleportConsumer(player, spawnLoc, claim, true))))
.hoverEvent(HoverEvent.showText(MessageCache.getInstance().CLAIMINFO_UI_TELEPORT_SPAWN))
.build();
.append(spawnPos.toString(), TextColor.GRAY);
if (canPlayerTeleport) {
spawnBuilder.clickEvent(ClickEvent.runCommand(GDCallbackHolder.getInstance().createCallbackRunCommand(CommandHelper.createTeleportConsumer(player, spawnLoc, claim, true))))
.hoverEvent(HoverEvent.showText(MessageCache.getInstance().CLAIMINFO_UI_TELEPORT_SPAWN));
}
claimSpawn = spawnBuilder.build();
}
Component southCorners = null;
Component northCorners = null;
if (!claim.isWilderness() && player != null && PermissionUtil.getInstance().canPlayerTeleport(player, gdClaim)) {
Component southWestCorner = TextComponent.builder()
if (!claim.isWilderness() && player != null) {
TextComponent.Builder southWestCorner = TextComponent.builder()
.append("SW", TextColor.LIGHT_PURPLE)
.append(" : ")
.append(VecHelper.toVector3i(southWest).toString(), TextColor.GRAY)
.append(" ")
.append(VecHelper.toVector3i(southWest).toString(), TextColor.GRAY);
if (canPlayerTeleport) {
southWestCorner.append(" ")
.clickEvent(ClickEvent.runCommand(GDCallbackHolder.getInstance().createCallbackRunCommand(CommandHelper.createTeleportConsumer(player, southWest, claim))))
.hoverEvent(HoverEvent.showText(MessageStorage.MESSAGE_DATA.getMessage(MessageStorage.CLAIMINFO_UI_TELEPORT_DIRECTION,
ImmutableMap.of("direction", TextComponent.of("SW").color(TextColor.AQUA)))))
.build();
Component southEastCorner = TextComponent.builder()
ImmutableMap.of("direction", TextComponent.of("SW").color(TextColor.AQUA)))));
}
TextComponent.Builder southEastCorner = TextComponent.builder()
.append("SE", TextColor.LIGHT_PURPLE)
.append(" : ")
.append(VecHelper.toVector3i(southEast).toString(), TextColor.GRAY)
.append(" ")
.append(VecHelper.toVector3i(southEast).toString(), TextColor.GRAY);
if (canPlayerTeleport) {
southEastCorner.append(" ")
.clickEvent(ClickEvent.runCommand(GDCallbackHolder.getInstance().createCallbackRunCommand(CommandHelper.createTeleportConsumer(player, southEast, claim))))
.hoverEvent(HoverEvent.showText(MessageStorage.MESSAGE_DATA.getMessage(MessageStorage.CLAIMINFO_UI_TELEPORT_DIRECTION,
ImmutableMap.of("direction", TextComponent.of("SE").color(TextColor.AQUA)))))
.build();
ImmutableMap.of("direction", TextComponent.of("SE").color(TextColor.AQUA)))));
}
southCorners = TextComponent.builder()
.append(MessageCache.getInstance().CLAIMINFO_UI_SOUTH_CORNERS.color(TextColor.YELLOW))
.append(" : ")
.append(southWestCorner)
.append(southEastCorner).build();
Component northWestCorner = TextComponent.builder()
.append(southWestCorner.build())
.append(southEastCorner.build()).build();
TextComponent.Builder northWestCorner = TextComponent.builder()
.append("NW", TextColor.LIGHT_PURPLE)
.append(" : ")
.append(VecHelper.toVector3i(northWest).toString(), TextColor.GRAY)
.append(" ")
.append(VecHelper.toVector3i(northWest).toString(), TextColor.GRAY);
if (canPlayerTeleport) {
northWestCorner.append(" ")
.clickEvent(ClickEvent.runCommand(GDCallbackHolder.getInstance().createCallbackRunCommand(CommandHelper.createTeleportConsumer(player, northWest, claim))))
.hoverEvent(HoverEvent.showText(MessageStorage.MESSAGE_DATA.getMessage(MessageStorage.CLAIMINFO_UI_TELEPORT_DIRECTION,
ImmutableMap.of("direction", TextComponent.of("NW").color(TextColor.AQUA)))))
.build();
Component northEastCorner = TextComponent.builder()
ImmutableMap.of("direction", TextComponent.of("NW").color(TextColor.AQUA)))));
}
TextComponent.Builder northEastCorner = TextComponent.builder()
.append("NE", TextColor.LIGHT_PURPLE)
.append(" : ")
.append(VecHelper.toVector3i(northEast).toString(), TextColor.GRAY)
.append(" ")
.append(VecHelper.toVector3i(northEast).toString(), TextColor.GRAY);
if (canPlayerTeleport) {
northEastCorner.append(" ")
.clickEvent(ClickEvent.runCommand(GDCallbackHolder.getInstance().createCallbackRunCommand(CommandHelper.createTeleportConsumer(player, northEast, claim))))
.hoverEvent(HoverEvent.showText(MessageStorage.MESSAGE_DATA.getMessage(MessageStorage.CLAIMINFO_UI_TELEPORT_DIRECTION,
ImmutableMap.of("direction", TextComponent.of("NE").color(TextColor.AQUA)))))
.build();
ImmutableMap.of("direction", TextComponent.of("NE").color(TextColor.AQUA)))));
}
northCorners = TextComponent.builder()
.append(MessageCache.getInstance().CLAIMINFO_UI_NORTH_CORNERS.color(TextColor.YELLOW))
.append(" : ")
.append(northWestCorner)
.append(northEastCorner).build();
.append(northWestCorner.build())
.append(northEastCorner.build()).build();
}
Component dateCreated = TextComponent.builder()
.append(MessageCache.getInstance().LABEL_CREATED.color(TextColor.YELLOW))
@ -644,9 +651,17 @@ public void execute(CommandSource src, String[] args) {
}
textList.add(claimGreeting);
textList.add(claimFarewell);
textList.add(dateCreated);
textList.add(dateLastActive);
textList.add(claimId);
if (allowEdit == null || isAdmin) {
if (src.hasPermission(GDPermissions.COMMAND_CLAIM_INFO_OTHERS_CREATION_DATE)) {
textList.add(dateCreated);
}
if (src.hasPermission(GDPermissions.COMMAND_CLAIM_INFO_OTHERS_LAST_ACTIVE)) {
textList.add(dateLastActive);
}
if (src.hasPermission(GDPermissions.COMMAND_CLAIM_INFO_OTHERS_CLAIM_UUID)) {
textList.add(claimId);
}
}
if (northCorners != null && southCorners != null) {
textList.add(northCorners);
textList.add(southCorners);
@ -869,7 +884,8 @@ private static Consumer<CommandSource> createClaimTypeConsumer(CommandSource src
TextAdapter.sendComponent(src, MessageCache.getInstance().CLAIM_NOT_YOURS);
return;
}
final ClaimResult result = claim.changeType(clicked, Optional.of(player.getUniqueId()), src);
// Use same claim owner when changing claim type
final ClaimResult result = claim.changeType(clicked, Optional.empty(), src);
if (result.successful()) {
CommandHelper.executeCommand(src, "claiminfo", gpClaim.getUniqueId().toString());
} else {

View File

@ -0,0 +1,207 @@
/*
* 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;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import com.google.common.collect.ImmutableMap;
import com.google.common.reflect.TypeToken;
import com.griefdefender.GDPlayerData;
import com.griefdefender.GriefDefenderPlugin;
import com.griefdefender.api.claim.Claim;
import com.griefdefender.api.permission.option.Options;
import com.griefdefender.api.permission.option.type.CreateModeTypes;
import com.griefdefender.cache.MessageCache;
import com.griefdefender.claim.GDClaim;
import com.griefdefender.configuration.MessageStorage;
import com.griefdefender.internal.provider.GDWorldEditProvider;
import com.griefdefender.internal.util.BlockUtil;
import com.griefdefender.internal.visual.GDClaimVisual;
import com.griefdefender.permission.GDPermissionManager;
import com.griefdefender.permission.GDPermissions;
import com.griefdefender.util.PlayerUtil;
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.Optional;
import co.aikar.commands.annotation.Subcommand;
import co.aikar.commands.annotation.Syntax;
import net.kyori.text.Component;
import org.spongepowered.api.entity.living.player.Player;
import org.spongepowered.api.world.Location;
import org.spongepowered.api.world.World;
@CommandAlias("%griefdefender")
@CommandPermission(GDPermissions.COMMAND_CLAIM_INVESTIGATE)
public class CommandClaimInvestigate extends BaseCommand {
@CommandAlias("claiminvestigate")
@Description("Investigates the target or nearby claims.")
@Syntax("[area|hide|hideall]")
@Subcommand("claim investigate")
public void execute(Player player, @Optional String cmd) {
final GDPlayerData playerData = GriefDefenderPlugin.getInstance().dataStore.getOrCreatePlayerData(player.getWorld(), player.getUniqueId());
if (!playerData.queuedVisuals.isEmpty()) {
final Component message = GriefDefenderPlugin.getInstance().messageData.getMessage(MessageStorage.VISUAL_UPDATE_IN_PROGRESS,
ImmutableMap.of(
"count", playerData.queuedVisuals.size()));
GriefDefenderPlugin.sendMessage(player, message);
return;
}
final GDWorldEditProvider worldEditProvider = GriefDefenderPlugin.getInstance().getWorldEditProvider();
if (cmd != null && cmd.equalsIgnoreCase("hideall")) {
if (worldEditProvider != null) {
worldEditProvider.revertVisuals(player, playerData, null);
}
playerData.revertAllVisuals();
return;
}
final boolean hideTargetClaimVisual = cmd != null && cmd.equalsIgnoreCase("hide");
final boolean checkArea = cmd != null && cmd.equalsIgnoreCase("area");
GDClaim claim = null;
Location<World> location = null;
if (hideTargetClaimVisual || checkArea) {
final int maxDistance = GDPermissionManager.getInstance().getInternalOptionValue(TypeToken.of(Integer.class), player, Options.RADIUS_INSPECT);
claim = PlayerUtil.getInstance().findNearbyClaim(player, playerData, maxDistance, hideTargetClaimVisual);
if (checkArea) {
if (!playerData.canIgnoreClaim(claim) && !player.hasPermission(GDPermissions.VISUALIZE_CLAIMS_NEARBY)) {
GriefDefenderPlugin.sendMessage(player, MessageCache.getInstance().PERMISSION_VISUAL_CLAIMS_NEARBY);
return;
}
Location<World> nearbyLocation = playerData.lastValidInspectLocation != null ? playerData.lastValidInspectLocation : player.getLocation();
Set<Claim> claims = BlockUtil.getInstance().getNearbyClaims(nearbyLocation, maxDistance, true);
List<Claim> visualClaims = new ArrayList<>();
for (Claim nearbyClaim : claims) {
if (!((GDClaim) nearbyClaim).hasActiveVisual(player)) {
visualClaims.add(nearbyClaim);
}
}
int height = (int) (playerData.lastValidInspectLocation != null ? playerData.lastValidInspectLocation.getBlockY() : PlayerUtil.getInstance().getEyeHeight(player));
boolean hideBorders = worldEditProvider != null &&
worldEditProvider.hasCUISupport(player) &&
GriefDefenderPlugin.getActiveConfig(player.getWorld().getUniqueId()).getConfig().visual.hideBorders;
if (!hideBorders) {
for (Claim visualClaim : visualClaims) {
final GDClaimVisual visual = ((GDClaim) visualClaim).getVisualizer();
visual.createClaimBlockVisuals(playerData.getClaimCreateMode() == CreateModeTypes.VOLUME ? height : PlayerUtil.getInstance().getEyeHeight(player), player.getLocation(), playerData);
visual.apply(player);
}
}
final Component message = GriefDefenderPlugin.getInstance().messageData.getMessage(MessageStorage.CLAIM_SHOW_NEARBY,
ImmutableMap.of(
"amount", claims.size()));
GriefDefenderPlugin.sendMessage(player, message);
if (!claims.isEmpty()) {
if (worldEditProvider != null && !visualClaims.isEmpty()) {
worldEditProvider.visualizeClaims(visualClaims, player, playerData, true);
}
CommandHelper.showClaims(player, claims);
}
return;
}
if (claim != null && claim.isWilderness()) {
playerData.lastValidInspectLocation = null;
GriefDefenderPlugin.sendMessage(player, GriefDefenderPlugin.getInstance().messageData.getMessage(MessageStorage.BLOCK_NOT_CLAIMED));
return;
}
} else {
boolean ignoreAir = false;
if (worldEditProvider != null) {
// Ignore air so players can use client-side WECUI block target which uses max reach distance
if (worldEditProvider.hasCUISupport(player) && playerData.getClaimCreateMode() == CreateModeTypes.VOLUME && playerData.lastShovelLocation != null) {
ignoreAir = true;
}
}
final int distance = !ignoreAir ? 100 : 5;
location = BlockUtil.getInstance().getTargetBlock(player, playerData, distance, ignoreAir).orElse(null);
if (location == null) {
return;
}
claim = GriefDefenderPlugin.getInstance().dataStore.getClaimAtPlayer(location, playerData, true);
if (claim.isWilderness()) {
GriefDefenderPlugin.sendMessage(player, GriefDefenderPlugin.getInstance().messageData.getMessage(MessageStorage.BLOCK_NOT_CLAIMED));
return;
}
}
// Handle left-click visual revert
if (claim != null && !claim.isWilderness() && hideTargetClaimVisual) {
if (claim.hasActiveVisual(player)) {
final int maxDistance = GDPermissionManager.getInstance().getInternalOptionValue(TypeToken.of(Integer.class), player, Options.RADIUS_INSPECT);
if (!((GDClaim) claim).children.isEmpty()) {
claim = PlayerUtil.getInstance().findNearbyClaim(player, playerData, maxDistance, true);
}
if (!claim.hasActiveVisual(player) && claim.parent != null) {
GDClaim parent = claim.parent;
while (parent != null) {
if (parent.hasActiveVisual(player)) {
claim = parent;
parent = null;
} else {
parent = parent.parent;
}
}
}
if (claim != null && claim.hasActiveVisual(player)) {
playerData.revertClaimVisual(claim);
}
return;
}
}
int height = PlayerUtil.getInstance().getEyeHeight(player);
if (playerData.lastValidInspectLocation != null || location != null) {
height = playerData.lastValidInspectLocation != null ? playerData.lastValidInspectLocation.getBlockY() : location.getBlockY();
}
if (claim != null) {
// always show visual borders for resize purposes
final GDClaimVisual visual = claim.getVisualizer();
visual.createClaimBlockVisuals(playerData.getClaimCreateMode() == CreateModeTypes.VOLUME ? height : PlayerUtil.getInstance().getEyeHeight(player), player.getLocation(), playerData);
visual.apply(player);
if (worldEditProvider != null) {
worldEditProvider.displayClaimCUIVisual(claim, player, playerData, true);
}
Set<Claim> claims = new HashSet<>();
claims.add(claim);
playerData.showNoClaimsFoundMessage = false;
CommandHelper.showClaims(player, claims);
Component message = GriefDefenderPlugin.getInstance().messageData.getMessage(MessageStorage.BLOCK_CLAIMED,
ImmutableMap.of(
"player", claim.getOwnerDisplayName()));
GriefDefenderPlugin.sendMessage(player, message);
}
}
}

View File

@ -51,7 +51,7 @@ public CommandClaimOption() {
@Syntax("[<option> <value> [context[key=value]]")
@Subcommand("option claim")
public void execute(Player player, @Optional String[] args) throws InvalidCommandArgument {
this.subject = GriefDefenderPlugin.DEFAULT_HOLDER;
this.subject = GriefDefenderPlugin.GD_OPTION_HOLDER;
this.friendlySubjectName = "ALL";
super.execute(player, args);
}

View File

@ -77,10 +77,6 @@ public void execute(Player player, String arg) throws InvalidCommandArgument {
}
Double salePrice = null;
if (!claim.getEconomyData().isForSale()) {
GriefDefenderPlugin.sendMessage(player, MessageCache.getInstance().ECONOMY_CLAIM_NOT_FOR_SALE);
return;
}
if (arg.equalsIgnoreCase("cancel")) {
claim.getEconomyData().setForSale(false);
claim.getEconomyData().setSalePrice(-1);

View File

@ -0,0 +1,56 @@
/*
* This file is part of GriefDefender, licensed under the MIT License (MIT).
*
* Copyright (c) bloodmc
* Copyright (c) contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package com.griefdefender.command;
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 net.kyori.text.adapter.spongeapi.TextAdapter;
import org.spongepowered.api.entity.living.player.Player;
@CommandAlias("%griefdefender")
@CommandPermission(GDPermissions.COMMAND_CLAIM_TOOL)
public class CommandClaimTool extends BaseCommand {
@CommandAlias("claimtool")
@Description("Toggles claim tool on/off.")
@Subcommand("mode tool")
public void execute(Player player) {
final GDPlayerData playerData = GriefDefenderPlugin.getInstance().dataStore.getOrCreatePlayerData(player.getWorld(), player.getUniqueId());
playerData.claimTool = !playerData.claimTool;
if (!playerData.claimTool) {
TextAdapter.sendComponent(player, MessageCache.getInstance().COMMAND_CLAIMTOOL_DISABLED);
} else {
TextAdapter.sendComponent(player, MessageCache.getInstance().COMMAND_CLAIMTOOL_ENABLED);
}
}
}

View File

@ -342,7 +342,13 @@ public static PermissionResult applyFlagPermission(CommandSource src, GDPermissi
}
if (subject == GriefDefenderPlugin.DEFAULT_HOLDER) {
PermissionUtil.getInstance().setPermissionValue(GriefDefenderPlugin.DEFAULT_HOLDER, flag, value, contexts);
if (flagType == MenuType.OVERRIDE) {
PermissionUtil.getInstance().setPermissionValue(GriefDefenderPlugin.GD_OVERRIDE_HOLDER, flag, value, contexts);
} else if (flagType == MenuType.CLAIM) {
PermissionUtil.getInstance().setPermissionValue(GriefDefenderPlugin.GD_CLAIM_HOLDER, flag, value, contexts);
} else {
PermissionUtil.getInstance().setPermissionValue(GriefDefenderPlugin.GD_DEFAULT_HOLDER, flag, value, contexts);
}
if (!clicked && src instanceof Player) {
TextAdapter.sendComponent(src, TextComponent.builder("")
.append(TextComponent.builder("\n[").append(MessageCache.getInstance().FLAG_UI_RETURN_FLAGS.color(TextColor.AQUA)).append("]\n")

View File

@ -437,10 +437,6 @@ public double getRentBalance(UUID uuid) {
@Override
public void setRentBalance(UUID uuid, double balance) {
if (balance <= 0) {
this.rentBalances.remove(uuid);
return;
}
this.rentBalances.put(uuid, balance);
}
}

View File

@ -98,6 +98,8 @@ public class MessageStorage {
public static final String ABANDON_WORLD_WARNING = "abandon-world-warning";
public static final String ADJUST_ACCRUED_BLOCKS_SUCCESS = "adjust-accrued-blocks-success";
public static final String ADJUST_BONUS_BLOCKS_SUCCESS = "adjust-bonus-blocks-success";
public static final String ADJUST_BONUS_BLOCKS_ALL_SUCCESS = "adjust-bonus-blocks-all-success";
public static final String ADJUST_BONUS_BLOCKS_ALL_WARNING = "adjust-bonus-blocks-all-warning";
public static final String BANK_DEPOSIT = "bank-deposit";
public static final String BANK_INFO = "bank-info";
public static final String BANK_NO_PERMISSION = "bank-no-permission";
@ -199,6 +201,8 @@ public class MessageStorage {
public static final String ECONOMY_CLAIM_RENT_CONFIRMATION_MIN = "economy-claim-rent-confirmation-min";
public static final String ECONOMY_CLAIM_RENT_CONFIRMATION_MIN_MAX = "economy-claim-rent-confirmation-min-max";
public static final String ECONOMY_CLAIM_RENT_CONFIRMED = "economy-claim-rent-confirmed";
public static final String ECONOMY_CLAIM_RENT_END = "economy-claim-rent-end";
public static final String ECONOMY_CLAIM_RENT_END_RESTORE = "economy-claim-rent-end-restore";
public static final String ECONOMY_CLAIM_RENT_INVALID_PRICE = "economy-claim-rent-invalid-price";
public static final String ECONOMY_CLAIM_RENT_NOT_ENOUGH_FUNDS = "economy-claim-rent-not-enough-funds";
public static final String ECONOMY_CLAIM_RENT_PAYMENT_FAILURE = "economy-claim-rent-payment-failure";
@ -212,6 +216,7 @@ public class MessageStorage {
public static final String ECONOMY_CLAIM_RENTER_CONFIRMATION_MIN = "economy-claim-renter-confirmation-min";
public static final String ECONOMY_CLAIM_RENTER_CONFIRMATION_MIN_MAX = "economy-claim-renter-confirmation-min-max";
public static final String ECONOMY_CLAIM_RENTER_CONFIRMED = "economy-claim-renter-confirmed";
public static final String ECONOMY_CLAIM_RENTER_END = "economy-claim-renter-end";
public static final String ECONOMY_CLAIM_RENTED_TIME_WARNING = "economy-claim-rented-time-warning";
public static final String ECONOMY_CLAIM_RENTED_TIME_WARNING_RESTORE_ = "economy-claim-rented-time-warning-restore";
public static final String ECONOMY_CLAIM_RENTED_NO_CANCEL = "economy-claim-rented-no-cancel";

View File

@ -41,7 +41,7 @@
public class OptionStorage extends ConfigCategory {
@Setting(value = "option-control", comment = "Controls which options are enabled.\nNote: To enable an option, set the value to 'true'."
+ "\nSee https://github.com/bloodmc/GriefDefender/wiki/Advanced-Options for info on how each option works.")
+ "\nSee https://github.com/bloodmc/GriefDefender/wiki/Options for info on how each option works.")
private Map<String, Boolean> control = Maps.newHashMap();
@Setting(value = "default-options")

View File

@ -53,6 +53,8 @@ public class ClaimCategory extends ConfigCategory {
@Setting(value = "border-block-radius", comment = "Set claim border of specified radius (in blocks), centered on claim. If set to 1, adds an additional 1 block protected radius around claim.\n" +
"Note: It is not recommended to set this value too high as performance can degrade due to deeper claim searches.")
public int borderBlockRadius = 0;
@Setting(value = "restrict-world-max-height", comment = "Whether to restrict claiming to world max height. (Default: True")
public boolean restrictWorldMaxHeight = true;
@Setting(value = "expiration-cleanup-interval", comment = "The interval in minutes for cleaning up expired claims. Default: 0. Set to 0 to disable.")
public int expirationCleanupInterval = 0;
@Setting(value = "auto-nature-restore", comment = "Whether survival claims will be automatically restored to world generated state when expired. \nNote: This only supports world generated blocks. Consider using 'auto-schematic-restore' if using a custom world.")

View File

@ -32,7 +32,6 @@
import com.griefdefender.GriefDefenderPlugin;
import com.griefdefender.api.permission.Context;
import com.griefdefender.api.permission.flag.FlagData;
import com.griefdefender.api.permission.flag.FlagDefinition;
import com.griefdefender.cache.PermissionHolderCache;
import com.griefdefender.permission.GDPermissionHolder;
@ -106,30 +105,21 @@ public void initDefaults() {
groupStr = context.getValue();
}
}
GDPermissionHolder holder = GriefDefenderPlugin.DEFAULT_HOLDER;
GDPermissionHolder holder = GriefDefenderPlugin.GD_DEFINITION_HOLDER;
if (groupStr != null) {
if (PermissionUtil.getInstance().hasGroupSubject(groupStr)) {
holder = PermissionHolderCache.getInstance().getOrCreateGroup(groupStr);
if (holder == null) {
holder = GriefDefenderPlugin.DEFAULT_HOLDER;
holder = GriefDefenderPlugin.GD_DEFINITION_HOLDER;
}
}
}
for (FlagData flagData : flagDefinition.getFlagData()) {
Set<Context> permissionContexts = new HashSet<>();
permissionContexts.addAll(flagData.getContexts());
// apply defaults
for (Context context : defaultContexts) {
permissionContexts.add(context);
PermissionUtil.getInstance().setTransientPermission(holder, flagData.getFlag().getPermission(), flagDefinition.getDefaultValue(), permissionContexts);
permissionContexts.remove(context);
}
// apply overrides
for (Context context : overrideContexts) {
permissionContexts.add(context);
PermissionUtil.getInstance().setPermissionValue(holder, flagData.getFlag().getPermission(), flagDefinition.getDefaultValue(), permissionContexts);
permissionContexts.remove(context);
}
if (!defaultContexts.isEmpty()) {
PermissionUtil.getInstance().setFlagDefinition(holder, flagDefinition, flagDefinition.getDefaultValue(), defaultContexts, false);
}
if (!overrideContexts.isEmpty()) {
PermissionUtil.getInstance().setFlagDefinition(holder, flagDefinition, flagDefinition.getDefaultValue(), overrideContexts, false);
}
}
}

View File

@ -29,6 +29,10 @@
import java.util.List;
import java.util.Map;
import com.griefdefender.api.claim.ClaimType;
import com.griefdefender.api.claim.ClaimTypes;
import com.griefdefender.registry.ClaimTypeRegistryModule;
import ninja.leaping.configurate.objectmapping.Setting;
import ninja.leaping.configurate.objectmapping.serialize.ConfigSerializable;
@ -38,6 +42,9 @@ public class DynmapCategory {
@Setting("enabled")
public boolean enabled = true;
@Setting("claimtype-styles")
public Map<String, DynmapOwnerStyleCategory> claimTypeStyles = new HashMap<>();
@Setting("owner-styles")
public Map<String, DynmapOwnerStyleCategory> ownerStyles = new HashMap<>();
@ -74,4 +81,15 @@ public class DynmapCategory {
+ "Trust: <span style=\"font-weight:bold;\">%builders%</span><br/>"
+ "Container Trust: <span style=\"font-weight:bold;\">%containers%</span><br/>"
+ "Access Trust: <span style=\"font-weight:bold;\">%accessors%</span></div>";
public DynmapCategory() {
for (ClaimType type : ClaimTypeRegistryModule.getInstance().getAll()) {
if (type == ClaimTypes.WILDERNESS) {
continue;
}
if (this.claimTypeStyles.get(type.getName().toLowerCase()) == null) {
this.claimTypeStyles.put(type.getName().toLowerCase(), new DynmapOwnerStyleCategory(type));
}
}
}
}

View File

@ -24,6 +24,9 @@
*/
package com.griefdefender.configuration.category;
import com.griefdefender.api.claim.ClaimType;
import com.griefdefender.api.claim.ClaimTypes;
import ninja.leaping.configurate.objectmapping.Setting;
import ninja.leaping.configurate.objectmapping.serialize.ConfigSerializable;
@ -47,4 +50,26 @@ public class DynmapOwnerStyleCategory {
@Setting("label")
public String label = "none";
public DynmapOwnerStyleCategory() {
}
public DynmapOwnerStyleCategory(ClaimType type) {
if (type.equals(ClaimTypes.ADMIN)) {
this.strokeColor = "#FF0000";
this.fillColor = "#FF0000";
} else if (type.equals(ClaimTypes.BASIC)) {
this.strokeColor = "#FFFF00";
this.fillColor = "#FFFF00";
} else if (type.equals(ClaimTypes.TOWN)) {
this.strokeColor = "#00FF00";
this.fillColor = "#00FF00";
} else if (type.equals(ClaimTypes.SUBDIVISION)) {
this.strokeColor = "#FF9C00";
this.fillColor = "#FF9C00";
} else {
this.strokeColor = "#FF0000";
this.fillColor = "#FF0000";
}
}
}

View File

@ -35,4 +35,7 @@ public class PvpCategory extends ConfigCategory {
@Setting(value = "allow-fly", comment = "Whether flying is allowed during PvP.")
public boolean allowFly = false;
@Setting(value = "combat-logout", comment = "Whether players should be killed if they logout while in pvp combat.")
public boolean combatLogout = false;
}

View File

@ -80,6 +80,7 @@
import org.spongepowered.api.entity.Entity;
import org.spongepowered.api.entity.FallingBlock;
import org.spongepowered.api.entity.Item;
import org.spongepowered.api.entity.hanging.ItemFrame;
import org.spongepowered.api.entity.living.player.Player;
import org.spongepowered.api.entity.living.player.User;
import org.spongepowered.api.event.Listener;
@ -433,7 +434,7 @@ public void onBlockCollide(CollideBlockEvent event, @Root Entity source) {
}
final GDBlockType gdBlock = BlockTypeRegistryModule.getInstance().getById(event.getTargetBlock().getType().getId()).orElse(null);
if (gdBlock != null && !gdBlock.isCollidable()) {
if (gdBlock != null && !gdBlock.isCollidable() && !(source instanceof ItemFrame)) {
return;
}
if (event.getTargetBlock().getType() == BlockTypes.PORTAL) {
@ -635,6 +636,7 @@ public void onExplosionDetonate(ExplosionEvent.Detonate event) {
}
}
}
if (GriefDefenderPlugin.isSourceIdBlacklisted(Flags.EXPLOSION_BLOCK.getName(), source, event.getExplosion().getWorld().getProperties())) {
return;
}
@ -647,7 +649,7 @@ public void onExplosionDetonate(ExplosionEvent.Detonate event) {
final int cancelBlockLimit = GriefDefenderPlugin.getGlobalConfig().getConfig().claim.explosionCancelBlockLimit;
boolean denySurfaceExplosion = GriefDefenderPlugin.getActiveConfig(world.getUniqueId()).getConfig().claim.explosionBlockSurfaceBlacklist.contains(sourceId);
if (!denySurfaceExplosion) {
denySurfaceExplosion = !GriefDefenderPlugin.getActiveConfig(world.getUniqueId()).getConfig().claim.explosionBlockSurfaceBlacklist.contains("any");
denySurfaceExplosion = GriefDefenderPlugin.getActiveConfig(world.getUniqueId()).getConfig().claim.explosionBlockSurfaceBlacklist.contains("any");
}
for (Location<World> location : event.getAffectedLocations()) {
if (location.getBlockType().equals(BlockTypes.AIR)) {
@ -986,7 +988,7 @@ public void onSignChangeEvent(ChangeSignEvent event) {
}
final GriefDefenderConfig<?> activeConfig = GriefDefenderPlugin.getActiveConfig(event.getTargetTile().getWorld().getUniqueId());
if (!activeConfig.getConfig().economy.rentSystem || (!activeConfig.getConfig().economy.isRentSignEnabled() && !activeConfig.getConfig().economy.isSellSignEnabled())) {
if (!activeConfig.getConfig().economy.isRentSignEnabled() && !activeConfig.getConfig().economy.isSellSignEnabled()) {
return;
}
@ -1033,7 +1035,7 @@ public void onSignChangeEvent(ChangeSignEvent event) {
}
SignUtil.setClaimForSale(claim, user.getOnlinePlayer(), sign, price);
} else if (line1.equalsIgnoreCase("rent") && activeConfig.getConfig().economy.isRentSignEnabled()) {
} else if (line1.equalsIgnoreCase("rent") && activeConfig.getConfig().economy.isRentSignEnabled() && activeConfig.getConfig().economy.rentSystem) {
if (!player.hasPermission(GDPermissions.USER_RENT_SIGN)) {
return;
}

View File

@ -405,7 +405,7 @@ private void runPlayerCommands(GDClaim claim, GDPermissionUser user, boolean ent
return;
}
final Player player = user.getOnlinePlayer();
if (player == null) {
if (player == null || NMSUtil.getInstance().isFakePlayer(player)) {
// Most likely NPC
return;
}
@ -484,7 +484,7 @@ private void checkPlayerFlight(GDPermissionUser user, GDClaim fromClaim, GDClaim
return;
}
final Player player = user.getOnlinePlayer();
if (player == null || !player.get(Keys.IS_FLYING).get()) {
if (player == null || NMSUtil.getInstance().isFakePlayer(player) || !player.get(Keys.IS_FLYING).get()) {
// Most likely NPC
return;
}
@ -497,21 +497,18 @@ private void checkPlayerFlight(GDPermissionUser user, GDClaim fromClaim, GDClaim
if (gameMode == null || gameMode == GameModes.SPECTATOR) {
return;
}
if (gameMode == GameModes.CREATIVE) {
if (playerData.inPvpCombat() && !GriefDefenderPlugin.getActiveConfig(player.getWorld().getUniqueId()).getConfig().pvp.allowFly) {
player.offer(Keys.CAN_FLY, false);
player.offer(Keys.IS_FLYING, false);
playerData.ignoreFallDamage = true;
Location<World> safeLocation = Sponge.getGame().getTeleportHelper()
.getSafeLocation(player.getLocation(), 80, 0)
.orElseGet(() -> Sponge.getGame().getTeleportHelper()
.getSafeLocation(player.getLocation(), 80, 6)
.orElse(player.getWorld().getSpawnLocation())
);
player.setTransform(player.getTransform().setLocation(safeLocation));
GriefDefenderPlugin.sendMessage(player, MessageCache.getInstance().OPTION_APPLY_PLAYER_DENY_FLIGHT);
return;
}
if (playerData.inPvpCombat() && !GriefDefenderPlugin.getActiveConfig(player.getWorld().getUniqueId()).getConfig().pvp.allowFly) {
player.offer(Keys.CAN_FLY, false);
player.offer(Keys.IS_FLYING, false);
playerData.ignoreFallDamage = true;
Location<World> safeLocation = Sponge.getGame().getTeleportHelper()
.getSafeLocation(player.getLocation(), 80, 0)
.orElseGet(() -> Sponge.getGame().getTeleportHelper()
.getSafeLocation(player.getLocation(), 80, 6)
.orElse(player.getWorld().getSpawnLocation())
);
player.setTransform(player.getTransform().setLocation(safeLocation));
GriefDefenderPlugin.sendMessage(player, MessageCache.getInstance().OPTION_APPLY_PLAYER_DENY_FLIGHT);
return;
}
@ -566,7 +563,7 @@ private void checkPlayerGodMode(GDPermissionUser user, GDClaim fromClaim, GDClai
return;
}
final Player player = user.getOnlinePlayer();
if (player == null || !player.get(Keys.INVULNERABLE).get()) {
if (player == null || NMSUtil.getInstance().isFakePlayer(player) || !player.get(Keys.INVULNERABLE).get()) {
// Most likely NPC
return;
}
@ -597,7 +594,7 @@ private void checkPlayerGameMode(GDPermissionUser user, GDClaim fromClaim, GDCla
return;
}
final Player player = user.getOnlinePlayer();
if (player == null) {
if (player == null || NMSUtil.getInstance().isFakePlayer(player)) {
// Most likely Citizens NPC
return;
}
@ -636,7 +633,7 @@ private void checkPlayerFlySpeed(GDPermissionUser user, GDClaim fromClaim, GDCla
return;
}
final Player player = user.getOnlinePlayer();
if (player == null || !player.get(Keys.IS_FLYING).get()) {
if (player == null || NMSUtil.getInstance().isFakePlayer(player) || !player.get(Keys.IS_FLYING).get()) {
// Most likely Citizens NPC
return;
}
@ -688,7 +685,7 @@ private void checkPlayerWalkSpeed(GDPermissionUser user, GDClaim fromClaim, GDCl
return;
}
final Player player = user.getOnlinePlayer();
if (player == null || player.get(Keys.IS_FLYING).get()) {
if (player == null || NMSUtil.getInstance().isFakePlayer(player) || player.get(Keys.IS_FLYING).get()) {
// Most likely Citizens NPC
return;
}
@ -740,7 +737,7 @@ public void checkPlayerWeather(GDPermissionUser user, GDClaim fromClaim, GDClaim
return;
}
final Player player = user.getOnlinePlayer();
if (player == null) {
if (player == null || NMSUtil.getInstance().isFakePlayer(player)) {
// Most likely Citizens NPC
return;
}

View File

@ -465,7 +465,7 @@ public boolean protectEntity(Event event, Entity targetEntity, Cause cause, Dama
}
if (targetEntity instanceof Living && targetEntity.get(Keys.TAMED_OWNER).isPresent()) {
final UUID ownerID = targetEntity.get(Keys.TAMED_OWNER).get().orElse(null);
if (ownerID != null) {
if (ownerID != null && !ownerID.equals(GriefDefenderPlugin.WORLD_USER_UUID)) {
// always allow owner to interact with their pets
if (player.getUniqueId().equals(ownerID)) {
return false;
@ -882,8 +882,8 @@ public void onEntityCollideEntity(CollideEntityEvent event) {
event.filterEntities(new Predicate<Entity>() {
@Override
public boolean test(Entity entity) {
// Avoid living entities breaking itemframes
if (isRootEntityItemFrame && entity instanceof Living) {
// Avoid entities breaking itemframes
if (isRootEntityItemFrame) {
return false;
}

Some files were not shown because too many files have changed in this diff Show More