diff --git a/src/main/java/org/cubewhy/celestial/Celestial.java b/src/main/java/org/cubewhy/celestial/Celestial.java index d5669edf..bace724d 100644 --- a/src/main/java/org/cubewhy/celestial/Celestial.java +++ b/src/main/java/org/cubewhy/celestial/Celestial.java @@ -226,11 +226,13 @@ private static void initConfig() { // weave JsonObject weave = new JsonObject(); weave.addProperty("enable", false); + weave.addProperty("installation", new File(System.getProperty("user.home"), ".cubewhy/lunarcn/loaders/weave.jar").getPath()); weave.addProperty("check-update", true); addon.add("weave", weave); // lccn JsonObject lunarcn = new JsonObject(); lunarcn.addProperty("enable", false); + weave.addProperty("installation", new File(System.getProperty("user.home"), ".cubewhy/lunarcn/loaders/cn.jar").getPath()); lunarcn.addProperty("check-update", true); addon.add("lunarcn", lunarcn); @@ -359,6 +361,19 @@ public static GameArgsResult getArgs(String version, String branch, String modul for (JavaAgent agent : javaAgents) { args.add(agent.getJvmArg()); } + // === loaders === + JsonObject weave = config.getValue("addon").getAsJsonObject().getAsJsonObject("weave"); + JsonObject cn = config.getValue("addon").getAsJsonObject().getAsJsonObject("cn"); + if (weave.get("enable").getAsBoolean()) { + String file = weave.get("installation").getAsString(); + log.info("Weave enabled! " + file); + javaAgents.add(new JavaAgent(file)); + } + if (cn.get("enable").getAsBoolean()) { + String file = cn.get("installation").getAsString(); + log.info("LunarCN enabled! " + file); + javaAgents.add(new JavaAgent(file)); + } // === custom vm args === List customVMArgs = new ArrayList<>(); for (JsonElement jsonElement : config.getValue("vm-args").getAsJsonArray()) { diff --git a/src/main/java/org/cubewhy/celestial/game/addon/LunarCNMod.java b/src/main/java/org/cubewhy/celestial/game/addon/LunarCNMod.java index a028c431..fca325f2 100644 --- a/src/main/java/org/cubewhy/celestial/game/addon/LunarCNMod.java +++ b/src/main/java/org/cubewhy/celestial/game/addon/LunarCNMod.java @@ -10,14 +10,18 @@ import lombok.extern.slf4j.Slf4j; import org.cubewhy.celestial.Celestial; import org.cubewhy.celestial.game.BaseAddon; +import org.cubewhy.celestial.utils.AddonUtils; import org.jetbrains.annotations.Contract; import org.jetbrains.annotations.NotNull; import java.io.File; +import java.net.MalformedURLException; import java.util.ArrayList; import java.util.List; import java.util.Objects; +import static org.cubewhy.celestial.Celestial.config; + @Getter @Slf4j public class LunarCNMod extends BaseAddon { @@ -50,4 +54,9 @@ public static List findAll() { } return list; } + + public static boolean checkUpdate() throws MalformedURLException { + log.info("Updating LunarCN Loader..."); + return AddonUtils.downloadLoader("CubeWhyMC/LunarClient-CN", new File(config.getValue("addon").getAsJsonObject().getAsJsonObject("lunarcn").get("installation").getAsString())); + } } diff --git a/src/main/java/org/cubewhy/celestial/game/addon/WeaveMod.java b/src/main/java/org/cubewhy/celestial/game/addon/WeaveMod.java index 1d8cc3f5..3b23202b 100644 --- a/src/main/java/org/cubewhy/celestial/game/addon/WeaveMod.java +++ b/src/main/java/org/cubewhy/celestial/game/addon/WeaveMod.java @@ -6,14 +6,15 @@ package org.cubewhy.celestial.game.addon; -import com.google.gson.Gson; import lombok.Getter; +import lombok.extern.slf4j.Slf4j; import okhttp3.Response; import org.cubewhy.celestial.entities.Assets; import org.cubewhy.celestial.entities.ReleaseEntity; import org.cubewhy.celestial.files.DownloadManager; import org.cubewhy.celestial.files.Downloadable; import org.cubewhy.celestial.game.BaseAddon; +import org.cubewhy.celestial.utils.AddonUtils; import org.cubewhy.celestial.utils.RequestUtils; import org.cubewhy.celestial.utils.TextUtils; import org.jetbrains.annotations.Contract; @@ -31,6 +32,7 @@ import static org.cubewhy.celestial.Celestial.config; @Getter +@Slf4j public class WeaveMod extends BaseAddon { public static final String build = "Weave-MC/Weave-Loader"; // https://github.com//releases/latest public static final File modFolder = new File(System.getProperty("user.home"), ".weave/mods"); @@ -67,25 +69,8 @@ public String toString() { return this.file.getName(); } - public boolean downloadWeaveLoader() throws MalformedURLException { - String api_json; - try (Response response = RequestUtils.get("https://api.github.com/repos/Weave-MC/Weave-Loader/releases/latest").execute()) { - assert response.body() != null; - api_json = response.body().string(); - } catch (IOException e) { - return false; - } - ReleaseEntity releaseEntity = TextUtils.jsonToObj(api_json, ReleaseEntity.class); - if (releaseEntity != null) { - Assets[] assetsArray = releaseEntity.getAssets().toArray(new Assets[0]); - for (Assets assets : assetsArray) { - if (assets.getName().endsWith(".jar")) { - //TODO: download assets.browser_download_url() to ~/.cubewhy/addon/Weave-<%s>.jar, releaseEntity.getName() - - DownloadManager.download(new Downloadable(new URL(assets.getBrowser_download_url()), new File(config.getValue("addon").getAsJsonObject().getAsJsonObject("weave").get("installation").getAsString()), "")); - } - } - } - return true; + public static boolean checkUpdate() throws MalformedURLException { + log.info("Updating Weave Loader"); + return AddonUtils.downloadLoader("Weave-MC/Weave-Loader", new File(config.getValue("addon").getAsJsonObject().getAsJsonObject("weave").get("installation").getAsString())); } } diff --git a/src/main/java/org/cubewhy/celestial/gui/elements/GuiVersionSelect.java b/src/main/java/org/cubewhy/celestial/gui/elements/GuiVersionSelect.java index cbce5436..f1032f04 100644 --- a/src/main/java/org/cubewhy/celestial/gui/elements/GuiVersionSelect.java +++ b/src/main/java/org/cubewhy/celestial/gui/elements/GuiVersionSelect.java @@ -15,6 +15,8 @@ import org.cubewhy.celestial.event.impl.GameStartEvent; import org.cubewhy.celestial.event.impl.GameTerminateEvent; import org.cubewhy.celestial.files.DownloadManager; +import org.cubewhy.celestial.game.addon.LunarCNMod; +import org.cubewhy.celestial.game.addon.WeaveMod; import org.cubewhy.celestial.utils.CrashReportType; import org.cubewhy.celestial.utils.SystemUtils; import org.cubewhy.celestial.utils.TextUtils; @@ -123,8 +125,7 @@ private void initGui() throws IOException { }); } - private void beforeLaunch() throws IOException, AttachNotSupportedException { - Celestial.completeSession(); + private void beforeLaunch() throws IOException, AttachNotSupportedException, InterruptedException { if (gamePid.get() != 0) { if (SystemUtils.findJava(LauncherData.getMainClass(null)) != null) { JOptionPane.showMessageDialog(this, f.getString("gui.version.launched.message"), f.getString("gui.version.launched.title"), JOptionPane.WARNING_MESSAGE); @@ -132,6 +133,22 @@ private void beforeLaunch() throws IOException, AttachNotSupportedException { gamePid.set(0); } } + Celestial.completeSession(); + // check update for loaders + JsonObject weave = config.getValue("addon").getAsJsonObject().getAsJsonObject("weave"); + JsonObject cn = config.getValue("addon").getAsJsonObject().getAsJsonObject("cn"); + boolean checkUpdate = false; + if (weave.get("enable").getAsBoolean() && weave.get("check-update").getAsBoolean()) { + checkUpdate = WeaveMod.checkUpdate(); + } + if (cn.get("enable").getAsBoolean() && cn.get("check-update").getAsBoolean()) { + checkUpdate = LunarCNMod.checkUpdate(); + } + + if (checkUpdate) { + statusBar.setText(f.getString("gui.addon.update")); + DownloadManager.waitForAll(); + } } private void runGame(CreateProcess cp, Runnable run) throws IOException { @@ -218,7 +235,7 @@ private void runGame(CreateProcess cp, Runnable run) throws IOException { }).start(); } - private void online() throws IOException, AttachNotSupportedException { + private void online() throws IOException, AttachNotSupportedException, InterruptedException { if (isLaunching) { JOptionPane.showMessageDialog(this, f.getString("gui.launch.launching.message"), f.getString("gui.launch.launching.title"), JOptionPane.ERROR_MESSAGE); return; diff --git a/src/main/java/org/cubewhy/celestial/utils/AddonUtils.java b/src/main/java/org/cubewhy/celestial/utils/AddonUtils.java index a7542c0c..83ce5965 100644 --- a/src/main/java/org/cubewhy/celestial/utils/AddonUtils.java +++ b/src/main/java/org/cubewhy/celestial/utils/AddonUtils.java @@ -6,12 +6,22 @@ package org.cubewhy.celestial.utils; +import okhttp3.Response; +import org.cubewhy.celestial.entities.Assets; +import org.cubewhy.celestial.entities.ReleaseEntity; +import org.cubewhy.celestial.files.DownloadManager; +import org.cubewhy.celestial.files.Downloadable; import org.jetbrains.annotations.NotNull; import java.io.File; import java.io.IOException; +import java.net.MalformedURLException; +import java.net.URL; import java.util.jar.JarFile; +import static org.cubewhy.celestial.Celestial.config; +import static org.cubewhy.celestial.Celestial.f; + public final class AddonUtils { private AddonUtils() { } @@ -45,4 +55,41 @@ public static boolean isLunarCNMod(@NotNull JarFile jar) { // find lunarcn.mod.json return jar.getJarEntry("lunarcn.mod.json") != null; } + + public static boolean downloadLoader(String repo, File file) throws MalformedURLException { + String apiJson; + try (Response response = RequestUtils.get(String.format("https://%s/repos/%s/releases/latest", f.getString("url.github.api"), repo)).execute()) { + assert response.body() != null; + apiJson = response.body().string(); + } catch (Exception e) { + return false; + } + ReleaseEntity releaseEntity = TextUtils.jsonToObj(apiJson, ReleaseEntity.class); + String hash = null; + URL loader = null; + if (releaseEntity != null) { + Assets[] assetsArray = releaseEntity.getAssets().toArray(new Assets[0]); + for (Assets assets : assetsArray) { + URL url = new URL(assets.getBrowser_download_url()); + url = new URL("https", f.getString("url.github"), 443, url.getPath()); + if (assets.getName().endsWith(".jar")) { + loader = url; + } + if (assets.getName().endsWith(".sha256")) { + try (Response response = RequestUtils.get(url).execute()) { + assert response.body() != null; + hash = response.body().string().split(" ")[0]; + } catch (Exception ignored) { + // it's OK to be null + } + } + } + } + if (loader == null) { + return false; + } + // send download + DownloadManager.download(new Downloadable(loader, file, hash)); + return true; + } } diff --git a/src/main/resources/languages/launcher.properties b/src/main/resources/languages/launcher.properties index 15f032d4..06dca226 100644 --- a/src/main/resources/languages/launcher.properties +++ b/src/main/resources/languages/launcher.properties @@ -121,4 +121,7 @@ gui.addon.mods.incorrect=Mod type incorrect!\ After clicking OK, it will still be added, but the game may not load properly.\n\ ------------\n\ Debug information:\n\ - Mod: %s \ No newline at end of file + Mod: %s +url.github.api=api.github.com +url.github=github.com +gui.addon.update=Checking for mod loader updates diff --git a/src/main/resources/languages/launcher_en.properties b/src/main/resources/languages/launcher_en.properties index 15f032d4..6b3636ec 100644 --- a/src/main/resources/languages/launcher_en.properties +++ b/src/main/resources/languages/launcher_en.properties @@ -121,4 +121,7 @@ gui.addon.mods.incorrect=Mod type incorrect!\ After clicking OK, it will still be added, but the game may not load properly.\n\ ------------\n\ Debug information:\n\ - Mod: %s \ No newline at end of file + Mod: %s +url.github.api=api.github.com +url.github=github.com +gui.addon.update=Checking for mod loader updates \ No newline at end of file diff --git a/src/main/resources/languages/launcher_zh.properties b/src/main/resources/languages/launcher_zh.properties index 1a920aa3..2a9d2091 100644 --- a/src/main/resources/languages/launcher_zh.properties +++ b/src/main/resources/languages/launcher_zh.properties @@ -121,3 +121,6 @@ gui.addon.mods.incorrect=Mod类型不正确!\ ------------\n\ Debug信息:\n\ 模组文件: %s +url.github.api=api.github.ink +url.github=github.ink +gui.addon.update=正在检查模组加载器的更新