diff --git a/src/main/java/com/volmit/iris/Iris.java b/src/main/java/com/volmit/iris/Iris.java index 5f40ed292..845197f2e 100644 --- a/src/main/java/com/volmit/iris/Iris.java +++ b/src/main/java/com/volmit/iris/Iris.java @@ -28,6 +28,7 @@ import com.volmit.iris.util.GroupedExecutor; import com.volmit.iris.util.IO; import com.volmit.iris.util.IrisLock; import com.volmit.iris.util.IrisPostBlockFilter; +import com.volmit.iris.util.J; import com.volmit.iris.util.KList; import com.volmit.iris.util.MortarPlugin; import com.volmit.iris.util.Permission; @@ -83,8 +84,14 @@ public class Iris extends MortarPlugin struct = new StructureManager(); proj = new ProjectManager(); board = new IrisBoardManager(); + J.a(() -> IO.delete(getTemp())); super.onEnable(); } + + public static File getTemp() + { + return instance.getDataFolder("cache", "temp"); + } public void onDisable() { @@ -208,6 +215,29 @@ public class Iris extends MortarPlugin return ""; } + public static File getNonCachedFile(String name, String url) + { + String h = IO.hash(name + "*" + url); + File f = Iris.instance.getDataFile("cache", h.substring(0, 2), h.substring(3, 5), h); + + try(BufferedInputStream in = new BufferedInputStream(new URL(url).openStream()); FileOutputStream fileOutputStream = new FileOutputStream(f)) + { + byte dataBuffer[] = new byte[1024]; + int bytesRead; + while((bytesRead = in.read(dataBuffer, 0, 1024)) != -1) + { + fileOutputStream.write(dataBuffer, 0, bytesRead); + } + } + + catch(IOException e) + { + + } + + return f; + } + public static void warn(String string) { msg(C.YELLOW + string); diff --git a/src/main/java/com/volmit/iris/ProjectManager.java b/src/main/java/com/volmit/iris/ProjectManager.java index 4ee5776a2..411cb5f6d 100644 --- a/src/main/java/com/volmit/iris/ProjectManager.java +++ b/src/main/java/com/volmit/iris/ProjectManager.java @@ -21,8 +21,10 @@ import org.bukkit.block.Biome; import org.bukkit.enchantments.Enchantment; import org.bukkit.potion.PotionEffectType; import org.zeroturnaround.zip.ZipUtil; +import org.zeroturnaround.zip.commons.FileUtils; import com.google.gson.Gson; +import com.google.gson.JsonSyntaxException; import com.volmit.iris.gen.IrisChunkGenerator; import com.volmit.iris.gen.post.Post; import com.volmit.iris.object.DecorationPart; @@ -78,6 +80,7 @@ import lombok.Data; @Data public class ProjectManager { + private KMap cacheListing = null; private IrisChunkGenerator currentProject; private TaskExecutor tx = new TaskExecutor(8, Thread.MIN_PRIORITY, "Iris Compiler"); private ReentrantLock lock = new ReentrantLock(); @@ -107,6 +110,142 @@ public class ProjectManager }); } + public void downloadSearch(MortarSender sender, String key, boolean trim) + { + String repo = getListing(false).get(key); + + if(repo == null) + { + sender.sendMessage("Couldn't find the pack '" + key + "' in the iris repo listing."); + return; + } + + sender.sendMessage("Found '" + key + "' in the Iris Listing as " + repo); + try + { + download(sender, repo, trim); + } + catch(JsonSyntaxException | IOException e) + { + sender.sendMessage("Failed to download '" + key + "'."); + } + } + + public void download(MortarSender sender, String repo, boolean trim) throws JsonSyntaxException, IOException + { + String url = "https://codeload.github.com/" + repo + "/zip/master"; + sender.sendMessage("Downloading " + url); + File zip = Iris.getNonCachedFile("pack-" + trim + "-" + repo, url); + File temp = Iris.getTemp(); + File work = new File(temp, "dl-" + UUID.randomUUID()); + File packs = Iris.instance.getDataFolder("packs"); + sender.sendMessage("Unpacking " + repo); + ZipUtil.unpack(zip, work); + File dir = work.listFiles().length == 1 && work.listFiles()[0].isDirectory() ? work.listFiles()[0] : null; + + if(dir == null) + { + sender.sendMessage("Invalid Format. Missing root folder or too many folders!"); + return; + } + + File dimensions = new File(dir, "dimensions"); + + if(!(dimensions.exists() && dimensions.isDirectory())) + { + sender.sendMessage("Invalid Format. Missing dimensions folder"); + return; + } + + if(dimensions.listFiles().length != 1) + { + sender.sendMessage("Dimensions folder must have 1 file in it"); + return; + } + + File dim = dimensions.listFiles()[0]; + + if(!dim.isFile()) + { + sender.sendMessage("Invalid dimension (folder) in dimensions folder"); + return; + } + + String key = dim.getName().split("\\Q.\\E")[0]; + IrisDimension d = new Gson().fromJson(IO.readAll(dim), IrisDimension.class); + sender.sendMessage("Importing " + d.getName() + " (" + key + ")"); + Iris.globaldata.dump(); + Iris.globaldata.preferFolder(null); + + if(Iris.globaldata.getDimensionLoader().load(key) != null) + { + sender.sendMessage("Another dimension in the packs folder is already using the key " + key + " IMPORT FAILED!"); + return; + } + + File packEntry = new File(packs, key); + + if(packEntry.exists()) + { + sender.sendMessage("Another pack is using the key " + key + ". IMPORT FAILED!"); + return; + } + + FileUtils.copyDirectory(dir, packEntry); + + if(trim) + { + sender.sendMessage("Trimming " + key); + File cp = compilePackage(sender, key, false, false); + IO.delete(packEntry); + packEntry.mkdirs(); + ZipUtil.unpack(cp, packEntry); + } + + sender.sendMessage("Successfully Aquired " + d.getName()); + Iris.globaldata.dump(); + Iris.globaldata.preferFolder(null); + } + + public KMap getListing(boolean cached) + { + if(cached && cacheListing != null) + { + return cacheListing; + } + + JSONArray a = new JSONArray(); + + if(cached) + { + a = new JSONArray(Iris.getCached("cachedlisting", "https://raw.githubusercontent.com/VolmitSoftware/Iris/master/listing.json")); + } + + else + { + a = new JSONArray(Iris.getNonCached(!cached + "listing", "https://raw.githubusercontent.com/VolmitSoftware/Iris/master/listing.json")); + } + + KMap l = new KMap<>(); + + for(int i = 0; i < a.length(); i++) + { + try + { + String m = a.getString(i).trim(); + String[] v = m.split("\\Q \\E"); + l.put(v[0], v[1]); + } + + catch(Throwable e) + { + + } + } + + return l; + } + public boolean isProjectOpen() { return currentProject != null; @@ -254,7 +393,7 @@ public class ProjectManager } } - public File compilePackage(MortarSender sender, String dim, boolean obfuscate) + public File compilePackage(MortarSender sender, String dim, boolean obfuscate, boolean minify) { Iris.globaldata.dump(); Iris.globaldata.preferFolder(null); @@ -300,7 +439,7 @@ public class ProjectManager continue; } - String name = UUID.randomUUID().toString().replaceAll("-", ""); + String name = !obfuscate ? k : UUID.randomUUID().toString().replaceAll("-", ""); b.append(name); newNames.add(name); renameObjects.put(k, name); @@ -325,7 +464,7 @@ public class ProjectManager continue; } - String name = UUID.randomUUID().toString().replaceAll("-", ""); + String name = !obfuscate ? k : UUID.randomUUID().toString().replaceAll("-", ""); b.append(name); newNames.add(name); renameObjects.put(k, name); @@ -350,7 +489,7 @@ public class ProjectManager continue; } - String name = UUID.randomUUID().toString().replaceAll("-", ""); + String name = !obfuscate ? k : UUID.randomUUID().toString().replaceAll("-", ""); b.append(name); newNames.add(name); renameObjects.put(k, name); @@ -442,13 +581,13 @@ public class ProjectManager try { - a = new JSONObject(new Gson().toJson(dimension)).toString(0); + a = new JSONObject(new Gson().toJson(dimension)).toString(minify ? 0 : 4); 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); + a = new JSONObject(new Gson().toJson(i)).toString(minify ? 0 : 4); IO.writeAll(new File(folder, "generators/" + i.getLoadKey() + ".json"), a); b.append(IO.hash(a)); } @@ -458,28 +597,28 @@ public class ProjectManager for(IrisRegion i : regions) { - a = new JSONObject(new Gson().toJson(i)).toString(0); + a = new JSONObject(new Gson().toJson(i)).toString(minify ? 0 : 4); IO.writeAll(new File(folder, "regions/" + i.getLoadKey() + ".json"), a); b.append(IO.hash(a)); } for(IrisStructure i : structures) { - a = new JSONObject(new Gson().toJson(i)).toString(0); + a = new JSONObject(new Gson().toJson(i)).toString(minify ? 0 : 4); IO.writeAll(new File(folder, "structures/" + i.getLoadKey() + ".json"), a); b.append(IO.hash(a)); } for(IrisBiome i : biomes) { - a = new JSONObject(new Gson().toJson(i)).toString(0); + a = new JSONObject(new Gson().toJson(i)).toString(minify ? 0 : 4); IO.writeAll(new File(folder, "biomes/" + i.getLoadKey() + ".json"), a); b.append(IO.hash(a)); } for(IrisLootTable i : loot) { - a = new JSONObject(new Gson().toJson(i)).toString(0); + a = new JSONObject(new Gson().toJson(i)).toString(minify ? 0 : 4); IO.writeAll(new File(folder, "loot/" + i.getLoadKey() + ".json"), a); b.append(IO.hash(a)); } @@ -491,7 +630,7 @@ public class ProjectManager meta.put("hash", finalHash); meta.put("time", M.ms()); meta.put("version", dimension.getVersion()); - IO.writeAll(new File(folder, "package.json"), meta.toString(0)); + IO.writeAll(new File(folder, "package.json"), meta.toString(minify ? 0 : 4)); File p = new File(Iris.instance.getDataFolder(), "exports/" + dimension.getLoadKey() + ".iris"); Iris.info("Compressing Package"); ZipUtil.pack(folder, p, 9); diff --git a/src/main/java/com/volmit/iris/command/CommandIrisCreate.java b/src/main/java/com/volmit/iris/command/CommandIrisCreate.java index 46b9f636b..035547eca 100644 --- a/src/main/java/com/volmit/iris/command/CommandIrisCreate.java +++ b/src/main/java/com/volmit/iris/command/CommandIrisCreate.java @@ -82,11 +82,19 @@ public class CommandIrisCreate extends MortarCommand else { sender.sendMessage("Foind " + type + " dimension in packs folder. Repackaging"); - ZipUtil.unpack(Iris.proj.compilePackage(sender, type, true), iris); + ZipUtil.unpack(Iris.proj.compilePackage(sender, type, true, true), iris); } File dimf = new File(iris, "dimensions/" + type + ".json"); + if(!dimf.exists() || !dimf.isFile()) + { + Iris.globaldata.dump(); + Iris.globaldata.preferFolder(null); + Iris.proj.downloadSearch(sender, type, false); + ZipUtil.unpack(Iris.proj.compilePackage(sender, type, true, true), iris); + } + if(!dimf.exists() || !dimf.isFile()) { sender.sendMessage("Can't find the " + dimf.getName() + " in the dimensions folder of this pack! Failed!"); diff --git a/src/main/java/com/volmit/iris/command/CommandIrisStudio.java b/src/main/java/com/volmit/iris/command/CommandIrisStudio.java index f5c6c78ef..a3631dcc1 100644 --- a/src/main/java/com/volmit/iris/command/CommandIrisStudio.java +++ b/src/main/java/com/volmit/iris/command/CommandIrisStudio.java @@ -15,6 +15,9 @@ public class CommandIrisStudio extends MortarCommand @Command private CommandIrisStudioClose close; + + @Command + private CommandIrisStudioDownload download; @Command private CommandIrisStudioPackage pkg; diff --git a/src/main/java/com/volmit/iris/command/CommandIrisStudioDownload.java b/src/main/java/com/volmit/iris/command/CommandIrisStudioDownload.java new file mode 100644 index 000000000..02af88026 --- /dev/null +++ b/src/main/java/com/volmit/iris/command/CommandIrisStudioDownload.java @@ -0,0 +1,50 @@ +package com.volmit.iris.command; + +import com.volmit.iris.Iris; +import com.volmit.iris.util.C; +import com.volmit.iris.util.J; +import com.volmit.iris.util.MortarCommand; +import com.volmit.iris.util.MortarSender; + +public class CommandIrisStudioDownload extends MortarCommand +{ + public CommandIrisStudioDownload() + { + super("download", "down", "dl"); + requiresPermission(Iris.perm.studio); + setDescription("Download a project."); + setCategory("Studio"); + } + + @Override + public boolean handle(MortarSender sender, String[] args) + { + if(args.length < 1) + { + sender.sendMessage("/iris std dl " + C.BOLD + ""); + return true; + } + + boolean trim = false; + + for(String i : args) + { + if(i.equals("-t") || i.equals("--trim")) + { + trim = true; + } + } + + boolean btrim = trim; + + J.a(() -> Iris.proj.downloadSearch(sender, args[0], btrim)); + + return true; + } + + @Override + protected String getArgsUsage() + { + return " [-t/--trim]"; + } +} diff --git a/src/main/java/com/volmit/iris/command/CommandIrisStudioPackage.java b/src/main/java/com/volmit/iris/command/CommandIrisStudioPackage.java index 366f87de7..5f7a4ea03 100644 --- a/src/main/java/com/volmit/iris/command/CommandIrisStudioPackage.java +++ b/src/main/java/com/volmit/iris/command/CommandIrisStudioPackage.java @@ -27,6 +27,7 @@ public class CommandIrisStudioPackage extends MortarCommand J.a(() -> { boolean o = false; + boolean m = true; for(String i : args) { @@ -37,7 +38,7 @@ public class CommandIrisStudioPackage extends MortarCommand } String dim = args[0]; - Iris.proj.compilePackage(sender, dim, o); + Iris.proj.compilePackage(sender, dim, o, m); }); return true; @@ -46,6 +47,6 @@ public class CommandIrisStudioPackage extends MortarCommand @Override protected String getArgsUsage() { - return "[dimension] [-o]"; + return "[dimension] [-o] [-m]"; } } diff --git a/src/main/java/com/volmit/iris/object/IrisRegion.java b/src/main/java/com/volmit/iris/object/IrisRegion.java index 470ef614d..0d5bf688f 100644 --- a/src/main/java/com/volmit/iris/object/IrisRegion.java +++ b/src/main/java/com/volmit/iris/object/IrisRegion.java @@ -330,6 +330,8 @@ public class IrisRegion extends IrisRegistrant implements IRare names.addAll(caveBiomes); names.addAll(seaBiomes); names.addAll(shoreBiomes); + names.addAll(riverBiomes); + names.addAll(lakeBiomes); spotBiomes.forEach((i) -> names.add(i.getBiome())); ridgeBiomes.forEach((i) -> names.add(i.getBiome()));