From ea3e7f9ace39e65dbfb8f156bcf2ee5842090c87 Mon Sep 17 00:00:00 2001 From: Daniel Mills Date: Sat, 1 Aug 2020 12:16:42 -0400 Subject: [PATCH] Worlds --- .../java/com/volmit/iris/ProjectManager.java | 126 ++++++++++++++++++ .../command/CommandIrisStudioPackage.java | 112 ++-------------- .../volmit/iris/gen/layer/GenLayerCave.java | 9 +- .../com/volmit/iris/object/IrisDimension.java | 4 + src/main/java/com/volmit/iris/util/IO.java | 20 +++ .../volmit/iris/util/VoidOutputStream.java | 13 ++ 6 files changed, 182 insertions(+), 102 deletions(-) create mode 100644 src/main/java/com/volmit/iris/util/VoidOutputStream.java diff --git a/src/main/java/com/volmit/iris/ProjectManager.java b/src/main/java/com/volmit/iris/ProjectManager.java index d54b00ca8..7cbd226f9 100644 --- a/src/main/java/com/volmit/iris/ProjectManager.java +++ b/src/main/java/com/volmit/iris/ProjectManager.java @@ -10,12 +10,23 @@ import org.bukkit.Location; import org.bukkit.World; import org.bukkit.WorldCreator; import org.bukkit.WorldType; +import org.zeroturnaround.zip.ZipUtil; +import com.google.gson.Gson; import com.volmit.iris.gen.IrisChunkGenerator; +import com.volmit.iris.object.IrisBiome; import com.volmit.iris.object.IrisDimension; +import com.volmit.iris.object.IrisGenerator; +import com.volmit.iris.object.IrisObjectPlacement; +import com.volmit.iris.object.IrisRegion; import com.volmit.iris.util.Form; import com.volmit.iris.util.IO; import com.volmit.iris.util.J; +import com.volmit.iris.util.JSONObject; +import com.volmit.iris.util.KList; +import com.volmit.iris.util.KMap; +import com.volmit.iris.util.KSet; +import com.volmit.iris.util.M; import com.volmit.iris.util.MortarSender; import com.volmit.iris.util.O; @@ -151,4 +162,119 @@ public class ProjectManager J.attemptAsync(() -> IO.delete(folder)); } } + + public void compilePackage(MortarSender sender, String dim, boolean obfuscate) + { + String dimm = dim; + IrisDimension dimension = Iris.data.getDimensionLoader().load(dimm); + File folder = new File(Iris.instance.getDataFolder(), "exports/" + dimension.getLoadKey()); + folder.mkdirs(); + Iris.info("Packaging Dimension " + dimension.getName() + " " + (obfuscate ? "(Obfuscated)" : "")); + KSet regions = new KSet<>(); + KSet biomes = new KSet<>(); + KSet generators = new KSet<>(); + dimension.getRegions().forEach((i) -> regions.add(Iris.data.getRegionLoader().load(i))); + regions.forEach((i) -> biomes.addAll(i.getAllBiomes())); + biomes.forEach((i) -> i.getGenerators().forEach((j) -> generators.add(j.getCachedGenerator()))); + KMap renameObjects = new KMap<>(); + String a = ""; + StringBuilder b = new StringBuilder(); + StringBuilder c = new StringBuilder(); + + for(IrisBiome i : biomes) + { + for(IrisObjectPlacement j : i.getObjects()) + { + b.append(j.hashCode()); + KList newNames = new KList<>(); + + for(String k : j.getPlace()) + { + if(renameObjects.containsKey(k)) + { + newNames.add(renameObjects.get(k)); + continue; + } + + String name = UUID.randomUUID().toString().replaceAll("-", ""); + b.append(name); + newNames.add(name); + renameObjects.put(k, name); + } + + j.setPlace(newNames); + } + } + + KMap> lookupObjects = renameObjects.flip(); + StringBuilder gb = new StringBuilder(); + + biomes.forEach((i) -> i.getObjects().forEach((j) -> j.getPlace().forEach((k) -> + { + try + { + File f = Iris.data.getObjectLoader().findFile(lookupObjects.get(k).get(0)); + IO.copyFile(f, new File(folder, "objects/" + k + ".iob")); + gb.append(IO.hash(f)); + } + + catch(Throwable e) + { + + } + }))); + + b.append(IO.hash(gb.toString())); + c.append(IO.hash(b.toString())); + b = new StringBuilder(); + + try + { + a = new JSONObject(new Gson().toJson(dimension)).toString(0); + IO.writeAll(new File(folder, "dimensions/" + dimension.getLoadKey() + ".json"), a); + b.append(IO.hash(a)); + + for(IrisGenerator i : generators) + { + a = new JSONObject(new Gson().toJson(i)).toString(0); + IO.writeAll(new File(folder, "generators/" + i.getLoadKey() + ".json"), a); + b.append(IO.hash(a)); + } + + c.append(IO.hash(b.toString())); + b = new StringBuilder(); + + for(IrisRegion i : regions) + { + a = new JSONObject(new Gson().toJson(i)).toString(0); + IO.writeAll(new File(folder, "regions/" + i.getLoadKey() + ".json"), a); + b.append(IO.hash(a)); + } + + for(IrisBiome i : biomes) + { + a = new JSONObject(new Gson().toJson(i)).toString(0); + IO.writeAll(new File(folder, "biomes/" + i.getLoadKey() + ".json"), a); + b.append(IO.hash(a)); + } + + c.append(IO.hash(b.toString())); + b = new StringBuilder(); + String finalHash = IO.hash(c.toString()); + JSONObject meta = new JSONObject(); + meta.put("hash", finalHash); + meta.put("time", M.ms()); + meta.put("version", dimension.getVersion()); + IO.writeAll(new File(folder, "package.json"), meta.toString(0)); + ZipUtil.pack(folder, new File(Iris.instance.getDataFolder(), "exports/" + dimension.getLoadKey() + ".iris"), 9); + IO.delete(folder); + } + + catch(Throwable e) + { + e.printStackTrace(); + } + + sender.sendMessage("Done!"); + } } diff --git a/src/main/java/com/volmit/iris/command/CommandIrisStudioPackage.java b/src/main/java/com/volmit/iris/command/CommandIrisStudioPackage.java index 79a504ea8..366f87de7 100644 --- a/src/main/java/com/volmit/iris/command/CommandIrisStudioPackage.java +++ b/src/main/java/com/volmit/iris/command/CommandIrisStudioPackage.java @@ -1,23 +1,7 @@ package com.volmit.iris.command; -import java.io.File; -import java.util.UUID; - -import org.zeroturnaround.zip.ZipUtil; - -import com.google.gson.Gson; import com.volmit.iris.Iris; -import com.volmit.iris.object.IrisBiome; -import com.volmit.iris.object.IrisDimension; -import com.volmit.iris.object.IrisGenerator; -import com.volmit.iris.object.IrisObjectPlacement; -import com.volmit.iris.object.IrisRegion; -import com.volmit.iris.util.IO; import com.volmit.iris.util.J; -import com.volmit.iris.util.JSONObject; -import com.volmit.iris.util.KList; -import com.volmit.iris.util.KMap; -import com.volmit.iris.util.KSet; import com.volmit.iris.util.MortarCommand; import com.volmit.iris.util.MortarSender; @@ -34,100 +18,26 @@ public class CommandIrisStudioPackage extends MortarCommand @Override public boolean handle(MortarSender sender, String[] args) { + if(args.length == 0) + { + sender.sendMessage("/iris std package [-o]"); + return true; + } J.a(() -> { - String dim = "overworld"; + boolean o = false; - if(args.length > 1) + for(String i : args) { - dim = args[1]; - } - - String dimm = dim; - IrisDimension dimension = Iris.data.getDimensionLoader().load(dimm); - File folder = new File(Iris.instance.getDataFolder(), "exports/" + dimension.getLoadKey()); - folder.mkdirs(); - Iris.info("Packaging Dimension " + dimension.getName()); - KSet regions = new KSet<>(); - KSet biomes = new KSet<>(); - KSet generators = new KSet<>(); - dimension.getRegions().forEach((i) -> regions.add(Iris.data.getRegionLoader().load(i))); - regions.forEach((i) -> biomes.addAll(i.getAllBiomes())); - biomes.forEach((i) -> i.getGenerators().forEach((j) -> generators.add(j.getCachedGenerator()))); - KMap renameObjects = new KMap<>(); - - for(IrisBiome i : biomes) - { - for(IrisObjectPlacement j : i.getObjects()) + if(i.equalsIgnoreCase("-o")) { - KList newNames = new KList<>(); - - for(String k : j.getPlace()) - { - if(renameObjects.containsKey(k)) - { - newNames.add(renameObjects.get(k)); - continue; - } - - String name = UUID.randomUUID().toString().replaceAll("-", ""); - newNames.add(name); - renameObjects.put(k, name); - } - - j.setPlace(newNames); + o = true; } } - KMap> lookupObjects = renameObjects.flip(); - - biomes.forEach((i) -> i.getObjects().forEach((j) -> j.getPlace().forEach((k) -> - { - try - { - Iris.info("- " + k + " (Object)"); - IO.copyFile(Iris.data.getObjectLoader().findFile(lookupObjects.get(k).get(0)), new File(folder, "objects/" + k + ".iob")); - } - - catch(Throwable e) - { - - } - }))); - - try - { - IO.writeAll(new File(folder, "dimensions/" + dimension.getLoadKey() + ".json"), new JSONObject(new Gson().toJson(dimension)).toString(0)); - - for(IrisGenerator i : generators) - { - Iris.info("- " + i.getLoadKey() + " (Generator)"); - IO.writeAll(new File(folder, "generators/" + i.getLoadKey() + ".json"), new JSONObject(new Gson().toJson(i)).toString(0)); - } - - for(IrisRegion i : regions) - { - Iris.info("- " + i.getName() + " (Region)"); - IO.writeAll(new File(folder, "regions/" + i.getLoadKey() + ".json"), new JSONObject(new Gson().toJson(i)).toString(0)); - } - - for(IrisBiome i : biomes) - { - Iris.info("- " + i.getName() + " (Biome)"); - IO.writeAll(new File(folder, "biomes/" + i.getLoadKey() + ".json"), new JSONObject(new Gson().toJson(i)).toString(0)); - } - - ZipUtil.pack(folder, new File(Iris.instance.getDataFolder(), "exports/" + dimension.getLoadKey() + ".iris"), 9); - IO.delete(folder); - } - - catch(Throwable e) - { - e.printStackTrace(); - } - - sender.sendMessage("Done!"); + String dim = args[0]; + Iris.proj.compilePackage(sender, dim, o); }); return true; diff --git a/src/main/java/com/volmit/iris/gen/layer/GenLayerCave.java b/src/main/java/com/volmit/iris/gen/layer/GenLayerCave.java index 18af52c07..57feb0aec 100644 --- a/src/main/java/com/volmit/iris/gen/layer/GenLayerCave.java +++ b/src/main/java/com/volmit/iris/gen/layer/GenLayerCave.java @@ -158,9 +158,11 @@ public class GenLayerCave extends GenLayer { Material a = data.getType(y); Material c = data.getType(y + 1); + Material d = data.getType(y + 2); + Material e = data.getType(y + 3); Material f = data.getType(y - 1); - if(can(a) && canAir(c) && canAir(f)) + if(can(a) && canAir(c) && canAir(f) && canWater(d) && canWater(e)) { data.set(y, CAVE_AIR); return true; @@ -174,6 +176,11 @@ public class GenLayerCave extends GenLayer return (m.isSolid() || m.equals(Material.AIR) || m.equals(Material.CAVE_AIR)) && !m.equals(Material.BEDROCK); } + public boolean canWater(Material m) + { + return !m.equals(Material.WATER); + } + public boolean can(Material m) { return m.isSolid() && !m.equals(Material.BEDROCK); diff --git a/src/main/java/com/volmit/iris/object/IrisDimension.java b/src/main/java/com/volmit/iris/object/IrisDimension.java index f0cf79f1d..567b4c89a 100644 --- a/src/main/java/com/volmit/iris/object/IrisDimension.java +++ b/src/main/java/com/volmit/iris/object/IrisDimension.java @@ -42,6 +42,10 @@ public class IrisDimension extends IrisRegistrant @Desc("The Thickness scale of cave veins") private double caveThickness = 1D; + @DontObfuscate + @Desc("The version of this dimension. Changing this will stop users from accidentally upgrading (and breaking their worlds).") + private int version = 1; + @DontObfuscate @Desc("The cave web scale. Smaller values means scaled up vein networks.") private double caveScale = 1D; diff --git a/src/main/java/com/volmit/iris/util/IO.java b/src/main/java/com/volmit/iris/util/IO.java index 445b8e605..8c0a49a0c 100644 --- a/src/main/java/com/volmit/iris/util/IO.java +++ b/src/main/java/com/volmit/iris/util/IO.java @@ -21,6 +21,7 @@ import java.io.Reader; import java.io.StringWriter; import java.io.Writer; import java.nio.charset.StandardCharsets; +import java.security.DigestInputStream; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.util.ArrayList; @@ -116,6 +117,25 @@ public class IO return "¯\\_(ツ)_/¯"; } + public static String hash(File b) + { + try + { + MessageDigest d = MessageDigest.getInstance("SHA-256"); + DigestInputStream din = new DigestInputStream(new FileInputStream(b), d); + fullTransfer(din, new VoidOutputStream(), 8192); + din.close(); + return bytesToHex(din.getMessageDigest().digest()); + } + + catch(Throwable e) + { + e.printStackTrace(); + } + + return "¯\\_(ツ)_/¯"; + } + public static String bytesToHex(byte[] bytes) { char[] hexChars = new char[bytes.length * 2]; diff --git a/src/main/java/com/volmit/iris/util/VoidOutputStream.java b/src/main/java/com/volmit/iris/util/VoidOutputStream.java new file mode 100644 index 000000000..f30c0b7ba --- /dev/null +++ b/src/main/java/com/volmit/iris/util/VoidOutputStream.java @@ -0,0 +1,13 @@ +package com.volmit.iris.util; + +import java.io.IOException; +import java.io.OutputStream; + +public class VoidOutputStream extends OutputStream +{ + @Override + public void write(int b) throws IOException + { + // poof + } +}