3129 lines
129 KiB
Java
3129 lines
129 KiB
Java
/*
|
|
* 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.claim;
|
|
|
|
import static com.google.common.base.Preconditions.checkNotNull;
|
|
|
|
import com.flowpowered.math.vector.Vector3i;
|
|
import com.google.common.base.Objects;
|
|
import com.google.common.collect.ImmutableList;
|
|
import com.google.common.collect.ImmutableMap;
|
|
import com.google.common.collect.ImmutableSet;
|
|
import com.google.common.reflect.TypeToken;
|
|
import com.griefdefender.GDPlayerData;
|
|
import com.griefdefender.GriefDefenderPlugin;
|
|
import com.griefdefender.api.GriefDefender;
|
|
import com.griefdefender.api.Tristate;
|
|
import com.griefdefender.api.User;
|
|
import com.griefdefender.api.claim.Claim;
|
|
import com.griefdefender.api.claim.ClaimBlockSystem;
|
|
import com.griefdefender.api.claim.ClaimContexts;
|
|
import com.griefdefender.api.claim.ClaimManager;
|
|
import com.griefdefender.api.claim.ClaimResult;
|
|
import com.griefdefender.api.claim.ClaimResultType;
|
|
import com.griefdefender.api.claim.ClaimSchematic;
|
|
import com.griefdefender.api.claim.ClaimType;
|
|
import com.griefdefender.api.claim.ClaimTypes;
|
|
import com.griefdefender.api.claim.ClaimVisual;
|
|
import com.griefdefender.api.claim.ClaimVisualTypes;
|
|
import com.griefdefender.api.claim.ShovelTypes;
|
|
import com.griefdefender.api.claim.TrustType;
|
|
import com.griefdefender.api.claim.TrustTypes;
|
|
import com.griefdefender.api.data.ClaimData;
|
|
import com.griefdefender.api.permission.Context;
|
|
import com.griefdefender.api.permission.ContextKeys;
|
|
import com.griefdefender.api.permission.flag.Flags;
|
|
import com.griefdefender.api.permission.option.Options;
|
|
import com.griefdefender.cache.MessageCache;
|
|
import com.griefdefender.cache.PermissionHolderCache;
|
|
import com.griefdefender.configuration.ClaimDataConfig;
|
|
import com.griefdefender.configuration.ClaimStorageData;
|
|
import com.griefdefender.configuration.IClaimData;
|
|
import com.griefdefender.configuration.MessageStorage;
|
|
import com.griefdefender.configuration.TownDataConfig;
|
|
import com.griefdefender.configuration.TownStorageData;
|
|
import com.griefdefender.event.GDCauseStackManager;
|
|
import com.griefdefender.event.GDChangeClaimEvent;
|
|
import com.griefdefender.event.GDCreateClaimEvent;
|
|
import com.griefdefender.event.GDRemoveClaimEvent;
|
|
import com.griefdefender.event.GDGroupTrustClaimEvent;
|
|
import com.griefdefender.event.GDSaveClaimEvent;
|
|
import com.griefdefender.event.GDTransferClaimEvent;
|
|
import com.griefdefender.event.GDUserTrustClaimEvent;
|
|
import com.griefdefender.internal.provider.WorldGuardProvider;
|
|
import com.griefdefender.internal.registry.GDEntityType;
|
|
import com.griefdefender.internal.tracking.chunk.GDChunk;
|
|
import com.griefdefender.internal.util.VecHelper;
|
|
import com.griefdefender.internal.visual.GDClaimVisual;
|
|
import com.griefdefender.permission.GDPermissionHolder;
|
|
import com.griefdefender.permission.GDPermissionManager;
|
|
import com.griefdefender.permission.GDPermissionUser;
|
|
import com.griefdefender.permission.GDPermissions;
|
|
import com.griefdefender.provider.VaultProvider;
|
|
import com.griefdefender.registry.TrustTypeRegistryModule;
|
|
import com.griefdefender.storage.BaseStorage;
|
|
import com.griefdefender.util.BlockUtil;
|
|
import com.griefdefender.util.EconomyUtil;
|
|
import com.griefdefender.util.PermissionUtil;
|
|
|
|
import net.kyori.text.Component;
|
|
import net.kyori.text.TextComponent;
|
|
import net.kyori.text.format.TextColor;
|
|
import net.kyori.text.serializer.plain.PlainComponentSerializer;
|
|
import net.milkbowl.vault.economy.Economy;
|
|
import net.milkbowl.vault.economy.EconomyResponse;
|
|
import org.bukkit.Bukkit;
|
|
import org.bukkit.Chunk;
|
|
import org.bukkit.Location;
|
|
import org.bukkit.World;
|
|
import org.bukkit.command.CommandSender;
|
|
import org.bukkit.entity.Entity;
|
|
import org.bukkit.entity.Player;
|
|
import org.checkerframework.checker.nullness.qual.Nullable;
|
|
|
|
import java.io.File;
|
|
import java.io.IOException;
|
|
import java.nio.file.Files;
|
|
import java.nio.file.Path;
|
|
import java.util.ArrayList;
|
|
import java.util.Collection;
|
|
import java.util.Collections;
|
|
import java.util.HashMap;
|
|
import java.util.HashSet;
|
|
import java.util.List;
|
|
import java.util.Map;
|
|
import java.util.Optional;
|
|
import java.util.Set;
|
|
import java.util.UUID;
|
|
|
|
public class GDClaim implements Claim {
|
|
|
|
public static final BaseStorage DATASTORE = GriefDefenderPlugin.getInstance().dataStore;
|
|
// Note: 2D cuboids will ignore the upper Y value while 3D cuboids do not
|
|
public Vector3i lesserBoundaryCorner;
|
|
public Vector3i greaterBoundaryCorner;
|
|
private World world;
|
|
private ClaimType type = ClaimTypes.BASIC;
|
|
private Set<Long> chunkHashes;
|
|
private final int hashCode;
|
|
private final GDClaimManager worldClaimManager;
|
|
private final Claim wildernessClaim;
|
|
private final VaultProvider vaultProvider = GriefDefenderPlugin.getInstance().getVaultProvider();
|
|
|
|
// Permission Context
|
|
private final Context context;
|
|
private final Context overrideClaimContext;
|
|
private final Context worldContext;
|
|
|
|
private UUID id = null;
|
|
private UUID ownerUniqueId;
|
|
|
|
public boolean cuboid = false;
|
|
public boolean markVisualDirty = false;
|
|
|
|
protected ClaimStorageData claimStorage;
|
|
protected IClaimData claimData;
|
|
|
|
public GDClaim parent = null;
|
|
public GDClaimVisual claimVisual;
|
|
public Map<String, ClaimSchematic> schematics = new HashMap<>();
|
|
public Set<UUID> playersWatching = new HashSet<>();
|
|
public Set<Claim> children = new HashSet<>();
|
|
public Set<Long> loadedChunkHashes = new HashSet<>();
|
|
|
|
private GDPlayerData ownerPlayerData;
|
|
|
|
public GDClaim(World world, Vector3i point1, Vector3i point2, ClaimType type, UUID ownerUniqueId, boolean cuboid) {
|
|
this(world, point1, point2, type, ownerUniqueId, cuboid, null);
|
|
}
|
|
|
|
public GDClaim(World world, Vector3i point1, Vector3i point2, ClaimType type, UUID ownerUniqueId, boolean cuboid, GDClaim parent) {
|
|
int minx = Math.min(point1.getX(), point2.getX());
|
|
int miny = Math.min(point1.getY(), point2.getY());
|
|
int minz = Math.min(point1.getZ(), point2.getZ());
|
|
int maxx = Math.max(point1.getX(), point2.getX());
|
|
int maxy = Math.max(point1.getY(), point2.getY());
|
|
int maxz = Math.max(point1.getZ(), point2.getZ());
|
|
|
|
this.world = world;
|
|
this.lesserBoundaryCorner = new Vector3i(minx, miny, minz);
|
|
this.greaterBoundaryCorner = new Vector3i(maxx, maxy, maxz);
|
|
if (ownerUniqueId != null) {
|
|
this.ownerUniqueId = ownerUniqueId;
|
|
this.ownerPlayerData = GriefDefenderPlugin.getInstance().dataStore.getOrCreatePlayerData(this.world, this.ownerUniqueId);
|
|
}
|
|
this.type = type;
|
|
this.id = UUID.randomUUID();
|
|
this.context = new Context("gd_claim", this.id.toString());
|
|
this.worldContext = new Context("world", world.getName().toLowerCase());
|
|
this.overrideClaimContext = new Context("gd_claim_override", this.id.toString());
|
|
this.cuboid = cuboid;
|
|
this.parent = parent;
|
|
this.hashCode = this.id.hashCode();
|
|
this.worldClaimManager = GriefDefenderPlugin.getInstance().dataStore.getClaimWorldManager(this.world.getUID());
|
|
if (this.type == ClaimTypes.WILDERNESS) {
|
|
this.wildernessClaim = this;
|
|
} else {
|
|
this.wildernessClaim = this.worldClaimManager.getWildernessClaim();
|
|
}
|
|
}
|
|
|
|
// Used for visualizations
|
|
public GDClaim(World world, Vector3i lesserBoundaryCorner, Vector3i greaterBoundaryCorner, ClaimType type, boolean cuboid) {
|
|
this(world, lesserBoundaryCorner, greaterBoundaryCorner, UUID.randomUUID(), type, null, cuboid);
|
|
}
|
|
|
|
// Used at server startup
|
|
public GDClaim(World world, Vector3i lesserBoundaryCorner, Vector3i greaterBoundaryCorner, UUID claimId, ClaimType type, UUID ownerUniqueId, boolean cuboid) {
|
|
this.id = claimId;
|
|
this.overrideClaimContext = new Context("gd_claim_override", this.id.toString());
|
|
this.lesserBoundaryCorner = lesserBoundaryCorner;
|
|
this.greaterBoundaryCorner = greaterBoundaryCorner;
|
|
this.world = world;
|
|
if (ownerUniqueId != null) {
|
|
this.ownerUniqueId = ownerUniqueId;
|
|
this.ownerPlayerData = GriefDefenderPlugin.getInstance().dataStore.getOrCreatePlayerData(this.world, this.ownerUniqueId);
|
|
}
|
|
this.type = type;
|
|
this.cuboid = cuboid;
|
|
this.context = new Context("gd_claim", this.id.toString());
|
|
this.worldContext = new Context("world", world.getName().toLowerCase());
|
|
this.hashCode = this.id.hashCode();
|
|
this.worldClaimManager = GriefDefenderPlugin.getInstance().dataStore.getClaimWorldManager(this.world.getUID());
|
|
if (this.type == ClaimTypes.WILDERNESS) {
|
|
this.wildernessClaim = this;
|
|
} else {
|
|
this.wildernessClaim = this.worldClaimManager.getWildernessClaim();
|
|
}
|
|
}
|
|
|
|
public void initializeClaimData(GDClaim parent) {
|
|
Path claimDataFolderPath = null;
|
|
// check if main world
|
|
if (parent != null) {
|
|
claimDataFolderPath = parent.getClaimStorage().filePath.getParent().resolve(this.type.getName().toLowerCase());
|
|
} else {
|
|
claimDataFolderPath = BaseStorage.worldConfigMap.get(this.world.getUID()).getPath().getParent().resolve("ClaimData").resolve(this.type.getName().toLowerCase());
|
|
}
|
|
try {
|
|
if (Files.notExists(claimDataFolderPath)) {
|
|
Files.createDirectories(claimDataFolderPath);
|
|
}
|
|
} catch (IOException e) {
|
|
e.printStackTrace();
|
|
}
|
|
File claimFile = new File(claimDataFolderPath + File.separator + this.id);
|
|
if (this.isTown()) {
|
|
this.claimStorage = new TownStorageData(claimFile.toPath(), this.world.getUID(), this.ownerUniqueId, this.cuboid);
|
|
} else {
|
|
this.claimStorage = new ClaimStorageData(claimFile.toPath(), this.world.getUID(), this.ownerUniqueId, this.type, this.cuboid);
|
|
}
|
|
this.claimData = this.claimStorage.getConfig();
|
|
this.parent = parent;
|
|
if (parent != null) {
|
|
this.claimStorage.getConfig().setParent(parent.getUniqueId());
|
|
}
|
|
this.updateClaimStorageData();
|
|
}
|
|
|
|
public ClaimType getType() {
|
|
return this.type;
|
|
}
|
|
|
|
public void setType(ClaimType type) {
|
|
this.type = type;
|
|
if (this.claimData != null) {
|
|
this.claimData.setType(type);
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public ClaimVisual getClaimVisual() {
|
|
return this.getVisualizer();
|
|
}
|
|
|
|
public GDClaimVisual getVisualizer() {
|
|
if (this.claimVisual == null || this.markVisualDirty) {
|
|
this.claimVisual = new GDClaimVisual(this, GDClaimVisual.getClaimVisualType(this));
|
|
this.markVisualDirty = false;
|
|
}
|
|
return this.claimVisual;
|
|
}
|
|
|
|
public void resetVisuals() {
|
|
List<UUID> playersWatching = new ArrayList<>(this.playersWatching);
|
|
for (UUID playerUniqueId : playersWatching) {
|
|
final Player spongePlayer = Bukkit.getServer().getPlayer(playerUniqueId);
|
|
final GDPlayerData data = this.worldClaimManager.getOrCreatePlayerData(playerUniqueId);
|
|
if (spongePlayer != null) {
|
|
data.revertClaimVisual(this);
|
|
}
|
|
}
|
|
this.claimVisual = null;
|
|
}
|
|
|
|
@Override
|
|
public boolean hasActiveVisual(User user) {
|
|
if (user == null) {
|
|
return false;
|
|
}
|
|
|
|
final GDPermissionUser gdUser = (GDPermissionUser) user;
|
|
if (gdUser.getOnlinePlayer() != null) {
|
|
return this.hasActiveVisual(gdUser.getOnlinePlayer());
|
|
}
|
|
return false;
|
|
}
|
|
|
|
public boolean hasActiveVisual(Player player) {
|
|
List<UUID> playersWatching = new ArrayList<>(this.playersWatching);
|
|
for (UUID playerUniqueId : playersWatching) {
|
|
if (player.getUniqueId().equals(playerUniqueId)) {
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
public GDPlayerData getOwnerPlayerData() {
|
|
if (this.ownerPlayerData == null && this.ownerUniqueId != null) {
|
|
this.ownerPlayerData = GriefDefenderPlugin.getInstance().dataStore.getOrCreatePlayerData(this.world.getUID(), this.ownerUniqueId);
|
|
}
|
|
|
|
return this.ownerPlayerData;
|
|
}
|
|
|
|
public UUID getOwnerUniqueId() {
|
|
if (this.isAdminClaim()) {
|
|
return GriefDefenderPlugin.ADMIN_USER_UUID;
|
|
}
|
|
if (this.ownerUniqueId == null) {
|
|
if (this.parent != null) {
|
|
return this.parent.getOwnerUniqueId();
|
|
}
|
|
|
|
return GriefDefenderPlugin.ADMIN_USER_UUID;
|
|
}
|
|
|
|
return this.ownerUniqueId;
|
|
}
|
|
|
|
public void setOwnerUniqueId(UUID uniqueId) {
|
|
this.ownerUniqueId = uniqueId;
|
|
}
|
|
|
|
public boolean isAdminClaim() {
|
|
return this.type == ClaimTypes.ADMIN;
|
|
}
|
|
|
|
@Override
|
|
public boolean isCuboid() {
|
|
if (this.claimData != null) {
|
|
return this.claimData.isCuboid();
|
|
}
|
|
|
|
return this.cuboid;
|
|
}
|
|
|
|
@Override
|
|
public boolean isInTown() {
|
|
if (this.isTown()) {
|
|
return true;
|
|
}
|
|
|
|
GDClaim parent = this.parent;
|
|
while (parent != null) {
|
|
if (parent.isTown()) {
|
|
return true;
|
|
}
|
|
parent = parent.parent;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
@Override
|
|
public Optional<Claim> getTown() {
|
|
return Optional.ofNullable(this.getTownClaim());
|
|
}
|
|
|
|
@Nullable
|
|
public GDClaim getTownClaim() {
|
|
if (this.isTown()) {
|
|
return this;
|
|
}
|
|
|
|
if (this.parent == null) {
|
|
return null;
|
|
}
|
|
|
|
GDClaim parent = this.parent;
|
|
while (parent != null) {
|
|
if (parent.isTown()) {
|
|
return parent;
|
|
}
|
|
parent = parent.parent;
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
@Override
|
|
public UUID getUniqueId() {
|
|
return this.id;
|
|
}
|
|
|
|
public Optional<Component> getName() {
|
|
if (this.claimData == null) {
|
|
return Optional.empty();
|
|
}
|
|
return this.claimData.getName();
|
|
}
|
|
|
|
public String getFriendlyName() {
|
|
final Component claimName = this.claimData.getName().orElse(null);
|
|
if (claimName == null) {
|
|
return "none";
|
|
}
|
|
return PlainComponentSerializer.INSTANCE.serialize(claimName);
|
|
}
|
|
|
|
public Component getFriendlyNameType() {
|
|
return this.getFriendlyNameType(this.type, false);
|
|
}
|
|
|
|
public Component getFriendlyNameType(boolean upper) {
|
|
return this.getFriendlyNameType(this.type, upper);
|
|
}
|
|
|
|
public Component getFriendlyNameType(ClaimType claimType, boolean upper) {
|
|
if (claimType == ClaimTypes.ADMIN) {
|
|
if (upper) {
|
|
return TextComponent.of(claimType.getName().toUpperCase(), TextColor.RED);
|
|
}
|
|
return TextComponent.of("Admin", TextColor.RED);
|
|
}
|
|
|
|
if (claimType == ClaimTypes.BASIC) {
|
|
if (upper) {
|
|
return TextComponent.of(claimType.getName().toUpperCase(), TextColor.YELLOW);
|
|
}
|
|
return TextComponent.of("Basic", TextColor.YELLOW);
|
|
}
|
|
|
|
if (claimType == ClaimTypes.SUBDIVISION) {
|
|
if (upper) {
|
|
return TextComponent.of(claimType.getName().toUpperCase(), TextColor.AQUA);
|
|
}
|
|
return TextComponent.of("Subdivision", TextColor.AQUA);
|
|
}
|
|
|
|
if (upper) {
|
|
return TextComponent.of(claimType.getName().toUpperCase(), TextColor.GREEN);
|
|
}
|
|
return TextComponent.of("Town", TextColor.GREEN);
|
|
}
|
|
|
|
@Override
|
|
public int getClaimBlocks() {
|
|
if (GriefDefenderPlugin.CLAIM_BLOCK_SYSTEM == ClaimBlockSystem.VOLUME) {
|
|
return this.getVolume();
|
|
}
|
|
|
|
return this.getArea();
|
|
}
|
|
|
|
@Override
|
|
public int getArea() {
|
|
final int claimWidth = this.greaterBoundaryCorner.getX() - this.lesserBoundaryCorner.getX() + 1;
|
|
final int claimLength = this.greaterBoundaryCorner.getZ() - this.lesserBoundaryCorner.getZ() + 1;
|
|
|
|
return claimWidth * claimLength;
|
|
}
|
|
|
|
@Override
|
|
public int getVolume() {
|
|
final int claimWidth = this.greaterBoundaryCorner.getX() - this.lesserBoundaryCorner.getX() + 1;
|
|
final int claimLength = this.greaterBoundaryCorner.getZ() - this.lesserBoundaryCorner.getZ() + 1;
|
|
final int claimHeight = this.greaterBoundaryCorner.getY() - this.lesserBoundaryCorner.getY() + 1;
|
|
|
|
return claimWidth * claimLength * claimHeight;
|
|
}
|
|
|
|
@Override
|
|
public int getWidth() {
|
|
return this.greaterBoundaryCorner.getX() - this.lesserBoundaryCorner.getX() + 1;
|
|
}
|
|
|
|
@Override
|
|
public int getHeight() {
|
|
return this.greaterBoundaryCorner.getY() - this.lesserBoundaryCorner.getY() + 1;
|
|
}
|
|
|
|
@Override
|
|
public int getLength() {
|
|
return this.greaterBoundaryCorner.getZ() - this.lesserBoundaryCorner.getZ() + 1;
|
|
}
|
|
|
|
public Component allowEdit(Player player) {
|
|
final GDPermissionUser user = PermissionHolderCache.getInstance().getOrCreateUser(player);
|
|
if (user != null) {
|
|
return allowEdit(user);
|
|
}
|
|
|
|
return TextComponent.of("");
|
|
}
|
|
|
|
public Component allowEdit(GDPermissionUser holder) {
|
|
return allowEdit(holder, false);
|
|
}
|
|
|
|
public Component allowEdit(GDPermissionUser holder, boolean forced) {
|
|
if (this.isUserTrusted(holder, TrustTypes.MANAGER, null, forced)) {
|
|
return null;
|
|
}
|
|
|
|
// Owners are not trusted while renting
|
|
if (!holder.getInternalPlayerData().canIgnoreClaim(this) && this.getEconomyData() != null && this.getEconomyData().isRented() && holder.getUniqueId().equals(this.ownerUniqueId)) {
|
|
return TextComponent.of("");
|
|
}
|
|
|
|
if (PermissionUtil.getInstance().holderHasPermission(holder, GDPermissions.COMMAND_DELETE_CLAIMS)) {
|
|
return null;
|
|
}
|
|
|
|
if (this.parent != null && this.getData().doesInheritParent()) {
|
|
return this.parent.allowEdit(holder);
|
|
}
|
|
|
|
final GDPlayerData playerData = GriefDefenderPlugin.getInstance().dataStore.getOrCreatePlayerData(this.getWorldUniqueId(), holder.getUniqueId());
|
|
if (playerData.canIgnoreClaim(this)) {
|
|
return null;
|
|
}
|
|
|
|
final Component message = MessageStorage.MESSAGE_DATA.getMessage(MessageStorage.CLAIM_OWNER_ONLY, ImmutableMap.of(
|
|
"player", this.getOwnerDisplayName()));
|
|
return message;
|
|
}
|
|
|
|
public Component allowGrantPermission(Player player) {
|
|
if(this.allowEdit(player) == null) {
|
|
return null;
|
|
}
|
|
|
|
for(int i = 0; i < this.claimData.getManagers().size(); i++) {
|
|
UUID managerID = this.claimData.getManagers().get(i);
|
|
if(player.getUniqueId().equals(managerID)) {
|
|
return null;
|
|
}
|
|
}
|
|
|
|
if(this.parent != null && this.getData().doesInheritParent()) {
|
|
return this.parent.allowGrantPermission(player);
|
|
}
|
|
|
|
final Component reason = MessageStorage.MESSAGE_DATA.getMessage(MessageStorage.PERMISSION_TRUST, ImmutableMap.of(
|
|
"player", this.getOwnerDisplayName()));
|
|
return reason;
|
|
}
|
|
|
|
@Override
|
|
public Vector3i getLesserBoundaryCorner() {
|
|
return this.lesserBoundaryCorner.clone();
|
|
}
|
|
|
|
@Override
|
|
public Vector3i getGreaterBoundaryCorner() {
|
|
return this.greaterBoundaryCorner.clone();
|
|
}
|
|
|
|
@Override
|
|
public Component getOwnerDisplayName() {
|
|
if (this.isAdminClaim() || this.isWilderness()) {
|
|
return MessageCache.getInstance().OWNER_ADMIN;
|
|
}
|
|
|
|
if (this.getOwnerPlayerData() == null) {
|
|
return TextComponent.of("[unknown]");
|
|
}
|
|
|
|
return TextComponent.of(this.getOwnerPlayerData().getName());
|
|
}
|
|
|
|
public String getOwnerName() {
|
|
if (this.isAdminClaim()) {
|
|
return "administrator";
|
|
}
|
|
if (this.isWilderness()) {
|
|
return "wilderness";
|
|
}
|
|
final GDPlayerData playerData = this.ownerPlayerData;
|
|
if (playerData == null) {
|
|
return "[unknown]";
|
|
}
|
|
return playerData.getName();
|
|
}
|
|
|
|
@Override
|
|
public boolean contains(int x, int y, int z, boolean excludeChildren) {
|
|
return this.contains(x, y, z, excludeChildren, null, false);
|
|
}
|
|
|
|
public boolean contains(Vector3i pos, GDPlayerData playerData, boolean useBorderBlockRadius) {
|
|
return this.contains(pos.getX(), pos.getY(), pos.getZ(), false, playerData, useBorderBlockRadius);
|
|
}
|
|
|
|
public boolean contains(int x, int y, int z, boolean excludeChildren, GDPlayerData playerData, boolean useBorderBlockRadius) {
|
|
int borderBlockRadius = 0;
|
|
if (useBorderBlockRadius && (playerData != null && !playerData.bypassBorderCheck)) {
|
|
final int borderRadiusConfig = GriefDefenderPlugin.getActiveConfig(this.world.getUID()).getConfig().claim.borderBlockRadius;
|
|
if (borderRadiusConfig > 0 && !this.isUserTrusted(playerData.getSubject(), TrustTypes.BUILDER)) {
|
|
borderBlockRadius = borderRadiusConfig;
|
|
}
|
|
}
|
|
|
|
boolean inClaim = (
|
|
y >= (this.lesserBoundaryCorner.getY() - borderBlockRadius)) &&
|
|
y < (this.greaterBoundaryCorner.getY() + 1 + borderBlockRadius) &&
|
|
x >= (this.lesserBoundaryCorner.getX() - borderBlockRadius) &&
|
|
x < (this.greaterBoundaryCorner.getX() + 1 + borderBlockRadius) &&
|
|
z >= (this.lesserBoundaryCorner.getZ() - borderBlockRadius) &&
|
|
z < (this.greaterBoundaryCorner.getZ() + 1 + borderBlockRadius);
|
|
|
|
if (!inClaim) {
|
|
return false;
|
|
}
|
|
|
|
if (!excludeChildren && this.parent != null && (this.getData() == null || (this.getData() != null && this.getData().doesInheritParent()))) {
|
|
return this.parent.contains(x, y, z, false, null, false);
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
public boolean isClaimOnBorder(GDClaim claim) {
|
|
if (claim.cuboid) {
|
|
return false;
|
|
}
|
|
|
|
boolean result = claim.lesserBoundaryCorner.getX() == this.lesserBoundaryCorner.getX() ||
|
|
claim.greaterBoundaryCorner.getX() == this.greaterBoundaryCorner.getX() ||
|
|
claim.lesserBoundaryCorner.getZ() == this.lesserBoundaryCorner.getZ() ||
|
|
claim.greaterBoundaryCorner.getZ() == this.greaterBoundaryCorner.getZ();
|
|
if (claim.cuboid) {
|
|
result = claim.lesserBoundaryCorner.getY() == this.lesserBoundaryCorner.getY() ||
|
|
claim.greaterBoundaryCorner.getY() == this.greaterBoundaryCorner.getY();
|
|
}
|
|
return result;
|
|
}
|
|
|
|
@Override
|
|
public boolean overlaps(Claim other) {
|
|
GDClaim otherClaim = (GDClaim) other;
|
|
if (this.id == otherClaim.id) {
|
|
return false;
|
|
}
|
|
|
|
// Handle claims entirely within a town
|
|
if (this.isTown() && !otherClaim.isTown() && otherClaim.isInside(this)) {
|
|
return false;
|
|
}
|
|
|
|
//verify that no claim's lesser boundary point is inside this new claim, to cover the "existing claim is entirely inside new claim" case
|
|
if(this.contains(otherClaim.getLesserBoundaryCorner(), false)) {
|
|
return true;
|
|
}
|
|
|
|
return this.isBandingAcross(otherClaim);
|
|
}
|
|
|
|
//Checks if claim bands across another claim, either horizontally or vertically
|
|
public boolean isBandingAcross(GDClaim otherClaim) {
|
|
final boolean isClaimInside = otherClaim.isInside(this);
|
|
if (isClaimInside) {
|
|
return false;
|
|
}
|
|
|
|
final int smallX = otherClaim.getLesserBoundaryCorner().getX();
|
|
final int smallY = otherClaim.getLesserBoundaryCorner().getY();
|
|
final int smallZ = otherClaim.getLesserBoundaryCorner().getZ();
|
|
final int bigX = otherClaim.getGreaterBoundaryCorner().getX();
|
|
final int bigY = otherClaim.getGreaterBoundaryCorner().getY();
|
|
final int bigZ = otherClaim.getGreaterBoundaryCorner().getZ();
|
|
|
|
if(this.contains(otherClaim.lesserBoundaryCorner, false)) {
|
|
return true;
|
|
}
|
|
if(this.contains(otherClaim.greaterBoundaryCorner, false)) {
|
|
return true;
|
|
}
|
|
if(this.contains(new Vector3i(smallX, 0, bigZ), false)) {
|
|
return true;
|
|
}
|
|
if(this.contains(new Vector3i(bigX, 0, smallZ), false)) {
|
|
return true;
|
|
}
|
|
|
|
boolean inArea = false;
|
|
if(this.getLesserBoundaryCorner().getZ() <= bigZ &&
|
|
this.getLesserBoundaryCorner().getZ() >= smallZ &&
|
|
this.getLesserBoundaryCorner().getX() < smallX &&
|
|
this.getGreaterBoundaryCorner().getX() > bigX)
|
|
inArea = true;
|
|
|
|
if( this.getGreaterBoundaryCorner().getZ() <= bigZ &&
|
|
this.getGreaterBoundaryCorner().getZ() >= smallZ &&
|
|
this.getLesserBoundaryCorner().getX() < smallX &&
|
|
this.getGreaterBoundaryCorner().getX() > bigX )
|
|
inArea = true;
|
|
|
|
if( this.getLesserBoundaryCorner().getX() <= bigX &&
|
|
this.getLesserBoundaryCorner().getX() >= smallX &&
|
|
this.getLesserBoundaryCorner().getZ() < smallZ &&
|
|
this.getGreaterBoundaryCorner().getZ() > bigZ )
|
|
inArea = true;
|
|
|
|
if( this.getGreaterBoundaryCorner().getX() <= bigX &&
|
|
this.getGreaterBoundaryCorner().getX() >= smallX &&
|
|
this.getLesserBoundaryCorner().getZ() < smallZ &&
|
|
this.getGreaterBoundaryCorner().getZ() > bigZ )
|
|
inArea = true;
|
|
|
|
if (inArea) {
|
|
// check height
|
|
if ((this.lesserBoundaryCorner.getY() >= smallY &&
|
|
this.lesserBoundaryCorner.getY() <= bigY) ||
|
|
(this.greaterBoundaryCorner.getY() <= smallY &&
|
|
this.greaterBoundaryCorner.getY() >= smallY)) {
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
@Override
|
|
public boolean isInside(Claim claim) {
|
|
final GDClaim otherClaim = (GDClaim) claim;
|
|
if(!otherClaim.contains(this.lesserBoundaryCorner)) {
|
|
return false;
|
|
}
|
|
if(!otherClaim.contains(this.greaterBoundaryCorner)) {
|
|
return false;
|
|
}
|
|
|
|
if(!otherClaim.contains(new Vector3i(this.lesserBoundaryCorner.getX(), this.lesserBoundaryCorner.getY(), this.greaterBoundaryCorner.getZ()))) {
|
|
return false;
|
|
}
|
|
if(!otherClaim.contains(new Vector3i(this.greaterBoundaryCorner.getX(), this.greaterBoundaryCorner.getY(), this.lesserBoundaryCorner.getZ()))) {
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
@Override
|
|
public ArrayList<Vector3i> getChunkPositions() {
|
|
ArrayList<Vector3i> chunkPositions = new ArrayList<Vector3i>();
|
|
int smallX = this.lesserBoundaryCorner.getX() >> 4;
|
|
int smallZ = this.lesserBoundaryCorner.getZ() >> 4;
|
|
int largeX = this.greaterBoundaryCorner.getX() >> 4;
|
|
int largeZ = this.greaterBoundaryCorner.getZ() >> 4;
|
|
|
|
for (int x = smallX; x <= largeX; x++) {
|
|
for (int z = smallZ; z <= largeZ; z++) {
|
|
chunkPositions.add(new Vector3i(x, 0, z));
|
|
}
|
|
}
|
|
|
|
return chunkPositions;
|
|
}
|
|
|
|
public List<Chunk> getLoadedChunks() {
|
|
List<Chunk> chunks = new ArrayList<>();
|
|
for (long chunkHash : this.getChunkHashes()) {
|
|
final GDChunk gdChunk = this.worldClaimManager.getChunk(chunkHash);
|
|
if (gdChunk != null) {
|
|
chunks.add(gdChunk.getHandle());
|
|
}
|
|
}
|
|
return chunks;
|
|
}
|
|
|
|
public List<Chunk> getChunks() {
|
|
return this.getChunks(false);
|
|
}
|
|
|
|
public List<Chunk> getChunks(boolean force) {
|
|
if (!force || this.isWilderness()) {
|
|
return this.getLoadedChunks();
|
|
}
|
|
|
|
List<Chunk> chunks = new ArrayList<Chunk>();
|
|
|
|
Chunk lesserChunk = this.world
|
|
.getChunkAt(this.getLesserBoundaryCorner().getX() >> 4, this.getLesserBoundaryCorner().getZ() >> 4);
|
|
Chunk greaterChunk = this.world
|
|
.getChunkAt(this.getGreaterBoundaryCorner().getX() >> 4, this.getGreaterBoundaryCorner().getZ() >> 4);
|
|
|
|
if (lesserChunk != null && greaterChunk != null) {
|
|
for (int x = lesserChunk.getX(); x <= greaterChunk.getX(); x++) {
|
|
for (int z = lesserChunk.getZ(); z <= greaterChunk.getZ(); z++) {
|
|
final Chunk chunk = this.world.getChunkAt(x, z);
|
|
if (chunk != null) {
|
|
chunks.add(chunk);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return chunks;
|
|
}
|
|
|
|
public boolean canIgnoreHeight() {
|
|
if (this.isCuboid()) {
|
|
return false;
|
|
}
|
|
|
|
if (this.ownerPlayerData != null && (this.getOwnerMinClaimLevel() > 0 || this.getOwnerMaxClaimLevel() < 255)) {
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
public double getOwnerEconomyBlockCost() {
|
|
return this.getOwnerEconomyBlockCost(this.ownerPlayerData);
|
|
}
|
|
|
|
public double getOwnerEconomyBlockCost(GDPlayerData playerData) {
|
|
final GDPermissionHolder subject = playerData == null ? GriefDefenderPlugin.DEFAULT_HOLDER : playerData.getSubject();
|
|
return GDPermissionManager.getInstance().getInternalOptionValue(TypeToken.of(Double.class), subject, Options.ECONOMY_BLOCK_COST).doubleValue();
|
|
}
|
|
|
|
public int getOwnerMinClaimLevel() {
|
|
return this.getOwnerMinClaimLevel(this.ownerPlayerData);
|
|
}
|
|
|
|
public int getOwnerMinClaimLevel(GDPlayerData playerData) {
|
|
final GDPermissionHolder subject = playerData == null ? GriefDefenderPlugin.DEFAULT_HOLDER : playerData.getSubject();
|
|
return GDPermissionManager.getInstance().getInternalOptionValue(TypeToken.of(Integer.class), subject, Options.MIN_LEVEL).intValue();
|
|
}
|
|
|
|
public int getOwnerMaxClaimLevel() {
|
|
return this.getOwnerMaxClaimLevel(this.ownerPlayerData);
|
|
}
|
|
|
|
public int getOwnerMaxClaimLevel(GDPlayerData playerData) {
|
|
final GDPermissionHolder subject = playerData == null ? GriefDefenderPlugin.DEFAULT_HOLDER : playerData.getSubject();
|
|
return GDPermissionManager.getInstance().getInternalOptionValue(TypeToken.of(Integer.class), subject, Options.MAX_LEVEL).intValue();
|
|
}
|
|
|
|
@Override
|
|
public Set<Long> getChunkHashes() {
|
|
return this.getChunkHashes(false);
|
|
}
|
|
|
|
public Set<Long> getChunkHashes(boolean refresh) {
|
|
if (this.isWilderness()) {
|
|
return this.loadedChunkHashes;
|
|
}
|
|
if (this.chunkHashes == null || refresh) {
|
|
this.chunkHashes = new HashSet<Long>();
|
|
int smallX = this.lesserBoundaryCorner.getX() >> 4;
|
|
int smallZ = this.lesserBoundaryCorner.getZ() >> 4;
|
|
int largeX = this.greaterBoundaryCorner.getX() >> 4;
|
|
int largeZ = this.greaterBoundaryCorner.getZ() >> 4;
|
|
|
|
this.loadedChunkHashes.clear();
|
|
for (int x = smallX; x <= largeX; x++) {
|
|
for (int z = smallZ; z <= largeZ; z++) {
|
|
this.chunkHashes.add(BlockUtil.getInstance().asLong(x, z));
|
|
final GDChunk gdChunk = this.worldClaimManager.getChunkIfLoaded(x, z);
|
|
if (gdChunk != null) {
|
|
this.loadedChunkHashes.add(gdChunk.getChunkKey());
|
|
((GDClaim) this.wildernessClaim).loadedChunkHashes.remove(gdChunk.getChunkKey());
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return this.chunkHashes;
|
|
}
|
|
|
|
@Override
|
|
public ClaimData getData() {
|
|
return (ClaimData) this.claimData;
|
|
}
|
|
|
|
public IClaimData getInternalClaimData() {
|
|
return this.claimData;
|
|
}
|
|
|
|
@Nullable
|
|
public TownDataConfig getTownData() {
|
|
if (!(this.claimData instanceof TownDataConfig)) {
|
|
return null;
|
|
}
|
|
|
|
return (TownDataConfig) this.claimData;
|
|
}
|
|
|
|
public ClaimStorageData getClaimStorage() {
|
|
return this.claimStorage;
|
|
}
|
|
|
|
public void setClaimData(IClaimData data) {
|
|
this.claimData = data;
|
|
}
|
|
|
|
public void setClaimStorage(ClaimStorageData storage) {
|
|
this.claimStorage = storage;
|
|
}
|
|
|
|
public void updateClaimStorageData() {
|
|
if (!this.isAdminClaim()) {
|
|
this.claimStorage.getConfig().setOwnerUniqueId(this.getOwnerUniqueId());
|
|
}
|
|
this.claimStorage.getConfig().setWorldUniqueId(this.world.getUID());
|
|
this.claimData.setCuboid(this.cuboid);
|
|
this.claimData.setType(this.type);
|
|
this.claimData.setLesserBoundaryCorner(BlockUtil.getInstance().posToString(this.lesserBoundaryCorner));
|
|
this.claimData.setGreaterBoundaryCorner(BlockUtil.getInstance().posToString(this.greaterBoundaryCorner));
|
|
// Will save next world save
|
|
this.claimData.setRequiresSave(true);
|
|
}
|
|
|
|
public void save() {
|
|
for (Claim child : this.children) {
|
|
GDClaim childClaim = (GDClaim) child;
|
|
if (childClaim.getInternalClaimData().requiresSave()) {
|
|
childClaim.save();
|
|
}
|
|
}
|
|
GDSaveClaimEvent.Pre preEvent = new GDSaveClaimEvent.Pre(this);
|
|
GriefDefender.getEventManager().post(preEvent);
|
|
if (this.getInternalClaimData().requiresSave()) {
|
|
this.updateClaimStorageData();
|
|
this.getClaimStorage().save();
|
|
this.getInternalClaimData().setRequiresSave(false);
|
|
}
|
|
GDSaveClaimEvent.Post postEvent = new GDSaveClaimEvent.Post(this);
|
|
GriefDefender.getEventManager().post(postEvent);
|
|
}
|
|
|
|
@Override
|
|
public ClaimResult transferOwner(UUID newOwnerID) {
|
|
return this.transferOwner(newOwnerID, false, false);
|
|
}
|
|
|
|
public ClaimResult transferOwner(UUID newOwnerID, boolean checkEconomy, boolean withdrawFunds) {
|
|
if (this.isWilderness()) {
|
|
return new GDClaimResult(ClaimResultType.WRONG_CLAIM_TYPE, TextComponent.builder("").append("The wilderness cannot be transferred.", TextColor.RED).build());
|
|
}
|
|
|
|
if (this.isAdminClaim()) {
|
|
return new GDClaimResult(ClaimResultType.WRONG_CLAIM_TYPE, TextComponent.builder("").append("Admin claims cannot be transferred.", TextColor.RED).build());
|
|
}
|
|
|
|
GDPlayerData ownerData = DATASTORE.getOrCreatePlayerData(this.world, this.getOwnerUniqueId());
|
|
// determine new owner
|
|
GDPlayerData newOwnerData = DATASTORE.getOrCreatePlayerData(this.world, newOwnerID);
|
|
|
|
if (this.isBasicClaim() && this.claimData.requiresClaimBlocks()) {
|
|
if (GriefDefenderPlugin.getInstance().isEconomyModeEnabled()) {
|
|
if (checkEconomy) {
|
|
final GDClaimResult result = EconomyUtil.getInstance().checkEconomyFunds(this, newOwnerData, withdrawFunds);
|
|
if (!result.successful()) {
|
|
return result;
|
|
}
|
|
}
|
|
} else {
|
|
int remainingClaimBlocks = newOwnerData.getRemainingClaimBlocks();
|
|
if (remainingClaimBlocks < 0 || (this.getClaimBlocks() > remainingClaimBlocks)) {
|
|
return new GDClaimResult(ClaimResultType.INSUFFICIENT_CLAIM_BLOCKS);
|
|
}
|
|
}
|
|
}
|
|
|
|
// Check limits
|
|
final Player currentOwner = ownerData.getSubject() instanceof Player ? (Player) ownerData.getSubject() : null;
|
|
final int createClaimLimit = GDPermissionManager.getInstance().getInternalOptionValue(TypeToken.of(Integer.class), newOwnerData.getSubject(), Options.CREATE_LIMIT, this);
|
|
if (createClaimLimit > -1 && (newOwnerData.getClaimTypeCount(this.getType()) + 1) > createClaimLimit) {
|
|
if (currentOwner != null) {
|
|
GriefDefenderPlugin.sendMessage(currentOwner, MessageStorage.MESSAGE_DATA.getMessage(MessageStorage.CLAIM_TRANSFER_EXCEEDS_LIMIT));
|
|
}
|
|
return new GDClaimResult(this, ClaimResultType.EXCEEDS_MAX_CLAIM_LIMIT, MessageStorage.MESSAGE_DATA.getMessage(MessageStorage.CLAIM_TRANSFER_EXCEEDS_LIMIT));
|
|
}
|
|
|
|
// transfer
|
|
GDTransferClaimEvent event = new GDTransferClaimEvent(this, this.getOwnerUniqueId(), newOwnerID);
|
|
GriefDefender.getEventManager().post(event);
|
|
if (event.cancelled()) {
|
|
return new GDClaimResult(this, ClaimResultType.CLAIM_EVENT_CANCELLED, event.getMessage().orElse(null));
|
|
}
|
|
|
|
if (this.isAdminClaim()) {
|
|
// convert to basic
|
|
this.type = ClaimTypes.BASIC;
|
|
this.getVisualizer().setType(ClaimVisualTypes.BASIC);
|
|
this.claimData.setType(ClaimTypes.BASIC);
|
|
}
|
|
|
|
this.ownerUniqueId = event.getNewOwner();
|
|
if (!this.getOwnerUniqueId().equals(newOwnerID)) {
|
|
newOwnerData = GriefDefenderPlugin.getInstance().dataStore.getOrCreatePlayerData(this.world, this.getOwnerUniqueId());
|
|
}
|
|
|
|
this.claimData.setOwnerUniqueId(newOwnerID);
|
|
if (!this.isAdminClaim()) {
|
|
ownerData.getInternalClaims().remove(this);
|
|
newOwnerData.getInternalClaims().add(this);
|
|
}
|
|
|
|
this.ownerPlayerData = newOwnerData;
|
|
this.getClaimStorage().save();
|
|
if (this.isTown()) {
|
|
// update children
|
|
for (Claim child : this.children) {
|
|
if (child.getOwnerUniqueId().equals(ownerData.getUniqueId())) {
|
|
((GDClaim) child).claimData.setOwnerUniqueId(newOwnerID);
|
|
((GDClaim) child).ownerPlayerData = newOwnerData;
|
|
if (ownerData.getInternalClaims().remove(child)) {
|
|
newOwnerData.getInternalClaims().add(child);
|
|
}
|
|
((GDClaim) child).getClaimStorage().save();
|
|
}
|
|
}
|
|
}
|
|
return new GDClaimResult(this, ClaimResultType.SUCCESS);
|
|
}
|
|
|
|
public ClaimResult findParent(GDClaim claimToSearch) {
|
|
if (!this.isInside(claimToSearch)) {
|
|
return new GDClaimResult(ClaimResultType.CLAIM_NOT_FOUND);
|
|
}
|
|
Claim current = claimToSearch;
|
|
for (Claim child : current.getChildren(true)) {
|
|
if (this.isInside(child)) {
|
|
current = child;
|
|
}
|
|
}
|
|
return new GDClaimResult(current, ClaimResultType.SUCCESS);
|
|
}
|
|
|
|
public ClaimResult doesClaimOverlap() {
|
|
if (this.parent != null) {
|
|
final GDClaim parentClaim = (GDClaim) this.parent;
|
|
// 1 - Make sure new claim is inside parent
|
|
if (!this.isInside(parentClaim)) {
|
|
return new GDClaimResult(parentClaim, ClaimResultType.OVERLAPPING_CLAIM);
|
|
}
|
|
|
|
// 2 - Check parent children
|
|
for (Claim child : parentClaim.children) {
|
|
final GDClaim childClaim = (GDClaim) child;
|
|
if (this.isBandingAcross(childClaim) || childClaim.isBandingAcross(this)) {
|
|
return new GDClaimResult(childClaim, ClaimResultType.OVERLAPPING_CLAIM);
|
|
}
|
|
}
|
|
return new GDClaimResult(this, ClaimResultType.SUCCESS);
|
|
}
|
|
|
|
final GDClaimManager claimWorldManager = GriefDefenderPlugin.getInstance().dataStore.getClaimWorldManager(this.world.getUID());
|
|
final Set<Long> chunkHashes = this.getChunkHashes(true);
|
|
|
|
// Since there is no parent we need to check all claims stored in chunk hashes
|
|
for (Long chunkHash : chunkHashes) {
|
|
Set<Claim> claimsInChunk = claimWorldManager.getInternalChunksToClaimsMap().get(chunkHash);
|
|
if (claimsInChunk == null || claimsInChunk.size() == 0) {
|
|
continue;
|
|
}
|
|
for (Claim child : claimsInChunk) {
|
|
final GDClaim gpChild = (GDClaim) child;
|
|
// First check if newly resized claim is crossing another
|
|
if (this.isBandingAcross(gpChild) || gpChild.isBandingAcross(this)) {
|
|
return new GDClaimResult(child, ClaimResultType.OVERLAPPING_CLAIM);
|
|
}
|
|
}
|
|
}
|
|
|
|
return new GDClaimResult(this, ClaimResultType.SUCCESS);
|
|
}
|
|
|
|
// Scans area for any overlaps and migrates children to a newly created or resized claim
|
|
public ClaimResult checkArea(boolean resize) {
|
|
final List<Claim> claimsInArea = new ArrayList<>();
|
|
claimsInArea.add(this);
|
|
|
|
if (this.parent != null) {
|
|
return checkAreaParent(claimsInArea, resize);
|
|
}
|
|
|
|
final List<Claim> claimsToMigrate = new ArrayList<>();
|
|
// First check children
|
|
for (Claim child : this.children) {
|
|
final GDClaim childClaim = (GDClaim) child;
|
|
if (this.isBandingAcross(childClaim) || childClaim.isBandingAcross(this)) {
|
|
return new GDClaimResult(childClaim, ClaimResultType.OVERLAPPING_CLAIM);
|
|
}
|
|
if (childClaim.isInside(this)) {
|
|
if (!this.isAdminClaim()) {
|
|
if (this.type.equals(childClaim.type) || childClaim.isAdminClaim()) {
|
|
return new GDClaimResult(childClaim, ClaimResultType.OVERLAPPING_CLAIM);
|
|
}
|
|
}
|
|
} else {
|
|
// child is no longer within parent
|
|
// if resizing, migrate the child claim out
|
|
if (resize) {
|
|
claimsToMigrate.add(childClaim);
|
|
} else {
|
|
return new GDClaimResult(childClaim, ClaimResultType.OVERLAPPING_CLAIM);
|
|
}
|
|
}
|
|
}
|
|
|
|
if (!claimsToMigrate.isEmpty()) {
|
|
((GDClaim) this.wildernessClaim).migrateClaims(claimsToMigrate);
|
|
}
|
|
|
|
final GDClaimManager claimWorldManager = GriefDefenderPlugin.getInstance().dataStore.getClaimWorldManager(this.world.getUID());
|
|
final Set<Long> chunkHashes = this.getChunkHashes(true);
|
|
|
|
// Since there is no parent we need to check all claims stored in chunk hashes
|
|
for (Long chunkHash : chunkHashes) {
|
|
Set<Claim> claimsInChunk = claimWorldManager.getInternalChunksToClaimsMap().get(chunkHash);
|
|
if (claimsInChunk == null || claimsInChunk.size() == 0) {
|
|
continue;
|
|
}
|
|
for (Claim chunkClaim : claimsInChunk) {
|
|
final GDClaim gpChunkClaim = (GDClaim) chunkClaim;
|
|
if (gpChunkClaim.equals(this) || claimsInArea.contains(gpChunkClaim)) {
|
|
continue;
|
|
}
|
|
if (this.isAdminClaim() && gpChunkClaim.isAdminClaim() && gpChunkClaim.parent != null && gpChunkClaim.parent.equals(this)) {
|
|
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);
|
|
}
|
|
if (gpChunkClaim.isInside(this)) {
|
|
if (!this.isAdminClaim()) {
|
|
if (this.type.equals(gpChunkClaim.type) || gpChunkClaim.isAdminClaim()) {
|
|
return new GDClaimResult(gpChunkClaim, ClaimResultType.OVERLAPPING_CLAIM);
|
|
}
|
|
}
|
|
if (!this.canEnclose(gpChunkClaim)) {
|
|
return new GDClaimResult(gpChunkClaim, ClaimResultType.OVERLAPPING_CLAIM);
|
|
}
|
|
if (!this.isSubdivision()) {
|
|
claimsInArea.add(gpChunkClaim);
|
|
}
|
|
} else if (this.isInside(gpChunkClaim)) {
|
|
// Fix WorldEdit issue
|
|
// Make sure to check if chunk claim can enclose newly created claim
|
|
if (!gpChunkClaim.canEnclose(this)) {
|
|
return new GDClaimResult(gpChunkClaim, ClaimResultType.OVERLAPPING_CLAIM);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return new GDClaimResult(claimsInArea, ClaimResultType.SUCCESS);
|
|
}
|
|
|
|
public ClaimResult checkAreaParent(List<Claim> claimsInArea, boolean resize) {
|
|
if (this.isClaimOnBorder(this.parent)) {
|
|
return new GDClaimResult(this.parent, ClaimResultType.OVERLAPPING_CLAIM);
|
|
}
|
|
final GDClaim parentClaim = (GDClaim) this.parent;
|
|
// 1 - Make sure new claim is inside parent
|
|
if (!this.isInside(parentClaim)) {
|
|
return new GDClaimResult(parentClaim, ClaimResultType.OVERLAPPING_CLAIM);
|
|
}
|
|
|
|
// 2 - Check parent children
|
|
for (Claim child : parentClaim.children) {
|
|
final GDClaim childClaim = (GDClaim) child;
|
|
if (this.equals(child)) {
|
|
continue;
|
|
}
|
|
if (this.isBandingAcross(childClaim) || childClaim.isBandingAcross(this)) {
|
|
return new GDClaimResult(childClaim, ClaimResultType.OVERLAPPING_CLAIM);
|
|
}
|
|
|
|
if (childClaim.isInside(this)) {
|
|
if (!this.isAdminClaim()) {
|
|
if (this.type.equals(childClaim.type) || childClaim.isAdminClaim()) {
|
|
return new GDClaimResult(childClaim, ClaimResultType.OVERLAPPING_CLAIM);
|
|
}
|
|
}
|
|
if (!this.isSubdivision()) {
|
|
claimsInArea.add(childClaim);
|
|
}
|
|
}
|
|
// ignore claims not inside
|
|
}
|
|
|
|
if (resize) {
|
|
// Make sure children are still within their parent
|
|
final List<Claim> claimsToMigrate = new ArrayList<>();
|
|
for (Claim child : this.children) {
|
|
GDClaim childClaim = (GDClaim) child;
|
|
if (this.isBandingAcross(childClaim) || childClaim.isBandingAcross(this)) {
|
|
return new GDClaimResult(childClaim, ClaimResultType.OVERLAPPING_CLAIM);
|
|
}
|
|
if (!childClaim.isInside(this)) {
|
|
if (this.parent != null) {
|
|
claimsToMigrate.add(childClaim);
|
|
} else {
|
|
childClaim.parent = null;
|
|
this.children.remove(childClaim);
|
|
final GDClaimManager claimWorldManager = GriefDefenderPlugin.getInstance().dataStore.getClaimWorldManager(this.world.getUID());
|
|
claimWorldManager.addClaim(childClaim, true);
|
|
}
|
|
}
|
|
}
|
|
if (!claimsToMigrate.isEmpty()) {
|
|
this.parent.migrateClaims(claimsToMigrate);
|
|
}
|
|
}
|
|
return new GDClaimResult(claimsInArea, ClaimResultType.SUCCESS);
|
|
}
|
|
|
|
public boolean canEnclose(Claim claim) {
|
|
if (claim.isWilderness()) {
|
|
return false;
|
|
}
|
|
if (this.isAdminClaim()) {
|
|
// admin claims can enclose any type
|
|
return true;
|
|
}
|
|
if (this.isSubdivision()) {
|
|
return false;
|
|
}
|
|
if (this.isBasicClaim()) {
|
|
if (!claim.isSubdivision()) {
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
if (this.isTown()) {
|
|
if (claim.isAdminClaim()) {
|
|
return false;
|
|
}
|
|
if (!claim.isUserTrusted(this.ownerUniqueId, TrustTypes.MANAGER)) {
|
|
return false;
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
|
|
// Checks to see if the passed in claim is a parent of this claim
|
|
@Override
|
|
public boolean isParent(Claim claim) {
|
|
if (this.parent == null) {
|
|
return false;
|
|
}
|
|
|
|
GDClaim parent = this.parent;
|
|
while (parent != null) {
|
|
if (parent.getUniqueId().equals(claim.getUniqueId())) {
|
|
return true;
|
|
}
|
|
parent = parent.parent;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
@Override
|
|
public ClaimResult resize(int x1, int x2, int y1, int y2, int z1, int z2) {
|
|
int minx = Math.min(x1, x2);
|
|
int miny = Math.min(y1, y2);
|
|
int minz = Math.min(z1, z2);
|
|
int maxx = Math.max(x1, x2);
|
|
int maxy = Math.max(y1, y2);
|
|
int maxz = Math.max(z1, z2);
|
|
|
|
final Object root = GDCauseStackManager.getInstance().getCurrentCause().root();
|
|
final GDPermissionUser user = root instanceof GDPermissionUser ? (GDPermissionUser) root : null;
|
|
final Player player = user != null ? user.getOnlinePlayer() : null;
|
|
if (this.cuboid) {
|
|
// make sure resize doesn't cross paths
|
|
if (minx >= maxx || miny > maxy || minz >= maxz) {
|
|
return new GDClaimResult(this, ClaimResultType.OVERLAPPING_CLAIM);
|
|
}
|
|
}
|
|
|
|
Location startCorner = null;
|
|
Location endCorner = null;
|
|
GDPlayerData playerData = null;
|
|
if (player != null) {
|
|
playerData = GriefDefenderPlugin.getInstance().dataStore.getPlayerData(this.world, player.getUniqueId());
|
|
} else if (!this.isAdminClaim() && this.ownerUniqueId != null) {
|
|
playerData = GriefDefenderPlugin.getInstance().dataStore.getPlayerData(this.world, this.ownerUniqueId);
|
|
}
|
|
|
|
if (playerData == null) {
|
|
if (GriefDefenderPlugin.getActiveConfig(this.world.getUID()).getConfig().claim.claimAutoSchematicRestore) {
|
|
return new GDClaimResult(this, ClaimResultType.FAILURE);
|
|
}
|
|
} else {
|
|
if (!playerData.canIgnoreClaim(this) && GriefDefenderPlugin.getActiveConfig(this.world.getUID()).getConfig().claim.claimAutoSchematicRestore) {
|
|
return new GDClaimResult(this, ClaimResultType.FAILURE);
|
|
}
|
|
}
|
|
|
|
final int minClaimLevel = this.getOwnerMinClaimLevel();
|
|
final int maxClaimLevel = this.getOwnerMaxClaimLevel();
|
|
if (!this.cuboid) {
|
|
// Auto-adjust Y levels for 2D claims
|
|
if (playerData != null) {
|
|
miny = minClaimLevel;
|
|
maxy = maxClaimLevel;
|
|
}
|
|
} else {
|
|
if (playerData != null && playerData.shovelMode != ShovelTypes.ADMIN && miny < minClaimLevel) {
|
|
final Component message = MessageStorage.MESSAGE_DATA.getMessage(MessageStorage.CLAIM_BELOW_LEVEL, ImmutableMap.of(
|
|
"limit", minClaimLevel));
|
|
GriefDefenderPlugin.sendMessage(player, message);
|
|
return new GDClaimResult(ClaimResultType.BELOW_MIN_LEVEL);
|
|
}
|
|
if (playerData != null && playerData.shovelMode != ShovelTypes.ADMIN && maxy > maxClaimLevel) {
|
|
final Component message = MessageStorage.MESSAGE_DATA.getMessage(MessageStorage.CLAIM_ABOVE_LEVEL, ImmutableMap.of(
|
|
"limit", maxClaimLevel));
|
|
GriefDefenderPlugin.sendMessage(player, message);
|
|
return new GDClaimResult(ClaimResultType.ABOVE_MAX_LEVEL);
|
|
}
|
|
// check if child extends past parent limits
|
|
if (this.parent != null) {
|
|
if (minx < this.parent.getLesserBoundaryCorner().getX() ||
|
|
miny < this.parent.getLesserBoundaryCorner().getY() ||
|
|
minz < this.parent.getLesserBoundaryCorner().getZ()) {
|
|
return new GDClaimResult(this.parent, ClaimResultType.OVERLAPPING_CLAIM);
|
|
}
|
|
if (maxx > this.parent.getGreaterBoundaryCorner().getX() ||
|
|
(this.parent.isCuboid() && maxy > this.parent.getGreaterBoundaryCorner().getY()) ||
|
|
maxz > this.parent.getGreaterBoundaryCorner().getZ()) {
|
|
return new GDClaimResult(this.parent, ClaimResultType.OVERLAPPING_CLAIM);
|
|
}
|
|
}
|
|
}
|
|
|
|
Vector3i currentLesserCorner = this.getLesserBoundaryCorner();
|
|
Vector3i currentGreaterCorner = this.getGreaterBoundaryCorner();
|
|
Vector3i newLesserCorner = new Vector3i(minx, miny, minz);
|
|
Vector3i newGreaterCorner = new Vector3i(maxx, maxy, maxz);
|
|
|
|
startCorner = new Location(this.world, minx, miny, minz);
|
|
endCorner = new Location(this.world, maxx, maxy, maxz);
|
|
GDChangeClaimEvent.Resize event = new GDChangeClaimEvent.Resize(this, startCorner, endCorner);
|
|
GriefDefender.getEventManager().post(event);
|
|
if (event.cancelled()) {
|
|
return new GDClaimResult(this, ClaimResultType.CLAIM_EVENT_CANCELLED, event.getMessage().orElse(null));
|
|
}
|
|
|
|
this.lesserBoundaryCorner = newLesserCorner;
|
|
this.greaterBoundaryCorner = newGreaterCorner;
|
|
|
|
// checkArea refreshes the current chunk hashes so it is important
|
|
// to make a copy before making the call
|
|
final Set<Long> currentChunkHashes = new HashSet<>(this.chunkHashes);
|
|
|
|
final ClaimResult result = this.checkArea(true);
|
|
if (!result.successful()) {
|
|
this.lesserBoundaryCorner = currentLesserCorner;
|
|
this.greaterBoundaryCorner = currentGreaterCorner;
|
|
return result;
|
|
}
|
|
|
|
if (this.type != ClaimTypes.ADMIN && this.type != ClaimTypes.WILDERNESS) {
|
|
ClaimResult claimResult = checkSizeLimits(player, playerData, newLesserCorner, newGreaterCorner);
|
|
if (!claimResult.successful()) {
|
|
this.lesserBoundaryCorner = currentLesserCorner;
|
|
this.greaterBoundaryCorner = currentGreaterCorner;
|
|
return claimResult;
|
|
}
|
|
}
|
|
|
|
// The current values must be used in order for getClaimBlocks to return current cost
|
|
this.lesserBoundaryCorner = currentLesserCorner;
|
|
this.greaterBoundaryCorner = currentGreaterCorner;
|
|
if (!this.cuboid || GriefDefenderPlugin.CLAIM_BLOCK_SYSTEM == ClaimBlockSystem.VOLUME) {
|
|
// check player has enough claim blocks
|
|
if ((this.isBasicClaim() || this.isTown()) && this.claimData.requiresClaimBlocks()) {
|
|
final int newCost = BlockUtil.getInstance().getClaimBlockCost(this.world, newLesserCorner, newGreaterCorner, this.cuboid);
|
|
final int currentCost = BlockUtil.getInstance().getClaimBlockCost(this.world, currentLesserCorner, currentGreaterCorner, this.cuboid);
|
|
if (GriefDefenderPlugin.getInstance().isEconomyModeEnabled()) {
|
|
if (!this.vaultProvider.getApi().hasAccount(player)) {
|
|
return new GDClaimResult(ClaimResultType.ECONOMY_ACCOUNT_NOT_FOUND);
|
|
}
|
|
|
|
final double requiredFunds = Math.abs((newCost - currentCost) * this.getOwnerEconomyBlockCost());
|
|
if (newCost > currentCost) {
|
|
final double currentFunds = this.vaultProvider.getApi().getBalance(player);
|
|
final EconomyResponse economyResponse = EconomyUtil.getInstance().withdrawFunds(player, requiredFunds);
|
|
if (!economyResponse.transactionSuccess()) {
|
|
Component message = null;
|
|
if (player != null) {
|
|
message = MessageStorage.MESSAGE_DATA.getMessage(MessageStorage.ECONOMY_NOT_ENOUGH_FUNDS, ImmutableMap.of(
|
|
"balance", this.vaultProvider.getApi().getBalance(player),
|
|
"amount", requiredFunds));
|
|
GriefDefenderPlugin.sendMessage(player, message);
|
|
}
|
|
|
|
this.lesserBoundaryCorner = currentLesserCorner;
|
|
this.greaterBoundaryCorner = currentGreaterCorner;
|
|
return new GDClaimResult(ClaimResultType.ECONOMY_NOT_ENOUGH_FUNDS, message);
|
|
}
|
|
} else {
|
|
final EconomyResponse economyResponse = this.vaultProvider.getApi().depositPlayer(player, requiredFunds);
|
|
}
|
|
} else if (newCost > currentCost) {
|
|
final int remainingClaimBlocks = this.ownerPlayerData.getRemainingClaimBlocks() - (newCost - currentCost);
|
|
if (remainingClaimBlocks < 0) {
|
|
if (player != null) {
|
|
if (GriefDefenderPlugin.CLAIM_BLOCK_SYSTEM == ClaimBlockSystem.VOLUME) {
|
|
final double claimableChunks = Math.abs(remainingClaimBlocks / 65536.0);
|
|
GriefDefenderPlugin.sendMessage(player, MessageStorage.MESSAGE_DATA.getMessage(MessageStorage.CLAIM_SIZE_NEED_BLOCKS_3D, ImmutableMap.of(
|
|
"chunk-amount", Math.round(claimableChunks * 100.0)/100.0,
|
|
"block-amount", Math.abs(remainingClaimBlocks))));
|
|
} else {
|
|
GriefDefenderPlugin.sendMessage(player, GriefDefenderPlugin.getInstance().messageData.getMessage(MessageStorage.CLAIM_SIZE_NEED_BLOCKS_2D, ImmutableMap.of(
|
|
"block-amount", Math.abs(remainingClaimBlocks))));
|
|
}
|
|
}
|
|
|
|
this.lesserBoundaryCorner = currentLesserCorner;
|
|
this.greaterBoundaryCorner = currentGreaterCorner;
|
|
return new GDClaimResult(ClaimResultType.INSUFFICIENT_CLAIM_BLOCKS);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
this.lesserBoundaryCorner = newLesserCorner;
|
|
this.greaterBoundaryCorner = newGreaterCorner;
|
|
GDClaimManager claimWorldManager = GriefDefenderPlugin.getInstance().dataStore.getClaimWorldManager(this.world.getUID());
|
|
|
|
// resize validated, remove invalid chunkHashes
|
|
if (this.parent == null) {
|
|
for (Long chunkHash : currentChunkHashes) {
|
|
Set<Claim> claimsInChunk = claimWorldManager.getInternalChunksToClaimsMap().get(chunkHash);
|
|
if (claimsInChunk != null && claimsInChunk.size() > 0) {
|
|
claimsInChunk.remove(this);
|
|
}
|
|
}
|
|
|
|
final Set<Long> newChunkHashes = this.getChunkHashes(true);
|
|
// add new chunk hashes
|
|
for (Long chunkHash : newChunkHashes) {
|
|
Set<Claim> claimsInChunk = claimWorldManager.getInternalChunksToClaimsMap().get(chunkHash);
|
|
if (claimsInChunk == null) {
|
|
claimsInChunk = new HashSet<>();
|
|
claimWorldManager.getInternalChunksToClaimsMap().put(chunkHash, claimsInChunk);
|
|
}
|
|
|
|
claimsInChunk.add(this);
|
|
}
|
|
}
|
|
|
|
this.claimData.setLesserBoundaryCorner(BlockUtil.getInstance().posToString(this.lesserBoundaryCorner));
|
|
this.claimData.setGreaterBoundaryCorner(BlockUtil.getInstance().posToString(this.greaterBoundaryCorner));
|
|
this.claimData.setRequiresSave(true);
|
|
this.getClaimStorage().save();
|
|
|
|
if (result.getClaims().size() > 1) {
|
|
this.migrateClaims(new ArrayList<>(result.getClaims()));
|
|
}
|
|
this.resetVisuals();
|
|
return new GDClaimResult(this, ClaimResultType.SUCCESS);
|
|
}
|
|
|
|
private ClaimResult checkSizeLimits(Player player, GDPlayerData playerData, Vector3i lesserCorner, Vector3i greaterCorner) {
|
|
if (playerData == null) {
|
|
return new GDClaimResult(ClaimResultType.SUCCESS);
|
|
}
|
|
|
|
final GDPermissionHolder holder = PermissionHolderCache.getInstance().getOrCreateUser(playerData.playerID);
|
|
final int minClaimX = GDPermissionManager.getInstance().getInternalOptionValue(TypeToken.of(Integer.class), holder, Options.MIN_SIZE_X, this);
|
|
final int minClaimY = GDPermissionManager.getInstance().getInternalOptionValue(TypeToken.of(Integer.class), holder, Options.MIN_SIZE_Y, this);
|
|
final int minClaimZ = GDPermissionManager.getInstance().getInternalOptionValue(TypeToken.of(Integer.class), holder, Options.MIN_SIZE_Z, this);
|
|
final int maxClaimX = GDPermissionManager.getInstance().getInternalOptionValue(TypeToken.of(Integer.class), holder, Options.MAX_SIZE_X, this);
|
|
final int maxClaimY = GDPermissionManager.getInstance().getInternalOptionValue(TypeToken.of(Integer.class), holder, Options.MAX_SIZE_Y, this);
|
|
final int maxClaimZ = GDPermissionManager.getInstance().getInternalOptionValue(TypeToken.of(Integer.class), holder, Options.MAX_SIZE_Z, this);
|
|
|
|
// Handle single block selection
|
|
if ((this.isCuboid() && greaterCorner.equals(lesserCorner)) || (!this.isCuboid() && greaterCorner.getX() == lesserCorner.getX() && greaterCorner.getZ() == lesserCorner.getZ())) {
|
|
if (playerData.claimResizing != null) {
|
|
final Component message = MessageCache.getInstance().RESIZE_SAME_LOCATION;
|
|
GriefDefenderPlugin.sendMessage(player, message);
|
|
// TODO: Add new result type for this
|
|
return new GDClaimResult(ClaimResultType.BELOW_MIN_SIZE_X, message);
|
|
}
|
|
if (playerData.claimSubdividing == null) {
|
|
final Component message = MessageCache.getInstance().CREATE_SUBDIVISION_ONLY;
|
|
GriefDefenderPlugin.sendMessage(player, message);
|
|
// TODO: Add new result type for this
|
|
return new GDClaimResult(ClaimResultType.BELOW_MIN_SIZE_X, message);
|
|
}
|
|
}
|
|
Component message = null;
|
|
String maxCuboidArea = maxClaimX + "x" + maxClaimY + "x" + maxClaimZ;
|
|
if (maxClaimX == 0 && maxClaimY == 0 && maxClaimZ == 0) {
|
|
maxCuboidArea = "∞";
|
|
}
|
|
String maxArea = maxClaimX + "x" + maxClaimZ;
|
|
if (maxClaimX == 0 && maxClaimZ == 0) {
|
|
maxArea = "∞";
|
|
}
|
|
|
|
if (maxClaimX > 0) {
|
|
int size = Math.abs(greaterCorner.getX() - lesserCorner.getX()) + 1;
|
|
if (size > maxClaimX) {
|
|
if (player != null) {
|
|
if (this.isCuboid()) {
|
|
message = MessageStorage.MESSAGE_DATA.getMessage(MessageStorage.CLAIM_SIZE_MAX, ImmutableMap.of(
|
|
"axis", "x",
|
|
"size", size,
|
|
"max-size", maxClaimX == 0 ? "∞" : maxClaimX,
|
|
"min-area", minClaimX + "x" + minClaimY + "x" + minClaimZ,
|
|
"max-area", maxCuboidArea));
|
|
} else {
|
|
message = MessageStorage.MESSAGE_DATA.getMessage(MessageStorage.CLAIM_SIZE_MAX, ImmutableMap.of(
|
|
"axis", "x",
|
|
"size", size,
|
|
"max-size", maxClaimX == 0 ? "∞" : maxClaimX,
|
|
"min-area", minClaimX + "x" + minClaimZ,
|
|
"max-area", maxArea));
|
|
}
|
|
GriefDefenderPlugin.sendMessage(player, message);
|
|
}
|
|
return new GDClaimResult(ClaimResultType.EXCEEDS_MAX_SIZE_X, message);
|
|
}
|
|
}
|
|
if (this.cuboid && maxClaimY > 0) {
|
|
int size = Math.abs(greaterCorner.getY() - lesserCorner.getY()) + 1;
|
|
if (size > maxClaimY) {
|
|
if (player != null) {
|
|
if (this.isCuboid()) {
|
|
message = MessageStorage.MESSAGE_DATA.getMessage(MessageStorage.CLAIM_SIZE_MAX, ImmutableMap.of(
|
|
"axis", "y",
|
|
"size", size,
|
|
"max-size", maxClaimY == 0 ? "∞" : maxClaimY,
|
|
"min-area", minClaimX + "x" + minClaimY + "x" + minClaimZ,
|
|
"max-area", maxCuboidArea));
|
|
} else {
|
|
message = MessageStorage.MESSAGE_DATA.getMessage(MessageStorage.CLAIM_SIZE_MAX, ImmutableMap.of(
|
|
"axis", "y",
|
|
"size", size,
|
|
"max-size", maxClaimY == 0 ? "∞" : maxClaimY,
|
|
"min-area", minClaimX + "x" + minClaimZ,
|
|
"max-area", maxArea));
|
|
}
|
|
GriefDefenderPlugin.sendMessage(player, message);
|
|
}
|
|
return new GDClaimResult(ClaimResultType.EXCEEDS_MAX_SIZE_Y, message);
|
|
}
|
|
}
|
|
if (maxClaimZ > 0) {
|
|
int size = Math.abs(greaterCorner.getZ() - lesserCorner.getZ()) + 1;
|
|
if (size > maxClaimZ) {
|
|
if (player != null) {
|
|
if (this.isCuboid()) {
|
|
message = MessageStorage.MESSAGE_DATA.getMessage(MessageStorage.CLAIM_SIZE_MAX, ImmutableMap.of(
|
|
"axis", "z",
|
|
"size", size,
|
|
"max-size", maxClaimZ == 0 ? "∞" : maxClaimZ,
|
|
"min-area", minClaimX + "x" + minClaimY + "x" + minClaimZ,
|
|
"max-area", maxCuboidArea));
|
|
} else {
|
|
message = MessageStorage.MESSAGE_DATA.getMessage(MessageStorage.CLAIM_SIZE_MAX, ImmutableMap.of(
|
|
"axis", "z",
|
|
"size", size,
|
|
"max-size", maxClaimZ == 0 ? "∞" : maxClaimZ,
|
|
"min-area", minClaimX + "x" + minClaimZ,
|
|
"max-area", maxArea));
|
|
}
|
|
GriefDefenderPlugin.sendMessage(player, message);
|
|
}
|
|
return new GDClaimResult(ClaimResultType.EXCEEDS_MAX_SIZE_Z, message);
|
|
}
|
|
}
|
|
if (minClaimX > 0) {
|
|
int size = Math.abs(greaterCorner.getX() - lesserCorner.getX()) + 1;
|
|
if (size < minClaimX) {
|
|
if (player != null) {
|
|
if (this.isCuboid()) {
|
|
message = MessageStorage.MESSAGE_DATA.getMessage(MessageStorage.CLAIM_SIZE_MIN, ImmutableMap.of(
|
|
"axis", "x",
|
|
"size", size,
|
|
"min-size", minClaimX == 0 ? "∞" : minClaimX,
|
|
"min-area", minClaimX + "x" + minClaimY + "x" + minClaimZ,
|
|
"max-area", maxCuboidArea));
|
|
} else {
|
|
message = MessageStorage.MESSAGE_DATA.getMessage(MessageStorage.CLAIM_SIZE_MIN, ImmutableMap.of(
|
|
"axis", "x",
|
|
"size", size,
|
|
"min-size", minClaimX,
|
|
"min-area", minClaimX + "x" + minClaimZ,
|
|
"max-area", maxArea));
|
|
}
|
|
GriefDefenderPlugin.sendMessage(player, message);
|
|
}
|
|
return new GDClaimResult(ClaimResultType.BELOW_MIN_SIZE_X, message);
|
|
}
|
|
}
|
|
if (this.cuboid && minClaimY > 0) {
|
|
int size = Math.abs(greaterCorner.getY() - lesserCorner.getY()) + 1;
|
|
if (size < minClaimY) {
|
|
if (player != null) {
|
|
if (this.isCuboid()) {
|
|
message = MessageStorage.MESSAGE_DATA.getMessage(MessageStorage.CLAIM_SIZE_MIN, ImmutableMap.of(
|
|
"axis", "y",
|
|
"size", size,
|
|
"min-size", minClaimY == 0 ? "∞" : minClaimY,
|
|
"min-area", minClaimX + "x" + minClaimY + "x" + minClaimZ,
|
|
"max-area", maxCuboidArea));
|
|
} else {
|
|
message = MessageStorage.MESSAGE_DATA.getMessage(MessageStorage.CLAIM_SIZE_MIN, ImmutableMap.of(
|
|
"axis", "y",
|
|
"size", size,
|
|
"min-size", minClaimY == 0 ? "∞" : minClaimY,
|
|
"min-area", minClaimX + "x" + minClaimZ,
|
|
"max-area", maxArea));
|
|
}
|
|
GriefDefenderPlugin.sendMessage(player, message);
|
|
}
|
|
return new GDClaimResult(ClaimResultType.BELOW_MIN_SIZE_Y, message);
|
|
}
|
|
}
|
|
if (minClaimZ > 0) {
|
|
int size = Math.abs(greaterCorner.getZ() - lesserCorner.getZ()) + 1;
|
|
if (size < minClaimZ) {
|
|
if (player != null) {
|
|
if (this.isCuboid()) {
|
|
message = MessageStorage.MESSAGE_DATA.getMessage(MessageStorage.CLAIM_SIZE_MIN, ImmutableMap.of(
|
|
"axis", "z",
|
|
"size", size,
|
|
"min-size", minClaimZ == 0 ? "∞" : minClaimZ,
|
|
"min-area", minClaimX + "x" + minClaimY + "x" + minClaimZ,
|
|
"max-area", maxCuboidArea));
|
|
} else {
|
|
message = MessageStorage.MESSAGE_DATA.getMessage(MessageStorage.CLAIM_SIZE_MIN, ImmutableMap.of(
|
|
"axis", "z",
|
|
"size", size,
|
|
"min-size", minClaimZ == 0 ? "∞" : minClaimZ,
|
|
"min-area", minClaimX + "x" + minClaimZ,
|
|
"max-area", maxArea));
|
|
}
|
|
GriefDefenderPlugin.sendMessage(player, message);
|
|
}
|
|
return new GDClaimResult(ClaimResultType.BELOW_MIN_SIZE_Z, message);
|
|
}
|
|
}
|
|
|
|
return new GDClaimResult(ClaimResultType.SUCCESS);
|
|
}
|
|
|
|
public void unload() {
|
|
// clear any references
|
|
this.world = null;
|
|
if (this.ownerPlayerData != null) {
|
|
this.ownerPlayerData.getInternalClaims().remove(this);
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public Claim getWilderness() {
|
|
return this.wildernessClaim;
|
|
}
|
|
|
|
@Override
|
|
public ClaimManager getClaimManager() {
|
|
return (ClaimManager) this.worldClaimManager;
|
|
}
|
|
|
|
@Override
|
|
public Context getContext() {
|
|
return this.context;
|
|
}
|
|
|
|
public Context getInheritContext() {
|
|
if (this.parent == null || !this.getData().doesInheritParent()) {
|
|
return this.context;
|
|
}
|
|
|
|
return this.parent.getInheritContext();
|
|
}
|
|
|
|
public boolean hasAdminParent() {
|
|
if (this.parent == null || this.isAdminClaim()) {
|
|
return false;
|
|
}
|
|
|
|
if (this.parent.isAdminClaim()) {
|
|
return true;
|
|
}
|
|
|
|
return this.parent.hasAdminParent();
|
|
}
|
|
|
|
@Override
|
|
public boolean extend(int newDepth) {
|
|
return false;
|
|
}
|
|
|
|
@Override
|
|
public Optional<Claim> getParent() {
|
|
return Optional.ofNullable(this.parent);
|
|
}
|
|
|
|
@Override
|
|
public UUID getWorldUniqueId() {
|
|
return this.world.getUID();
|
|
}
|
|
|
|
public World getWorld() {
|
|
return this.world;
|
|
}
|
|
|
|
public void setWorld(World world) {
|
|
this.world = world;
|
|
}
|
|
|
|
public List<Entity> getEntities() {
|
|
Collection<Entity> worldEntityList = Bukkit.getServer().getWorld(this.world.getUID()).getEntities();
|
|
List<Entity> entityList = new ArrayList<>();
|
|
for (Entity entity : worldEntityList) {
|
|
if (!(entity.isDead() && this.contains(VecHelper.toVector3i(entity.getLocation())))) {
|
|
entityList.add(entity);
|
|
}
|
|
}
|
|
|
|
return entityList;
|
|
}
|
|
|
|
@Override
|
|
public List<UUID> getPlayers() {
|
|
Collection<Player> worldPlayerList = Bukkit.getServer().getWorld(this.world.getUID()).getPlayers();
|
|
List<UUID> playerList = new ArrayList<>();
|
|
for (Player player : worldPlayerList) {
|
|
if (!player.isDead() && this.contains(VecHelper.toVector3i(player.getLocation()))) {
|
|
playerList.add(player.getUniqueId());
|
|
}
|
|
}
|
|
|
|
return playerList;
|
|
}
|
|
|
|
@Override
|
|
public Set<Claim> getChildren(boolean recursive) {
|
|
if (recursive) {
|
|
Set<Claim> claimList = new HashSet<>(this.children);
|
|
List<Claim> subChildren = new ArrayList<>();
|
|
for (Claim child : claimList) {
|
|
GDClaim childClaim = (GDClaim) child;
|
|
if (!childClaim.children.isEmpty()) {
|
|
subChildren.addAll(childClaim.getChildren(true));
|
|
}
|
|
}
|
|
claimList.addAll(subChildren);
|
|
return claimList;
|
|
}
|
|
return ImmutableSet.copyOf(this.children);
|
|
}
|
|
|
|
@Override
|
|
public List<Claim> getParents(boolean recursive) {
|
|
List<Claim> parents = new ArrayList<>();
|
|
GDClaim currentClaim = this;
|
|
while (currentClaim.parent != null) {
|
|
parents.add(currentClaim.parent);
|
|
currentClaim = currentClaim.parent;
|
|
}
|
|
|
|
// Index 0 is highest parent while last index represents direct
|
|
Collections.reverse(parents);
|
|
return ImmutableList.copyOf(parents);
|
|
}
|
|
|
|
public List<Claim> getInheritedParents() {
|
|
List<Claim> parents = new ArrayList<>();
|
|
GDClaim currentClaim = this;
|
|
while (currentClaim.parent != null && (currentClaim.getData() == null || currentClaim.getData().doesInheritParent())) {
|
|
if (currentClaim.isAdminClaim()) {
|
|
if (currentClaim.parent.isAdminClaim()) {
|
|
parents.add(currentClaim.parent);
|
|
}
|
|
} else {
|
|
parents.add(currentClaim.parent);
|
|
}
|
|
currentClaim = currentClaim.parent;
|
|
}
|
|
|
|
// Index 0 is highest parent while last index represents direct
|
|
Collections.reverse(parents);
|
|
return ImmutableList.copyOf(parents);
|
|
}
|
|
|
|
@Override
|
|
public ClaimResult deleteChild(Claim child) {
|
|
boolean found = false;
|
|
for (Claim childClaim : this.children) {
|
|
if (childClaim.getUniqueId().equals(child.getUniqueId())) {
|
|
found = true;
|
|
}
|
|
}
|
|
|
|
if (!found) {
|
|
return new GDClaimResult(ClaimResultType.CLAIM_NOT_FOUND);
|
|
}
|
|
|
|
final GDClaimManager claimManager = GriefDefenderPlugin.getInstance().dataStore.getClaimWorldManager(this.world.getUID());
|
|
return claimManager.deleteClaim(child, true);
|
|
}
|
|
|
|
@Override
|
|
public ClaimResult deleteChildren() {
|
|
return this.deleteChildren(null);
|
|
}
|
|
|
|
@Override
|
|
public ClaimResult deleteChildren(ClaimType claimType) {
|
|
List<Claim> claimList = new ArrayList<>();
|
|
for (Claim child : this.children) {
|
|
if (claimType == null || child.getType() == claimType) {
|
|
claimList.add(child);
|
|
}
|
|
}
|
|
|
|
if (claimList.isEmpty()) {
|
|
return new GDClaimResult(ClaimResultType.CLAIM_NOT_FOUND);
|
|
}
|
|
|
|
GDRemoveClaimEvent event = new GDRemoveClaimEvent(claimList);
|
|
GriefDefender.getEventManager().post(event);
|
|
if (event.cancelled()) {
|
|
return new GDClaimResult(claimList, ClaimResultType.CLAIM_EVENT_CANCELLED);
|
|
}
|
|
|
|
final GDClaimManager claimManager = GriefDefenderPlugin.getInstance().dataStore.getClaimWorldManager(this.world.getUID());
|
|
for (Claim child : claimList) {
|
|
claimManager.deleteClaimInternal(child, true);
|
|
}
|
|
|
|
return new GDClaimResult(event.getClaims(), ClaimResultType.SUCCESS);
|
|
}
|
|
|
|
@Override
|
|
public ClaimResult changeType(ClaimType type, Optional<UUID> ownerUniqueId) {
|
|
return changeType(type, ownerUniqueId, null);
|
|
}
|
|
|
|
public ClaimResult changeType(ClaimType type, Optional<UUID> ownerUniqueId, CommandSender src) {
|
|
if (type == this.type) {
|
|
return new GDClaimResult(ClaimResultType.SUCCESS);
|
|
}
|
|
|
|
GDChangeClaimEvent.Type event = new GDChangeClaimEvent.Type(this, type);
|
|
GriefDefender.getEventManager().post(event);
|
|
if (event.cancelled()) {
|
|
return new GDClaimResult(ClaimResultType.CLAIM_EVENT_CANCELLED, event.getMessage().orElse(null));
|
|
}
|
|
|
|
final GDClaimManager claimWorldManager = GriefDefenderPlugin.getInstance().dataStore.getClaimWorldManager(this.world.getUID());
|
|
final GDPlayerData sourcePlayerData = src != null && src instanceof Player ? claimWorldManager.getOrCreatePlayerData(((Player) src).getUniqueId()) : null;
|
|
UUID newOwnerUUID = ownerUniqueId.orElse(this.ownerUniqueId);
|
|
final ClaimResult result = this.validateClaimType(type, newOwnerUUID, sourcePlayerData);
|
|
if (!result.successful()) {
|
|
return result;
|
|
}
|
|
|
|
if (type == ClaimTypes.ADMIN) {
|
|
newOwnerUUID = GriefDefenderPlugin.ADMIN_USER_UUID;
|
|
}
|
|
|
|
final String fileName = this.getClaimStorage().filePath.getFileName().toString();
|
|
final Path newPath = this.getClaimStorage().folderPath.getParent().resolve(type.getName().toLowerCase()).resolve(fileName);
|
|
try {
|
|
if (Files.notExists(newPath.getParent())) {
|
|
Files.createDirectories(newPath.getParent());
|
|
}
|
|
Files.move(this.getClaimStorage().filePath, newPath);
|
|
if (type == ClaimTypes.TOWN) {
|
|
this.setClaimStorage(new TownStorageData(newPath, this.getWorldUniqueId(), newOwnerUUID, this.cuboid));
|
|
} else {
|
|
this.setClaimStorage(new ClaimStorageData(newPath, this.getWorldUniqueId(), (ClaimDataConfig) this.getInternalClaimData()));
|
|
}
|
|
this.claimData = this.claimStorage.getConfig();
|
|
this.getClaimStorage().save();
|
|
} catch (IOException e) {
|
|
e.printStackTrace();
|
|
return new GDClaimResult(ClaimResultType.CLAIM_NOT_FOUND, TextComponent.of(e.getMessage()));
|
|
}
|
|
|
|
// If switched to admin or new owner, remove from player claim list
|
|
if (type == ClaimTypes.ADMIN || (this.ownerUniqueId != null && !this.ownerUniqueId.equals(newOwnerUUID))) {
|
|
final Set<Claim> currentPlayerClaims = claimWorldManager.getInternalPlayerClaims(this.ownerUniqueId);
|
|
if (currentPlayerClaims != null) {
|
|
currentPlayerClaims.remove(this);
|
|
}
|
|
}
|
|
if (type != ClaimTypes.ADMIN) {
|
|
final Set<Claim> newPlayerClaims = claimWorldManager.getInternalPlayerClaims(newOwnerUUID);
|
|
if (newPlayerClaims != null && !newPlayerClaims.contains(this)) {
|
|
newPlayerClaims.add(this);
|
|
}
|
|
}
|
|
|
|
if (!this.isAdminClaim() && this.ownerPlayerData != null) {
|
|
final Player player = Bukkit.getServer().getPlayer(this.ownerUniqueId);
|
|
if (player != null) {
|
|
this.ownerPlayerData.revertClaimVisual(this);
|
|
}
|
|
}
|
|
|
|
// revert visuals for all players watching this claim
|
|
List<UUID> playersWatching = new ArrayList<>(this.playersWatching);
|
|
for (UUID playerUniqueId : playersWatching) {
|
|
final Player spongePlayer = Bukkit.getServer().getPlayer(playerUniqueId);
|
|
final GDPlayerData playerData = claimWorldManager.getOrCreatePlayerData(playerUniqueId);
|
|
if (spongePlayer != null) {
|
|
playerData.revertClaimVisual(this);
|
|
}
|
|
}
|
|
|
|
if (!newOwnerUUID.equals(GriefDefenderPlugin.ADMIN_USER_UUID)) {
|
|
this.setOwnerUniqueId(newOwnerUUID);
|
|
}
|
|
this.setType(type);
|
|
this.claimVisual = null;
|
|
this.getInternalClaimData().setRequiresSave(true);
|
|
this.getClaimStorage().save();
|
|
return new GDClaimResult(ClaimResultType.SUCCESS);
|
|
}
|
|
|
|
public ClaimResult validateClaimType(ClaimType type, UUID newOwnerUUID, GDPlayerData playerData) {
|
|
boolean isAdmin = false;
|
|
if (playerData != null && (playerData.canManageAdminClaims || playerData.canIgnoreClaim(this))) {
|
|
isAdmin = true;
|
|
}
|
|
|
|
GDPermissionUser user = null;
|
|
if (newOwnerUUID != null) {
|
|
user = PermissionHolderCache.getInstance().getOrCreateUser(newOwnerUUID);
|
|
}
|
|
|
|
if (type == ClaimTypes.ADMIN) {
|
|
if (!isAdmin) {
|
|
final Component message = MessageStorage.MESSAGE_DATA.getMessage(MessageStorage.RESULT_TYPE_CHANGE_NOT_ADMIN,
|
|
ImmutableMap.of("type", TextComponent.of("ADMIN").color(TextColor.RED)));
|
|
return new GDClaimResult(ClaimResultType.WRONG_CLAIM_TYPE, message);
|
|
}
|
|
} else if (type == ClaimTypes.BASIC) {
|
|
if (this.isAdminClaim() && newOwnerUUID == null) {
|
|
return new GDClaimResult(ClaimResultType.REQUIRES_OWNER, MessageStorage.MESSAGE_DATA.getMessage(MessageStorage.RESULT_TYPE_REQUIRES_OWNER,
|
|
ImmutableMap.of(
|
|
"type", TextComponent.of("ADMIN", TextColor.RED),
|
|
"target_type", TextComponent.of("BASIC", TextColor.GREEN))));
|
|
}
|
|
if (this.parent != null && this.parent.isBasicClaim()) {
|
|
final Component message = MessageStorage.MESSAGE_DATA.getMessage(MessageStorage.RESULT_TYPE_CHILD_SAME,
|
|
ImmutableMap.of("type", TextComponent.of("BASIC").color(TextColor.GREEN)));
|
|
return new GDClaimResult(ClaimResultType.WRONG_CLAIM_TYPE, message);
|
|
}
|
|
for (Claim child : this.children) {
|
|
if (!child.isSubdivision()) {
|
|
final Component message = MessageStorage.MESSAGE_DATA.getMessage(MessageStorage.RESULT_TYPE_ONLY_SUBDIVISION,
|
|
ImmutableMap.of("type", TextComponent.of("BASIC").color(TextColor.GREEN)));
|
|
return new GDClaimResult(ClaimResultType.WRONG_CLAIM_TYPE, message);
|
|
}
|
|
}
|
|
} else if (type == ClaimTypes.SUBDIVISION) {
|
|
if (!this.children.isEmpty()) {
|
|
final Component message = MessageStorage.MESSAGE_DATA.getMessage(MessageStorage.RESULT_TYPE_NO_CHILDREN,
|
|
ImmutableMap.of("type", TextComponent.of("SUBDIVISION").color(TextColor.AQUA)));
|
|
return new GDClaimResult(ClaimResultType.WRONG_CLAIM_TYPE, message);
|
|
}
|
|
if (this.parent == null) {
|
|
final Component message = MessageStorage.MESSAGE_DATA.getMessage(MessageStorage.RESULT_TYPE_CREATE_DENY,
|
|
ImmutableMap.of(
|
|
"type", this.getFriendlyNameType(type, true),
|
|
"target_type", TextComponent.of("WILDERNESS", TextColor.GREEN)));
|
|
return new GDClaimResult(ClaimResultType.WRONG_CLAIM_TYPE, message);
|
|
}
|
|
if (this.isAdminClaim() && newOwnerUUID == null) {
|
|
return new GDClaimResult(ClaimResultType.REQUIRES_OWNER, MessageStorage.MESSAGE_DATA.getMessage(MessageStorage.RESULT_TYPE_REQUIRES_OWNER,
|
|
ImmutableMap.of(
|
|
"type", this.getFriendlyNameType(type, true),
|
|
"target_type", TextComponent.of("SUBDIVISION", TextColor.AQUA))));
|
|
}
|
|
} else if (type == ClaimTypes.TOWN) {
|
|
if (this.parent != null && this.parent.isTown()) {
|
|
final Component message = MessageStorage.MESSAGE_DATA.getMessage(MessageStorage.RESULT_TYPE_NO_CHILDREN,
|
|
ImmutableMap.of("type", TextComponent.of("TOWN").color(TextColor.GREEN)));
|
|
return new GDClaimResult(ClaimResultType.WRONG_CLAIM_TYPE, message);
|
|
}
|
|
if (!isAdmin && user != null && !PermissionUtil.getInstance().holderHasPermission(user, GDPermissions.CLAIM_CREATE_TOWN)) {
|
|
final Component message = MessageStorage.MESSAGE_DATA.getMessage(MessageStorage.RESULT_TYPE_CREATE_DENY,
|
|
ImmutableMap.of(
|
|
"type", this.getFriendlyNameType(type, true),
|
|
"target_type", TextComponent.of("TOWN", TextColor.GREEN)));
|
|
return new GDClaimResult(ClaimResultType.WRONG_CLAIM_TYPE, message);
|
|
}
|
|
} else if (type == ClaimTypes.WILDERNESS) {
|
|
final Component message = MessageStorage.MESSAGE_DATA.getMessage(MessageStorage.RESULT_TYPE_CHANGE_DENY,
|
|
ImmutableMap.of("type", TextComponent.of("WILDERNESS").color(TextColor.GREEN)));
|
|
return new GDClaimResult(ClaimResultType.WRONG_CLAIM_TYPE, message);
|
|
}
|
|
|
|
return new GDClaimResult(ClaimResultType.SUCCESS);
|
|
}
|
|
|
|
public int getSpawnLimit(Set<Context> contexts) {
|
|
final List<Claim> parents = this.getParents(true);
|
|
for (Claim claim : parents) {
|
|
final int parentSpawnLimit = GDPermissionManager.getInstance().getInternalOptionValue(TypeToken.of(Integer.class), GriefDefenderPlugin.DEFAULT_HOLDER, Options.SPAWN_LIMIT, claim, new HashSet<>(contexts));
|
|
if (parentSpawnLimit > -1) {
|
|
return parentSpawnLimit;
|
|
}
|
|
}
|
|
|
|
return GDPermissionManager.getInstance().getInternalOptionValue(TypeToken.of(Integer.class), GriefDefenderPlugin.DEFAULT_HOLDER, Options.SPAWN_LIMIT, this, new HashSet<>(contexts));
|
|
}
|
|
|
|
public int countEntities(Entity spawnedEntity) {
|
|
int count = 0;
|
|
for (Chunk chunk : this.getChunks()) {
|
|
for (Entity entity : chunk.getEntities()) {
|
|
if (spawnedEntity.getType() == entity.getType()) {
|
|
count++;
|
|
}
|
|
}
|
|
}
|
|
|
|
return count;
|
|
}
|
|
|
|
@Override
|
|
public boolean equals(Object o) {
|
|
if (this == o) {
|
|
return true;
|
|
}
|
|
if (o == null || !(o instanceof GDClaim)) {
|
|
return false;
|
|
}
|
|
GDClaim that = (GDClaim) o;
|
|
return this.type == that.type &&
|
|
Objects.equal(this.id, that.id);
|
|
}
|
|
|
|
@Override
|
|
public int hashCode() {
|
|
return this.hashCode;
|
|
}
|
|
|
|
@Override
|
|
public List<UUID> getUserTrusts() {
|
|
List<UUID> trustList = new ArrayList<>();
|
|
trustList.addAll(this.claimData.getAccessors());
|
|
trustList.addAll(this.claimData.getContainers());
|
|
trustList.addAll(this.claimData.getBuilders());
|
|
trustList.addAll(this.claimData.getManagers());
|
|
return ImmutableList.copyOf(trustList);
|
|
}
|
|
|
|
@Override
|
|
public List<UUID> getUserTrusts(TrustType type) {
|
|
return ImmutableList.copyOf(this.getUserTrustList(type));
|
|
}
|
|
|
|
public boolean isUserTrusted(Player player, TrustType type) {
|
|
final GDPermissionUser user = PermissionHolderCache.getInstance().getOrCreateUser(player);
|
|
return isUserTrusted(user, type, null);
|
|
}
|
|
|
|
public boolean isUserTrusted(GDPermissionUser user, TrustType type) {
|
|
return isUserTrusted(user, type, null);
|
|
}
|
|
|
|
@Override
|
|
public boolean isUserTrusted(UUID uuid, TrustType type) {
|
|
final GDPermissionUser user = PermissionHolderCache.getInstance().getOrCreateUser(uuid);
|
|
return isUserTrusted(user, type, null);
|
|
}
|
|
|
|
public boolean isUserTrusted(GDPermissionUser user, TrustType type, Set<Context> contexts) {
|
|
return isUserTrusted(user, type, contexts, false);
|
|
}
|
|
|
|
public boolean isUserTrusted(GDPermissionUser user, TrustType type, Set<Context> contexts, boolean forced) {
|
|
if (user == null) {
|
|
return false;
|
|
}
|
|
|
|
final GDPlayerData playerData = GriefDefenderPlugin.getInstance().dataStore.getOrCreatePlayerData(world, user.getUniqueId());
|
|
if (!playerData.canIgnoreClaim(this) && this.getInternalClaimData().isExpired()) {
|
|
return false;
|
|
}
|
|
if (forced || !playerData.debugClaimPermissions) {
|
|
// Owners are not trusted while renting
|
|
if (!playerData.canIgnoreClaim(this) && this.getEconomyData() != null && this.getEconomyData().isRented() && user.getUniqueId().equals(this.ownerUniqueId)) {
|
|
return false;
|
|
}
|
|
|
|
if (user.getUniqueId().equals(this.getOwnerUniqueId())) {
|
|
return true;
|
|
}
|
|
if (this.isAdminClaim() && playerData.canManageAdminClaims) {
|
|
return true;
|
|
}
|
|
if (this.isWilderness() && playerData.canManageWilderness) {
|
|
return true;
|
|
}
|
|
if (playerData.canIgnoreClaim(this)) {
|
|
return true;
|
|
}
|
|
}
|
|
|
|
if (type == null) {
|
|
return true;
|
|
}
|
|
if (this.isPublicTrusted(type)) {
|
|
return true;
|
|
}
|
|
|
|
if (type == TrustTypes.ACCESSOR) {
|
|
if (this.claimData.getAccessors().contains(user.getUniqueId())) {
|
|
return true;
|
|
}
|
|
if (this.claimData.getBuilders().contains(user.getUniqueId())) {
|
|
return true;
|
|
}
|
|
if (this.claimData.getContainers().contains(user.getUniqueId())) {
|
|
return true;
|
|
}
|
|
if (this.claimData.getManagers().contains(user.getUniqueId())) {
|
|
return true;
|
|
}
|
|
} else if (type == TrustTypes.BUILDER) {
|
|
if (this.claimData.getBuilders().contains(user.getUniqueId())) {
|
|
return true;
|
|
}
|
|
if (this.claimData.getManagers().contains(user.getUniqueId())) {
|
|
return true;
|
|
}
|
|
} else if (type == TrustTypes.CONTAINER) {
|
|
if (this.claimData.getContainers().contains(user.getUniqueId())) {
|
|
return true;
|
|
}
|
|
if (this.claimData.getBuilders().contains(user.getUniqueId())) {
|
|
return true;
|
|
}
|
|
if (this.claimData.getManagers().contains(user.getUniqueId())) {
|
|
return true;
|
|
}
|
|
} else if (type == TrustTypes.MANAGER) {
|
|
if (this.claimData.getManagers().contains(user.getUniqueId())) {
|
|
return true;
|
|
}
|
|
}
|
|
|
|
if (contexts == null) {
|
|
contexts = new HashSet<>();
|
|
contexts.add(this.getContext());
|
|
}
|
|
|
|
if (PermissionUtil.getInstance().getPermissionValue(this, user, GDPermissions.getTrustPermission(type), contexts) == Tristate.TRUE) {
|
|
return true;
|
|
}
|
|
|
|
// Only check parent if this claim inherits
|
|
if (this.parent != null && this.getData().doesInheritParent()) {
|
|
return this.parent.isUserTrusted(user, type, contexts);
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
private boolean isPublicTrusted(TrustType type) {
|
|
if (type == TrustTypes.ACCESSOR) {
|
|
if (this.claimData.getAccessors().contains(GriefDefenderPlugin.PUBLIC_UUID)) {
|
|
return true;
|
|
}
|
|
if (this.claimData.getBuilders().contains(GriefDefenderPlugin.PUBLIC_UUID)) {
|
|
return true;
|
|
}
|
|
if (this.claimData.getContainers().contains(GriefDefenderPlugin.PUBLIC_UUID)) {
|
|
return true;
|
|
}
|
|
if (this.claimData.getManagers().contains(GriefDefenderPlugin.PUBLIC_UUID)) {
|
|
return true;
|
|
}
|
|
} else if (type == TrustTypes.BUILDER) {
|
|
if (this.claimData.getBuilders().contains(GriefDefenderPlugin.PUBLIC_UUID)) {
|
|
return true;
|
|
}
|
|
if (this.claimData.getManagers().contains(GriefDefenderPlugin.PUBLIC_UUID)) {
|
|
return true;
|
|
}
|
|
} else if (type == TrustTypes.CONTAINER) {
|
|
if (this.claimData.getContainers().contains(GriefDefenderPlugin.PUBLIC_UUID)) {
|
|
return true;
|
|
}
|
|
if (this.claimData.getBuilders().contains(GriefDefenderPlugin.PUBLIC_UUID)) {
|
|
return true;
|
|
}
|
|
if (this.claimData.getManagers().contains(GriefDefenderPlugin.PUBLIC_UUID)) {
|
|
return true;
|
|
}
|
|
} else if (type == TrustTypes.MANAGER) {
|
|
if (this.claimData.getManagers().contains(GriefDefenderPlugin.PUBLIC_UUID)) {
|
|
return true;
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
@Override
|
|
public boolean isGroupTrusted(String name, TrustType type) {
|
|
if (name == null) {
|
|
return false;
|
|
}
|
|
|
|
if (!PermissionUtil.getInstance().hasGroupSubject(name)) {
|
|
return false;
|
|
}
|
|
|
|
final GDPermissionHolder holder = PermissionHolderCache.getInstance().getOrCreateHolder(name);
|
|
Set<Context> contexts = new HashSet<>();
|
|
contexts.add(this.getContext());
|
|
|
|
return PermissionUtil.getInstance().getPermissionValue(this, holder, GDPermissions.getTrustPermission(type), contexts) == Tristate.TRUE;
|
|
}
|
|
|
|
@Override
|
|
public ClaimResult addUserTrust(UUID uuid, TrustType type) {
|
|
GDUserTrustClaimEvent.Add event = new GDUserTrustClaimEvent.Add(this, ImmutableList.of(uuid), type);
|
|
GriefDefender.getEventManager().post(event);
|
|
if (event.cancelled()) {
|
|
return new GDClaimResult(ClaimResultType.CLAIM_EVENT_CANCELLED, event.getMessage().orElse(null));
|
|
}
|
|
|
|
List<UUID> userList = this.getUserTrustList(type);
|
|
if (!userList.contains(uuid)) {
|
|
userList.add(uuid);
|
|
}
|
|
|
|
this.claimData.setRequiresSave(true);
|
|
this.claimData.save();
|
|
return new GDClaimResult(this, ClaimResultType.SUCCESS);
|
|
}
|
|
|
|
@Override
|
|
public ClaimResult addUserTrusts(List<UUID> uuids, TrustType type) {
|
|
GDUserTrustClaimEvent.Add event = new GDUserTrustClaimEvent.Add(this, uuids, type);
|
|
GriefDefender.getEventManager().post(event);
|
|
if (event.cancelled()) {
|
|
return new GDClaimResult(ClaimResultType.CLAIM_EVENT_CANCELLED, event.getMessage().orElse(null));
|
|
}
|
|
|
|
for (UUID uuid : uuids) {
|
|
List<UUID> userList = this.getUserTrustList(type);
|
|
if (!userList.contains(uuid)) {
|
|
userList.add(uuid);
|
|
}
|
|
}
|
|
|
|
this.claimData.setRequiresSave(true);
|
|
this.claimData.save();
|
|
return new GDClaimResult(this, ClaimResultType.SUCCESS);
|
|
}
|
|
|
|
@Override
|
|
public ClaimResult removeUserTrust(UUID uuid, TrustType type) {
|
|
GDUserTrustClaimEvent.Remove event = new GDUserTrustClaimEvent.Remove(this, ImmutableList.of(uuid), type);
|
|
GriefDefender.getEventManager().post(event);
|
|
if (event.cancelled()) {
|
|
return new GDClaimResult(ClaimResultType.CLAIM_EVENT_CANCELLED, event.getMessage().orElse(null));
|
|
}
|
|
|
|
if (type == TrustTypes.NONE) {
|
|
final ClaimResult result = this.removeAllTrustsFromUser(uuid);
|
|
this.claimData.setRequiresSave(true);
|
|
this.claimData.save();
|
|
return result;
|
|
}
|
|
|
|
this.getUserTrustList(type).remove(uuid);
|
|
this.claimData.setRequiresSave(true);
|
|
this.claimData.save();
|
|
return new GDClaimResult(this, ClaimResultType.SUCCESS);
|
|
}
|
|
|
|
@Override
|
|
public ClaimResult removeUserTrusts(List<UUID> uuids, TrustType type) {
|
|
GDUserTrustClaimEvent.Remove event = new GDUserTrustClaimEvent.Remove(this, uuids, type);
|
|
GriefDefender.getEventManager().post(event);
|
|
if (event.cancelled()) {
|
|
return new GDClaimResult(ClaimResultType.CLAIM_EVENT_CANCELLED, event.getMessage().orElse(null));
|
|
}
|
|
|
|
if (type == TrustTypes.NONE) {
|
|
for (UUID uuid : uuids) {
|
|
this.removeAllTrustsFromUser(uuid);
|
|
}
|
|
|
|
this.claimData.setRequiresSave(true);
|
|
this.claimData.save();
|
|
return new GDClaimResult(this, ClaimResultType.SUCCESS);
|
|
}
|
|
|
|
List<UUID> userList = this.getUserTrustList(type);
|
|
for (UUID uuid : uuids) {
|
|
if (userList.contains(uuid)) {
|
|
userList.remove(uuid);
|
|
}
|
|
}
|
|
|
|
this.claimData.setRequiresSave(true);
|
|
this.claimData.save();
|
|
return new GDClaimResult(this, ClaimResultType.SUCCESS);
|
|
}
|
|
|
|
@Override
|
|
public ClaimResult addGroupTrust(String group, TrustType type) {
|
|
GDGroupTrustClaimEvent.Add event = new GDGroupTrustClaimEvent.Add(this, ImmutableList.of(group), type);
|
|
GriefDefender.getEventManager().post(event);
|
|
if (event.cancelled()) {
|
|
return new GDClaimResult(ClaimResultType.CLAIM_EVENT_CANCELLED, event.getMessage().orElse(null));
|
|
}
|
|
|
|
List<String> groupList = this.getGroupTrustList(type);
|
|
if (!groupList.contains(group)) {
|
|
groupList.add(group);
|
|
}
|
|
|
|
this.claimData.setRequiresSave(true);
|
|
this.claimData.save();
|
|
return new GDClaimResult(this, ClaimResultType.SUCCESS);
|
|
}
|
|
|
|
@Override
|
|
public ClaimResult addGroupTrusts(List<String> groups, TrustType type) {
|
|
GDGroupTrustClaimEvent.Add event = new GDGroupTrustClaimEvent.Add(this, groups, type);
|
|
GriefDefender.getEventManager().post(event);
|
|
if (event.cancelled()) {
|
|
return new GDClaimResult(ClaimResultType.CLAIM_EVENT_CANCELLED, event.getMessage().orElse(null));
|
|
}
|
|
|
|
for (String group : groups) {
|
|
List<String> groupList = this.getGroupTrustList(type);
|
|
if (!groupList.contains(group)) {
|
|
groupList.add(group);
|
|
}
|
|
}
|
|
|
|
this.claimData.setRequiresSave(true);
|
|
this.claimData.save();
|
|
return new GDClaimResult(this, ClaimResultType.SUCCESS);
|
|
}
|
|
|
|
@Override
|
|
public ClaimResult removeGroupTrust(String group, TrustType type) {
|
|
GDGroupTrustClaimEvent.Remove event = new GDGroupTrustClaimEvent.Remove(this, ImmutableList.of(group), type);
|
|
GriefDefender.getEventManager().post(event);
|
|
if (event.cancelled()) {
|
|
return new GDClaimResult(ClaimResultType.CLAIM_EVENT_CANCELLED, event.getMessage().orElse(null));
|
|
}
|
|
|
|
if (type == TrustTypes.NONE) {
|
|
final ClaimResult result = this.removeAllTrustsFromGroup(group);
|
|
this.claimData.setRequiresSave(true);
|
|
this.claimData.save();
|
|
return result;
|
|
}
|
|
|
|
this.getGroupTrustList(type).remove(group);
|
|
this.claimData.setRequiresSave(true);
|
|
this.claimData.save();
|
|
return new GDClaimResult(this, ClaimResultType.SUCCESS);
|
|
}
|
|
|
|
@Override
|
|
public ClaimResult removeGroupTrusts(List<String> groups, TrustType type) {
|
|
GDGroupTrustClaimEvent.Remove event = new GDGroupTrustClaimEvent.Remove(this, groups, type);
|
|
GriefDefender.getEventManager().post(event);
|
|
if (event.cancelled()) {
|
|
return new GDClaimResult(ClaimResultType.CLAIM_EVENT_CANCELLED, event.getMessage().orElse(null));
|
|
}
|
|
|
|
if (type == TrustTypes.NONE) {
|
|
for (String group : groups) {
|
|
this.removeAllTrustsFromGroup(group);
|
|
}
|
|
|
|
this.claimData.setRequiresSave(true);
|
|
this.claimData.save();
|
|
return new GDClaimResult(this, ClaimResultType.SUCCESS);
|
|
}
|
|
|
|
List<String> groupList = this.getGroupTrustList(type);
|
|
for (String group : groups) {
|
|
if (groupList.contains(group)) {
|
|
groupList.remove(group);
|
|
}
|
|
}
|
|
|
|
this.claimData.setRequiresSave(true);
|
|
this.claimData.save();
|
|
return new GDClaimResult(this, ClaimResultType.SUCCESS);
|
|
}
|
|
|
|
@Override
|
|
public ClaimResult removeAllTrusts() {
|
|
List<UUID> userTrustList = this.getUserTrusts();
|
|
GDUserTrustClaimEvent.Remove userEvent = new GDUserTrustClaimEvent.Remove(this, userTrustList, TrustTypes.NONE);
|
|
GriefDefender.getEventManager().post(userEvent);
|
|
if (userEvent.cancelled()) {
|
|
return new GDClaimResult(ClaimResultType.CLAIM_EVENT_CANCELLED, userEvent.getMessage().orElse(null));
|
|
}
|
|
|
|
List<String> groupTrustList = this.getGroupTrusts();
|
|
GDGroupTrustClaimEvent.Remove event = new GDGroupTrustClaimEvent.Remove(this, groupTrustList, TrustTypes.NONE);
|
|
GriefDefender.getEventManager().post(event);
|
|
if (event.cancelled()) {
|
|
return new GDClaimResult(ClaimResultType.CLAIM_EVENT_CANCELLED, event.getMessage().orElse(null));
|
|
}
|
|
|
|
for (TrustType type : TrustTypeRegistryModule.getInstance().getAll()) {
|
|
this.getUserTrustList(type).clear();
|
|
}
|
|
|
|
for (TrustType type : TrustTypeRegistryModule.getInstance().getAll()) {
|
|
this.getGroupTrustList(type).clear();
|
|
}
|
|
|
|
this.claimData.setRequiresSave(true);
|
|
this.claimData.save();
|
|
return new GDClaimResult(this, ClaimResultType.SUCCESS);
|
|
}
|
|
|
|
@Override
|
|
public ClaimResult removeAllUserTrusts() {
|
|
List<UUID> trustList = this.getUserTrusts();
|
|
GDUserTrustClaimEvent.Remove event = new GDUserTrustClaimEvent.Remove(this, trustList, TrustTypes.NONE);
|
|
GriefDefender.getEventManager().post(event);
|
|
if (event.cancelled()) {
|
|
return new GDClaimResult(ClaimResultType.CLAIM_EVENT_CANCELLED, event.getMessage().orElse(null));
|
|
}
|
|
|
|
for (TrustType type : TrustTypeRegistryModule.getInstance().getAll()) {
|
|
this.getUserTrustList(type).clear();
|
|
}
|
|
|
|
this.claimData.setRequiresSave(true);
|
|
this.claimData.save();
|
|
return new GDClaimResult(this, ClaimResultType.SUCCESS);
|
|
}
|
|
|
|
@Override
|
|
public ClaimResult removeAllGroupTrusts() {
|
|
List<String> trustList = this.getGroupTrusts();
|
|
GDGroupTrustClaimEvent.Remove event = new GDGroupTrustClaimEvent.Remove(this, trustList, TrustTypes.NONE);
|
|
GriefDefender.getEventManager().post(event);
|
|
if (event.cancelled()) {
|
|
return new GDClaimResult(ClaimResultType.CLAIM_EVENT_CANCELLED, event.getMessage().orElse(null));
|
|
}
|
|
|
|
for (TrustType type : TrustTypeRegistryModule.getInstance().getAll()) {
|
|
this.getGroupTrustList(type).clear();
|
|
}
|
|
|
|
this.claimData.setRequiresSave(true);
|
|
this.claimData.save();
|
|
return new GDClaimResult(this, ClaimResultType.SUCCESS);
|
|
}
|
|
|
|
public ClaimResult removeAllTrustsFromUser(UUID userUniqueId) {
|
|
for (TrustType type : TrustTypeRegistryModule.getInstance().getAll()) {
|
|
this.getUserTrustList(type).remove(userUniqueId);
|
|
}
|
|
|
|
return new GDClaimResult(this, ClaimResultType.SUCCESS);
|
|
}
|
|
|
|
public ClaimResult removeAllTrustsFromGroup(String group) {
|
|
for (TrustType type : TrustTypeRegistryModule.getInstance().getAll()) {
|
|
this.getGroupTrustList(type).remove(group);
|
|
}
|
|
|
|
return new GDClaimResult(this, ClaimResultType.SUCCESS);
|
|
}
|
|
|
|
public List<UUID> getUserTrustList(TrustType type) {
|
|
if (type == TrustTypes.NONE) {
|
|
return new ArrayList<>();
|
|
}
|
|
if (type == TrustTypes.ACCESSOR) {
|
|
return this.claimData.getAccessors();
|
|
}
|
|
if (type == TrustTypes.CONTAINER) {
|
|
return this.claimData.getContainers();
|
|
}
|
|
if (type == TrustTypes.BUILDER) {
|
|
return this.claimData.getBuilders();
|
|
}
|
|
return this.claimData.getManagers();
|
|
}
|
|
|
|
public List<UUID> getParentUserTrustList(TrustType type) {
|
|
List<UUID> userList = new ArrayList<>();
|
|
for (Claim claim : this.getInheritedParents()) {
|
|
GDClaim parentClaim = (GDClaim) claim;
|
|
userList.addAll(parentClaim.getUserTrusts(type));
|
|
}
|
|
return userList;
|
|
}
|
|
|
|
public List<String> getParentGroupTrustList(TrustType type) {
|
|
List<String> trustList = new ArrayList<>();
|
|
for (Claim claim : this.getInheritedParents()) {
|
|
GDClaim parentClaim = (GDClaim) claim;
|
|
trustList.addAll(parentClaim.getGroupTrusts(type));
|
|
}
|
|
return trustList;
|
|
}
|
|
|
|
public List<UUID> getUserTrustList(TrustType type, boolean includeParents) {
|
|
List<UUID> trustList = new ArrayList<>();
|
|
if (type == TrustTypes.ACCESSOR) {
|
|
trustList.addAll(this.claimData.getAccessors());
|
|
} else if (type == TrustTypes.CONTAINER) {
|
|
trustList.addAll(this.claimData.getContainers());
|
|
} else if (type == TrustTypes.BUILDER) {
|
|
trustList.addAll(this.claimData.getBuilders());
|
|
} else {
|
|
trustList.addAll(this.claimData.getManagers());
|
|
}
|
|
|
|
if (includeParents) {
|
|
List<UUID> parentList = getParentUserTrustList(type);
|
|
for (UUID uuid : parentList) {
|
|
if (!trustList.contains(uuid)) {
|
|
trustList.add(uuid);
|
|
}
|
|
}
|
|
}
|
|
|
|
return trustList;
|
|
}
|
|
|
|
public List<String> getGroupTrustList(TrustType type) {
|
|
if (type == TrustTypes.NONE) {
|
|
return new ArrayList<>();
|
|
}
|
|
if (type == TrustTypes.ACCESSOR) {
|
|
return this.claimData.getAccessorGroups();
|
|
}
|
|
if (type == TrustTypes.CONTAINER) {
|
|
return this.claimData.getContainerGroups();
|
|
}
|
|
if (type == TrustTypes.BUILDER) {
|
|
return this.claimData.getBuilderGroups();
|
|
}
|
|
return this.claimData.getManagerGroups();
|
|
}
|
|
|
|
public List<String> getGroupTrustList(TrustType type, boolean includeParents) {
|
|
List<String> trustList = new ArrayList<>();
|
|
if (type == TrustTypes.ACCESSOR) {
|
|
trustList.addAll(this.claimData.getAccessorGroups());
|
|
} else if (type == TrustTypes.CONTAINER) {
|
|
trustList.addAll(this.claimData.getContainerGroups());
|
|
} else if (type == TrustTypes.BUILDER) {
|
|
trustList.addAll(this.claimData.getBuilderGroups());
|
|
} else {
|
|
trustList.addAll(this.claimData.getManagerGroups());
|
|
}
|
|
|
|
if (includeParents) {
|
|
List<String> parentList = getParentGroupTrustList(type);
|
|
for (String groupId : parentList) {
|
|
if (!trustList.contains(groupId)) {
|
|
trustList.add(groupId);
|
|
}
|
|
}
|
|
}
|
|
|
|
return trustList;
|
|
}
|
|
|
|
@Override
|
|
public List<String> getGroupTrusts() {
|
|
List<String> groups = new ArrayList<>();
|
|
groups.addAll(this.getInternalClaimData().getAccessorGroups());
|
|
groups.addAll(this.getInternalClaimData().getBuilderGroups());
|
|
groups.addAll(this.getInternalClaimData().getContainerGroups());
|
|
groups.addAll(this.getInternalClaimData().getManagerGroups());
|
|
return ImmutableList.copyOf(groups);
|
|
}
|
|
|
|
@Override
|
|
public List<String> getGroupTrusts(TrustType type) {
|
|
return ImmutableList.copyOf(this.getGroupTrustList(type));
|
|
}
|
|
|
|
public Optional<UUID> getEconomyAccountId() {
|
|
if (this.vaultProvider == null || this.vaultProvider.getApi() == null || !this.vaultProvider.getApi().hasBankSupport() || this.isAdminClaim() || this.isSubdivision() || !GriefDefenderPlugin.getGlobalConfig().getConfig().economy.bankSystem) {
|
|
return Optional.empty();
|
|
}
|
|
|
|
if (this.vaultProvider.getApi().getBanks().contains(this.id.toString())) {
|
|
return Optional.of(this.id);
|
|
}
|
|
|
|
if (this.vaultProvider != null) {
|
|
this.vaultProvider.getApi().createBank(this.claimStorage.filePath.getFileName().toString(), this.ownerPlayerData.getSubject().getOfflinePlayer());
|
|
return Optional.ofNullable(this.id);
|
|
}
|
|
return Optional.empty();
|
|
}
|
|
|
|
@Override
|
|
public boolean isPvpAllowed() {
|
|
final Set<Context> contexts = new HashSet<>();
|
|
contexts.add(new Context(ContextKeys.SOURCE, "minecraft:player"));
|
|
contexts.add(new Context(ContextKeys.TARGET, "minecraft:player"));
|
|
final Tristate result = GDPermissionManager.getInstance().getActiveFlagPermissionValue(this, GriefDefenderPlugin.DEFAULT_HOLDER, Flags.ENTITY_DAMAGE, contexts);
|
|
return result == Tristate.TRUE;
|
|
}
|
|
|
|
public static class ClaimBuilder implements Builder {
|
|
|
|
private UUID ownerUniqueId;
|
|
private ClaimType type = ClaimTypes.BASIC;
|
|
private boolean cuboid = false;
|
|
private boolean requiresClaimBlocks = true;
|
|
private boolean denyMessages = true;
|
|
private boolean expire = true;
|
|
private boolean resizable = true;
|
|
private boolean inherit = true;
|
|
private boolean overrides = true;
|
|
private boolean createLimitRestrictions = true;
|
|
private boolean levelRestrictions = true;
|
|
private boolean sizeRestrictions = true;
|
|
private UUID worldUniqueId;
|
|
private Vector3i point1;
|
|
private Vector3i point2;
|
|
private Vector3i spawnPos;
|
|
private Component greeting;
|
|
private Component farewell;
|
|
private Claim parent;
|
|
|
|
public ClaimBuilder() {
|
|
|
|
}
|
|
|
|
@Override
|
|
public Builder bounds(int x1, int x2, int y1, int y2, int z1, int z2) {
|
|
int minx = Math.min(x1, x2);
|
|
int miny = Math.min(y1, y2);
|
|
int minz = Math.min(z1, z2);
|
|
int maxx = Math.max(x1, x2);
|
|
int maxy = Math.max(y1, y2);
|
|
int maxz = Math.max(z1, z2);
|
|
|
|
this.point1 = new Vector3i(minx, miny, minz);
|
|
this.point2 = new Vector3i(maxx, maxy, maxz);
|
|
return this;
|
|
}
|
|
|
|
@Override
|
|
public Builder cuboid(boolean cuboid) {
|
|
this.cuboid = cuboid;
|
|
return this;
|
|
}
|
|
|
|
@Override
|
|
public Builder owner(UUID ownerUniqueId) {
|
|
this.ownerUniqueId = ownerUniqueId;
|
|
return this;
|
|
}
|
|
|
|
@Override
|
|
public Builder parent(Claim parentClaim) {
|
|
this.parent = parentClaim;
|
|
return this;
|
|
}
|
|
|
|
@Override
|
|
public Builder type(ClaimType type) {
|
|
this.type = type;
|
|
return this;
|
|
}
|
|
|
|
@Override
|
|
public Builder world(UUID worldUniqueId) {
|
|
this.worldUniqueId = worldUniqueId;
|
|
return this;
|
|
}
|
|
|
|
@Override
|
|
public Builder createLimitRestrictions(boolean checkCreateLimit) {
|
|
this.createLimitRestrictions = checkCreateLimit;
|
|
return this;
|
|
}
|
|
|
|
@Override
|
|
public Builder levelRestrictions(boolean checkLevel) {
|
|
this.levelRestrictions = checkLevel;
|
|
return this;
|
|
}
|
|
|
|
@Override
|
|
public Builder sizeRestrictions(boolean checkSize) {
|
|
this.sizeRestrictions = checkSize;
|
|
return this;
|
|
}
|
|
|
|
@Override
|
|
public Builder requireClaimBlocks(boolean requiresClaimBlocks) {
|
|
this.requiresClaimBlocks = requiresClaimBlocks;
|
|
return this;
|
|
}
|
|
|
|
@Override
|
|
public Builder denyMessages(boolean allowDenyMessages) {
|
|
this.denyMessages = allowDenyMessages;
|
|
return this;
|
|
}
|
|
|
|
@Override
|
|
public Builder expire(boolean allowExpire) {
|
|
this.expire = allowExpire;
|
|
return this;
|
|
}
|
|
|
|
@Override
|
|
public Builder inherit(boolean inherit) {
|
|
this.inherit = inherit;
|
|
return this;
|
|
}
|
|
|
|
@Override
|
|
public Builder resizable(boolean allowResize) {
|
|
this.resizable = allowResize;
|
|
return this;
|
|
}
|
|
|
|
@Override
|
|
public Builder overrides(boolean allowOverrides) {
|
|
this.overrides = allowOverrides;
|
|
return this;
|
|
}
|
|
|
|
@Override
|
|
public Builder farewell(Component farewell) {
|
|
this.farewell = farewell;
|
|
return this;
|
|
}
|
|
|
|
@Override
|
|
public Builder greeting(Component greeting) {
|
|
this.greeting = greeting;
|
|
return this;
|
|
}
|
|
|
|
@Override
|
|
public Builder spawnPos(int x, int y, int z) {
|
|
this.spawnPos = new Vector3i(x, y, z);
|
|
return this;
|
|
}
|
|
|
|
@Override
|
|
public Builder reset() {
|
|
this.ownerUniqueId = null;
|
|
this.type = ClaimTypes.BASIC;
|
|
this.cuboid = false;
|
|
this.worldUniqueId = null;
|
|
this.point1 = null;
|
|
this.point2 = null;
|
|
this.parent = null;
|
|
return this;
|
|
}
|
|
|
|
@Override
|
|
public ClaimResult build() {
|
|
checkNotNull(this.type);
|
|
checkNotNull(this.worldUniqueId);
|
|
checkNotNull(this.point1);
|
|
checkNotNull(this.point2);
|
|
|
|
final World world = Bukkit.getServer().getWorld(this.worldUniqueId);
|
|
if (world == null) {
|
|
return new GDClaimResult(ClaimResultType.WORLD_NOT_FOUND);
|
|
}
|
|
|
|
if (this.type == ClaimTypes.SUBDIVISION) {
|
|
checkNotNull(this.parent);
|
|
}
|
|
|
|
if (this.type == ClaimTypes.ADMIN || this.type == ClaimTypes.WILDERNESS) {
|
|
this.sizeRestrictions = false;
|
|
this.levelRestrictions = false;
|
|
}
|
|
|
|
GDClaim claim = null;
|
|
if (this.type == ClaimTypes.TOWN) {
|
|
claim = new GDTown(world, this.point1, this.point2, this.type, this.ownerUniqueId, this.cuboid);
|
|
} else {
|
|
claim = new GDClaim(world, this.point1, this.point2, this.type, this.ownerUniqueId, this.cuboid);
|
|
}
|
|
claim.parent = (GDClaim) this.parent;
|
|
Player player = null;
|
|
final Object source = GDCauseStackManager.getInstance().getCurrentCause().root();
|
|
if (source instanceof GDPermissionUser) {
|
|
final GDPermissionUser user = (GDPermissionUser) source;
|
|
player = (Player) user.getOnlinePlayer();
|
|
}
|
|
GDPlayerData playerData = null;
|
|
double requiredFunds = 0;
|
|
|
|
if (this.ownerUniqueId != null) {
|
|
if (playerData == null) {
|
|
playerData = GriefDefenderPlugin.getInstance().dataStore.getOrCreatePlayerData(this.worldUniqueId, this.ownerUniqueId);
|
|
}
|
|
|
|
final WorldGuardProvider worldGuardProvider = GriefDefenderPlugin.getInstance().getWorldGuardProvider();
|
|
if (worldGuardProvider != null) {
|
|
if (player != null) {
|
|
if (!worldGuardProvider.allowClaimCreate(claim, player)) {
|
|
return new GDClaimResult(claim, ClaimResultType.CLAIM_EVENT_CANCELLED);
|
|
}
|
|
} else {
|
|
final GDPermissionUser user = playerData.getSubject();
|
|
if (user != null && !worldGuardProvider.allowClaimCreate(claim, user.getOnlinePlayer())) {
|
|
return new GDClaimResult(claim, ClaimResultType.CLAIM_EVENT_CANCELLED);
|
|
}
|
|
}
|
|
}
|
|
|
|
if (this.levelRestrictions) {
|
|
final int minClaimLevel = claim.getOwnerMinClaimLevel();
|
|
if (claim.getLesserBoundaryCorner().getY() < minClaimLevel) {
|
|
Component message = null;
|
|
if (player != null) {
|
|
message = GriefDefenderPlugin.getInstance().messageData.getMessage(MessageStorage.CLAIM_BELOW_LEVEL, ImmutableMap.of(
|
|
"limit", minClaimLevel));
|
|
GriefDefenderPlugin.sendMessage(player, message);
|
|
}
|
|
return new GDClaimResult(claim, ClaimResultType.BELOW_MIN_LEVEL, message);
|
|
}
|
|
final int maxClaimLevel = claim.getOwnerMaxClaimLevel();
|
|
if (claim.getGreaterBoundaryCorner().getY() > maxClaimLevel) {
|
|
Component message = null;
|
|
if (player != null) {
|
|
message = GriefDefenderPlugin.getInstance().messageData.getMessage(MessageStorage.CLAIM_ABOVE_LEVEL, ImmutableMap.of(
|
|
"limit", maxClaimLevel));
|
|
GriefDefenderPlugin.sendMessage(player, message);
|
|
}
|
|
return new GDClaimResult(claim, ClaimResultType.ABOVE_MAX_LEVEL, message);
|
|
}
|
|
}
|
|
|
|
if (this.sizeRestrictions) {
|
|
ClaimResult claimResult = claim.checkSizeLimits(player, playerData, this.point1, this.point2);
|
|
if (!claimResult.successful()) {
|
|
return claimResult;
|
|
}
|
|
}
|
|
|
|
final GDPermissionUser user = PermissionHolderCache.getInstance().getOrCreateUser(this.ownerUniqueId);
|
|
if (this.createLimitRestrictions && !PermissionUtil.getInstance().holderHasPermission(user, GDPermissions.BYPASS_CLAIM_LIMIT)) {
|
|
final int createClaimLimit = GDPermissionManager.getInstance().getInternalOptionValue(TypeToken.of(Integer.class), user, Options.CREATE_LIMIT, claim);
|
|
if (createClaimLimit > -1 && (playerData.getClaimTypeCount(claim.getType()) + 1) > createClaimLimit) {
|
|
final Component message = GriefDefenderPlugin.getInstance().messageData.getMessage(MessageStorage.CREATE_FAILED_CLAIM_LIMIT, ImmutableMap.of(
|
|
"limit", createClaimLimit,
|
|
"type", claim.getType().getName()));
|
|
if (player != null) {
|
|
GriefDefenderPlugin.sendMessage(player, message);
|
|
}
|
|
return new GDClaimResult(claim, ClaimResultType.EXCEEDS_MAX_CLAIM_LIMIT, message);
|
|
}
|
|
}
|
|
|
|
// check player has enough claim blocks
|
|
if ((claim.isBasicClaim() || claim.isTown()) && this.requiresClaimBlocks) {
|
|
final int claimCost = BlockUtil.getInstance().getClaimBlockCost(world, claim.lesserBoundaryCorner, claim.greaterBoundaryCorner, claim.cuboid);
|
|
if (GriefDefenderPlugin.getInstance().isEconomyModeEnabled()) {
|
|
final GDClaimResult result = EconomyUtil.getInstance().checkEconomyFunds(claim, playerData, true);
|
|
if (!result.successful()) {
|
|
return result;
|
|
}
|
|
requiredFunds = claimCost * claim.getOwnerEconomyBlockCost();
|
|
} else {
|
|
final int remainingClaimBlocks = playerData.getRemainingClaimBlocks() - claimCost;
|
|
if (remainingClaimBlocks < 0) {
|
|
Component message = null;
|
|
if (player != null) {
|
|
if (GriefDefenderPlugin.CLAIM_BLOCK_SYSTEM == ClaimBlockSystem.VOLUME) {
|
|
final double claimableChunks = Math.abs(remainingClaimBlocks / 65536.0);
|
|
message = GriefDefenderPlugin.getInstance().messageData.getMessage(MessageStorage.CLAIM_SIZE_NEED_BLOCKS_3D, ImmutableMap.of(
|
|
"chunk-amount", Math.round(claimableChunks * 100.0)/100.0,
|
|
"block-amount", Math.abs(remainingClaimBlocks)));
|
|
} else {
|
|
message = GriefDefenderPlugin.getInstance().messageData.getMessage(MessageStorage.CLAIM_SIZE_NEED_BLOCKS_2D, ImmutableMap.of(
|
|
"block-amount", Math.abs(remainingClaimBlocks)));
|
|
}
|
|
GriefDefenderPlugin.sendMessage(player, message);
|
|
}
|
|
//playerData.lastShovelLocation = null;
|
|
playerData.claimResizing = null;
|
|
return new GDClaimResult(ClaimResultType.INSUFFICIENT_CLAIM_BLOCKS, message);
|
|
}
|
|
}
|
|
}
|
|
|
|
if (claim.isTown() && player != null) {
|
|
final double townCost = GriefDefenderPlugin.getGlobalConfig().getConfig().town.cost;
|
|
if (townCost > 0) {
|
|
final Economy economy = GriefDefenderPlugin.getInstance().getVaultProvider().getApi();
|
|
if (!economy.hasAccount(player)) {
|
|
final Component message = GriefDefenderPlugin.getInstance().messageData.getMessage(MessageStorage.ECONOMY_PLAYER_NOT_FOUND, ImmutableMap.of(
|
|
"player", claim.getOwnerDisplayName()));
|
|
GriefDefenderPlugin.sendMessage(player, message);
|
|
return new GDClaimResult(claim, ClaimResultType.NOT_ENOUGH_FUNDS, message);
|
|
}
|
|
final double balance = economy.getBalance(player);
|
|
if (balance < townCost) {
|
|
final Component message = GriefDefenderPlugin.getInstance().messageData.getMessage(MessageStorage.TOWN_CREATE_NOT_ENOUGH_FUNDS, ImmutableMap.of(
|
|
"amount", String.valueOf("$" +townCost),
|
|
"balance", String.valueOf("$" + balance),
|
|
"amount-needed", String.valueOf("$" + (townCost - balance))));
|
|
GriefDefenderPlugin.sendMessage(player, message);
|
|
return new GDClaimResult(claim, ClaimResultType.NOT_ENOUGH_FUNDS, message);
|
|
}
|
|
EconomyUtil.getInstance().withdrawFunds(player, townCost);
|
|
}
|
|
}
|
|
}
|
|
|
|
final ClaimResult claimResult = claim.checkArea(false);
|
|
if (!claimResult.successful()) {
|
|
if (player != null && (claim.isBasicClaim() || claim.isTown()) && this.requiresClaimBlocks && GriefDefenderPlugin.getInstance().isEconomyModeEnabled()) {
|
|
GriefDefenderPlugin.getInstance().getVaultProvider().getApi().depositPlayer(player, requiredFunds);
|
|
}
|
|
return claimResult;
|
|
}
|
|
|
|
GDCreateClaimEvent.Pre event = new GDCreateClaimEvent.Pre(claim);
|
|
GriefDefender.getEventManager().post(event);
|
|
if (event.cancelled()) {
|
|
final Component message = event.getMessage().orElse(null);
|
|
if (message != null && player != null) {
|
|
GriefDefenderPlugin.sendMessage(player, message);
|
|
}
|
|
if (player != null && (claim.isBasicClaim() || claim.isTown()) && this.requiresClaimBlocks && GriefDefenderPlugin.getGlobalConfig().getConfig().economy.economyMode) {
|
|
GriefDefenderPlugin.getInstance().getVaultProvider().getApi().depositPlayer(player, requiredFunds);
|
|
}
|
|
return new GDClaimResult(claim, ClaimResultType.CLAIM_EVENT_CANCELLED, message);
|
|
}
|
|
|
|
claim.initializeClaimData((GDClaim) this.parent);
|
|
if (this.parent != null) {
|
|
if (this.parent.isTown()) {
|
|
claim.getData().setInheritParent(true);
|
|
}
|
|
claim.getData().setParent(this.parent.getUniqueId());
|
|
}
|
|
|
|
claim.getData().setExpiration(this.expire);
|
|
claim.getData().setDenyMessages(this.denyMessages);
|
|
claim.getData().setFlagOverrides(this.overrides);
|
|
claim.getData().setInheritParent(this.inherit);
|
|
claim.getData().setResizable(this.resizable);
|
|
claim.getData().setRequiresClaimBlocks(this.requiresClaimBlocks);
|
|
claim.getData().setFarewell(this.farewell);
|
|
claim.getData().setGreeting(this.greeting);
|
|
claim.getData().setSpawnPos(this.spawnPos);
|
|
claim.getData().setSizeRestrictions(this.sizeRestrictions);
|
|
final GDClaimManager claimManager = GriefDefenderPlugin.getInstance().dataStore.getClaimWorldManager(this.worldUniqueId);
|
|
claimManager.addClaim(claim, true);
|
|
|
|
if (claimResult.getClaims().size() > 1) {
|
|
claim.migrateClaims(new ArrayList<>(claimResult.getClaims()));
|
|
}
|
|
|
|
GDCreateClaimEvent.Post postEvent = new GDCreateClaimEvent.Post(claim);
|
|
GriefDefender.getEventManager().post(postEvent);
|
|
if (postEvent.cancelled()) {
|
|
final Component message = postEvent.getMessage().orElse(null);
|
|
if (message != null && player != null) {
|
|
GriefDefenderPlugin.sendMessage(player, message);
|
|
}
|
|
final GDClaimManager claimWorldManager = GriefDefenderPlugin.getInstance().dataStore.getClaimWorldManager(world.getUID());
|
|
claimWorldManager.deleteClaimInternal(claim, true);
|
|
return new GDClaimResult(claim, ClaimResultType.CLAIM_EVENT_CANCELLED, message);
|
|
}
|
|
|
|
if (GriefDefenderPlugin.getInstance().getWorldEditProvider() != null) {
|
|
if (GriefDefenderPlugin.getActiveConfig(this.worldUniqueId).getConfig().claim.claimAutoSchematicRestore) {
|
|
final ClaimSchematic schematic = ClaimSchematic.builder().claim(claim).name("__restore__").build().orElse(null);
|
|
}
|
|
}
|
|
return new GDClaimResult(claim, ClaimResultType.SUCCESS);
|
|
}
|
|
}
|
|
|
|
public boolean migrateClaims(List<Claim> claims) {
|
|
GDClaim parentClaim = this;
|
|
for (Claim child : claims) {
|
|
if (child.equals(this)) {
|
|
continue;
|
|
}
|
|
|
|
moveChildToParent(parentClaim, (GDClaim) child);
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
public void moveChildToParent(GDClaim parentClaim, GDClaim childClaim) {
|
|
// Remove child from current parent if available
|
|
if (childClaim.parent != null && childClaim.parent != parentClaim) {
|
|
childClaim.parent.children.remove(childClaim);
|
|
}
|
|
childClaim.parent = parentClaim;
|
|
String fileName = childClaim.getClaimStorage().filePath.getFileName().toString();
|
|
Path newPath = parentClaim.getClaimStorage().folderPath.resolve(childClaim.getType().getName().toLowerCase()).resolve(fileName);
|
|
try {
|
|
if (Files.notExists(newPath.getParent())) {
|
|
Files.createDirectories(newPath.getParent());
|
|
}
|
|
Files.move(childClaim.getClaimStorage().filePath, newPath);
|
|
if (childClaim.getClaimStorage().folderPath.toFile().listFiles().length == 0) {
|
|
Files.delete(childClaim.getClaimStorage().folderPath);
|
|
}
|
|
childClaim.setClaimStorage(new ClaimStorageData(newPath, this.getWorldUniqueId(), (ClaimDataConfig) childClaim.getInternalClaimData()));
|
|
} catch (IOException e) {
|
|
e.printStackTrace();
|
|
}
|
|
|
|
// Make sure to update new parent in storage
|
|
childClaim.getInternalClaimData().setParent(parentClaim.getUniqueId());
|
|
this.worldClaimManager.addClaim(childClaim, true);
|
|
for (Claim child : childClaim.children) {
|
|
moveChildToParent(childClaim, (GDClaim) child);
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public Context getDefaultTypeContext() {
|
|
if (this.isAdminClaim()) {
|
|
return ClaimContexts.ADMIN_DEFAULT_CONTEXT;
|
|
}
|
|
if (this.isBasicClaim() || this.isSubdivision()) {
|
|
return ClaimContexts.BASIC_DEFAULT_CONTEXT;
|
|
}
|
|
if (this.isTown()) {
|
|
return ClaimContexts.TOWN_DEFAULT_CONTEXT;
|
|
}
|
|
|
|
return ClaimContexts.WILDERNESS_DEFAULT_CONTEXT;
|
|
}
|
|
|
|
@Override
|
|
public Context getOverrideTypeContext() {
|
|
if (this.isAdminClaim()) {
|
|
return ClaimContexts.ADMIN_OVERRIDE_CONTEXT;
|
|
}
|
|
if (this.isBasicClaim() || this.isSubdivision()) {
|
|
return ClaimContexts.BASIC_OVERRIDE_CONTEXT;
|
|
}
|
|
if (this.isTown()) {
|
|
return ClaimContexts.TOWN_OVERRIDE_CONTEXT;
|
|
}
|
|
|
|
return ClaimContexts.WILDERNESS_OVERRIDE_CONTEXT;
|
|
}
|
|
|
|
@Override
|
|
public Context getOverrideClaimContext() {
|
|
return this.overrideClaimContext;
|
|
}
|
|
|
|
public Context getWorldContext() {
|
|
return this.worldContext;
|
|
}
|
|
|
|
@Override
|
|
public Map<String, ClaimSchematic> getSchematics() {
|
|
return this.schematics;
|
|
}
|
|
|
|
@Override
|
|
public boolean deleteSchematic(String name) {
|
|
if (GriefDefenderPlugin.getInstance().getWorldEditProvider() == null) {
|
|
return false;
|
|
}
|
|
|
|
final ClaimSchematic schematic = this.schematics.remove(name);
|
|
if (schematic == null) {
|
|
return true;
|
|
}
|
|
final Path schematicPath = GriefDefenderPlugin.getInstance().getWorldEditProvider().getSchematicWorldMap().get(schematic.getClaim().getWorldUniqueId()).resolve(schematic.getClaim().getUniqueId().toString());
|
|
if (!Files.exists(schematicPath)) {
|
|
return false;
|
|
}
|
|
|
|
File outputFile = schematicPath.resolve(schematic.getName() + ".schematic").toFile();
|
|
if (outputFile.delete()) {
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
}
|