package com.flemmli97.flan.claim; import com.flemmli97.flan.IClaimData; import com.flemmli97.flan.player.PlayerClaimData; import com.google.common.collect.ImmutableSet; import com.google.common.collect.Lists; import com.google.common.collect.Maps; import com.google.common.collect.Sets; import com.google.gson.Gson; import com.google.gson.GsonBuilder; import com.google.gson.JsonArray; import com.google.gson.JsonObject; import com.ibm.icu.impl.Pair; import it.unimi.dsi.fastutil.longs.Long2ObjectArrayMap; import net.minecraft.entity.player.PlayerEntity; import net.minecraft.nbt.CompoundTag; import net.minecraft.nbt.ListTag; import net.minecraft.server.MinecraftServer; import net.minecraft.server.world.ServerWorld; import net.minecraft.text.Text; import net.minecraft.util.WorldSavePath; import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.ChunkPos; import net.minecraft.util.registry.RegistryKey; import net.minecraft.world.World; import net.minecraft.world.dimension.DimensionType; import org.yaml.snakeyaml.Yaml; import java.io.File; import java.io.FileReader; import java.io.FileWriter; import java.io.IOException; import java.util.Arrays; import java.util.Collection; import java.util.List; import java.util.Map; import java.util.Set; import java.util.UUID; public class ClaimStorage { public static final Gson GSON = new GsonBuilder().setPrettyPrinting().disableHtmlEscaping().create(); public final Long2ObjectArrayMap> claims = new Long2ObjectArrayMap<>(); public final Map claimUUIDMap = Maps.newHashMap(); public final Map> playerClaimMap = Maps.newHashMap(); public static ClaimStorage get(ServerWorld world) { return (ClaimStorage) ((IClaimData) world).getClaimData(); } public ClaimStorage(MinecraftServer server, RegistryKey key) { this.read(server, key); } public UUID generateUUID() { UUID uuid = UUID.randomUUID(); if (this.claimUUIDMap.containsKey(uuid)) return generateUUID(); return uuid; } public boolean createClaim(BlockPos pos1, BlockPos pos2, PlayerEntity player) { Claim claim = new Claim(pos1.down(5), pos2.down(5), player.getUuid()); boolean conflicts = conflicts(claim, null); if (!conflicts) { PlayerClaimData data = PlayerClaimData.get(player); if (!data.useClaimBlocks(claim.getPlane())) return false; claim.setClaimID(this.generateUUID()); this.addClaim(claim); data.addDisplayClaim(claim); return true; } player.sendMessage(Text.of("Error creating claim"), false); return false; } private boolean conflicts(Claim claim, Claim except) { int[] chunks = getChunkPos(claim); for (int x = chunks[0]; x <= chunks[1]; x++) for (int z = chunks[2]; z <= chunks[3]; z++) { List claims = this.claims.get(new ChunkPos(x, z).toLong()); if (claims != null) for (Claim other : claims) { if (claim.intersects(other) && !claim.equals(except)) { return true; } } } return false; } public boolean deleteClaim(Claim claim) { System.out.println("claim " + claim); System.out.println("claimmap " + this.claims); claim.remove(); int[] pos = getChunkPos(claim); System.out.println("" + Arrays.toString(pos)); for (int x = pos[0]; x <= pos[1]; x++) for (int z = pos[2]; z <= pos[3]; z++) { ChunkPos chunkPos = new ChunkPos(x, z); this.claims.compute(chunkPos.toLong(), (key, val) -> { if (val == null) return null; val.remove(claim); return val.isEmpty() ? null : val; }); } System.out.println(this.claims); this.playerClaimMap.getOrDefault(claim.getOwner(), Sets.newHashSet()).remove(claim); return this.claimUUIDMap.remove(claim.getClaimID()) != null; } public boolean resizeClaim(Claim claim, BlockPos pos) { return false; } public Claim getClaimAt(BlockPos pos) { long chunk = new ChunkPos(pos).toLong(); if (this.claims.containsKey(chunk)) for (Claim claim : this.claims.get(chunk)) { if (claim.insideClaim(pos)) return claim; } return null; } private void addClaim(Claim claim) { System.out.println("adding claim " + claim); int[] pos = getChunkPos(claim); System.out.println("" + Arrays.toString(pos)); for (int x = pos[0]; x <= pos[1]; x++) for (int z = pos[2]; z <= pos[3]; z++) { ChunkPos chunkPos = new ChunkPos(x, z); this.claims.merge(chunkPos.toLong(), Lists.newArrayList(claim), (key, val) -> { val.add(claim); return val; }); } System.out.println("claimmap " + this.claims); this.claimUUIDMap.put(claim.getClaimID(), claim); this.playerClaimMap.merge(claim.getOwner(), Sets.newHashSet(claim), (key, val) -> { val.add(claim); return val; }); } public Collection allClaimsFromPlayer(UUID player) { return this.playerClaimMap.containsKey(player) ? ImmutableSet.copyOf(this.playerClaimMap.get(player)) : ImmutableSet.of(); } public static int[] getChunkPos(Claim claim) { int[] dim = claim.getDimensions(); int[] pos = new int[4]; pos[0] = dim[0] >> 4; pos[1] = dim[1] >> 4; pos[2] = dim[2] >> 4; pos[3] = dim[3] >> 4; return pos; } public void fromTag(CompoundTag compoundTag) { ListTag list = compoundTag.getList("Claims", 10); list.forEach(tag -> { Claim claim = Claim.fromTag((CompoundTag) tag); this.addClaim(claim); }); } public CompoundTag toTag(CompoundTag compoundTag) { ListTag list = new ListTag(); this.claims.forEach((l, cList) -> cList.forEach(claim -> list.add(claim.save(new CompoundTag())))); compoundTag.put("Claims", list); return compoundTag; } public void read(MinecraftServer server, RegistryKey reg) { File dir = new File(DimensionType.getSaveDirectory(reg, server.getSavePath(WorldSavePath.ROOT).toFile()), "/data/claims/"); if (dir.exists()) { try { for (File file : dir.listFiles()) { if (!file.getName().endsWith(".json")) continue; UUID uuid = UUID.fromString(file.getName().replace(".json", "")); FileReader reader = new FileReader(file); JsonArray arr = GSON.fromJson(reader, JsonArray.class); if (arr == null) continue; arr.forEach(el -> { if (el.isJsonObject()) { this.addClaim(Claim.fromJson((JsonObject) el, uuid)); } }); reader.close(); } } catch (IOException e) { } } } public void save(MinecraftServer server, RegistryKey reg) { File dir = new File(DimensionType.getSaveDirectory(reg, server.getSavePath(WorldSavePath.ROOT).toFile()), "/data/claims/"); if (!dir.exists()) dir.mkdir(); try { for (Map.Entry> e : this.playerClaimMap.entrySet()) { File file = new File(dir, e.getKey().toString() + ".json"); if (!file.exists()) { if (e.getValue().isEmpty()) continue; file.createNewFile(); } FileWriter writer = new FileWriter(file); JsonArray arr = new JsonArray(); e.getValue().forEach(claim -> arr.add(claim.toJson(new JsonObject()))); GSON.toJson(arr, writer); writer.close(); } } catch (IOException e) { } } public static void readGriefPreventionData(MinecraftServer server) { Yaml yml = new Yaml(); File griefPrevention = server.getSavePath(WorldSavePath.ROOT).resolve("GriefPreventionData/ClaimData").toFile(); if (!griefPrevention.exists()) return; Map> subClaimMap = Maps.newHashMap(); Map intFileMap = Maps.newHashMap(); try { //Get all parent claims for (File f : griefPrevention.listFiles()) { if (f.getName().endsWith(".yml")) { FileReader reader = new FileReader(f); Map values = yml.load(reader); if (values.get("Parent Claim ID").equals(-1)) { intFileMap.put(Integer.valueOf(values.get("Parent Claim ID").toString()), f); } } } //Map child to parent claims for (File f : griefPrevention.listFiles()) { if (f.getName().endsWith(".yml")) { FileReader reader = new FileReader(f); Map values = yml.load(reader); if (!values.get("Parent Claim ID").equals(-1)) { subClaimMap.merge(intFileMap.get(Integer.valueOf(values.get("Parent Claim ID").toString())) , Lists.newArrayList(f), (key, val) -> { val.add(f); return val; }); } } } for (File parent : intFileMap.values()) { Pair parentClaim = parseFromYaml(parent, yml); List childs = subClaimMap.get(parent); if (childs != null && !childs.isEmpty()) { for (File childF : childs) parentClaim.second.addSubClaims(parseFromYaml(childF, yml).second); } ClaimStorage.get(server.getWorld(worldRegFromString(parentClaim.first))).addClaim(parentClaim.second); } } catch (IOException e) { } } private static Pair parseFromYaml(File file, Yaml yml) throws IOException { FileReader reader = new FileReader(file); Map values = yml.load(reader); reader.close(); UUID owner = UUID.fromString(values.get("Owner").toString()); String[] lesserCorner = values.get("Lesser Boundary Corner").toString().split(";"); String[] greaterCorner = values.get("Greater Boundary Corner").toString().split(";"); Claim claim = new Claim(Integer.parseInt(lesserCorner[1]), Integer.parseInt(greaterCorner[1]), Integer.parseInt(lesserCorner[3]), Integer.parseInt(greaterCorner[3]), Integer.parseInt(lesserCorner[2]), owner); return Pair.of(lesserCorner[0], claim); } public static RegistryKey worldRegFromString(String spigot) { if (spigot.equals("world_the_end")) return World.END; if (spigot.equals("world_nether")) return World.NETHER; return World.OVERWORLD; } }