diff --git a/src/main/java/com/volmit/iris/core/tools/IrisToolbelt.java b/src/main/java/com/volmit/iris/core/tools/IrisToolbelt.java index e096bd505..9696b6163 100644 --- a/src/main/java/com/volmit/iris/core/tools/IrisToolbelt.java +++ b/src/main/java/com/volmit/iris/core/tools/IrisToolbelt.java @@ -20,21 +20,36 @@ package com.volmit.iris.core.tools; import com.volmit.iris.Iris; import com.volmit.iris.core.IrisSettings; +import com.volmit.iris.core.ProjectManager; import com.volmit.iris.core.gui.PregeneratorJob; import com.volmit.iris.core.pregenerator.PregenTask; import com.volmit.iris.core.pregenerator.PregeneratorMethod; import com.volmit.iris.core.pregenerator.methods.HeadlessPregenMethod; import com.volmit.iris.core.pregenerator.methods.HybridPregenMethod; +import com.volmit.iris.core.project.IrisProject; import com.volmit.iris.core.project.loader.IrisData; import com.volmit.iris.engine.object.dimensional.IrisDimension; import com.volmit.iris.engine.platform.HeadlessGenerator; import com.volmit.iris.engine.platform.PlatformChunkGenerator; +import com.volmit.iris.util.collection.KList; +import com.volmit.iris.util.data.IrisProjectRepo; +import com.volmit.iris.util.io.IO; import com.volmit.iris.util.plugin.VolmitSender; +import com.volmit.iris.util.scheduling.jobs.DownloadJob; +import com.volmit.iris.util.scheduling.jobs.Job; +import com.volmit.iris.util.scheduling.jobs.JobCollection; +import com.volmit.iris.util.scheduling.jobs.SingleJob; import org.bukkit.Bukkit; import org.bukkit.World; import org.bukkit.entity.Player; +import org.zeroturnaround.zip.ZipUtil; +import org.zeroturnaround.zip.commons.FileUtils; import java.io.File; +import java.io.IOException; +import java.net.MalformedURLException; +import java.nio.charset.StandardCharsets; +import java.util.UUID; /** * Something you really want to wear if working on Iris. Shit gets pretty hectic down there. @@ -167,6 +182,65 @@ public class IrisToolbelt { return false; } + /** + * Attempts to ensure that the pack is installed + * @param sender the sender + * @param dimension the dimension key + * @param force force install even if it already exists + * @throws Throwable shit happens + */ + public static void ensureInstalled(VolmitSender sender, String dimension, boolean force) throws Throwable { + IrisProjectRepo r = IrisProjectRepo.from(dimension); + + if(r != null) + { + dimension = r.getRepo(); + } + + File f = Iris.instance.getDataFolder("packs", dimension); + + if(f.exists() && force) + { + IO.delete(f); + } + + KList j = new KList<>(); + + if(!f.exists()) + { + File pack = new File(Iris.getTemp(), UUID.nameUUIDFromBytes(r.toURL().getBytes(StandardCharsets.UTF_8)) + ".zip"); + j.add(new DownloadJob(r.toURL(), pack)); + j.add(new SingleJob("Extracting", () -> { + File work = new File(Iris.getTemp(), "dltk-" + UUID.randomUUID()); + ZipUtil.unpack(pack, work); + File raw = work.listFiles()[0]; + try { + FileUtils.copyDirectory(raw, f); + } catch (IOException e) { + e.printStackTrace(); + } + })); + } + + if(j.isNotEmpty()) + { + JobCollection c = new JobCollection("Pack", j); + c.execute(sender); + } + } + + public static void download(VolmitSender sender, IrisProjectRepo repository) + { + String url = repository.toURL(); + Iris.info("Downmload"); + } + + /** + * Evacuate all players from the world + * @param world the world to leave + * @param m the message + * @return true if it was evacuated. + */ public static boolean evacuate(World world, String m) { for (World i : Bukkit.getWorlds()) { if (!i.getName().equals(world.getName())) { diff --git a/src/main/java/com/volmit/iris/util/data/IrisProjectRepo.java b/src/main/java/com/volmit/iris/util/data/IrisProjectRepo.java new file mode 100644 index 000000000..be71001d9 --- /dev/null +++ b/src/main/java/com/volmit/iris/util/data/IrisProjectRepo.java @@ -0,0 +1,116 @@ +/* + * Iris is a World Generator for Minecraft Bukkit Servers + * Copyright (c) 2021 Arcane Arts (Volmit Software) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.volmit.iris.util.data; + +import lombok.Builder; +import lombok.Data; + +@Data +@Builder +public class IrisProjectRepo { + @Builder.Default + private String user = "IrisDimensions"; + + @Builder.Default + private String repo = "overworld"; + + @Builder.Default + private String branch = "master"; + + @Builder.Default + private String tag = ""; + + public static IrisProjectRepo from(String g) + { + // https://github.com/IrisDimensions/overworld + if(g.startsWith("https://github.com/")) + { + String sub = g.split("\\Qgithub.com/\\E")[1]; + IrisProjectRepo r = IrisProjectRepo.builder() + .user(sub.split("\\Q/\\E")[0]) + .repo(sub.split("\\Q/\\E")[1]).build(); + + if(g.contains("/tree/")) + { + r.setBranch(g.split("/tree/")[1]); + } + + return r; + } + + else if(g.contains("/")) + { + String[] f = g.split("\\Q/\\E"); + + if(f.length == 1) + { + return from(g); + } + + else if(f.length == 2) + { + return IrisProjectRepo.builder() + .user(f[0]) + .repo(f[1]) + .build(); + } + + else if(f.length >= 3) + { + IrisProjectRepo r = IrisProjectRepo.builder() + .user(f[0]) + .repo(f[1]) + .build(); + + if(f[2].startsWith("#")) + { + r.setTag(f[2].substring(1)); + } + + else + { + r.setBranch(f[2]); + } + + return r; + } + } + + else + { + return IrisProjectRepo.builder() + .user("IrisDimensions") + .repo(g) + .branch(g.equals("overworld") ? "stable" : "master") + .build(); + } + + return null; + } + + public String toURL() + { + if(!tag.trim().isEmpty()) + { + return "https://codeload.github.com/" + user + "/" + repo + "/zip/refs/tags/" + tag; + } + + return "https://codeload.github.com/" + user + "/" + repo + "/zip/refs/heads/" + branch; + } +} diff --git a/src/main/java/com/volmit/iris/util/scheduling/jobs/DownloadJob.java b/src/main/java/com/volmit/iris/util/scheduling/jobs/DownloadJob.java new file mode 100644 index 000000000..70f048036 --- /dev/null +++ b/src/main/java/com/volmit/iris/util/scheduling/jobs/DownloadJob.java @@ -0,0 +1,89 @@ +/* + * Iris is a World Generator for Minecraft Bukkit Servers + * Copyright (c) 2021 Arcane Arts (Volmit Software) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.volmit.iris.util.scheduling.jobs; + +import com.volmit.iris.util.network.DL; +import com.volmit.iris.util.network.DownloadMonitor; + +import java.io.File; +import java.io.IOException; +import java.net.MalformedURLException; +import java.net.URL; + +public class DownloadJob implements Job{ + private DL.Download download; + private int tw; + private int cw; + + public DownloadJob(String url, File destination) throws MalformedURLException { + tw = 1; + cw = 0; + download = new DL.Download(new URL(url), destination, DL.DownloadFlag.CALCULATE_SIZE); + download.monitor(new DownloadMonitor() { + @Override + public void onUpdate(DL.DownloadState state, double progress, long elapsed, long estimated, long bps, long iobps, long size, long downloaded, long buffer, double bufferuse) { + if(size == -1) + { + tw = 1; + } + + else + { + tw = (int) (size / 100); + cw = (int) (downloaded / 100); + } + } + }); + } + + @Override + public String getName() { + return "Downloading"; + } + + @Override + public void execute() { + try { + download.start(); + while(download.isState(DL.DownloadState.DOWNLOADING)) + { + download.downloadChunk(); + } + } catch (IOException e) { + e.printStackTrace(); + } + + cw = tw; + } + + @Override + public void completeWork() { + + } + + @Override + public int getTotalWork() { + return tw; + } + + @Override + public int getWorkCompleted() { + return cw; + } +}