flan/src/main/java/com/flemmli97/flan/claim/Claim.java
2020-08-23 15:16:26 +02:00

418 lines
15 KiB
Java

package com.flemmli97.flan.claim;
import com.flemmli97.flan.player.PlayerClaimData;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.gson.JsonArray;
import com.google.gson.JsonObject;
import com.mojang.authlib.GameProfile;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.nbt.ListTag;
import net.minecraft.nbt.StringTag;
import net.minecraft.server.MinecraftServer;
import net.minecraft.util.math.BlockPos;
import java.util.EnumMap;
import java.util.EnumSet;
import java.util.List;
import java.util.Map;
import java.util.UUID;
public class Claim {
private boolean dirty;
private int minX, minZ, maxX, maxZ, minY;
private UUID owner;
private UUID claimID;
private final EnumSet<EnumPermission> globalPerm = EnumSet.noneOf(EnumPermission.class);
private final Map<String, EnumMap<EnumPermission, Boolean>> permissions = Maps.newHashMap();
private final Map<UUID, String> playersGroups = Maps.newHashMap();
private final List<Claim> subClaims = Lists.newArrayList();
/**
* Flag for players tracking this claim
*/
private boolean removed;
private Claim() {
}
public Claim(BlockPos pos1, BlockPos pos2, UUID creator) {
this(pos1.getX(), pos2.getX(), pos1.getZ(), pos2.getZ(), Math.min(pos1.getY(), pos2.getY()), creator);
}
public Claim(int x1, int x2, int z1, int z2, int minY, UUID creator) {
this.minX = Math.min(x1, x2);
this.minZ = Math.min(z1, z2);
this.maxX = Math.max(x1, x2);
this.maxZ = Math.max(z1, z2);
this.minY = Math.max(0, minY);
this.owner = creator;
}
public static Claim fromTag(CompoundTag tag) {
Claim claim = new Claim();
claim.read(tag);
return claim;
}
public static Claim fromJson(JsonObject obj, UUID owner) {
Claim claim = new Claim();
claim.readJson(obj, owner);
return claim;
}
public void setClaimID(UUID uuid) {
this.claimID = uuid;
this.setDirty();
}
public UUID getClaimID() {
return this.claimID;
}
public UUID getOwner() {
return this.owner;
}
public int getPlane() {
return (this.maxX - this.minX) * (this.maxZ - this.minZ);
}
/**
* @return The claims dimension in order: x, X, z, Z, y
*/
public int[] getDimensions() {
return new int[]{this.minX, this.maxX, this.minZ, this.maxZ, this.minY};
}
public boolean insideClaim(BlockPos pos) {
return this.minX <= pos.getX() && this.maxX >= pos.getX() && this.minZ <= pos.getZ() && this.maxZ >= pos.getZ() && this.minY <= pos.getY();
}
public boolean intersects(Claim other) {
return this.minX < other.maxX && this.maxX > other.minX && this.minZ < other.maxZ && this.maxZ > other.minZ;
}
public boolean isCorner(BlockPos pos) {
return (pos.getX() == this.minX && pos.getZ() == this.minZ) || (pos.getX() == this.minX && pos.getZ() == this.maxZ)
|| (pos.getX() == this.maxX && pos.getZ() == this.minZ) || (pos.getX() == this.maxX && pos.getZ() == this.maxZ);
}
public void remove() {
this.removed = true;
}
public boolean isRemoved() {
return this.removed;
}
public boolean canInteract(PlayerEntity player, EnumPermission perm, BlockPos pos) {
if (perm == EnumPermission.EXPLOSIONS || perm == EnumPermission.WITHER) {
for (Claim claim : this.subClaims) {
if (claim.insideClaim(pos)) {
if (claim.canInteract(player, perm, pos))
return true;
break;
}
}
return this.permEnabled(perm);
}
if (player.getUuid().equals(this.owner))
return true;
PlayerClaimData data = PlayerClaimData.get(player);
if (player.hasPermissionLevel(2) && data.isAdminIgnoreClaim())
return true;
for (Claim claim : this.subClaims) {
if (claim.insideClaim(pos)) {
if (claim.canInteract(player, perm, pos))
return true;
break;
}
}
if (this.playersGroups.containsKey(player.getUuid())) {
EnumMap<EnumPermission, Boolean> map = this.permissions.get(this.playersGroups.get(player.getUuid()));
if (map != null && map.containsKey(perm))
return map.get(perm);
}
return this.permEnabled(perm);
}
public boolean permEnabled(EnumPermission perm) {
return this.globalPerm.contains(perm);
}
public boolean tryCreateSubClaim(BlockPos pos1, BlockPos pos2) {
return false;
}
public Claim getSubClaim(BlockPos pos) {
for (Claim claim : this.subClaims)
if (claim.insideClaim(pos))
return claim;
return null;
}
public boolean setPlayerGroup(UUID player, String group, boolean force) {
if (group == null) {
this.playersGroups.remove(player);
this.setDirty();
return true;
}
if (!this.playersGroups.containsKey(player) || force) {
this.playersGroups.put(player, group);
this.setDirty();
return true;
}
return false;
}
public List<String> playersFromGroup(MinecraftServer server, String group) {
List<UUID> l = Lists.newArrayList();
this.playersGroups.forEach((uuid, g) -> {
if (g.equals(group))
l.add(uuid);
});
List<String> names = Lists.newArrayList();
l.forEach(uuid -> {
GameProfile prof = server.getUserCache().getByUuid(uuid);
if (prof != null)
names.add(prof.getName());
});
names.sort(null);
return names;
}
public void editGlobalPerms(EnumPermission toggle) {
if (this.globalPerm.contains(toggle))
this.globalPerm.remove(toggle);
else
this.globalPerm.add(toggle);
this.setDirty();
}
/**
* Edit the permissions for a group. If not defined for the group creates a new default permission map for that group
*
* @param mode -1 = makes it resort to the global perm, 0 = deny perm, 1 = allow perm
* @return If editing was successful or not
*/
public boolean editPerms(PlayerEntity player, String group, EnumPermission perm, int mode) {
if (player.getUuid().equals(this.owner) || this.canInteract(player, EnumPermission.EDITPERMS, player.getBlockPos())) {
if (mode > 1)
mode = -1;
boolean has = this.permissions.containsKey(group);
EnumMap<EnumPermission, Boolean> perms = has ? this.permissions.get(group) : new EnumMap<>(EnumPermission.class);
if (mode == -1)
perms.remove(perm);
else
perms.put(perm, mode == 1);
if (!has)
this.permissions.put(group, perms);
this.setDirty();
return true;
}
return false;
}
public boolean removePermGroup(PlayerEntity player, String group) {
if (player.getUuid().equals(this.owner) || this.canInteract(player, EnumPermission.EDITPERMS, player.getBlockPos())) {
this.permissions.remove(group);
List<UUID> toRemove = Lists.newArrayList();
this.playersGroups.forEach((uuid, g) -> {
if (g.equals(group))
toRemove.add(uuid);
});
toRemove.forEach(this.playersGroups::remove);
this.setDirty();
return true;
}
return false;
}
public int groupHasPerm(String rank, EnumPermission perm) {
if (!this.permissions.containsKey(rank) || !this.permissions.get(rank).containsKey(perm))
return -1;
return this.permissions.get(rank).get(perm) ? 1 : 0;
}
public List<String> groups() {
List<String> l = Lists.newArrayList(this.permissions.keySet());
l.sort(null);
return l;
}
public boolean addSubClaims(Claim claim) {
return false;
}
public void setDirty() {
this.dirty = true;
}
public boolean isDirty() {
return this.dirty;
}
public void readJson(JsonObject obj, UUID uuid) {
JsonArray pos = obj.getAsJsonArray("PosxXzZY");
this.minX = pos.get(0).getAsInt();
this.maxX = pos.get(1).getAsInt();
this.minZ = pos.get(2).getAsInt();
this.maxZ = pos.get(3).getAsInt();
this.minY = pos.get(4).getAsInt();
this.owner = uuid;
this.claimID = UUID.fromString(obj.get("ID").getAsString());
this.globalPerm.clear();
this.permissions.clear();
this.subClaims.clear();
if (obj.has("GlobalPerms")) {
obj.getAsJsonArray("GlobalPerms").forEach(perm -> this.globalPerm.add(EnumPermission.valueOf(perm.getAsString())));
}
if (obj.has("PermGroup")) {
JsonObject perms = obj.getAsJsonObject("PermGroup");
perms.entrySet().forEach(key -> {
EnumMap<EnumPermission, Boolean> map = new EnumMap<>(EnumPermission.class);
JsonObject group = key.getValue().getAsJsonObject();
group.entrySet().forEach(gkey -> map.put(EnumPermission.valueOf(gkey.getKey()), gkey.getValue().getAsBoolean()));
this.permissions.put(key.getKey(), map);
});
}
if (obj.has("PlayerPerms")) {
JsonObject pl = obj.getAsJsonObject("PlayerPerms");
pl.entrySet().forEach(key -> this.playersGroups.put(UUID.fromString(key.getKey()), key.getValue().getAsString()));
}
if (obj.has("SubClaims")) {
obj.getAsJsonArray("SubClaims").forEach(sub -> this.subClaims.add(Claim.fromJson(sub.getAsJsonObject(), this.owner)));
}
}
public JsonObject toJson(JsonObject obj) {
JsonArray pos = new JsonArray();
pos.add(this.minX);
pos.add(this.maxX);
pos.add(this.minZ);
pos.add(this.maxZ);
pos.add(this.minY);
obj.add("PosxXzZY", pos);
obj.addProperty("ID", this.claimID.toString());
if (!this.globalPerm.isEmpty()) {
JsonArray gPerm = new JsonArray();
this.globalPerm.forEach(p -> gPerm.add(p.toString()));
obj.add("GlobalPerms", gPerm);
}
if (!this.permissions.isEmpty()) {
JsonObject perms = new JsonObject();
this.permissions.forEach((s, pmap) -> {
JsonObject group = new JsonObject();
pmap.forEach((perm, bool) -> group.addProperty(perm.toString(), bool));
perms.add(s, group);
});
obj.add("PermGroup", perms);
}
if (!this.playersGroups.isEmpty()) {
JsonObject pl = new JsonObject();
this.playersGroups.forEach((uuid, s) -> pl.addProperty(uuid.toString(), s));
obj.add("PlayerPerms", pl);
}
if (!this.subClaims.isEmpty()) {
JsonArray list = new JsonArray();
this.subClaims.forEach(p -> list.add(p.toJson(new JsonObject())));
obj.add("SubClaims", list);
}
return obj;
}
public CompoundTag save(CompoundTag tag) {
tag.putIntArray("PosxXzZY", new int[]{this.minX, this.maxX, this.minZ, this.maxZ, this.minY});
tag.putUuid("Owner", this.owner);
tag.putUuid("ID", this.claimID);
if (!this.globalPerm.isEmpty()) {
ListTag list = new ListTag();
this.globalPerm.forEach(p -> list.add(StringTag.of(p.toString())));
tag.put("GlobalPerms", list);
}
if (!this.permissions.isEmpty()) {
CompoundTag perms = new CompoundTag();
this.permissions.forEach((s, pmap) -> {
CompoundTag group = new CompoundTag();
pmap.forEach((perm, bool) -> group.putBoolean(perm.toString(), bool));
perms.put(s, group);
});
tag.put("PermGroup", perms);
}
if (!this.playersGroups.isEmpty()) {
CompoundTag pl = new CompoundTag();
this.playersGroups.forEach((uuid, s) -> pl.putString(uuid.toString(), s));
tag.put("PlayerPerms", pl);
}
if (!this.subClaims.isEmpty()) {
ListTag list = new ListTag();
this.subClaims.forEach(p -> list.add(p.save(new CompoundTag())));
tag.put("SubClaims", list);
}
return tag;
}
public void read(CompoundTag tag) {
int[] pos = tag.getIntArray("PosxXzZY");
this.minY = pos[0];
this.maxX = pos[1];
this.minZ = pos[2];
this.maxZ = pos[3];
this.minY = pos[4];
this.owner = tag.getUuid("Owner");
this.claimID = tag.getUuid("ID");
this.globalPerm.clear();
this.permissions.clear();
this.subClaims.clear();
if (tag.contains("GlobalPerms")) {
tag.getList("GlobalPerms", 8).forEach(perm -> this.globalPerm.add(EnumPermission.valueOf(perm.asString())));
}
if (tag.contains("PermGroup")) {
CompoundTag perms = tag.getCompound("PermGroup");
perms.getKeys().forEach(key -> {
EnumMap<EnumPermission, Boolean> map = new EnumMap<>(EnumPermission.class);
CompoundTag group = perms.getCompound(key);
group.getKeys().forEach(gkey -> map.put(EnumPermission.valueOf(gkey), group.getBoolean(gkey)));
this.permissions.put(key, map);
});
}
if (tag.contains("PlayerPerms")) {
CompoundTag pl = tag.getCompound("PlayerPerms");
pl.getKeys().forEach(key -> this.playersGroups.put(UUID.fromString(key), pl.getString(key)));
}
if (tag.contains("SubClaims")) {
tag.getList("SubClaims", 10).forEach(sub -> this.subClaims.add(Claim.fromTag((CompoundTag) sub)));
}
}
@Override
public int hashCode() {
return this.claimID.hashCode();
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj instanceof Claim)
return this.claimID.equals(((Claim) obj).claimID);
return false;
}
@Override
public String toString() {
return String.format("Claim:[Owner:%s, from: x=%d; z=%d, to: x=%d, z=%d", this.owner.toString(), this.minX, this.minZ, this.maxX, this.maxZ);
}
public String formattedClaim() {
return String.format("[x=%d,z=%d] to: [x=%d,z=%d]", this.minX, this.minZ, this.maxX, this.maxZ);
}
}