From 2e74adaa02fb6cce8c2d052af8a8c2f2ad47e800 Mon Sep 17 00:00:00 2001 From: cubewhy Date: Sun, 24 Dec 2023 22:06:54 +0800 Subject: [PATCH 01/42] todo: complete vanilla Minecraft textures --- .../java/org/cubewhy/celestial/Celestial.java | 10 +++ .../celestial/utils/game/MinecraftData.java | 77 +++++++++++++++++++ 2 files changed, 87 insertions(+) create mode 100644 src/main/java/org/cubewhy/celestial/utils/game/MinecraftData.java diff --git a/src/main/java/org/cubewhy/celestial/Celestial.java b/src/main/java/org/cubewhy/celestial/Celestial.java index 572093df..3d3d65f7 100644 --- a/src/main/java/org/cubewhy/celestial/Celestial.java +++ b/src/main/java/org/cubewhy/celestial/Celestial.java @@ -16,6 +16,7 @@ import org.cubewhy.celestial.game.JavaAgent; import org.cubewhy.celestial.gui.GuiLauncher; import org.cubewhy.celestial.utils.*; +import org.cubewhy.celestial.utils.game.MinecraftData; import org.cubewhy.celestial.utils.lunar.LauncherData; import org.jetbrains.annotations.Contract; import org.jetbrains.annotations.NotNull; @@ -32,6 +33,8 @@ import java.nio.file.Files; import java.util.*; +import static org.cubewhy.celestial.gui.GuiLauncher.statusBar; + @Slf4j public class Celestial { @@ -44,6 +47,7 @@ public class Celestial { public static LauncherData launcherData; public static JsonObject metadata; + public static JsonObject minecraftManifest; public static GuiLauncher launcherFrame; public static boolean themed = true; public static String os = System.getProperty("os.name"); @@ -193,6 +197,7 @@ private static void checkJava() throws IOException { public static void initLauncher() throws IOException { metadata = launcherData.metadata(); + minecraftManifest = MinecraftData.manifest(); if (metadata.has("error")) { // trouble here log.error("Metadata info: " + metadata); @@ -499,5 +504,10 @@ public synchronized static void checkUpdate(String version, String module, Strin File file = new File(installation, "textures/" + fileName); DownloadManager.download(new Downloadable(url, file, full[full.length - 1])); }); + + // TODO vanilla Minecraft textures + statusBar.setText("Complete textures for vanilla Minecraft"); + JsonObject textureIndex = MinecraftData.getTextureIndex(Objects.requireNonNull(MinecraftData.getVersion(version, minecraftManifest))); + } } diff --git a/src/main/java/org/cubewhy/celestial/utils/game/MinecraftData.java b/src/main/java/org/cubewhy/celestial/utils/game/MinecraftData.java new file mode 100644 index 00000000..572aba71 --- /dev/null +++ b/src/main/java/org/cubewhy/celestial/utils/game/MinecraftData.java @@ -0,0 +1,77 @@ +/* + * Celestial Launcher + * License under GPLv3 + * Do NOT remove this note if you want to copy this file. + */ + +package org.cubewhy.celestial.utils.game; + +import com.google.gson.JsonArray; +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; +import com.google.gson.JsonParser; +import okhttp3.Response; +import org.cubewhy.celestial.utils.RequestUtils; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.json.JSONObject; + +import java.io.IOException; +import java.net.MalformedURLException; +import java.net.URL; + +public final class MinecraftData { + public static final URL versionManifest; + + static { + try { + versionManifest = new URL("https://launchermeta.mojang.com/mc/game/version_manifest_v2.json"); + } catch (MalformedURLException e) { + throw new RuntimeException(e); + } + } + + private MinecraftData() { + } + + public static JsonObject manifest() throws IOException { + try (Response response = RequestUtils.get(versionManifest).execute()) { + assert response.body() != null; + return JsonParser.parseString(response.body().string()).getAsJsonObject(); + } + } + + /** + * Get information of a Minecraft release + * + * @param version version id + * @return version json + */ + public static @Nullable JsonObject getVersion(String version, @NotNull JsonElement json) throws IOException { + JsonArray versionsArray = json.getAsJsonObject().getAsJsonArray("versions"); + for (JsonElement element : versionsArray) { + if (element.getAsJsonObject().get("id").getAsString().equals(version)) { + String url = element.getAsJsonObject().get("url").getAsString(); + try (Response response = RequestUtils.get(url).execute()) { + assert response.body() != null; + return JsonParser.parseString(response.body().string()).getAsJsonObject(); + } + } + } + return null; + } + + /** + * Get texture index (Minecraft) + * + * @param json json object from MinecraftData.getVersion + * @return json of texture index + * */ + public static JsonObject getTextureIndex(@NotNull JsonElement json) throws IOException{ + URL url = new URL(json.getAsJsonObject().getAsJsonObject("assetIndex").get("url").getAsString()); + try (Response response = RequestUtils.get(url).execute()) { + assert response.body() != null; + return JsonParser.parseString(response.body().string()).getAsJsonObject(); + } + } +} From 9a0bc46bb946d672d3a8642e5f4a2480a7f747fa Mon Sep 17 00:00:00 2001 From: cubewhy Date: Tue, 26 Dec 2023 20:08:15 +0800 Subject: [PATCH 02/42] complete minecraft textures --- .../java/org/cubewhy/celestial/Celestial.java | 18 +++++++++++++++++- .../files/sources/DownloadSource.java | 14 ++++++++++++++ .../celestial/utils/game/MinecraftData.java | 2 ++ 3 files changed, 33 insertions(+), 1 deletion(-) create mode 100644 src/main/java/org/cubewhy/celestial/files/sources/DownloadSource.java diff --git a/src/main/java/org/cubewhy/celestial/Celestial.java b/src/main/java/org/cubewhy/celestial/Celestial.java index 3d3d65f7..a872ace3 100644 --- a/src/main/java/org/cubewhy/celestial/Celestial.java +++ b/src/main/java/org/cubewhy/celestial/Celestial.java @@ -505,9 +505,25 @@ public synchronized static void checkUpdate(String version, String module, Strin DownloadManager.download(new Downloadable(url, file, full[full.length - 1])); }); + File minecraftFolder = new File(config.getValue("game-dir").getAsString()); + // TODO vanilla Minecraft textures statusBar.setText("Complete textures for vanilla Minecraft"); JsonObject textureIndex = MinecraftData.getTextureIndex(Objects.requireNonNull(MinecraftData.getVersion(version, minecraftManifest))); - + // dump to .minecraft/assets/indexes + File assetsFolder = new File(minecraftFolder, "assets"); + File indexFile = new File(assetsFolder, "indexes/" + String.join(".", Arrays.copyOfRange(version.split("\\."), 0, 2)) + ".json"); + org.apache.commons.io.FileUtils.writeStringToFile(indexFile, new Gson().toJson(textureIndex), StandardCharsets.UTF_8); + + Map objects = textureIndex.getAsJsonObject("objects").asMap(); + // baseURL/hash[0:2]/hash + for (JsonElement s : objects.values()) { + JsonObject resource = s.getAsJsonObject(); + String hash = resource.get("hash").getAsString(); + String folder = hash.substring(0, 2); + URL finalURL = new URL(String.format("%s/%s/%s", MinecraftData.texture, folder, hash)); + File finalFile = new File(assetsFolder, "objects/" + folder + "/" + hash); + DownloadManager.download(new Downloadable(finalURL, finalFile, hash)); + } } } diff --git a/src/main/java/org/cubewhy/celestial/files/sources/DownloadSource.java b/src/main/java/org/cubewhy/celestial/files/sources/DownloadSource.java new file mode 100644 index 00000000..1ce68e93 --- /dev/null +++ b/src/main/java/org/cubewhy/celestial/files/sources/DownloadSource.java @@ -0,0 +1,14 @@ +/* + * Celestial Launcher + * License under GPLv3 + * Do NOT remove this note if you want to copy this file. + */ + +package org.cubewhy.celestial.files.sources; + +import java.net.URL; + +public interface DownloadSource { + // TODO complete this class + URL getBaseURL(); +} diff --git a/src/main/java/org/cubewhy/celestial/utils/game/MinecraftData.java b/src/main/java/org/cubewhy/celestial/utils/game/MinecraftData.java index 572aba71..3046b053 100644 --- a/src/main/java/org/cubewhy/celestial/utils/game/MinecraftData.java +++ b/src/main/java/org/cubewhy/celestial/utils/game/MinecraftData.java @@ -22,10 +22,12 @@ public final class MinecraftData { public static final URL versionManifest; + public static final URL texture; static { try { versionManifest = new URL("https://launchermeta.mojang.com/mc/game/version_manifest_v2.json"); + texture = new URL("https://resources.download.minecraft.net"); } catch (MalformedURLException e) { throw new RuntimeException(e); } From 635c238707044aa62468feed1c5db46719f0a93c Mon Sep 17 00:00:00 2001 From: cubewhy Date: Wed, 27 Dec 2023 21:05:01 +0800 Subject: [PATCH 03/42] addon manager --- .../gui/elements/GuiAddonManager.java | 47 +++++++++++++++++++ .../celestial/gui/pages/GuiVersion.java | 3 ++ .../resources/languages/launcher.properties | 6 ++- .../languages/launcher_zh.properties | 5 ++ 4 files changed, 60 insertions(+), 1 deletion(-) create mode 100644 src/main/java/org/cubewhy/celestial/gui/elements/GuiAddonManager.java diff --git a/src/main/java/org/cubewhy/celestial/gui/elements/GuiAddonManager.java b/src/main/java/org/cubewhy/celestial/gui/elements/GuiAddonManager.java new file mode 100644 index 00000000..7e89c2da --- /dev/null +++ b/src/main/java/org/cubewhy/celestial/gui/elements/GuiAddonManager.java @@ -0,0 +1,47 @@ +/* + * Celestial Launcher + * License under GPLv3 + * Do NOT remove this note if you want to copy this file. + */ + +package org.cubewhy.celestial.gui.elements; + +import lombok.extern.slf4j.Slf4j; +import org.cubewhy.celestial.game.JavaAgent; + +import javax.swing.*; +import javax.swing.border.TitledBorder; +import java.awt.*; + +import static org.cubewhy.celestial.Celestial.f; + +@Slf4j +public class GuiAddonManager extends JPanel { + private final JTabbedPane tab = new JTabbedPane(); + + public GuiAddonManager() { + this.setBorder(new TitledBorder(null, f.getString("gui.addons.title"), TitledBorder.DEFAULT_JUSTIFICATION, TitledBorder.DEFAULT_POSITION, null, Color.orange)); + this.setLayout(new BoxLayout(this, BoxLayout.Y_AXIS)); + + this.initGui(); + } + + private void initGui() { + DefaultListModel lunarCN = new DefaultListModel<>(); + DefaultListModel weave = new DefaultListModel<>(); + DefaultListModel agents = new DefaultListModel<>(); + // load items + for (JavaAgent javaAgent : JavaAgent.findAll()) { + agents.addElement(javaAgent.getFile().getName()); + } + + JList list1 = new JList<>(lunarCN); + JList list2 = new JList<>(weave); + JList list3 = new JList<>(agents); + tab.addTab(f.getString("gui.addons.mods.cn"), new JScrollPane(list1)); + tab.addTab(f.getString("gui.addons.mods.weave"), new JScrollPane(list2)); + tab.addTab(f.getString("gui.addons.agents"), new JScrollPane(list3)); + + this.add(tab); + } +} diff --git a/src/main/java/org/cubewhy/celestial/gui/pages/GuiVersion.java b/src/main/java/org/cubewhy/celestial/gui/pages/GuiVersion.java index 04aa7a58..aa4a346c 100644 --- a/src/main/java/org/cubewhy/celestial/gui/pages/GuiVersion.java +++ b/src/main/java/org/cubewhy/celestial/gui/pages/GuiVersion.java @@ -1,6 +1,7 @@ package org.cubewhy.celestial.gui.pages; import lombok.extern.slf4j.Slf4j; +import org.cubewhy.celestial.gui.elements.GuiAddonManager; import org.cubewhy.celestial.gui.elements.GuiVersionSelect; import javax.swing.*; @@ -14,10 +15,12 @@ public class GuiVersion extends JPanel { public GuiVersion() throws IOException { this.setBorder(new TitledBorder(null, f.getString("gui.version.title"), TitledBorder.DEFAULT_JUSTIFICATION, TitledBorder.DEFAULT_POSITION, null, Color.orange)); +// this.setLayout(new BoxLayout(this, BoxLayout.Y_AXIS)); this.initGui(); } private void initGui() throws IOException { this.add(new GuiVersionSelect()); + this.add(new GuiAddonManager()); } } diff --git a/src/main/resources/languages/launcher.properties b/src/main/resources/languages/launcher.properties index 6ef90dbf..fc4cc6ef 100644 --- a/src/main/resources/languages/launcher.properties +++ b/src/main/resources/languages/launcher.properties @@ -74,4 +74,8 @@ status.launch.crashed=Game crashed status.launch.started=Game launched, PID is %s gui.help=Wiki gui.launch.server.failure.message=The server gave an invalid response. It is recommended to check whether the corresponding Json file is configured. -gui.launch.server.failure.title=Failed to launch \ No newline at end of file +gui.launch.server.failure.title=Failed to launch +gui.addons.title=Addons Manager +gui.addons.mods.cn=LunarCN Mods +gui.addons.agents=JavaAgents +gui.addons.mods.weave=Weave Mods \ 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 fb4dc2f2..78979dd0 100644 --- a/src/main/resources/languages/launcher_zh.properties +++ b/src/main/resources/languages/launcher_zh.properties @@ -73,3 +73,8 @@ status.launch.started=游戏已启动, 进程ID为%s gui.help=帮助文档 gui.launch.server.failure.message=服务器给出了无效的响应, 建议检查是否配置了对应的Json文件 gui.launch.server.failure.title=启动失败 +gui.addons.title=加载项管理器 +gui.addons.title=加载项管理器 +gui.addons.mods.cn=LunarCN模组 +gui.addons.agents=爪哇岛助理 +gui.addons.mods.weave=Weave模组 From 8224686e5f2166bfcdb4d11a2f637aff40f0369b Mon Sep 17 00:00:00 2001 From: cubewhy Date: Wed, 27 Dec 2023 21:06:02 +0800 Subject: [PATCH 04/42] move --- src/main/java/org/cubewhy/celestial/Celestial.java | 2 +- .../org/cubewhy/celestial/game/{ => addon}/JavaAgent.java | 8 +++++++- .../cubewhy/celestial/gui/elements/GuiAddonManager.java | 2 +- 3 files changed, 9 insertions(+), 3 deletions(-) rename src/main/java/org/cubewhy/celestial/game/{ => addon}/JavaAgent.java (94%) diff --git a/src/main/java/org/cubewhy/celestial/Celestial.java b/src/main/java/org/cubewhy/celestial/Celestial.java index a872ace3..8531b85c 100644 --- a/src/main/java/org/cubewhy/celestial/Celestial.java +++ b/src/main/java/org/cubewhy/celestial/Celestial.java @@ -13,7 +13,7 @@ import org.cubewhy.celestial.game.AuthServer; import org.cubewhy.celestial.game.GameArgs; import org.cubewhy.celestial.game.GameArgsResult; -import org.cubewhy.celestial.game.JavaAgent; +import org.cubewhy.celestial.game.addon.JavaAgent; import org.cubewhy.celestial.gui.GuiLauncher; import org.cubewhy.celestial.utils.*; import org.cubewhy.celestial.utils.game.MinecraftData; diff --git a/src/main/java/org/cubewhy/celestial/game/JavaAgent.java b/src/main/java/org/cubewhy/celestial/game/addon/JavaAgent.java similarity index 94% rename from src/main/java/org/cubewhy/celestial/game/JavaAgent.java rename to src/main/java/org/cubewhy/celestial/game/addon/JavaAgent.java index b0724253..3d8addb6 100644 --- a/src/main/java/org/cubewhy/celestial/game/JavaAgent.java +++ b/src/main/java/org/cubewhy/celestial/game/addon/JavaAgent.java @@ -1,4 +1,10 @@ -package org.cubewhy.celestial.game; +/* + * Celestial Launcher + * License under GPLv3 + * Do NOT remove this note if you want to copy this file. + */ + +package org.cubewhy.celestial.game.addon; import com.google.gson.JsonObject; import lombok.Getter; diff --git a/src/main/java/org/cubewhy/celestial/gui/elements/GuiAddonManager.java b/src/main/java/org/cubewhy/celestial/gui/elements/GuiAddonManager.java index 7e89c2da..295009fd 100644 --- a/src/main/java/org/cubewhy/celestial/gui/elements/GuiAddonManager.java +++ b/src/main/java/org/cubewhy/celestial/gui/elements/GuiAddonManager.java @@ -7,7 +7,7 @@ package org.cubewhy.celestial.gui.elements; import lombok.extern.slf4j.Slf4j; -import org.cubewhy.celestial.game.JavaAgent; +import org.cubewhy.celestial.game.addon.JavaAgent; import javax.swing.*; import javax.swing.border.TitledBorder; From 410483410715a9df105816057ef80b8e4097712d Mon Sep 17 00:00:00 2001 From: cubewhy Date: Wed, 27 Dec 2023 21:22:53 +0800 Subject: [PATCH 05/42] class of mods --- .../celestial/game/addon/LunarCNMod.java | 35 +++++++++++++++++++ .../celestial/game/addon/WeaveMod.java | 34 ++++++++++++++++++ 2 files changed, 69 insertions(+) create mode 100644 src/main/java/org/cubewhy/celestial/game/addon/LunarCNMod.java create mode 100644 src/main/java/org/cubewhy/celestial/game/addon/WeaveMod.java diff --git a/src/main/java/org/cubewhy/celestial/game/addon/LunarCNMod.java b/src/main/java/org/cubewhy/celestial/game/addon/LunarCNMod.java new file mode 100644 index 00000000..e9f8d7db --- /dev/null +++ b/src/main/java/org/cubewhy/celestial/game/addon/LunarCNMod.java @@ -0,0 +1,35 @@ +/* + * Celestial Launcher + * License under GPLv3 + * Do NOT remove this note if you want to copy this file. + */ + +package org.cubewhy.celestial.game.addon; + +import org.cubewhy.celestial.Celestial; +import org.jetbrains.annotations.Contract; +import org.jetbrains.annotations.NotNull; + +import java.io.File; +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; + +public record LunarCNMod(File file) { + public static final File modFolder = new File(Celestial.configDir, "mods"); + + /** + * Find all mods in the lunarcn mods folder + * */ + @NotNull + @Contract(pure = true) + public static List findAll() { + List list = new ArrayList<>(); + for (File file : Objects.requireNonNull(modFolder.listFiles())) { + if (file.getName().endsWith(".jar") && file.isFile()) { + list.add(new LunarCNMod(file)); + } + } + return list; + } +} diff --git a/src/main/java/org/cubewhy/celestial/game/addon/WeaveMod.java b/src/main/java/org/cubewhy/celestial/game/addon/WeaveMod.java new file mode 100644 index 00000000..d8edd0b5 --- /dev/null +++ b/src/main/java/org/cubewhy/celestial/game/addon/WeaveMod.java @@ -0,0 +1,34 @@ +/* + * Celestial Launcher + * License under GPLv3 + * Do NOT remove this note if you want to copy this file. + */ + +package org.cubewhy.celestial.game.addon; + +import org.jetbrains.annotations.Contract; +import org.jetbrains.annotations.NotNull; + +import java.io.File; +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; + +public record WeaveMod(File file) { + public static final File modFolder = new File(System.getProperty("user.home"), ".weave/mods"); + + /** + * Find all mods in the lunarcn mods folder + * */ + @NotNull + @Contract(pure = true) + public static List findAll() { + List list = new ArrayList<>(); + for (File file : Objects.requireNonNull(modFolder.listFiles())) { + if (file.getName().endsWith(".jar") && file.isFile()) { + list.add(new WeaveMod(file)); + } + } + return list; + } +} From 46d08c2830855a9762c70e1457599a3a9f73a903 Mon Sep 17 00:00:00 2001 From: cubewhy Date: Fri, 29 Dec 2023 21:32:23 +0800 Subject: [PATCH 06/42] add mods --- .../org/cubewhy/celestial/game/addon/LunarCNMod.java | 9 ++++++++- .../org/cubewhy/celestial/game/addon/WeaveMod.java | 11 +++++++++-- .../celestial/gui/elements/GuiAddonManager.java | 8 ++++++++ 3 files changed, 25 insertions(+), 3 deletions(-) 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 e9f8d7db..aa495367 100644 --- a/src/main/java/org/cubewhy/celestial/game/addon/LunarCNMod.java +++ b/src/main/java/org/cubewhy/celestial/game/addon/LunarCNMod.java @@ -6,6 +6,7 @@ package org.cubewhy.celestial.game.addon; +import lombok.Getter; import org.cubewhy.celestial.Celestial; import org.jetbrains.annotations.Contract; import org.jetbrains.annotations.NotNull; @@ -15,8 +16,14 @@ import java.util.List; import java.util.Objects; -public record LunarCNMod(File file) { +@Getter +public class LunarCNMod { public static final File modFolder = new File(Celestial.configDir, "mods"); + private final File file; + + public LunarCNMod(File file) { + this.file = file; + } /** * Find all mods in the lunarcn mods folder 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 d8edd0b5..cbfcb383 100644 --- a/src/main/java/org/cubewhy/celestial/game/addon/WeaveMod.java +++ b/src/main/java/org/cubewhy/celestial/game/addon/WeaveMod.java @@ -6,6 +6,7 @@ package org.cubewhy.celestial.game.addon; +import lombok.Getter; import org.jetbrains.annotations.Contract; import org.jetbrains.annotations.NotNull; @@ -14,12 +15,18 @@ import java.util.List; import java.util.Objects; -public record WeaveMod(File file) { +@Getter +public class WeaveMod { public static final File modFolder = new File(System.getProperty("user.home"), ".weave/mods"); + private final File file; + + public WeaveMod(File file) { + this.file = file; + } /** * Find all mods in the lunarcn mods folder - * */ + */ @NotNull @Contract(pure = true) public static List findAll() { diff --git a/src/main/java/org/cubewhy/celestial/gui/elements/GuiAddonManager.java b/src/main/java/org/cubewhy/celestial/gui/elements/GuiAddonManager.java index 295009fd..bf54f6ea 100644 --- a/src/main/java/org/cubewhy/celestial/gui/elements/GuiAddonManager.java +++ b/src/main/java/org/cubewhy/celestial/gui/elements/GuiAddonManager.java @@ -8,6 +8,8 @@ import lombok.extern.slf4j.Slf4j; import org.cubewhy.celestial.game.addon.JavaAgent; +import org.cubewhy.celestial.game.addon.LunarCNMod; +import org.cubewhy.celestial.game.addon.WeaveMod; import javax.swing.*; import javax.swing.border.TitledBorder; @@ -34,6 +36,12 @@ private void initGui() { for (JavaAgent javaAgent : JavaAgent.findAll()) { agents.addElement(javaAgent.getFile().getName()); } + for (WeaveMod weaveMod : WeaveMod.findAll()) { + weave.addElement(weaveMod.getFile().getName()); + } + for (LunarCNMod lunarCNMod : LunarCNMod.findAll()) { + lunarCN.addElement(lunarCNMod.getFile().getName()); + } JList list1 = new JList<>(lunarCN); JList list2 = new JList<>(weave); From 20f0dfb9b4caaeb719de34cc3f9d0a350876308d Mon Sep 17 00:00:00 2001 From: cubewhy Date: Fri, 29 Dec 2023 21:34:18 +0800 Subject: [PATCH 07/42] else... --- .../java/org/cubewhy/celestial/game/addon/LunarCNMod.java | 8 +++++--- .../java/org/cubewhy/celestial/game/addon/WeaveMod.java | 8 +++++--- 2 files changed, 10 insertions(+), 6 deletions(-) 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 aa495367..bda165e4 100644 --- a/src/main/java/org/cubewhy/celestial/game/addon/LunarCNMod.java +++ b/src/main/java/org/cubewhy/celestial/game/addon/LunarCNMod.java @@ -32,9 +32,11 @@ public LunarCNMod(File file) { @Contract(pure = true) public static List findAll() { List list = new ArrayList<>(); - for (File file : Objects.requireNonNull(modFolder.listFiles())) { - if (file.getName().endsWith(".jar") && file.isFile()) { - list.add(new LunarCNMod(file)); + if (modFolder.isDirectory()) { + for (File file : Objects.requireNonNull(modFolder.listFiles())) { + if (file.getName().endsWith(".jar") && file.isFile()) { + list.add(new LunarCNMod(file)); + } } } return list; 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 cbfcb383..2be5faf9 100644 --- a/src/main/java/org/cubewhy/celestial/game/addon/WeaveMod.java +++ b/src/main/java/org/cubewhy/celestial/game/addon/WeaveMod.java @@ -31,9 +31,11 @@ public WeaveMod(File file) { @Contract(pure = true) public static List findAll() { List list = new ArrayList<>(); - for (File file : Objects.requireNonNull(modFolder.listFiles())) { - if (file.getName().endsWith(".jar") && file.isFile()) { - list.add(new WeaveMod(file)); + if (modFolder.isDirectory()) { + for (File file : Objects.requireNonNull(modFolder.listFiles())) { + if (file.getName().endsWith(".jar") && file.isFile()) { + list.add(new WeaveMod(file)); + } } } return list; From a38174b3e3f37cc617a83a372c5eea832d86dbef Mon Sep 17 00:00:00 2001 From: cubewhy Date: Sat, 30 Dec 2023 09:20:53 +0800 Subject: [PATCH 08/42] todo... --- .../gui/elements/GuiAddonManager.java | 27 ++++++++++++++++--- 1 file changed, 23 insertions(+), 4 deletions(-) diff --git a/src/main/java/org/cubewhy/celestial/gui/elements/GuiAddonManager.java b/src/main/java/org/cubewhy/celestial/gui/elements/GuiAddonManager.java index bf54f6ea..4b736894 100644 --- a/src/main/java/org/cubewhy/celestial/gui/elements/GuiAddonManager.java +++ b/src/main/java/org/cubewhy/celestial/gui/elements/GuiAddonManager.java @@ -42,13 +42,32 @@ private void initGui() { for (LunarCNMod lunarCNMod : LunarCNMod.findAll()) { lunarCN.addElement(lunarCNMod.getFile().getName()); } - JList list1 = new JList<>(lunarCN); JList list2 = new JList<>(weave); JList list3 = new JList<>(agents); - tab.addTab(f.getString("gui.addons.mods.cn"), new JScrollPane(list1)); - tab.addTab(f.getString("gui.addons.mods.weave"), new JScrollPane(list2)); - tab.addTab(f.getString("gui.addons.agents"), new JScrollPane(list3)); + // buttons + JButton btnAddLunarCNMod = new JButton("Add mod"); + JButton btnAddWeaveMod = new JButton("Add mod"); + JButton btnAddAgent = new JButton("Add agent"); + // TODO Stretch to the right + + // panels + final JPanel panelLunarCN = new JPanel(); + panelLunarCN.setLayout(new BoxLayout(panelLunarCN, BoxLayout.Y_AXIS)); + panelLunarCN.add(new JScrollPane(list1)); + panelLunarCN.add(btnAddLunarCNMod); + final JPanel panelWeave = new JPanel(); + panelWeave.setLayout(new BoxLayout(panelWeave, BoxLayout.Y_AXIS)); + panelWeave.add(new JScrollPane(list2)); + panelWeave.add(btnAddWeaveMod); + final JPanel panelAgents = new JPanel(); + panelAgents.setLayout(new BoxLayout(panelAgents, BoxLayout.Y_AXIS)); + panelAgents.add(new JScrollPane(list3)); + panelAgents.add(Box.createVerticalGlue()); + panelAgents.add(btnAddAgent); + tab.addTab(f.getString("gui.addons.mods.cn"), panelLunarCN); + tab.addTab(f.getString("gui.addons.mods.weave"), panelWeave); + tab.addTab(f.getString("gui.addons.agents"), panelAgents); this.add(tab); } From 0021ec2e13f48a9480d35d694c5efca7ca1d962f Mon Sep 17 00:00:00 2001 From: cubewhy Date: Sun, 31 Dec 2023 08:26:46 +0800 Subject: [PATCH 09/42] menu --- .../gui/elements/GuiAddonManager.java | 55 ++++++++++++++++--- .../resources/languages/launcher.properties | 8 ++- .../languages/launcher_zh.properties | 6 ++ 3 files changed, 59 insertions(+), 10 deletions(-) diff --git a/src/main/java/org/cubewhy/celestial/gui/elements/GuiAddonManager.java b/src/main/java/org/cubewhy/celestial/gui/elements/GuiAddonManager.java index 4b736894..09f9a9cd 100644 --- a/src/main/java/org/cubewhy/celestial/gui/elements/GuiAddonManager.java +++ b/src/main/java/org/cubewhy/celestial/gui/elements/GuiAddonManager.java @@ -10,10 +10,13 @@ import org.cubewhy.celestial.game.addon.JavaAgent; import org.cubewhy.celestial.game.addon.LunarCNMod; import org.cubewhy.celestial.game.addon.WeaveMod; +import org.jetbrains.annotations.NotNull; import javax.swing.*; import javax.swing.border.TitledBorder; import java.awt.*; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; import static org.cubewhy.celestial.Celestial.f; @@ -42,27 +45,48 @@ private void initGui() { for (LunarCNMod lunarCNMod : LunarCNMod.findAll()) { lunarCN.addElement(lunarCNMod.getFile().getName()); } - JList list1 = new JList<>(lunarCN); - JList list2 = new JList<>(weave); - JList list3 = new JList<>(agents); + JList listLunarCN = new JList<>(lunarCN); + JList listWeave = new JList<>(weave); + JList listAgents = new JList<>(agents); + // menus + JPopupMenu agentMenu = new JPopupMenu(); + JMenuItem manageArg = new JMenuItem(f.getString("gui.addon.agents.arg")); + JMenuItem removeAgent = new JMenuItem(f.getString("gui.addon.agents.remove")); + agentMenu.add(manageArg); + agentMenu.addSeparator(); + agentMenu.add(removeAgent); + + JPopupMenu weaveMenu = new JPopupMenu(); + JMenuItem removeWeaveMod = new JMenuItem(f.getString("gui.addon.mods.weave.remove")); + weaveMenu.add(removeWeaveMod); + + JPopupMenu lunarCNMenu = new JPopupMenu(); + JMenuItem removeLunarCNMod = new JMenuItem(f.getString("gui.addon.mods.cn.remove")); + lunarCNMenu.add(removeLunarCNMod); + // bind menus + bingMenu(listLunarCN, lunarCNMenu); + bingMenu(listWeave, weaveMenu); + bingMenu(listAgents, agentMenu); + + // buttons - JButton btnAddLunarCNMod = new JButton("Add mod"); - JButton btnAddWeaveMod = new JButton("Add mod"); - JButton btnAddAgent = new JButton("Add agent"); + JButton btnAddLunarCNMod = new JButton(f.getString("gui.addon.mods.add")); + JButton btnAddWeaveMod = new JButton(f.getString("gui.addon.mods.add")); + JButton btnAddAgent = new JButton(f.getString("gui.addon.agents.add")); // TODO Stretch to the right // panels final JPanel panelLunarCN = new JPanel(); panelLunarCN.setLayout(new BoxLayout(panelLunarCN, BoxLayout.Y_AXIS)); - panelLunarCN.add(new JScrollPane(list1)); + panelLunarCN.add(new JScrollPane(listLunarCN)); panelLunarCN.add(btnAddLunarCNMod); final JPanel panelWeave = new JPanel(); panelWeave.setLayout(new BoxLayout(panelWeave, BoxLayout.Y_AXIS)); - panelWeave.add(new JScrollPane(list2)); + panelWeave.add(new JScrollPane(listWeave)); panelWeave.add(btnAddWeaveMod); final JPanel panelAgents = new JPanel(); panelAgents.setLayout(new BoxLayout(panelAgents, BoxLayout.Y_AXIS)); - panelAgents.add(new JScrollPane(list3)); + panelAgents.add(new JScrollPane(listAgents)); panelAgents.add(Box.createVerticalGlue()); panelAgents.add(btnAddAgent); tab.addTab(f.getString("gui.addons.mods.cn"), panelLunarCN); @@ -71,4 +95,17 @@ private void initGui() { this.add(tab); } + + private void bingMenu(@NotNull JList listWeave, JPopupMenu weaveMenu) { + listWeave.addMouseListener(new MouseAdapter() { + @Override + public void mouseClicked(MouseEvent e) { + if (SwingUtilities.isRightMouseButton(e)) { + int index = listWeave.locationToIndex(e.getPoint()); + listWeave.setSelectedIndex(index); + weaveMenu.show(listWeave, e.getX(), e.getY()); + } + } + }); + } } diff --git a/src/main/resources/languages/launcher.properties b/src/main/resources/languages/launcher.properties index fc4cc6ef..779c2b57 100644 --- a/src/main/resources/languages/launcher.properties +++ b/src/main/resources/languages/launcher.properties @@ -78,4 +78,10 @@ gui.launch.server.failure.title=Failed to launch gui.addons.title=Addons Manager gui.addons.mods.cn=LunarCN Mods gui.addons.agents=JavaAgents -gui.addons.mods.weave=Weave Mods \ No newline at end of file +gui.addons.mods.weave=Weave Mods +gui.addon.agents.arg=Adjustment parameters +gui.addon.agents.remove=Delete +gui.addon.mods.weave.remove=Delete +gui.addon.mods.cn.remove=Delete +gui.addon.mods.add=Add a mod +gui.addon.agents.add=Add a agent \ 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 78979dd0..79d82e6f 100644 --- a/src/main/resources/languages/launcher_zh.properties +++ b/src/main/resources/languages/launcher_zh.properties @@ -78,3 +78,9 @@ gui.addons.title=加载项管理器 gui.addons.mods.cn=LunarCN模组 gui.addons.agents=爪哇岛助理 gui.addons.mods.weave=Weave模组 +gui.addon.agents.arg=调整参数 +gui.addon.agents.remove=删除 +gui.addon.mods.weave.remove=删除Mod +gui.addon.mods.cn.remove=删除Mod +gui.addon.mods.add=添加模组 +gui.addon.agents.add=添加助理 From 8748da67ab936e6c99b86143139b0a88c840316e Mon Sep 17 00:00:00 2001 From: cubewhy Date: Sun, 31 Dec 2023 09:08:41 +0800 Subject: [PATCH 10/42] agent arg manager --- .../org/cubewhy/celestial/game/BaseAddon.java | 17 ++++++ .../celestial/game/addon/JavaAgent.java | 35 +++++++++--- .../celestial/game/addon/LunarCNMod.java | 3 +- .../celestial/game/addon/WeaveMod.java | 3 +- .../gui/elements/GuiAddonManager.java | 54 +++++++++++++------ .../resources/languages/launcher.properties | 7 ++- .../languages/launcher_zh.properties | 5 ++ 7 files changed, 98 insertions(+), 26 deletions(-) create mode 100644 src/main/java/org/cubewhy/celestial/game/BaseAddon.java diff --git a/src/main/java/org/cubewhy/celestial/game/BaseAddon.java b/src/main/java/org/cubewhy/celestial/game/BaseAddon.java new file mode 100644 index 00000000..2c6f64e9 --- /dev/null +++ b/src/main/java/org/cubewhy/celestial/game/BaseAddon.java @@ -0,0 +1,17 @@ +/* + * Celestial Launcher + * License under GPLv3 + * Do NOT remove this note if you want to copy this file. + */ + +package org.cubewhy.celestial.game; + +import org.jetbrains.annotations.Contract; +import org.jetbrains.annotations.Nullable; + +public interface BaseAddon { + @Contract(pure = true) + static BaseAddon @Nullable [] findAll() { + return null; + } +} diff --git a/src/main/java/org/cubewhy/celestial/game/addon/JavaAgent.java b/src/main/java/org/cubewhy/celestial/game/addon/JavaAgent.java index 3d8addb6..a19fb193 100644 --- a/src/main/java/org/cubewhy/celestial/game/addon/JavaAgent.java +++ b/src/main/java/org/cubewhy/celestial/game/addon/JavaAgent.java @@ -9,6 +9,7 @@ import com.google.gson.JsonObject; import lombok.Getter; import lombok.extern.slf4j.Slf4j; +import org.cubewhy.celestial.game.BaseAddon; import org.jetbrains.annotations.Contract; import org.jetbrains.annotations.NotNull; @@ -22,7 +23,7 @@ @Getter @Slf4j -public class JavaAgent { +public class JavaAgent implements BaseAddon { public static final File javaAgentFolder = new File(configDir, "javaagents"); // share with LunarCN Launcher static { @@ -34,14 +35,12 @@ public class JavaAgent { /** * -- GETTER -- - * Get agent arg - * + * Get agent arg */ private String arg = ""; /** * -- GETTER -- - * Get a file of the javaagent - * + * Get a file of the javaagent */ private final File file; @@ -87,7 +86,7 @@ public JavaAgent(String path) { /** * Find all javaagents in the javaagent folder - * */ + */ @NotNull @Contract(pure = true) public static List findAll() { @@ -100,7 +99,19 @@ public static List findAll() { return list; } - private static String findAgentArg(String name) { + /** + * Set param for a Javaagent + * + * @param agent the agent + * @param arg new param + */ + public static void setArgFor(@NotNull JavaAgent agent, String arg) { + JsonObject ja = config.getValue("javaagents").getAsJsonObject(); + ja.addProperty(agent.file.getName(), arg); // leave empty + config.setValue("javaagents", ja); // dump + } + + public static String findAgentArg(String name) { JsonObject ja = config.getValue("javaagents").getAsJsonObject(); if (!ja.has(name)) { // create config for the agent @@ -110,6 +121,7 @@ private static String findAgentArg(String name) { return ja.get(name).getAsString(); } + /** * Get args which add to the jvm * @@ -126,4 +138,13 @@ public String getJvmArg() { } return jvmArgs; } + + @Override + public String toString() { + String result = this.file.getName(); + if (!this.arg.isBlank()) { + result += "=" + this.arg; + } + return result; + } } 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 bda165e4..e9f2d17d 100644 --- a/src/main/java/org/cubewhy/celestial/game/addon/LunarCNMod.java +++ b/src/main/java/org/cubewhy/celestial/game/addon/LunarCNMod.java @@ -8,6 +8,7 @@ import lombok.Getter; import org.cubewhy.celestial.Celestial; +import org.cubewhy.celestial.game.BaseAddon; import org.jetbrains.annotations.Contract; import org.jetbrains.annotations.NotNull; @@ -17,7 +18,7 @@ import java.util.Objects; @Getter -public class LunarCNMod { +public class LunarCNMod implements BaseAddon { public static final File modFolder = new File(Celestial.configDir, "mods"); private final File file; 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 2be5faf9..8791f727 100644 --- a/src/main/java/org/cubewhy/celestial/game/addon/WeaveMod.java +++ b/src/main/java/org/cubewhy/celestial/game/addon/WeaveMod.java @@ -7,6 +7,7 @@ package org.cubewhy.celestial.game.addon; import lombok.Getter; +import org.cubewhy.celestial.game.BaseAddon; import org.jetbrains.annotations.Contract; import org.jetbrains.annotations.NotNull; @@ -16,7 +17,7 @@ import java.util.Objects; @Getter -public class WeaveMod { +public class WeaveMod implements BaseAddon { public static final File modFolder = new File(System.getProperty("user.home"), ".weave/mods"); private final File file; diff --git a/src/main/java/org/cubewhy/celestial/gui/elements/GuiAddonManager.java b/src/main/java/org/cubewhy/celestial/gui/elements/GuiAddonManager.java index 09f9a9cd..ae7862f9 100644 --- a/src/main/java/org/cubewhy/celestial/gui/elements/GuiAddonManager.java +++ b/src/main/java/org/cubewhy/celestial/gui/elements/GuiAddonManager.java @@ -7,9 +7,11 @@ package org.cubewhy.celestial.gui.elements; import lombok.extern.slf4j.Slf4j; +import org.cubewhy.celestial.game.BaseAddon; import org.cubewhy.celestial.game.addon.JavaAgent; import org.cubewhy.celestial.game.addon.LunarCNMod; import org.cubewhy.celestial.game.addon.WeaveMod; +import org.cubewhy.celestial.gui.GuiLauncher; import org.jetbrains.annotations.NotNull; import javax.swing.*; @@ -32,22 +34,20 @@ public GuiAddonManager() { } private void initGui() { - DefaultListModel lunarCN = new DefaultListModel<>(); - DefaultListModel weave = new DefaultListModel<>(); - DefaultListModel agents = new DefaultListModel<>(); + DefaultListModel lunarCN = new DefaultListModel<>(); + DefaultListModel weave = new DefaultListModel<>(); + DefaultListModel agents = new DefaultListModel<>(); // load items - for (JavaAgent javaAgent : JavaAgent.findAll()) { - agents.addElement(javaAgent.getFile().getName()); - } + loadAgents(agents); for (WeaveMod weaveMod : WeaveMod.findAll()) { - weave.addElement(weaveMod.getFile().getName()); + weave.addElement(weaveMod); } for (LunarCNMod lunarCNMod : LunarCNMod.findAll()) { - lunarCN.addElement(lunarCNMod.getFile().getName()); + lunarCN.addElement(lunarCNMod); } - JList listLunarCN = new JList<>(lunarCN); - JList listWeave = new JList<>(weave); - JList listAgents = new JList<>(agents); + JList listLunarCN = new JList<>(lunarCN); + JList listWeave = new JList<>(weave); + JList listAgents = new JList<>(agents); // menus JPopupMenu agentMenu = new JPopupMenu(); JMenuItem manageArg = new JMenuItem(f.getString("gui.addon.agents.arg")); @@ -56,6 +56,22 @@ private void initGui() { agentMenu.addSeparator(); agentMenu.add(removeAgent); + manageArg.addActionListener(e -> { + // open a dialog + JavaAgent currentAgent = listAgents.getSelectedValue(); + String newArg = JOptionPane.showInputDialog(this, f.getString("gui.addon.agents.arg.message"), currentAgent.getArg()); + if (newArg != null && !currentAgent.getArg().equals(newArg)) { + JavaAgent.setArgFor(currentAgent, newArg); + if (newArg.isBlank()) { + GuiLauncher.statusBar.setText(String.format(f.getString("gui.addon.agents.arg.remove.success"), currentAgent.getFile().getName())); + } else { + GuiLauncher.statusBar.setText(String.format(f.getString("gui.addon.agents.arg.set.success"), currentAgent.getFile().getName(), newArg)); + } + agents.clear(); + loadAgents(agents); + } + }); + JPopupMenu weaveMenu = new JPopupMenu(); JMenuItem removeWeaveMod = new JMenuItem(f.getString("gui.addon.mods.weave.remove")); weaveMenu.add(removeWeaveMod); @@ -96,14 +112,20 @@ private void initGui() { this.add(tab); } - private void bingMenu(@NotNull JList listWeave, JPopupMenu weaveMenu) { - listWeave.addMouseListener(new MouseAdapter() { + private static void loadAgents(DefaultListModel agents) { + for (JavaAgent javaAgent : JavaAgent.findAll()) { + agents.addElement(javaAgent); + } + } + + private void bingMenu(@NotNull JList list, JPopupMenu menu) { + list.addMouseListener(new MouseAdapter() { @Override public void mouseClicked(MouseEvent e) { if (SwingUtilities.isRightMouseButton(e)) { - int index = listWeave.locationToIndex(e.getPoint()); - listWeave.setSelectedIndex(index); - weaveMenu.show(listWeave, e.getX(), e.getY()); + int index = list.locationToIndex(e.getPoint()); + list.setSelectedIndex(index); + menu.show(list, e.getX(), e.getY()); } } }); diff --git a/src/main/resources/languages/launcher.properties b/src/main/resources/languages/launcher.properties index 779c2b57..039a82f2 100644 --- a/src/main/resources/languages/launcher.properties +++ b/src/main/resources/languages/launcher.properties @@ -84,4 +84,9 @@ gui.addon.agents.remove=Delete gui.addon.mods.weave.remove=Delete gui.addon.mods.cn.remove=Delete gui.addon.mods.add=Add a mod -gui.addon.agents.add=Add a agent \ No newline at end of file +gui.addon.agents.add=Add a agent +gui.addon.agents.arg.message=Please enter the new JavaAgent parameters below +gui.addon.agents.arg.title=Adjustment parameters +gui.addon.agents.success=Add successful +gui.addon.agents.arg.set.success=The parameter of %s has been set to %s +gui.addon.agents.arg.remove.success=Parameters of %s have been removed \ 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 79d82e6f..4f5cf4e6 100644 --- a/src/main/resources/languages/launcher_zh.properties +++ b/src/main/resources/languages/launcher_zh.properties @@ -84,3 +84,8 @@ gui.addon.mods.weave.remove=删除Mod gui.addon.mods.cn.remove=删除Mod gui.addon.mods.add=添加模组 gui.addon.agents.add=添加助理 +gui.addon.agents.arg.message=请在下方输入新的JavaAgent参数 +gui.addon.agents.arg.title=参数管理 +gui.addon.agents.success=添加成功 +gui.addon.agents.arg.set.success=%s的参数已设置为%s +gui.addon.agents.arg.remove.success=已移除%s的参数 From 97d245bd34d36646cc2a49c4c58ff2e1189c3f8a Mon Sep 17 00:00:00 2001 From: cubewhy Date: Sun, 31 Dec 2023 10:23:30 +0800 Subject: [PATCH 11/42] add agent --- .../celestial/game/addon/JavaAgent.java | 32 ++++++++++- .../gui/elements/GuiAddonManager.java | 57 ++++++++++++++++++- .../cubewhy/celestial/gui/pages/GuiNews.java | 24 ++++---- .../resources/languages/launcher.properties | 21 ++++++- .../languages/launcher_zh.properties | 18 ++++++ 5 files changed, 136 insertions(+), 16 deletions(-) diff --git a/src/main/java/org/cubewhy/celestial/game/addon/JavaAgent.java b/src/main/java/org/cubewhy/celestial/game/addon/JavaAgent.java index a19fb193..eabf30b9 100644 --- a/src/main/java/org/cubewhy/celestial/game/addon/JavaAgent.java +++ b/src/main/java/org/cubewhy/celestial/game/addon/JavaAgent.java @@ -9,11 +9,13 @@ import com.google.gson.JsonObject; import lombok.Getter; import lombok.extern.slf4j.Slf4j; +import org.apache.commons.io.FileUtils; import org.cubewhy.celestial.game.BaseAddon; import org.jetbrains.annotations.Contract; import org.jetbrains.annotations.NotNull; import java.io.File; +import java.io.IOException; import java.util.ArrayList; import java.util.List; import java.util.Objects; @@ -103,11 +105,21 @@ public static List findAll() { * Set param for a Javaagent * * @param agent the agent - * @param arg new param + * @param arg param of the agent */ public static void setArgFor(@NotNull JavaAgent agent, String arg) { + setArgFor(agent.file.getName(), arg); + } + + /** + * Set param for a Javaagent + * + * @param name name of the agent + * @param arg param of the agent + */ + public static void setArgFor(String name, String arg) { JsonObject ja = config.getValue("javaagents").getAsJsonObject(); - ja.addProperty(agent.file.getName(), arg); // leave empty + ja.addProperty(name, arg); // leave empty config.setValue("javaagents", ja); // dump } @@ -121,6 +133,22 @@ public static String findAgentArg(String name) { return ja.get(name).getAsString(); } + public static boolean add(@NotNull File file, String arg) throws IOException { + String name = file.getName(); + if (!name.endsWith(".jar")) { + name += ".jar"; // adds an ends with for the file + } + File target = new File(javaAgentFolder, name); + if (target.exists()) { + return false; + } + FileUtils.copyFile(file, target); + if (arg != null) { + setArgFor(file.getName(), arg); + } + return true; + } + /** * Get args which add to the jvm diff --git a/src/main/java/org/cubewhy/celestial/gui/elements/GuiAddonManager.java b/src/main/java/org/cubewhy/celestial/gui/elements/GuiAddonManager.java index ae7862f9..61e3bcfa 100644 --- a/src/main/java/org/cubewhy/celestial/gui/elements/GuiAddonManager.java +++ b/src/main/java/org/cubewhy/celestial/gui/elements/GuiAddonManager.java @@ -7,18 +7,25 @@ package org.cubewhy.celestial.gui.elements; import lombok.extern.slf4j.Slf4j; +import org.apache.commons.io.filefilter.MagicNumberFileFilter; +import org.apache.commons.io.filefilter.SuffixFileFilter; +import org.cubewhy.celestial.Celestial; import org.cubewhy.celestial.game.BaseAddon; import org.cubewhy.celestial.game.addon.JavaAgent; import org.cubewhy.celestial.game.addon.LunarCNMod; import org.cubewhy.celestial.game.addon.WeaveMod; import org.cubewhy.celestial.gui.GuiLauncher; +import org.cubewhy.celestial.utils.TextUtils; import org.jetbrains.annotations.NotNull; import javax.swing.*; import javax.swing.border.TitledBorder; +import javax.swing.filechooser.FileNameExtensionFilter; import java.awt.*; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; +import java.io.File; +import java.io.IOException; import static org.cubewhy.celestial.Celestial.f; @@ -52,7 +59,9 @@ private void initGui() { JPopupMenu agentMenu = new JPopupMenu(); JMenuItem manageArg = new JMenuItem(f.getString("gui.addon.agents.arg")); JMenuItem removeAgent = new JMenuItem(f.getString("gui.addon.agents.remove")); + JMenuItem renameAgent = new JMenuItem(f.getString("gui.addon.rename")); agentMenu.add(manageArg); + agentMenu.add(renameAgent); agentMenu.addSeparator(); agentMenu.add(removeAgent); @@ -72,6 +81,28 @@ private void initGui() { } }); + removeAgent.addActionListener(e -> { + JavaAgent currentAgent = listAgents.getSelectedValue(); + String name = currentAgent.getFile().getName(); + if (JOptionPane.showConfirmDialog(this, String.format(f.getString("gui.addon.agents.remove.confirm.message"), name), f.getString("gui.addon.agents.remove.confirm.title"), JOptionPane.OK_CANCEL_OPTION) == JOptionPane.OK_OPTION && currentAgent.getFile().delete()) { + GuiLauncher.statusBar.setText(String.format(f.getString("gui.addon.agents.remove.success"), name)); + } + agents.clear(); + loadAgents(agents); + }); + + renameAgent.addActionListener(e -> { + JavaAgent currentAgent = listAgents.getSelectedValue(); + File file = currentAgent.getFile(); + String name = file.getName(); + String newName = JOptionPane.showInputDialog(this, f.getString("gui.addon.rename.dialog.message"), name.substring(0, name.length() - 4)); + if (newName != null && file.renameTo(new File(file.getParentFile(), newName + ".jar"))) { + GuiLauncher.statusBar.setText(String.format(f.getString("gui.addon.rename.success"), newName)); + agents.clear(); + loadAgents(agents); + } + }); + JPopupMenu weaveMenu = new JPopupMenu(); JMenuItem removeWeaveMod = new JMenuItem(f.getString("gui.addon.mods.weave.remove")); weaveMenu.add(removeWeaveMod); @@ -91,6 +122,28 @@ private void initGui() { JButton btnAddAgent = new JButton(f.getString("gui.addon.agents.add")); // TODO Stretch to the right + btnAddAgent.addActionListener(e -> { + FileDialog fileDialog = new FileDialog(Celestial.launcherFrame, "Choosing a file", FileDialog.LOAD); + fileDialog.setFilenameFilter(new SuffixFileFilter("jar")); // jar + fileDialog.setVisible(true); + File file = new File(fileDialog.getDirectory(), fileDialog.getFile()); + String arg = JOptionPane.showInputDialog(this, f.getString("gui.addon.agents.add.arg")); + try { + if (JavaAgent.add(file, arg)) { + // success + GuiLauncher.statusBar.setText(f.getString("gui.addon.agents.add.success")); + agents.clear(); + loadAgents(agents); + } else { + JOptionPane.showMessageDialog(this, f.getString("gui.addon.agents.add.failure.exists"), "Error", JOptionPane.ERROR_MESSAGE); + } + } catch (IOException ex) { + String trace = TextUtils.dumpTrace(ex); + log.error(trace); + JOptionPane.showMessageDialog(this, String.format(f.getString("gui.addon.agents.add.failure.io"), trace), "Error", JOptionPane.ERROR_MESSAGE); + } + }); + // panels final JPanel panelLunarCN = new JPanel(); panelLunarCN.setLayout(new BoxLayout(panelLunarCN, BoxLayout.Y_AXIS)); @@ -112,9 +165,9 @@ private void initGui() { this.add(tab); } - private static void loadAgents(DefaultListModel agents) { + private static void loadAgents(DefaultListModel agentsList) { for (JavaAgent javaAgent : JavaAgent.findAll()) { - agents.addElement(javaAgent); + agentsList.addElement(javaAgent); } } diff --git a/src/main/java/org/cubewhy/celestial/gui/pages/GuiNews.java b/src/main/java/org/cubewhy/celestial/gui/pages/GuiNews.java index 0610a09f..02bfae26 100644 --- a/src/main/java/org/cubewhy/celestial/gui/pages/GuiNews.java +++ b/src/main/java/org/cubewhy/celestial/gui/pages/GuiNews.java @@ -10,10 +10,8 @@ import javax.swing.*; import javax.swing.border.TitledBorder; - import java.awt.*; import java.io.IOException; -import java.net.MalformedURLException; import java.net.URL; import static org.cubewhy.celestial.Celestial.f; @@ -35,15 +33,19 @@ public GuiNews() throws IOException { private void initGui() throws IOException { // render blogPosts log.info("Loading blogPosts (gui)"); - log.info(String.valueOf(blogPosts)); - for (JsonElement blogPost : blogPosts) { - // cache the image if the image of the news isn't exist - JsonObject json = blogPost.getAsJsonObject(); - String imageURL = json.get("image").getAsString(); - String title = json.get("title").getAsString(); - if (DownloadManager.cache(new URL(imageURL), "news/" + title + ".png", false)) { - // load - panel.add(new LauncherNews(json)); + if (blogPosts.isJsonNull()) { + log.error("Failed to load blog posts"); + this.add(new JLabel("Failed to load news (blogPosts is null)")); + } else { + for (JsonElement blogPost : blogPosts) { + // cache the image if the image of the news doesn't exist + JsonObject json = blogPost.getAsJsonObject(); + String imageURL = json.get("image").getAsString(); + String title = json.get("title").getAsString(); + if (DownloadManager.cache(new URL(imageURL), "news/" + title + ".png", false)) { + // load + panel.add(new LauncherNews(json)); + } } } } diff --git a/src/main/resources/languages/launcher.properties b/src/main/resources/languages/launcher.properties index 039a82f2..d6d5db6f 100644 --- a/src/main/resources/languages/launcher.properties +++ b/src/main/resources/languages/launcher.properties @@ -89,4 +89,23 @@ gui.addon.agents.arg.message=Please enter the new JavaAgent parameters below gui.addon.agents.arg.title=Adjustment parameters gui.addon.agents.success=Add successful gui.addon.agents.arg.set.success=The parameter of %s has been set to %s -gui.addon.agents.arg.remove.success=Parameters of %s have been removed \ No newline at end of file +gui.addon.agents.arg.remove.success=Parameters of %s have been removed +gui.addon.agents.remove.success=%s removed successfully +gui.addon.agents.remove.confirm.message=Confirm removal of %s +gui.addon.agents.remove.confirm.title=Confirm removal of Agent +gui.addon.rename.dialog.message=Enter the new name (no need to add .jar in the end) +gui.addon.rename=Rename +gui.addon.rename.success=Renamed successful +gui.addon.agents.add.arg=Agent parameters (leave blank if not set) +gui.addon.agents.add.failure.exists=Failed to add agent\ +\n\ +Reason: File already exists +gui.addon.agents.add.success=Agent added successfully! +gui.addon.agents.add.failure.io=Failed to add agent\ +\n\ +Reason: IO error\ +\n\ +If necessary, you can take a screenshot of this page and send it to the developer.\ +\n\ +Log:\ +\n%s \ 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 4f5cf4e6..89edfcb7 100644 --- a/src/main/resources/languages/launcher_zh.properties +++ b/src/main/resources/languages/launcher_zh.properties @@ -89,3 +89,21 @@ gui.addon.agents.arg.title=参数管理 gui.addon.agents.success=添加成功 gui.addon.agents.arg.set.success=%s的参数已设置为%s gui.addon.agents.arg.remove.success=已移除%s的参数 +gui.addon.agents.remove.success=已成功移除%s +gui.addon.agents.remove.confirm.message=确认移除%s +gui.addon.agents.remove.confirm.title=确认移除Agent +gui.addon.rename.dialog.message=输入新名称(不用加.jar) +gui.addon.rename=重命名 +gui.addon.rename.success=重命名成功 +gui.addon.agents.add.arg=助理参数(若不设置请留空) +gui.addon.agents.add.failure.exists=添加助理失败\ +\n\ +原因: 文件已存在 +gui.addon.agents.add.success=添加助理成功! +gui.addon.agents.add.failure.io=添加助理失败\ +\n\ +原因: IO错误\ +\n\ +必要情况下可截图此页面给开发者\ +\n\ +\n%s From fa85d5a444b09f39cc36bc13e911477d4ea13fed Mon Sep 17 00:00:00 2001 From: cubewhy Date: Sun, 31 Dec 2023 11:03:02 +0800 Subject: [PATCH 12/42] migrate arg when rename --- src/main/java/org/cubewhy/celestial/Celestial.java | 11 ++++++++++- .../cubewhy/celestial/game/addon/JavaAgent.java | 14 ++++++++++++++ .../celestial/gui/elements/GuiAddonManager.java | 3 +++ .../cubewhy/celestial/gui/pages/GuiSettings.java | 2 +- src/main/resources/languages/launcher.properties | 3 ++- .../resources/languages/launcher_zh.properties | 1 + 6 files changed, 31 insertions(+), 3 deletions(-) diff --git a/src/main/java/org/cubewhy/celestial/Celestial.java b/src/main/java/org/cubewhy/celestial/Celestial.java index 8531b85c..94a237dd 100644 --- a/src/main/java/org/cubewhy/celestial/Celestial.java +++ b/src/main/java/org/cubewhy/celestial/Celestial.java @@ -40,6 +40,7 @@ public class Celestial { public static final File configDir = new File(System.getProperty("user.home"), ".cubewhy/lunarcn"); + public static final File themesDir = new File(configDir, "themes"); public static final ConfigFile config = new ConfigFile(new File(configDir, "celestial.json")); public static Locale locale; public static String userLanguage; @@ -206,6 +207,14 @@ public static void initLauncher() throws IOException { } private static void initConfig() { + // init dirs + if (configDir.mkdirs()) { + log.info("Making config dir"); + } + if (themesDir.mkdirs()) { + log.info("Making themes dir"); + } + // init config JsonObject resize = new JsonObject(); resize.addProperty("width", 854); resize.addProperty("height", 480); @@ -267,7 +276,7 @@ public static void initTheme() throws IOException { themed = false; } default -> { - File themeFile = new File(configDir, "themes/" + themeType); + File themeFile = new File(themesDir, themeType); if (!themeFile.exists()) { // cannot load custom theme without theme.json JOptionPane.showMessageDialog(null, f.getString("theme.custom.notfound.message"), f.getString("theme.custom.notfound.title"), JOptionPane.WARNING_MESSAGE); diff --git a/src/main/java/org/cubewhy/celestial/game/addon/JavaAgent.java b/src/main/java/org/cubewhy/celestial/game/addon/JavaAgent.java index eabf30b9..ae4d3ee9 100644 --- a/src/main/java/org/cubewhy/celestial/game/addon/JavaAgent.java +++ b/src/main/java/org/cubewhy/celestial/game/addon/JavaAgent.java @@ -149,6 +149,20 @@ public static boolean add(@NotNull File file, String arg) throws IOException { return true; } + /** + * Migrate the arg of an agent + * + * @param old name of the old agent + * @param n3w name of the new agent + * */ + public static void migrate(String old, String n3w) { + JsonObject ja = config.getValue("javaagents").getAsJsonObject(); + String arg = ja.get(old).getAsString(); + ja.addProperty(n3w, arg); // leave empty + ja.remove(old); + config.setValue("javaagents", ja); // dump + } + /** * Get args which add to the jvm diff --git a/src/main/java/org/cubewhy/celestial/gui/elements/GuiAddonManager.java b/src/main/java/org/cubewhy/celestial/gui/elements/GuiAddonManager.java index 61e3bcfa..c42166da 100644 --- a/src/main/java/org/cubewhy/celestial/gui/elements/GuiAddonManager.java +++ b/src/main/java/org/cubewhy/celestial/gui/elements/GuiAddonManager.java @@ -97,7 +97,10 @@ private void initGui() { String name = file.getName(); String newName = JOptionPane.showInputDialog(this, f.getString("gui.addon.rename.dialog.message"), name.substring(0, name.length() - 4)); if (newName != null && file.renameTo(new File(file.getParentFile(), newName + ".jar"))) { + log.info(String.format("Rename agent %s -> %s", name, newName + ".jar")); GuiLauncher.statusBar.setText(String.format(f.getString("gui.addon.rename.success"), newName)); + // rename the name in the config + JavaAgent.migrate(name, newName + ".jar"); agents.clear(); loadAgents(agents); } diff --git a/src/main/java/org/cubewhy/celestial/gui/pages/GuiSettings.java b/src/main/java/org/cubewhy/celestial/gui/pages/GuiSettings.java index f547f1f8..3cb328ab 100644 --- a/src/main/java/org/cubewhy/celestial/gui/pages/GuiSettings.java +++ b/src/main/java/org/cubewhy/celestial/gui/pages/GuiSettings.java @@ -8,7 +8,7 @@ public class GuiSettings extends JPanel { public GuiSettings() { - this.setBorder(new TitledBorder(null, f.getString("gui.version.title"), TitledBorder.DEFAULT_JUSTIFICATION, TitledBorder.DEFAULT_POSITION, null, Color.orange)); + this.setBorder(new TitledBorder(null, f.getString("gui.settings.title"), TitledBorder.DEFAULT_JUSTIFICATION, TitledBorder.DEFAULT_POSITION, null, Color.orange)); this.setLayout(new GridLayout(3, 3, 5, 5)); this.initGui(); } diff --git a/src/main/resources/languages/launcher.properties b/src/main/resources/languages/launcher.properties index d6d5db6f..87096940 100644 --- a/src/main/resources/languages/launcher.properties +++ b/src/main/resources/languages/launcher.properties @@ -108,4 +108,5 @@ Reason: IO error\ If necessary, you can take a screenshot of this page and send it to the developer.\ \n\ Log:\ -\n%s \ No newline at end of file +\n%s +gui.settings.title=Settings \ 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 89edfcb7..ec5e5904 100644 --- a/src/main/resources/languages/launcher_zh.properties +++ b/src/main/resources/languages/launcher_zh.properties @@ -107,3 +107,4 @@ gui.addon.agents.add.failure.io=添加助理失败\ 必要情况下可截图此页面给开发者\ \n\ \n%s +gui.settings.title=游戏设置 From a907a5a616f77d59ae1078cc4dd1dda9fae3390d Mon Sep 17 00:00:00 2001 From: cubewhy Date: Sun, 31 Dec 2023 11:08:10 +0800 Subject: [PATCH 13/42] AddonAddEvent --- .../celestial/event/impl/AddonAddEvent.java | 30 +++++++++++++++++++ .../celestial/game/addon/JavaAgent.java | 6 ++-- .../gui/elements/GuiAddonManager.java | 5 +++- .../resources/languages/launcher.properties | 2 +- .../languages/launcher_zh.properties | 3 +- 5 files changed, 40 insertions(+), 6 deletions(-) create mode 100644 src/main/java/org/cubewhy/celestial/event/impl/AddonAddEvent.java diff --git a/src/main/java/org/cubewhy/celestial/event/impl/AddonAddEvent.java b/src/main/java/org/cubewhy/celestial/event/impl/AddonAddEvent.java new file mode 100644 index 00000000..c4139dc1 --- /dev/null +++ b/src/main/java/org/cubewhy/celestial/event/impl/AddonAddEvent.java @@ -0,0 +1,30 @@ +/* + * Celestial Launcher + * License under GPLv3 + * Do NOT remove this note if you want to copy this file. + */ + +package org.cubewhy.celestial.event.impl; + +import org.cubewhy.celestial.event.Event; +import org.cubewhy.celestial.game.BaseAddon; + +import java.io.File; + +public class AddonAddEvent extends Event { + + public final Type type; + public final BaseAddon addon; + + public enum Type { + JAVAAGENT, + WEAVE, + LUNARCN; + } + + public AddonAddEvent(Type type, BaseAddon addon) { + this.type = type; + this.addon = addon; + } + +} diff --git a/src/main/java/org/cubewhy/celestial/game/addon/JavaAgent.java b/src/main/java/org/cubewhy/celestial/game/addon/JavaAgent.java index ae4d3ee9..00340005 100644 --- a/src/main/java/org/cubewhy/celestial/game/addon/JavaAgent.java +++ b/src/main/java/org/cubewhy/celestial/game/addon/JavaAgent.java @@ -133,20 +133,20 @@ public static String findAgentArg(String name) { return ja.get(name).getAsString(); } - public static boolean add(@NotNull File file, String arg) throws IOException { + public static JavaAgent add(@NotNull File file, String arg) throws IOException { String name = file.getName(); if (!name.endsWith(".jar")) { name += ".jar"; // adds an ends with for the file } File target = new File(javaAgentFolder, name); if (target.exists()) { - return false; + return null; } FileUtils.copyFile(file, target); if (arg != null) { setArgFor(file.getName(), arg); } - return true; + return new JavaAgent(file, arg); } /** diff --git a/src/main/java/org/cubewhy/celestial/gui/elements/GuiAddonManager.java b/src/main/java/org/cubewhy/celestial/gui/elements/GuiAddonManager.java index c42166da..bce0d80c 100644 --- a/src/main/java/org/cubewhy/celestial/gui/elements/GuiAddonManager.java +++ b/src/main/java/org/cubewhy/celestial/gui/elements/GuiAddonManager.java @@ -10,6 +10,7 @@ import org.apache.commons.io.filefilter.MagicNumberFileFilter; import org.apache.commons.io.filefilter.SuffixFileFilter; import org.cubewhy.celestial.Celestial; +import org.cubewhy.celestial.event.impl.AddonAddEvent; import org.cubewhy.celestial.game.BaseAddon; import org.cubewhy.celestial.game.addon.JavaAgent; import org.cubewhy.celestial.game.addon.LunarCNMod; @@ -132,8 +133,10 @@ private void initGui() { File file = new File(fileDialog.getDirectory(), fileDialog.getFile()); String arg = JOptionPane.showInputDialog(this, f.getString("gui.addon.agents.add.arg")); try { - if (JavaAgent.add(file, arg)) { + JavaAgent agent = JavaAgent.add(file, arg); + if (agent != null) { // success + new AddonAddEvent(AddonAddEvent.Type.JAVAAGENT, agent); GuiLauncher.statusBar.setText(f.getString("gui.addon.agents.add.success")); agents.clear(); loadAgents(agents); diff --git a/src/main/resources/languages/launcher.properties b/src/main/resources/languages/launcher.properties index 87096940..fe682989 100644 --- a/src/main/resources/languages/launcher.properties +++ b/src/main/resources/languages/launcher.properties @@ -85,7 +85,7 @@ gui.addon.mods.weave.remove=Delete gui.addon.mods.cn.remove=Delete gui.addon.mods.add=Add a mod gui.addon.agents.add=Add a agent -gui.addon.agents.arg.message=Please enter the new JavaAgent parameters below +gui.addon.agents.arg.message=Please enter the new JavaAgent parameters below (leave blank to remove) gui.addon.agents.arg.title=Adjustment parameters gui.addon.agents.success=Add successful gui.addon.agents.arg.set.success=The parameter of %s has been set to %s diff --git a/src/main/resources/languages/launcher_zh.properties b/src/main/resources/languages/launcher_zh.properties index ec5e5904..c77ac161 100644 --- a/src/main/resources/languages/launcher_zh.properties +++ b/src/main/resources/languages/launcher_zh.properties @@ -84,7 +84,7 @@ gui.addon.mods.weave.remove=删除Mod gui.addon.mods.cn.remove=删除Mod gui.addon.mods.add=添加模组 gui.addon.agents.add=添加助理 -gui.addon.agents.arg.message=请在下方输入新的JavaAgent参数 +gui.addon.agents.arg.message=请在下方输入新的JavaAgent参数(移除请留空) gui.addon.agents.arg.title=参数管理 gui.addon.agents.success=添加成功 gui.addon.agents.arg.set.success=%s的参数已设置为%s @@ -106,5 +106,6 @@ gui.addon.agents.add.failure.io=添加助理失败\ \n\ 必要情况下可截图此页面给开发者\ \n\ +Log:\ \n%s gui.settings.title=游戏设置 From 4eabc0af9f6c98c7f07ac51a28dd0b16fa7f61e5 Mon Sep 17 00:00:00 2001 From: cubewhy Date: Sun, 31 Dec 2023 11:13:12 +0800 Subject: [PATCH 14/42] remove some useless translation --- src/main/resources/languages/launcher.properties | 2 -- src/main/resources/languages/launcher_zh.properties | 2 -- 2 files changed, 4 deletions(-) diff --git a/src/main/resources/languages/launcher.properties b/src/main/resources/languages/launcher.properties index fe682989..e6e29368 100644 --- a/src/main/resources/languages/launcher.properties +++ b/src/main/resources/languages/launcher.properties @@ -86,8 +86,6 @@ gui.addon.mods.cn.remove=Delete gui.addon.mods.add=Add a mod gui.addon.agents.add=Add a agent gui.addon.agents.arg.message=Please enter the new JavaAgent parameters below (leave blank to remove) -gui.addon.agents.arg.title=Adjustment parameters -gui.addon.agents.success=Add successful gui.addon.agents.arg.set.success=The parameter of %s has been set to %s gui.addon.agents.arg.remove.success=Parameters of %s have been removed gui.addon.agents.remove.success=%s removed successfully diff --git a/src/main/resources/languages/launcher_zh.properties b/src/main/resources/languages/launcher_zh.properties index c77ac161..c1cac8ae 100644 --- a/src/main/resources/languages/launcher_zh.properties +++ b/src/main/resources/languages/launcher_zh.properties @@ -85,8 +85,6 @@ gui.addon.mods.cn.remove=删除Mod gui.addon.mods.add=添加模组 gui.addon.agents.add=添加助理 gui.addon.agents.arg.message=请在下方输入新的JavaAgent参数(移除请留空) -gui.addon.agents.arg.title=参数管理 -gui.addon.agents.success=添加成功 gui.addon.agents.arg.set.success=%s的参数已设置为%s gui.addon.agents.arg.remove.success=已移除%s的参数 gui.addon.agents.remove.success=已成功移除%s From 0dfcf5f701eb97a768f7e9958e0293eeb553dcdd Mon Sep 17 00:00:00 2001 From: cubewhy Date: Sun, 31 Dec 2023 11:33:22 +0800 Subject: [PATCH 15/42] correct words --- src/main/resources/languages/launcher.properties | 2 +- src/main/resources/languages/launcher_zh.properties | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/resources/languages/launcher.properties b/src/main/resources/languages/launcher.properties index e6e29368..04a04ee0 100644 --- a/src/main/resources/languages/launcher.properties +++ b/src/main/resources/languages/launcher.properties @@ -29,7 +29,7 @@ Necessary information (still sent after disabled)\ \n\ - your system information (used to find dependent libraries)\n\ \n\ -We strongly urge you to enable this feature (if you are a computer noob), but if you do not agree to share, we will not send any information to the server +We strongly urge you to enable this feature (if you are a computer noob), but if you do not agree to share, we will not send any optional information to the server gui.news.title=News gui.about.title=About trace.unzip-natives=Is game launched? Failed to unzip natives. diff --git a/src/main/resources/languages/launcher_zh.properties b/src/main/resources/languages/launcher_zh.properties index c1cac8ae..eabe871e 100644 --- a/src/main/resources/languages/launcher_zh.properties +++ b/src/main/resources/languages/launcher_zh.properties @@ -31,7 +31,7 @@ Celestial会发送如下信息\ \n\ - 你的系统信息 (用于查找依赖库)\n\ \n\ -我们强烈你开启这个功能(如果你是电脑小白), 但如果你不同意分享, 我们将不会发送任何信息到服务器 +我们强烈你开启这个功能(如果你是电脑小白), 但如果你不同意分享, 我们将不会发送任何可选信息到服务器 gui.news.title=赛博报纸 gui.about.title=关于 trace.unzip-natives=在解压Natives是发生了错误,游戏启动过了? From efcee0c1ae4925b60afe7b5d3e48525a42a61022 Mon Sep 17 00:00:00 2001 From: cubewhy Date: Sun, 31 Dec 2023 14:46:50 +0800 Subject: [PATCH 16/42] add mod --- .../org/cubewhy/celestial/game/BaseAddon.java | 22 +++- .../celestial/game/addon/JavaAgent.java | 20 ++-- .../celestial/game/addon/LunarCNMod.java | 2 +- .../celestial/game/addon/WeaveMod.java | 14 ++- .../gui/elements/GuiAddonManager.java | 102 +++++++++++++++--- .../org/cubewhy/celestial/utils/GuiUtils.java | 27 +++++ .../resources/languages/launcher.properties | 11 +- .../languages/launcher_zh.properties | 7 ++ 8 files changed, 168 insertions(+), 37 deletions(-) create mode 100644 src/main/java/org/cubewhy/celestial/utils/GuiUtils.java diff --git a/src/main/java/org/cubewhy/celestial/game/BaseAddon.java b/src/main/java/org/cubewhy/celestial/game/BaseAddon.java index 2c6f64e9..9b371214 100644 --- a/src/main/java/org/cubewhy/celestial/game/BaseAddon.java +++ b/src/main/java/org/cubewhy/celestial/game/BaseAddon.java @@ -6,12 +6,30 @@ package org.cubewhy.celestial.game; +import org.apache.commons.io.FileUtils; import org.jetbrains.annotations.Contract; import org.jetbrains.annotations.Nullable; -public interface BaseAddon { +import java.io.File; +import java.io.IOException; +import java.util.List; + +public abstract class BaseAddon { @Contract(pure = true) - static BaseAddon @Nullable [] findAll() { + public static List findAll() { return null; } + + protected static File autoCopy(File file, File folder) throws IOException { + String name = file.getName(); + if (!name.endsWith(".jar")) { + name += ".jar"; // adds an ends with for the file + } + File target = new File(folder, name); + if (target.exists()) { + return null; + } + FileUtils.copyFile(file, target); + return target; + } } diff --git a/src/main/java/org/cubewhy/celestial/game/addon/JavaAgent.java b/src/main/java/org/cubewhy/celestial/game/addon/JavaAgent.java index 00340005..7b073180 100644 --- a/src/main/java/org/cubewhy/celestial/game/addon/JavaAgent.java +++ b/src/main/java/org/cubewhy/celestial/game/addon/JavaAgent.java @@ -9,10 +9,10 @@ import com.google.gson.JsonObject; import lombok.Getter; import lombok.extern.slf4j.Slf4j; -import org.apache.commons.io.FileUtils; import org.cubewhy.celestial.game.BaseAddon; import org.jetbrains.annotations.Contract; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import java.io.File; import java.io.IOException; @@ -25,7 +25,7 @@ @Getter @Slf4j -public class JavaAgent implements BaseAddon { +public class JavaAgent extends BaseAddon { public static final File javaAgentFolder = new File(configDir, "javaagents"); // share with LunarCN Launcher static { @@ -133,20 +133,12 @@ public static String findAgentArg(String name) { return ja.get(name).getAsString(); } - public static JavaAgent add(@NotNull File file, String arg) throws IOException { - String name = file.getName(); - if (!name.endsWith(".jar")) { - name += ".jar"; // adds an ends with for the file - } - File target = new File(javaAgentFolder, name); - if (target.exists()) { - return null; - } - FileUtils.copyFile(file, target); + public static @Nullable JavaAgent add(@NotNull File file, String arg) throws IOException { + File target = autoCopy(file, javaAgentFolder); if (arg != null) { setArgFor(file.getName(), arg); } - return new JavaAgent(file, arg); + return (target == null) ? null : new JavaAgent(target, arg); } /** @@ -154,7 +146,7 @@ public static JavaAgent add(@NotNull File file, String arg) throws IOException { * * @param old name of the old agent * @param n3w name of the new agent - * */ + */ public static void migrate(String old, String n3w) { JsonObject ja = config.getValue("javaagents").getAsJsonObject(); String arg = ja.get(old).getAsString(); 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 e9f2d17d..0c4262bf 100644 --- a/src/main/java/org/cubewhy/celestial/game/addon/LunarCNMod.java +++ b/src/main/java/org/cubewhy/celestial/game/addon/LunarCNMod.java @@ -18,7 +18,7 @@ import java.util.Objects; @Getter -public class LunarCNMod implements BaseAddon { +public class LunarCNMod extends BaseAddon { public static final File modFolder = new File(Celestial.configDir, "mods"); private final File file; 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 8791f727..d6dbd5ef 100644 --- a/src/main/java/org/cubewhy/celestial/game/addon/WeaveMod.java +++ b/src/main/java/org/cubewhy/celestial/game/addon/WeaveMod.java @@ -10,14 +10,16 @@ import org.cubewhy.celestial.game.BaseAddon; import org.jetbrains.annotations.Contract; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import java.io.File; +import java.io.IOException; import java.util.ArrayList; import java.util.List; import java.util.Objects; @Getter -public class WeaveMod implements BaseAddon { +public class WeaveMod extends BaseAddon { public static final File modFolder = new File(System.getProperty("user.home"), ".weave/mods"); private final File file; @@ -41,4 +43,14 @@ public static List findAll() { } return list; } + + public static @Nullable WeaveMod add(@NotNull File file) throws IOException { + File target = autoCopy(file, modFolder); + return (target == null) ? null : new WeaveMod(target); + } + + @Override + public String toString() { + return this.file.getName(); + } } diff --git a/src/main/java/org/cubewhy/celestial/gui/elements/GuiAddonManager.java b/src/main/java/org/cubewhy/celestial/gui/elements/GuiAddonManager.java index bce0d80c..0e70c09a 100644 --- a/src/main/java/org/cubewhy/celestial/gui/elements/GuiAddonManager.java +++ b/src/main/java/org/cubewhy/celestial/gui/elements/GuiAddonManager.java @@ -7,7 +7,6 @@ package org.cubewhy.celestial.gui.elements; import lombok.extern.slf4j.Slf4j; -import org.apache.commons.io.filefilter.MagicNumberFileFilter; import org.apache.commons.io.filefilter.SuffixFileFilter; import org.cubewhy.celestial.Celestial; import org.cubewhy.celestial.event.impl.AddonAddEvent; @@ -16,12 +15,12 @@ import org.cubewhy.celestial.game.addon.LunarCNMod; import org.cubewhy.celestial.game.addon.WeaveMod; import org.cubewhy.celestial.gui.GuiLauncher; +import org.cubewhy.celestial.utils.GuiUtils; import org.cubewhy.celestial.utils.TextUtils; import org.jetbrains.annotations.NotNull; import javax.swing.*; import javax.swing.border.TitledBorder; -import javax.swing.filechooser.FileNameExtensionFilter; import java.awt.*; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; @@ -47,9 +46,7 @@ private void initGui() { DefaultListModel agents = new DefaultListModel<>(); // load items loadAgents(agents); - for (WeaveMod weaveMod : WeaveMod.findAll()) { - weave.addElement(weaveMod); - } + loadWeaveMods(weave); for (LunarCNMod lunarCNMod : LunarCNMod.findAll()) { lunarCN.addElement(lunarCNMod); } @@ -87,9 +84,9 @@ private void initGui() { String name = currentAgent.getFile().getName(); if (JOptionPane.showConfirmDialog(this, String.format(f.getString("gui.addon.agents.remove.confirm.message"), name), f.getString("gui.addon.agents.remove.confirm.title"), JOptionPane.OK_CANCEL_OPTION) == JOptionPane.OK_OPTION && currentAgent.getFile().delete()) { GuiLauncher.statusBar.setText(String.format(f.getString("gui.addon.agents.remove.success"), name)); + agents.clear(); + loadAgents(agents); } - agents.clear(); - loadAgents(agents); }); renameAgent.addActionListener(e -> { @@ -107,17 +104,59 @@ private void initGui() { } }); + // weave menu JPopupMenu weaveMenu = new JPopupMenu(); + JMenuItem renameWeaveMod = new JMenuItem(f.getString("gui.addon.rename")); JMenuItem removeWeaveMod = new JMenuItem(f.getString("gui.addon.mods.weave.remove")); + weaveMenu.add(renameWeaveMod); + weaveMenu.addSeparator(); weaveMenu.add(removeWeaveMod); + renameWeaveMod.addActionListener(e -> { + WeaveMod currentMod = listWeave.getSelectedValue(); + File file = currentMod.getFile(); + String name = file.getName(); + String newName = JOptionPane.showInputDialog(this, f.getString("gui.addon.rename.dialog.message"), name.substring(0, name.length() - 4)); + if (newName != null && file.renameTo(new File(file.getParentFile(), newName + ".jar"))) { + log.info(String.format("Rename weave mod %s -> %s", name, newName + ".jar")); + GuiLauncher.statusBar.setText(String.format(f.getString("gui.addon.rename.success"), newName)); + weave.clear(); + loadWeaveMods(weave); + } + }); + + removeWeaveMod.addActionListener(e -> { + WeaveMod currentMod = listWeave.getSelectedValue(); + String name = currentMod.getFile().getName(); + if (JOptionPane.showConfirmDialog(this, String.format(f.getString("gui.addon.mods.weave.remove.confirm.message"), name), f.getString("gui.addon.mods.weave.remove.confirm.title"), JOptionPane.OK_CANCEL_OPTION) == JOptionPane.OK_OPTION && currentMod.getFile().delete()) { + GuiLauncher.statusBar.setText(String.format(f.getString("gui.addon.mods.weave.remove.success"), name)); + weave.clear(); + loadWeaveMods(weave); + } + }); + JPopupMenu lunarCNMenu = new JPopupMenu(); + JMenuItem renameLunarCNMod = new JMenuItem(f.getString("gui.addon.rename")); JMenuItem removeLunarCNMod = new JMenuItem(f.getString("gui.addon.mods.cn.remove")); + lunarCNMenu.add(renameLunarCNMod); + lunarCNMenu.addSeparator(); lunarCNMenu.add(removeLunarCNMod); + + renameLunarCNMod.addActionListener(e -> { + LunarCNMod currentMod = listLunarCN.getSelectedValue(); + File file = currentMod.getFile(); + String name = file.getName(); + String newName = JOptionPane.showInputDialog(this, f.getString("gui.addon.rename.dialog.message"), name.substring(0, name.length() - 4)); + if (newName != null && file.renameTo(new File(file.getParentFile(), newName + ".jar"))) { + log.info(String.format("Rename LunarCN mod %s -> %s", name, newName + ".jar")); + GuiLauncher.statusBar.setText(String.format(f.getString("gui.addon.rename.success"), newName)); + } + }); + // bind menus - bingMenu(listLunarCN, lunarCNMenu); - bingMenu(listWeave, weaveMenu); - bingMenu(listAgents, agentMenu); + bindMenu(listLunarCN, lunarCNMenu); + bindMenu(listWeave, weaveMenu); + bindMenu(listAgents, agentMenu); // buttons @@ -127,10 +166,10 @@ private void initGui() { // TODO Stretch to the right btnAddAgent.addActionListener(e -> { - FileDialog fileDialog = new FileDialog(Celestial.launcherFrame, "Choosing a file", FileDialog.LOAD); - fileDialog.setFilenameFilter(new SuffixFileFilter("jar")); // jar - fileDialog.setVisible(true); - File file = new File(fileDialog.getDirectory(), fileDialog.getFile()); + File file = GuiUtils.chooseFile(new SuffixFileFilter(".jar")); + if (file == null) { + return; + } String arg = JOptionPane.showInputDialog(this, f.getString("gui.addon.agents.add.arg")); try { JavaAgent agent = JavaAgent.add(file, arg); @@ -150,6 +189,29 @@ private void initGui() { } }); + btnAddWeaveMod.addActionListener(e -> { + File file = GuiUtils.chooseFile(new SuffixFileFilter(".jar")); + if (file == null) { + return; + } + try { + WeaveMod mod = WeaveMod.add(file); + if (mod != null) { + // success + new AddonAddEvent(AddonAddEvent.Type.WEAVE, mod); + GuiLauncher.statusBar.setText(f.getString("gui.addon.mods.weave.add.success")); + weave.clear(); + loadWeaveMods(weave); + } else { + JOptionPane.showMessageDialog(this, f.getString("gui.addon.mods.weave.add.failure.exists"), "Error", JOptionPane.ERROR_MESSAGE); + } + } catch (IOException ex) { + String trace = TextUtils.dumpTrace(ex); + log.error(trace); + JOptionPane.showMessageDialog(this, String.format(f.getString("gui.addon.mods.weave.add.failure.io"), trace), "Error", JOptionPane.ERROR_MESSAGE); + } + }); + // panels final JPanel panelLunarCN = new JPanel(); panelLunarCN.setLayout(new BoxLayout(panelLunarCN, BoxLayout.Y_AXIS)); @@ -171,13 +233,19 @@ private void initGui() { this.add(tab); } - private static void loadAgents(DefaultListModel agentsList) { + private static void loadWeaveMods(DefaultListModel weave) { + for (WeaveMod weaveMod : WeaveMod.findAll()) { + weave.addElement(weaveMod); + } + } + + private static void loadAgents(DefaultListModel agentList) { for (JavaAgent javaAgent : JavaAgent.findAll()) { - agentsList.addElement(javaAgent); + agentList.addElement(javaAgent); } } - private void bingMenu(@NotNull JList list, JPopupMenu menu) { + private void bindMenu(@NotNull JList list, JPopupMenu menu) { list.addMouseListener(new MouseAdapter() { @Override public void mouseClicked(MouseEvent e) { diff --git a/src/main/java/org/cubewhy/celestial/utils/GuiUtils.java b/src/main/java/org/cubewhy/celestial/utils/GuiUtils.java new file mode 100644 index 00000000..ce5d2007 --- /dev/null +++ b/src/main/java/org/cubewhy/celestial/utils/GuiUtils.java @@ -0,0 +1,27 @@ +/* + * Celestial Launcher + * License under GPLv3 + * Do NOT remove this note if you want to copy this file. + */ + +package org.cubewhy.celestial.utils; + +import org.apache.commons.io.filefilter.AbstractFileFilter; +import org.apache.commons.io.filefilter.SuffixFileFilter; +import org.cubewhy.celestial.Celestial; +import org.jetbrains.annotations.Nullable; + +import java.awt.*; +import java.io.File; + +public final class GuiUtils { + private GuiUtils() { + } + + public static @Nullable File chooseFile(AbstractFileFilter filter) { + FileDialog fileDialog = new FileDialog(Celestial.launcherFrame, "Choosing a file", FileDialog.LOAD); + fileDialog.setFilenameFilter(filter); // jar + fileDialog.setVisible(true); + return (fileDialog.getFile() == null) ? null : new File(fileDialog.getDirectory(), fileDialog.getFile()); + } +} diff --git a/src/main/resources/languages/launcher.properties b/src/main/resources/languages/launcher.properties index 04a04ee0..518b167f 100644 --- a/src/main/resources/languages/launcher.properties +++ b/src/main/resources/languages/launcher.properties @@ -29,7 +29,7 @@ Necessary information (still sent after disabled)\ \n\ - your system information (used to find dependent libraries)\n\ \n\ -We strongly urge you to enable this feature (if you are a computer noob), but if you do not agree to share, we will not send any optional information to the server +We strongly urge you to enable this feature (if you are a computer noob), but if you do not agree to share, we will not send any information to the server gui.news.title=News gui.about.title=About trace.unzip-natives=Is game launched? Failed to unzip natives. @@ -107,4 +107,11 @@ If necessary, you can take a screenshot of this page and send it to the develope \n\ Log:\ \n%s -gui.settings.title=Settings \ No newline at end of file +gui.settings.title=Settings +gui.addon.mods.weave.remove.confirm.message=Confirm removal of %s +gui.addon.mods.weave.remove.confirm.title=Confirm removal of Weave mod +gui.addon.mods.weave.remove.success=Mod removed successfully: %s +gui.addon.mods.weave.add.failure.io=IO error occurred while adding a Weave Mod\ +\n%s +gui.addon.mods.weave.add.failure.exists=Mod already exists +gui.addon.mods.weave.add.success=Mod added successfully! \ 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 eabe871e..26c07e97 100644 --- a/src/main/resources/languages/launcher_zh.properties +++ b/src/main/resources/languages/launcher_zh.properties @@ -107,3 +107,10 @@ gui.addon.agents.add.failure.io=添加助理失败\ Log:\ \n%s gui.settings.title=游戏设置 +gui.addon.mods.weave.remove.confirm.message=确认移除%s +gui.addon.mods.weave.remove.confirm.title=确认移除Weave模组 +gui.addon.mods.weave.remove.success=已成功移除Mod: %s +gui.addon.mods.weave.add.failure.io=添加WeaveMod时发生IO错误\ +\n%s +gui.addon.mods.weave.add.failure.exists=模组已存在 +gui.addon.mods.weave.add.success=模组添加成功! From bf9f8cd471f1c5f87563fc9a298cf57761b3b7dc Mon Sep 17 00:00:00 2001 From: cubewhy Date: Sun, 31 Dec 2023 15:02:29 +0800 Subject: [PATCH 17/42] data sharing --- .../gui/elements/GuiVersionSelect.java | 28 ++++++++++--------- 1 file changed, 15 insertions(+), 13 deletions(-) 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 44e53301..0f39e66a 100644 --- a/src/main/java/org/cubewhy/celestial/gui/elements/GuiVersionSelect.java +++ b/src/main/java/org/cubewhy/celestial/gui/elements/GuiVersionSelect.java @@ -176,19 +176,21 @@ private void runGame(CreateProcess cp, Runnable run) throws IOException { statusBar.setText(f.getString("status.launch.crashed")); log.info("Client looks crashed, starting upload the log"); try { - String trace = FileUtils.readFileToString(gameLogFile, StandardCharsets.UTF_8); - String script = FileUtils.readFileToString(launchScript, StandardCharsets.UTF_8); - Map map1 = launcherData.uploadCrashReport(trace, CrashReportType.GAME, script); - if (!map1.isEmpty()) { - String url = map1.get("url"); - String id = map1.get("id"); - JOptionPane.showMessageDialog(this, String.format(""" - Your client was crashed: - Crash id: %s - View your crash report at %s - View the log of the latest launch: %s - - *%s*""", id, url, gameLogFile.getPath(), f.getString("gui.version.crash.tip")), "Game crashed!", JOptionPane.ERROR_MESSAGE); + if (config.getConfig().has("data-sharing") && config.getValue("data-sharing").getAsBoolean()) { + String trace = FileUtils.readFileToString(gameLogFile, StandardCharsets.UTF_8); + String script = FileUtils.readFileToString(launchScript, StandardCharsets.UTF_8); + Map map1 = launcherData.uploadCrashReport(trace, CrashReportType.GAME, script); + if (!map1.isEmpty()) { + String url = map1.get("url"); + String id = map1.get("id"); + JOptionPane.showMessageDialog(this, String.format(""" + Your client was crashed: + Crash id: %s + View your crash report at %s + View the log of the latest launch: %s + + *%s*""", id, url, gameLogFile.getPath(), f.getString("gui.version.crash.tip")), "Game crashed!", JOptionPane.ERROR_MESSAGE); + } } else { throw new RuntimeException("Failed to upload crash report"); } From fda99136a82beb12ada02c6931bf33ace1a4a60a Mon Sep 17 00:00:00 2001 From: cubewhy Date: Sun, 31 Dec 2023 15:13:04 +0800 Subject: [PATCH 18/42] windows 7 support --- src/main/java/org/cubewhy/celestial/Celestial.java | 11 ++++++----- .../celestial/gui/elements/GuiVersionSelect.java | 6 +++--- 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/src/main/java/org/cubewhy/celestial/Celestial.java b/src/main/java/org/cubewhy/celestial/Celestial.java index 94a237dd..30d41a9b 100644 --- a/src/main/java/org/cubewhy/celestial/Celestial.java +++ b/src/main/java/org/cubewhy/celestial/Celestial.java @@ -443,11 +443,12 @@ public static File launch(String version, String branch, String module) throws I try (FileWriter writer = new FileWriter(launchScript)) { if (OSEnum.getCurrent().equals(OSEnum.Windows)) { // Microsoft Windows - writer.write("@echo off\n"); - writer.write("rem Generated by LunarCN (Celestial Launcher)\nrem Website: https://www.lunarclient.top/\n"); - writer.write("rem Please donate to support us to continue develop https://www.lunarclient.top/donate\n"); - writer.write("rem You can run this script to debug your game, or share this script to developers to resolve your launch problem\n"); - writer.write("cd /d " + installationDir + "\n"); + // NEW: Use CRLF (Windows 7) + writer.write("@echo off\r\n"); + writer.write("rem Generated by LunarCN (Celestial Launcher)\nrem Website: https://www.lunarclient.top/\r\n"); + writer.write("rem Please donate to support us to continue develop https://www.lunarclient.top/donate\r\n"); + writer.write("rem You can run this script to debug your game, or share this script to developers to resolve your launch problem\r\n"); + writer.write("cd /d " + installationDir + "\r\n"); } else { // Others writer.write("#!/bin/bash\n"); 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 0f39e66a..e9496ef9 100644 --- a/src/main/java/org/cubewhy/celestial/gui/elements/GuiVersionSelect.java +++ b/src/main/java/org/cubewhy/celestial/gui/elements/GuiVersionSelect.java @@ -190,16 +190,16 @@ private void runGame(CreateProcess cp, Runnable run) throws IOException { View the log of the latest launch: %s *%s*""", id, url, gameLogFile.getPath(), f.getString("gui.version.crash.tip")), "Game crashed!", JOptionPane.ERROR_MESSAGE); + } else { + throw new RuntimeException("Failed to upload crash report"); } - } else { - throw new RuntimeException("Failed to upload crash report"); } } catch (Exception e) { JOptionPane.showMessageDialog(this, String.format(""" Your client was crashed: View the log of the latest launch: %s *%s* - """, gameLogFile.getPath(), f.getString("gui.version.crash.tip"))); + """, gameLogFile.getPath(), f.getString("gui.version.crash.tip")), "Game crashed!", JOptionPane.ERROR_MESSAGE); throw new RuntimeException(e); } } From b9b484418ef63fb7426e824e79865908ec6fe2b3 Mon Sep 17 00:00:00 2001 From: cubewhy Date: Sun, 31 Dec 2023 15:23:08 +0800 Subject: [PATCH 19/42] correct grammer --- .../java/org/cubewhy/celestial/utils/lunar/LauncherData.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/org/cubewhy/celestial/utils/lunar/LauncherData.java b/src/main/java/org/cubewhy/celestial/utils/lunar/LauncherData.java index 2fa08a1a..c611730e 100644 --- a/src/main/java/org/cubewhy/celestial/utils/lunar/LauncherData.java +++ b/src/main/java/org/cubewhy/celestial/utils/lunar/LauncherData.java @@ -100,12 +100,12 @@ public JsonObject metadata() throws IOException { } /** - * Get alert message + * Get the alert message * * @param metadata metadata from api * @return a map of the alert (title, message) * */ - public static Map getAlert(JsonObject metadata) { + public static @Nullable Map getAlert(JsonObject metadata) { if (metadata.has("alert") && !metadata.get("alert").isJsonNull()) { JsonObject alert = metadata.getAsJsonObject("alert"); Map map = new HashMap<>(); From 8f5c4d1b98c729b9d4492a028805534d9e719f8f Mon Sep 17 00:00:00 2001 From: cubewhy Date: Mon, 1 Jan 2024 09:20:01 +0800 Subject: [PATCH 20/42] readme --- README.md | 19 ++++++++++--------- build.gradle | 2 +- 2 files changed, 11 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index 71c0280c..c2a8845e 100644 --- a/README.md +++ b/README.md @@ -6,15 +6,16 @@ 1. Full open source (GPLv3) 2. No electron -3. No installation needed -4. Ready out of the box -5. External browser login support (In working) -6. Cross-platform (You might need to complete natives) -7. Custom API address ([LunarCN API](https://github.com/CubeWhyMC/website) only) -8. Multi version, one jre -9. Javaagent support (Experimental) -10. LunarCN support (In working) -11. Weave support (In working) +3. Lite, high performance (For example, the downloader) +4. No installation needed +5. Ready out of the box +6. External browser login support +7. Cross-platform (Experimental) +8. Custom API address ([LunarCN API](https://github.com/CubeWhyMC/website) only) +9. Multi version, one jre +10. Javaagent support (Experimental) +11. LunarCN support (In working) +12. Weave support (Experimental) ## Get celestial diff --git a/build.gradle b/build.gradle index a366b4ff..9c4a82ce 100644 --- a/build.gradle +++ b/build.gradle @@ -5,7 +5,7 @@ plugins { } group = 'org.cubewhy.celestial' -version = '1.2-pre1-SNAPSHOT' +version = '1.2-pre2-SNAPSHOT' println('Java: ' + System.getProperty('java.version') + ' JVM: ' + System.getProperty('java.vm.version') + '(' + System.getProperty('java.vendor') + ') Arch: ' + System.getProperty('os.arch')) println('Celestial Launcher -> https://www.lunarclient.top/celestial') From 249b1665f0cd920893179085dcc9e452bf05b535 Mon Sep 17 00:00:00 2001 From: cubewhy Date: Mon, 1 Jan 2024 09:20:25 +0800 Subject: [PATCH 21/42] readme --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index c2a8845e..f5e53618 100644 --- a/README.md +++ b/README.md @@ -31,7 +31,7 @@ Donate at [lunarclient.top](https://www.lunarclient.top/donate) (CNY only/仅支 ## Translation All languages except Chinese are translated via Google Translate. -If there are any translation errors, please submit a PR or issue (English) +If there are any translation errors, please submit a PR or an issue (in English) ## License From 31db67ad475e7c2a66d775d2fd1ead045a443356 Mon Sep 17 00:00:00 2001 From: cubewhy Date: Mon, 1 Jan 2024 09:59:26 +0800 Subject: [PATCH 22/42] anti multi launch --- build.gradle | 2 +- .../cubewhy/celestial/gui/elements/GuiVersionSelect.java | 7 +++++++ src/main/resources/languages/launcher.properties | 4 +++- src/main/resources/languages/launcher_zh.properties | 2 ++ 4 files changed, 13 insertions(+), 2 deletions(-) diff --git a/build.gradle b/build.gradle index 9c4a82ce..1f8d82f3 100644 --- a/build.gradle +++ b/build.gradle @@ -5,7 +5,7 @@ plugins { } group = 'org.cubewhy.celestial' -version = '1.2-pre2-SNAPSHOT' +version = '1.2-pre3-SNAPSHOT' println('Java: ' + System.getProperty('java.version') + ' JVM: ' + System.getProperty('java.vm.version') + '(' + System.getProperty('java.vendor') + ') Arch: ' + System.getProperty('os.arch')) println('Celestial Launcher -> https://www.lunarclient.top/celestial') 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 e9496ef9..8e3dc702 100644 --- a/src/main/java/org/cubewhy/celestial/gui/elements/GuiVersionSelect.java +++ b/src/main/java/org/cubewhy/celestial/gui/elements/GuiVersionSelect.java @@ -42,6 +42,7 @@ public class GuiVersionSelect extends JPanel { private boolean isFinishOk = false; private final JButton btnOnline = new JButton(f.getString("gui.version.online")); private final JButton btnOffline = new JButton(f.getString("gui.version.offline")); + private boolean isLaunching = false; private interface CreateProcess { Process create() throws IOException; @@ -213,6 +214,10 @@ private void runGame(CreateProcess cp, Runnable run) throws IOException { } private void online() throws IOException, AttachNotSupportedException { + if (isLaunching) { + JOptionPane.showMessageDialog(this, f.getString("gui.launch.launching.message"), f.getString("gui.launch.launching.title"), JOptionPane.ERROR_MESSAGE); + return; + } beforeLaunch(); File natives = launch((String) versionSelect.getSelectedItem(), branchInput.getText(), (String) moduleSelect.getSelectedItem()); if (natives == null) { @@ -228,6 +233,7 @@ private void online() throws IOException, AttachNotSupportedException { } }, () -> { try { + isLaunching = true; statusBar.setText(f.getString("status.launch.begin")); Celestial.checkUpdate((String) versionSelect.getSelectedItem(), (String) moduleSelect.getSelectedItem(), branchInput.getText()); DownloadManager.waitForAll(); @@ -241,6 +247,7 @@ private void online() throws IOException, AttachNotSupportedException { } // exec, run log.info("Everything is OK, starting game..."); + isLaunching = false; } catch (Exception e) { log.error("Failed to check update"); String trace = TextUtils.dumpTrace(e); diff --git a/src/main/resources/languages/launcher.properties b/src/main/resources/languages/launcher.properties index 518b167f..4ed39afb 100644 --- a/src/main/resources/languages/launcher.properties +++ b/src/main/resources/languages/launcher.properties @@ -114,4 +114,6 @@ gui.addon.mods.weave.remove.success=Mod removed successfully: %s gui.addon.mods.weave.add.failure.io=IO error occurred while adding a Weave Mod\ \n%s gui.addon.mods.weave.add.failure.exists=Mod already exists -gui.addon.mods.weave.add.success=Mod added successfully! \ No newline at end of file +gui.addon.mods.weave.add.success=Mod added successfully! +gui.launch.launching.message=The game is starting. If this message is wrong, please provide feedback to the developer. +gui.launch.launching.title=Launching \ 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 26c07e97..95300a77 100644 --- a/src/main/resources/languages/launcher_zh.properties +++ b/src/main/resources/languages/launcher_zh.properties @@ -114,3 +114,5 @@ gui.addon.mods.weave.add.failure.io=添加WeaveMod时发生IO错误\ \n%s gui.addon.mods.weave.add.failure.exists=模组已存在 gui.addon.mods.weave.add.success=模组添加成功! +gui.launch.launching.message=游戏正在启动,若此消息是错误的,请向开发者反馈 +gui.launch.launching.title=启动中 From f5960b2fe574ad3d0bcc3809c42b21bdee02608c Mon Sep 17 00:00:00 2001 From: cubewhy Date: Mon, 1 Jan 2024 11:39:13 +0800 Subject: [PATCH 23/42] add an open folder button --- .../gui/elements/GuiAddonManager.java | 36 ++++++++++++++++--- .../cubewhy/celestial/gui/pages/GuiNews.java | 10 ++++-- .../resources/languages/launcher.properties | 3 +- .../languages/launcher_zh.properties | 1 + 4 files changed, 41 insertions(+), 9 deletions(-) diff --git a/src/main/java/org/cubewhy/celestial/gui/elements/GuiAddonManager.java b/src/main/java/org/cubewhy/celestial/gui/elements/GuiAddonManager.java index 0e70c09a..b3462c29 100644 --- a/src/main/java/org/cubewhy/celestial/gui/elements/GuiAddonManager.java +++ b/src/main/java/org/cubewhy/celestial/gui/elements/GuiAddonManager.java @@ -216,23 +216,49 @@ private void initGui() { final JPanel panelLunarCN = new JPanel(); panelLunarCN.setLayout(new BoxLayout(panelLunarCN, BoxLayout.Y_AXIS)); panelLunarCN.add(new JScrollPane(listLunarCN)); - panelLunarCN.add(btnAddLunarCNMod); + final JPanel btnPanel1 = new JPanel(); + btnPanel1.setLayout(new BoxLayout(btnPanel1, BoxLayout.X_AXIS)); + btnPanel1.add(btnAddLunarCNMod); + btnPanel1.add(createButtonOpenFolder(f.getString("gui.addon.folder"), LunarCNMod.modFolder)); + panelLunarCN.add(btnPanel1); + final JPanel panelWeave = new JPanel(); panelWeave.setLayout(new BoxLayout(panelWeave, BoxLayout.Y_AXIS)); panelWeave.add(new JScrollPane(listWeave)); - panelWeave.add(btnAddWeaveMod); + final JPanel btnPanel2 = new JPanel(); + btnPanel2.setLayout(new BoxLayout(btnPanel2, BoxLayout.X_AXIS)); + btnPanel2.add(btnAddWeaveMod); + btnPanel2.add(createButtonOpenFolder(f.getString("gui.addon.folder"), WeaveMod.modFolder)); + panelWeave.add(btnPanel2); + final JPanel panelAgents = new JPanel(); panelAgents.setLayout(new BoxLayout(panelAgents, BoxLayout.Y_AXIS)); panelAgents.add(new JScrollPane(listAgents)); - panelAgents.add(Box.createVerticalGlue()); - panelAgents.add(btnAddAgent); + final JPanel btnPanel3 = new JPanel(); + btnPanel3.setLayout(new BoxLayout(btnPanel3, BoxLayout.X_AXIS)); + btnPanel3.add(btnAddAgent); + btnPanel3.add(createButtonOpenFolder(f.getString("gui.addon.folder"), JavaAgent.javaAgentFolder)); + panelAgents.add(btnPanel3); + + tab.addTab(f.getString("gui.addons.agents"), panelAgents); tab.addTab(f.getString("gui.addons.mods.cn"), panelLunarCN); tab.addTab(f.getString("gui.addons.mods.weave"), panelWeave); - tab.addTab(f.getString("gui.addons.agents"), panelAgents); this.add(tab); } + private JButton createButtonOpenFolder(String text, File folder) { + JButton btn = new JButton(text); + btn.addActionListener(e -> { + try { + Desktop.getDesktop().open(folder); + } catch (IOException ex) { + throw new RuntimeException(ex); + } + }); + return btn; + } + private static void loadWeaveMods(DefaultListModel weave) { for (WeaveMod weaveMod : WeaveMod.findAll()) { weave.addElement(weaveMod); diff --git a/src/main/java/org/cubewhy/celestial/gui/pages/GuiNews.java b/src/main/java/org/cubewhy/celestial/gui/pages/GuiNews.java index 02bfae26..4f2d4d04 100644 --- a/src/main/java/org/cubewhy/celestial/gui/pages/GuiNews.java +++ b/src/main/java/org/cubewhy/celestial/gui/pages/GuiNews.java @@ -42,9 +42,13 @@ private void initGui() throws IOException { JsonObject json = blogPost.getAsJsonObject(); String imageURL = json.get("image").getAsString(); String title = json.get("title").getAsString(); - if (DownloadManager.cache(new URL(imageURL), "news/" + title + ".png", false)) { - // load - panel.add(new LauncherNews(json)); + try { + if (DownloadManager.cache(new URL(imageURL), "news/" + title + ".png", false)) { + // load + panel.add(new LauncherNews(json)); + } + } catch (IOException e) { + log.warn("Failed to cache " + imageURL); } } } diff --git a/src/main/resources/languages/launcher.properties b/src/main/resources/languages/launcher.properties index 518b167f..70d078f2 100644 --- a/src/main/resources/languages/launcher.properties +++ b/src/main/resources/languages/launcher.properties @@ -114,4 +114,5 @@ gui.addon.mods.weave.remove.success=Mod removed successfully: %s gui.addon.mods.weave.add.failure.io=IO error occurred while adding a Weave Mod\ \n%s gui.addon.mods.weave.add.failure.exists=Mod already exists -gui.addon.mods.weave.add.success=Mod added successfully! \ No newline at end of file +gui.addon.mods.weave.add.success=Mod added successfully! +gui.addon.folder=Folder \ 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 26c07e97..62cd174a 100644 --- a/src/main/resources/languages/launcher_zh.properties +++ b/src/main/resources/languages/launcher_zh.properties @@ -114,3 +114,4 @@ gui.addon.mods.weave.add.failure.io=添加WeaveMod时发生IO错误\ \n%s gui.addon.mods.weave.add.failure.exists=模组已存在 gui.addon.mods.weave.add.success=模组添加成功! +gui.addon.folder=打开文件夹 From 8fd0add82d1edc94e69e9f578c5342fa0b6854b8 Mon Sep 17 00:00:00 2001 From: cubewhy Date: Mon, 1 Jan 2024 12:17:12 +0800 Subject: [PATCH 24/42] LITE: news are optional --- src/main/java/org/cubewhy/celestial/gui/pages/GuiNews.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/main/java/org/cubewhy/celestial/gui/pages/GuiNews.java b/src/main/java/org/cubewhy/celestial/gui/pages/GuiNews.java index 4f2d4d04..37ac2383 100644 --- a/src/main/java/org/cubewhy/celestial/gui/pages/GuiNews.java +++ b/src/main/java/org/cubewhy/celestial/gui/pages/GuiNews.java @@ -6,6 +6,7 @@ import lombok.extern.slf4j.Slf4j; import org.cubewhy.celestial.files.DownloadManager; import org.cubewhy.celestial.gui.LauncherNews; +import org.cubewhy.celestial.utils.TextUtils; import org.cubewhy.celestial.utils.lunar.LauncherData; import javax.swing.*; @@ -30,7 +31,7 @@ public GuiNews() throws IOException { this.initGui(); } - private void initGui() throws IOException { + private void initGui() { // render blogPosts log.info("Loading blogPosts (gui)"); if (blogPosts.isJsonNull()) { @@ -49,6 +50,8 @@ private void initGui() throws IOException { } } catch (IOException e) { log.warn("Failed to cache " + imageURL); + String trace = TextUtils.dumpTrace(e); + log.error(trace); } } } From f7445ad92675dd72eaf5791cb6504cb81dd2d281 Mon Sep 17 00:00:00 2001 From: cubewhy Date: Mon, 1 Jan 2024 14:48:45 +0800 Subject: [PATCH 25/42] show the error dialog when data-sharing is disabled & fix Chinese in the path --- build.gradle | 2 +- src/main/java/org/cubewhy/celestial/Celestial.java | 5 ++++- .../java/org/cubewhy/celestial/files/ConfigFile.java | 5 ++++- .../cubewhy/celestial/gui/elements/GuiVersionSelect.java | 9 +++++++-- .../java/org/cubewhy/celestial/gui/pages/GuiNews.java | 2 +- 5 files changed, 17 insertions(+), 6 deletions(-) diff --git a/build.gradle b/build.gradle index 9c4a82ce..ab8f7d2a 100644 --- a/build.gradle +++ b/build.gradle @@ -8,7 +8,7 @@ group = 'org.cubewhy.celestial' version = '1.2-pre2-SNAPSHOT' println('Java: ' + System.getProperty('java.version') + ' JVM: ' + System.getProperty('java.vm.version') + '(' + System.getProperty('java.vendor') + ') Arch: ' + System.getProperty('os.arch')) -println('Celestial Launcher -> https://www.lunarclient.top/celestial') +println('Celestial Launcher -> https://www.lunarclient.top/') compileJava.options.encoding = "UTF-8" diff --git a/src/main/java/org/cubewhy/celestial/Celestial.java b/src/main/java/org/cubewhy/celestial/Celestial.java index 30d41a9b..0d238ac9 100644 --- a/src/main/java/org/cubewhy/celestial/Celestial.java +++ b/src/main/java/org/cubewhy/celestial/Celestial.java @@ -70,6 +70,8 @@ public class Celestial { } public static void main(String[] args) throws Exception { + // set encoding + System.setProperty("file.encoding", "UTF-8"); log.info("Celestial v" + GitUtils.getBuildVersion() + " build by " + GitUtils.getBuildUser()); try { System.setProperty("file.encoding", "UTF-8"); @@ -440,7 +442,7 @@ public static File launch(String version, String branch, String module) throws I if (launchScript.createNewFile()) { log.info("Launch script was created"); } - try (FileWriter writer = new FileWriter(launchScript)) { + try (FileWriter writer = new FileWriter(launchScript, StandardCharsets.UTF_8)) { if (OSEnum.getCurrent().equals(OSEnum.Windows)) { // Microsoft Windows // NEW: Use CRLF (Windows 7) @@ -448,6 +450,7 @@ public static File launch(String version, String branch, String module) throws I writer.write("rem Generated by LunarCN (Celestial Launcher)\nrem Website: https://www.lunarclient.top/\r\n"); writer.write("rem Please donate to support us to continue develop https://www.lunarclient.top/donate\r\n"); writer.write("rem You can run this script to debug your game, or share this script to developers to resolve your launch problem\r\n"); + writer.write("chcp 65001\r\n"); // unicode support for Windows which uses Chinese writer.write("cd /d " + installationDir + "\r\n"); } else { // Others diff --git a/src/main/java/org/cubewhy/celestial/files/ConfigFile.java b/src/main/java/org/cubewhy/celestial/files/ConfigFile.java index 4ec84227..c5e3a816 100644 --- a/src/main/java/org/cubewhy/celestial/files/ConfigFile.java +++ b/src/main/java/org/cubewhy/celestial/files/ConfigFile.java @@ -8,6 +8,7 @@ import lombok.extern.slf4j.Slf4j; import java.io.*; +import java.nio.charset.StandardCharsets; @Slf4j public class ConfigFile { @@ -84,7 +85,7 @@ public ConfigFile load() { while (!successful) { try { - bufferedReader = new BufferedReader(new FileReader(this.file)); + bufferedReader = new BufferedReader(new FileReader(this.file, StandardCharsets.UTF_8)); config = gson.fromJson(bufferedReader, JsonObject.class); if (config == null) { config = new JsonObject(); @@ -100,6 +101,8 @@ public ConfigFile load() { } catch (IOException ex) { throw new RuntimeException(ex); } + } catch (IOException e) { + throw new RuntimeException(e); } } return this; 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 e9496ef9..07563e05 100644 --- a/src/main/java/org/cubewhy/celestial/gui/elements/GuiVersionSelect.java +++ b/src/main/java/org/cubewhy/celestial/gui/elements/GuiVersionSelect.java @@ -26,6 +26,7 @@ import java.awt.*; import java.io.File; import java.io.IOException; +import java.io.NotActiveException; import java.nio.charset.StandardCharsets; import java.util.ArrayList; import java.util.List; @@ -174,7 +175,7 @@ private void runGame(CreateProcess cp, Runnable run) throws IOException { if (code != 0) { // upload crash report statusBar.setText(f.getString("status.launch.crashed")); - log.info("Client looks crashed, starting upload the log"); + log.info("Client looks crashed"); try { if (config.getConfig().has("data-sharing") && config.getValue("data-sharing").getAsBoolean()) { String trace = FileUtils.readFileToString(gameLogFile, StandardCharsets.UTF_8); @@ -193,6 +194,8 @@ private void runGame(CreateProcess cp, Runnable run) throws IOException { } else { throw new RuntimeException("Failed to upload crash report"); } + } else { + throw new NotActiveException(); } } catch (Exception e) { JOptionPane.showMessageDialog(this, String.format(""" @@ -200,7 +203,9 @@ private void runGame(CreateProcess cp, Runnable run) throws IOException { View the log of the latest launch: %s *%s* """, gameLogFile.getPath(), f.getString("gui.version.crash.tip")), "Game crashed!", JOptionPane.ERROR_MESSAGE); - throw new RuntimeException(e); + if (!(e instanceof NotActiveException)) { + throw new RuntimeException(e); + } } } } catch (InterruptedException ex) { diff --git a/src/main/java/org/cubewhy/celestial/gui/pages/GuiNews.java b/src/main/java/org/cubewhy/celestial/gui/pages/GuiNews.java index 37ac2383..303d21f8 100644 --- a/src/main/java/org/cubewhy/celestial/gui/pages/GuiNews.java +++ b/src/main/java/org/cubewhy/celestial/gui/pages/GuiNews.java @@ -45,7 +45,7 @@ private void initGui() { String title = json.get("title").getAsString(); try { if (DownloadManager.cache(new URL(imageURL), "news/" + title + ".png", false)) { - // load + // load news panel.add(new LauncherNews(json)); } } catch (IOException e) { From 45a038c3aee96b28423a136a5316d814cdee1a01 Mon Sep 17 00:00:00 2001 From: cubewhy Date: Mon, 1 Jan 2024 14:51:00 +0800 Subject: [PATCH 26/42] correct grammar --- src/main/java/org/cubewhy/celestial/Celestial.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/java/org/cubewhy/celestial/Celestial.java b/src/main/java/org/cubewhy/celestial/Celestial.java index 0d238ac9..ae98e437 100644 --- a/src/main/java/org/cubewhy/celestial/Celestial.java +++ b/src/main/java/org/cubewhy/celestial/Celestial.java @@ -447,9 +447,9 @@ public static File launch(String version, String branch, String module) throws I // Microsoft Windows // NEW: Use CRLF (Windows 7) writer.write("@echo off\r\n"); - writer.write("rem Generated by LunarCN (Celestial Launcher)\nrem Website: https://www.lunarclient.top/\r\n"); - writer.write("rem Please donate to support us to continue develop https://www.lunarclient.top/donate\r\n"); - writer.write("rem You can run this script to debug your game, or share this script to developers to resolve your launch problem\r\n"); + writer.write("@rem Generated by LunarCN (Celestial Launcher)\nrem Website: https://www.lunarclient.top/\r\n"); + writer.write("@rem Please donate to support us to continue develop https://www.lunarclient.top/donate\r\n"); + writer.write("@rem You can run this script to debug your game, or share this script to developers to resolve your launch problem\r\n"); writer.write("chcp 65001\r\n"); // unicode support for Windows which uses Chinese writer.write("cd /d " + installationDir + "\r\n"); } else { From d746b02542c5829cbc002d2524d4c6db94c50d19 Mon Sep 17 00:00:00 2001 From: cubewhy Date: Mon, 1 Jan 2024 14:53:27 +0800 Subject: [PATCH 27/42] bump version --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index ab8f7d2a..9a6e26c4 100644 --- a/build.gradle +++ b/build.gradle @@ -5,7 +5,7 @@ plugins { } group = 'org.cubewhy.celestial' -version = '1.2-pre2-SNAPSHOT' +version = '1.2-pre3-SNAPSHOT' println('Java: ' + System.getProperty('java.version') + ' JVM: ' + System.getProperty('java.vm.version') + '(' + System.getProperty('java.vendor') + ') Arch: ' + System.getProperty('os.arch')) println('Celestial Launcher -> https://www.lunarclient.top/') From 1d77227c3910f72b3f8873d85bf5ad7afe6249f3 Mon Sep 17 00:00:00 2001 From: cubewhy Date: Mon, 1 Jan 2024 14:58:56 +0800 Subject: [PATCH 28/42] grammar --- .../java/org/cubewhy/celestial/utils/lunar/LauncherData.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/org/cubewhy/celestial/utils/lunar/LauncherData.java b/src/main/java/org/cubewhy/celestial/utils/lunar/LauncherData.java index c611730e..ea50c615 100644 --- a/src/main/java/org/cubewhy/celestial/utils/lunar/LauncherData.java +++ b/src/main/java/org/cubewhy/celestial/utils/lunar/LauncherData.java @@ -81,7 +81,7 @@ public static boolean getIchorState(JsonObject json) throws IOException { .getAsJsonObject("launchTypeData") .get("ichor").getAsBoolean(); } else { - return true; // force enable ichor in the latest api version + return true; // forces enable ichor in the latest api version } } From 6d4e44d265e3f86b7283cca21723f16e6723cae0 Mon Sep 17 00:00:00 2001 From: cubewhy Date: Mon, 1 Jan 2024 15:08:57 +0800 Subject: [PATCH 29/42] workflow --- .github/dependabot.yml | 7 +++++++ .github/workflows/build.yml | 29 +++++++++++++++++++++++++++++ 2 files changed, 36 insertions(+) create mode 100644 .github/dependabot.yml create mode 100644 .github/workflows/build.yml diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 00000000..9b233ebd --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,7 @@ +version: 2 +updates: + - package-ecosystem: gradle + directory: "/" + schedule: + interval: daily + open-pull-requests-limit: 10 \ No newline at end of file diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml new file mode 100644 index 00000000..b56bed9f --- /dev/null +++ b/.github/workflows/build.yml @@ -0,0 +1,29 @@ +name: build + +on: + - push + +jobs: + build: + runs-on: ubuntu-latest + steps: + - name: Checkout repository + uses: actions/checkout@v2 + with: + submodules: recursive + - name: Java setup + uses: actions/setup-java@v2 + with: + distribution: "zulu" + java-version: 17 + cache: "gradle" + - name: Set outputs + id: vars + run: echo "::set-output name=sha_short::$(git rev-parse --short HEAD)" + - name: Build + run: chmod +x ./gradlew && ./gradlew build + - name: Upload build artifacts + uses: actions/upload-artifact@v2 + with: + name: celestial + path: build/libs/celestial-*.jar \ No newline at end of file From 1d113920b919b5eef3accdd6ccb3ed896b78939c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 1 Jan 2024 07:09:53 +0000 Subject: [PATCH 30/42] Bump org.apache.logging.log4j:log4j-api from 2.20.0 to 2.22.1 Bumps org.apache.logging.log4j:log4j-api from 2.20.0 to 2.22.1. --- updated-dependencies: - dependency-name: org.apache.logging.log4j:log4j-api dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index 9a6e26c4..682e8676 100644 --- a/build.gradle +++ b/build.gradle @@ -32,7 +32,7 @@ dependencies { include 'org.slf4j:slf4j-api:2.0.7' include 'org.slf4j:slf4j-log4j12:2.0.7' - include 'org.apache.logging.log4j:log4j-api:2.20.0' + include 'org.apache.logging.log4j:log4j-api:2.22.1' include 'org.apache.logging.log4j:log4j-core:2.20.0' include 'com.squareup.okhttp3:okhttp:4.11.0' From 1383ac9efd5214d2ece6899beffb2f009dd01516 Mon Sep 17 00:00:00 2001 From: cubewhy Date: Mon, 1 Jan 2024 16:27:52 +0800 Subject: [PATCH 31/42] disable auto test --- build.gradle | 1 + 1 file changed, 1 insertion(+) diff --git a/build.gradle b/build.gradle index 9a6e26c4..dcf62a58 100644 --- a/build.gradle +++ b/build.gradle @@ -51,6 +51,7 @@ dependencies { } test { + enabled = false useJUnitPlatform() } From db80732c3e66197187f4621734026d5025fbf8e8 Mon Sep 17 00:00:00 2001 From: cubewhy Date: Mon, 1 Jan 2024 16:32:55 +0800 Subject: [PATCH 32/42] use v3 --- .github/workflows/build.yml | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index b56bed9f..c6dbbd1c 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -8,22 +8,22 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout repository - uses: actions/checkout@v2 + uses: actions/checkout@v3 with: submodules: recursive - name: Java setup - uses: actions/setup-java@v2 + uses: actions/setup-java@v3 with: distribution: "zulu" java-version: 17 cache: "gradle" - - name: Set outputs - id: vars - run: echo "::set-output name=sha_short::$(git rev-parse --short HEAD)" +# - name: Set outputs +# id: vars +# run: echo "::set-output name=sha_short::$(git rev-parse --short HEAD)" - name: Build run: chmod +x ./gradlew && ./gradlew build - name: Upload build artifacts - uses: actions/upload-artifact@v2 + uses: actions/upload-artifact@v3 with: name: celestial path: build/libs/celestial-*.jar \ No newline at end of file From 62cca28d77b04b4c68d9a6f630f1318c6ab1afc0 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 1 Jan 2024 08:36:56 +0000 Subject: [PATCH 33/42] Bump org.apache.logging.log4j:log4j-core from 2.20.0 to 2.22.1 Bumps org.apache.logging.log4j:log4j-core from 2.20.0 to 2.22.1. --- updated-dependencies: - dependency-name: org.apache.logging.log4j:log4j-core dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index deb6fb5c..256c1d35 100644 --- a/build.gradle +++ b/build.gradle @@ -33,7 +33,7 @@ dependencies { include 'org.slf4j:slf4j-api:2.0.7' include 'org.slf4j:slf4j-log4j12:2.0.7' include 'org.apache.logging.log4j:log4j-api:2.22.1' - include 'org.apache.logging.log4j:log4j-core:2.20.0' + include 'org.apache.logging.log4j:log4j-core:2.22.1' include 'com.squareup.okhttp3:okhttp:4.11.0' include 'com.google.code.gson:gson:2.10.1' From bb66a0088c94ac1918f98723370ec9819d9c6b10 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 1 Jan 2024 08:37:06 +0000 Subject: [PATCH 34/42] Bump com.squareup.okhttp3:okhttp from 4.11.0 to 4.12.0 Bumps [com.squareup.okhttp3:okhttp](https://github.com/square/okhttp) from 4.11.0 to 4.12.0. - [Changelog](https://github.com/square/okhttp/blob/master/CHANGELOG.md) - [Commits](https://github.com/square/okhttp/compare/parent-4.11.0...parent-4.12.0) --- updated-dependencies: - dependency-name: com.squareup.okhttp3:okhttp dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index deb6fb5c..7b3ee5bd 100644 --- a/build.gradle +++ b/build.gradle @@ -35,7 +35,7 @@ dependencies { include 'org.apache.logging.log4j:log4j-api:2.22.1' include 'org.apache.logging.log4j:log4j-core:2.20.0' - include 'com.squareup.okhttp3:okhttp:4.11.0' + include 'com.squareup.okhttp3:okhttp:4.12.0' include 'com.google.code.gson:gson:2.10.1' include 'net.sf.jopt-simple:jopt-simple:6.0-alpha-3' include 'com.formdev:flatlaf:3.3-SNAPSHOT' From cad15c752226850ddcd250befb84e08b3a58a15c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 1 Jan 2024 08:37:07 +0000 Subject: [PATCH 35/42] Bump org.slf4j:slf4j-api from 2.0.7 to 2.0.10 Bumps org.slf4j:slf4j-api from 2.0.7 to 2.0.10. --- updated-dependencies: - dependency-name: org.slf4j:slf4j-api dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index deb6fb5c..274c7173 100644 --- a/build.gradle +++ b/build.gradle @@ -30,7 +30,7 @@ dependencies { annotationProcessor 'org.projectlombok:lombok:1.18.30' - include 'org.slf4j:slf4j-api:2.0.7' + include 'org.slf4j:slf4j-api:2.0.10' include 'org.slf4j:slf4j-log4j12:2.0.7' include 'org.apache.logging.log4j:log4j-api:2.22.1' include 'org.apache.logging.log4j:log4j-core:2.20.0' From 9f7bfb20c3e6efcfe5f05e6655bc50615df40ac3 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 1 Jan 2024 08:39:34 +0000 Subject: [PATCH 36/42] Bump org.slf4j:slf4j-log4j12 from 2.0.7 to 2.0.10 Bumps org.slf4j:slf4j-log4j12 from 2.0.7 to 2.0.10. --- updated-dependencies: - dependency-name: org.slf4j:slf4j-log4j12 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index 94c2c8e4..c59a0808 100644 --- a/build.gradle +++ b/build.gradle @@ -31,7 +31,7 @@ dependencies { include 'org.slf4j:slf4j-api:2.0.10' - include 'org.slf4j:slf4j-log4j12:2.0.7' + include 'org.slf4j:slf4j-log4j12:2.0.10' include 'org.apache.logging.log4j:log4j-api:2.22.1' include 'org.apache.logging.log4j:log4j-core:2.22.1' From 08bccfb71ecb95255305aa7a6bee9f6f83471d47 Mon Sep 17 00:00:00 2001 From: cubewhy Date: Mon, 1 Jan 2024 17:22:45 +0800 Subject: [PATCH 37/42] add a version string in launch script and change scroll speed --- build.gradle | 2 +- src/main/java/org/cubewhy/celestial/Celestial.java | 12 +++++------- .../org/cubewhy/celestial/gui/pages/GuiNews.java | 1 + 3 files changed, 7 insertions(+), 8 deletions(-) diff --git a/build.gradle b/build.gradle index c59a0808..cfbb6f23 100644 --- a/build.gradle +++ b/build.gradle @@ -5,7 +5,7 @@ plugins { } group = 'org.cubewhy.celestial' -version = '1.2-pre3-SNAPSHOT' +version = '1.2-pre4-SNAPSHOT' println('Java: ' + System.getProperty('java.version') + ' JVM: ' + System.getProperty('java.vm.version') + '(' + System.getProperty('java.vendor') + ') Arch: ' + System.getProperty('os.arch')) println('Celestial Launcher -> https://www.lunarclient.top/') diff --git a/src/main/java/org/cubewhy/celestial/Celestial.java b/src/main/java/org/cubewhy/celestial/Celestial.java index ae98e437..36e71e91 100644 --- a/src/main/java/org/cubewhy/celestial/Celestial.java +++ b/src/main/java/org/cubewhy/celestial/Celestial.java @@ -189,12 +189,9 @@ private static void checkJava() throws IOException { JOptionPane.showMessageDialog(null, f.getString("compatibility.warn.message"), f.getString("compatibility.warn.title"), JOptionPane.WARNING_MESSAGE); } - // detect the official launcher (Windows only) - if (OSEnum.getCurrent().equals(OSEnum.Windows)) { - if (sessionFile.exists() && LunarUtils.isReallyOfficial(sessionFile)) { - log.warn("Detected the official launcher"); - JOptionPane.showMessageDialog(null, f.getString("warn.official-launcher.message"), f.getString("warn.official-launcher.title"), JOptionPane.WARNING_MESSAGE); - } + if (sessionFile.exists() && LunarUtils.isReallyOfficial(sessionFile)) { + log.warn("Detected the official launcher"); + JOptionPane.showMessageDialog(null, f.getString("warn.official-launcher.message"), f.getString("warn.official-launcher.title"), JOptionPane.WARNING_MESSAGE); } } @@ -447,7 +444,8 @@ public static File launch(String version, String branch, String module) throws I // Microsoft Windows // NEW: Use CRLF (Windows 7) writer.write("@echo off\r\n"); - writer.write("@rem Generated by LunarCN (Celestial Launcher)\nrem Website: https://www.lunarclient.top/\r\n"); + writer.write("@rem Generated by LunarCN (Celestial Launcher)\r\n@rem Website: https://www.lunarclient.top/\r\n"); + writer.write(String.format("@rem Version %s\r\n", GitUtils.getBuildVersion())); writer.write("@rem Please donate to support us to continue develop https://www.lunarclient.top/donate\r\n"); writer.write("@rem You can run this script to debug your game, or share this script to developers to resolve your launch problem\r\n"); writer.write("chcp 65001\r\n"); // unicode support for Windows which uses Chinese diff --git a/src/main/java/org/cubewhy/celestial/gui/pages/GuiNews.java b/src/main/java/org/cubewhy/celestial/gui/pages/GuiNews.java index 303d21f8..7dcfc131 100644 --- a/src/main/java/org/cubewhy/celestial/gui/pages/GuiNews.java +++ b/src/main/java/org/cubewhy/celestial/gui/pages/GuiNews.java @@ -33,6 +33,7 @@ public GuiNews() throws IOException { private void initGui() { // render blogPosts + this.getVerticalScrollBar().setUnitIncrement(30); log.info("Loading blogPosts (gui)"); if (blogPosts.isJsonNull()) { log.error("Failed to load blog posts"); From 7ca3e39a62a38295bd99ba429000f258346d310a Mon Sep 17 00:00:00 2001 From: cubewhy Date: Mon, 1 Jan 2024 17:28:14 +0800 Subject: [PATCH 38/42] change order of commands --- src/main/java/org/cubewhy/celestial/Celestial.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/org/cubewhy/celestial/Celestial.java b/src/main/java/org/cubewhy/celestial/Celestial.java index 36e71e91..68632b40 100644 --- a/src/main/java/org/cubewhy/celestial/Celestial.java +++ b/src/main/java/org/cubewhy/celestial/Celestial.java @@ -444,11 +444,11 @@ public static File launch(String version, String branch, String module) throws I // Microsoft Windows // NEW: Use CRLF (Windows 7) writer.write("@echo off\r\n"); + writer.write("chcp 65001\r\n"); // unicode support for Windows which uses Chinese writer.write("@rem Generated by LunarCN (Celestial Launcher)\r\n@rem Website: https://www.lunarclient.top/\r\n"); writer.write(String.format("@rem Version %s\r\n", GitUtils.getBuildVersion())); writer.write("@rem Please donate to support us to continue develop https://www.lunarclient.top/donate\r\n"); writer.write("@rem You can run this script to debug your game, or share this script to developers to resolve your launch problem\r\n"); - writer.write("chcp 65001\r\n"); // unicode support for Windows which uses Chinese writer.write("cd /d " + installationDir + "\r\n"); } else { // Others From 502e13e54b9417f83f71bed62fd2f0c90089340b Mon Sep 17 00:00:00 2001 From: cubewhy Date: Mon, 1 Jan 2024 17:33:35 +0800 Subject: [PATCH 39/42] atomic --- src/main/java/org/cubewhy/celestial/Celestial.java | 3 ++- .../java/org/cubewhy/celestial/gui/GuiLauncher.java | 4 +--- .../celestial/gui/elements/GuiVersionSelect.java | 12 ++++++------ 3 files changed, 9 insertions(+), 10 deletions(-) diff --git a/src/main/java/org/cubewhy/celestial/Celestial.java b/src/main/java/org/cubewhy/celestial/Celestial.java index 68632b40..00341a74 100644 --- a/src/main/java/org/cubewhy/celestial/Celestial.java +++ b/src/main/java/org/cubewhy/celestial/Celestial.java @@ -32,6 +32,7 @@ import java.nio.charset.StandardCharsets; import java.nio.file.Files; import java.util.*; +import java.util.concurrent.atomic.AtomicLong; import static org.cubewhy.celestial.gui.GuiLauncher.statusBar; @@ -56,7 +57,7 @@ public class Celestial { public static final File gameLogFile = new File(configDir, "logs/game.log"); public static final File launcherLogFile = new File(configDir, "logs/launcher.log"); public static final boolean isDevelopMode = System.getProperties().containsKey("dev-mode"); - public static long gamePid = 0; + public static final AtomicLong gamePid = new AtomicLong(); public static File sessionFile; static { diff --git a/src/main/java/org/cubewhy/celestial/gui/GuiLauncher.java b/src/main/java/org/cubewhy/celestial/gui/GuiLauncher.java index 59409e21..12d7f9fc 100644 --- a/src/main/java/org/cubewhy/celestial/gui/GuiLauncher.java +++ b/src/main/java/org/cubewhy/celestial/gui/GuiLauncher.java @@ -25,9 +25,7 @@ import java.awt.datatransfer.Clipboard; import java.awt.datatransfer.StringSelection; import java.io.IOException; -import java.net.MalformedURLException; import java.net.URI; -import java.net.URISyntaxException; import java.util.Map; import static org.cubewhy.celestial.Celestial.*; @@ -135,7 +133,7 @@ public void findExistGame() throws IOException { if (java != null) { String pid = java.id(); log.info("Exist game process found! Pid: " + pid); - gamePid = Long.parseLong(pid); + gamePid.set(Long.parseLong(pid)); JOptionPane.showMessageDialog(this, String.format(f.getString("gui.launcher.game.exist.message"), pid), f.getString("gui.launcher.game.exist.title"), JOptionPane.INFORMATION_MESSAGE); java.detach(); } 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 fc306c28..cbce5436 100644 --- a/src/main/java/org/cubewhy/celestial/gui/elements/GuiVersionSelect.java +++ b/src/main/java/org/cubewhy/celestial/gui/elements/GuiVersionSelect.java @@ -125,11 +125,11 @@ private void initGui() throws IOException { private void beforeLaunch() throws IOException, AttachNotSupportedException { Celestial.completeSession(); - if (gamePid != 0) { + 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); } else { - gamePid = 0; + gamePid.set(0); } } } @@ -149,16 +149,16 @@ private void runGame(CreateProcess cp, Runnable run) throws IOException { VirtualMachine java = SystemUtils.findJava(LauncherData.getMainClass(null)); assert java != null; String id = java.id(); - gamePid = Long.parseLong(id); + gamePid.set(Long.parseLong(id)); java.detach(); } catch (Exception ex) { log.error("Failed to get the real pid of the game, is Celestial launched non java program?"); log.warn("process.pid() will be used to get the process id, which may not be the real PID"); - gamePid = p[0].pid(); + gamePid.set(p[0].pid()); } log.info("Pid: " + gamePid); statusBar.setText(String.format(f.getString("status.launch.started"), gamePid)); - new GameStartEvent(gamePid).call(); + new GameStartEvent(gamePid.get()).call(); } }); new Thread(() -> { @@ -171,7 +171,7 @@ private void runGame(CreateProcess cp, Runnable run) throws IOException { int code = p[0].waitFor(); log.info("Game terminated"); statusBar.setText(f.getString("status.launch.terminated")); - Celestial.gamePid = 0; + gamePid.set(0); new GameTerminateEvent().call(); if (code != 0) { // upload crash report From c1a4d46634c5473f61255ea253a15b8330620bfb Mon Sep 17 00:00:00 2001 From: cubewhy Date: Mon, 1 Jan 2024 17:55:28 +0800 Subject: [PATCH 40/42] use the most modern dialog --- .../celestial/gui/elements/GuiAddonManager.java | 5 +++-- .../java/org/cubewhy/celestial/utils/GuiUtils.java | 12 +++++++----- 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/src/main/java/org/cubewhy/celestial/gui/elements/GuiAddonManager.java b/src/main/java/org/cubewhy/celestial/gui/elements/GuiAddonManager.java index b3462c29..fdbbe753 100644 --- a/src/main/java/org/cubewhy/celestial/gui/elements/GuiAddonManager.java +++ b/src/main/java/org/cubewhy/celestial/gui/elements/GuiAddonManager.java @@ -21,6 +21,7 @@ import javax.swing.*; import javax.swing.border.TitledBorder; +import javax.swing.filechooser.FileNameExtensionFilter; import java.awt.*; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; @@ -166,7 +167,7 @@ private void initGui() { // TODO Stretch to the right btnAddAgent.addActionListener(e -> { - File file = GuiUtils.chooseFile(new SuffixFileFilter(".jar")); + File file = GuiUtils.chooseFile(new FileNameExtensionFilter("Agent", "jar")); if (file == null) { return; } @@ -190,7 +191,7 @@ private void initGui() { }); btnAddWeaveMod.addActionListener(e -> { - File file = GuiUtils.chooseFile(new SuffixFileFilter(".jar")); + File file = GuiUtils.chooseFile(new FileNameExtensionFilter("Weave Mod", "jar")); if (file == null) { return; } diff --git a/src/main/java/org/cubewhy/celestial/utils/GuiUtils.java b/src/main/java/org/cubewhy/celestial/utils/GuiUtils.java index ce5d2007..3e87b486 100644 --- a/src/main/java/org/cubewhy/celestial/utils/GuiUtils.java +++ b/src/main/java/org/cubewhy/celestial/utils/GuiUtils.java @@ -11,6 +11,8 @@ import org.cubewhy.celestial.Celestial; import org.jetbrains.annotations.Nullable; +import javax.swing.*; +import javax.swing.filechooser.FileFilter; import java.awt.*; import java.io.File; @@ -18,10 +20,10 @@ public final class GuiUtils { private GuiUtils() { } - public static @Nullable File chooseFile(AbstractFileFilter filter) { - FileDialog fileDialog = new FileDialog(Celestial.launcherFrame, "Choosing a file", FileDialog.LOAD); - fileDialog.setFilenameFilter(filter); // jar - fileDialog.setVisible(true); - return (fileDialog.getFile() == null) ? null : new File(fileDialog.getDirectory(), fileDialog.getFile()); + public static @Nullable File chooseFile(FileFilter filter) { + JFileChooser fileDialog = new JFileChooser(); + fileDialog.addChoosableFileFilter(filter); + fileDialog.showDialog(Celestial.launcherFrame, null); + return fileDialog.getSelectedFile(); } } From f9c4f3277a241f48848f2fe844e179b2576bcc13 Mon Sep 17 00:00:00 2001 From: cubewhy Date: Mon, 1 Jan 2024 17:58:42 +0800 Subject: [PATCH 41/42] cancel --- src/main/java/org/cubewhy/celestial/utils/GuiUtils.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/main/java/org/cubewhy/celestial/utils/GuiUtils.java b/src/main/java/org/cubewhy/celestial/utils/GuiUtils.java index 3e87b486..25534e3e 100644 --- a/src/main/java/org/cubewhy/celestial/utils/GuiUtils.java +++ b/src/main/java/org/cubewhy/celestial/utils/GuiUtils.java @@ -23,7 +23,6 @@ private GuiUtils() { public static @Nullable File chooseFile(FileFilter filter) { JFileChooser fileDialog = new JFileChooser(); fileDialog.addChoosableFileFilter(filter); - fileDialog.showDialog(Celestial.launcherFrame, null); - return fileDialog.getSelectedFile(); + return (fileDialog.showOpenDialog(Celestial.launcherFrame) == JFileChooser.APPROVE_OPTION) ? null : fileDialog.getSelectedFile(); } } From ac61a86ce7760077dca8d9789c2d1308c82582e3 Mon Sep 17 00:00:00 2001 From: cubewhy Date: Sat, 6 Jan 2024 11:43:21 +0800 Subject: [PATCH 42/42] remove OperatingSystem.java --- .../celestial/utils}/ManagedProcess.java | 8 +- .../cubewhy/celestial/utils/SystemUtils.java | 5 - .../hmcl/util/platform/OperatingSystem.java | 367 ------------------ 3 files changed, 7 insertions(+), 373 deletions(-) rename src/main/java/org/{jackhuang/hmcl/util/platform => cubewhy/celestial/utils}/ManagedProcess.java (96%) delete mode 100644 src/main/java/org/jackhuang/hmcl/util/platform/OperatingSystem.java diff --git a/src/main/java/org/jackhuang/hmcl/util/platform/ManagedProcess.java b/src/main/java/org/cubewhy/celestial/utils/ManagedProcess.java similarity index 96% rename from src/main/java/org/jackhuang/hmcl/util/platform/ManagedProcess.java rename to src/main/java/org/cubewhy/celestial/utils/ManagedProcess.java index 4cfd6b88..c2ba5ead 100644 --- a/src/main/java/org/jackhuang/hmcl/util/platform/ManagedProcess.java +++ b/src/main/java/org/cubewhy/celestial/utils/ManagedProcess.java @@ -1,5 +1,11 @@ -package org.jackhuang.hmcl.util.platform; +/* + * Celestial Launcher + * License under GPLv3 + * Do NOT remove this note if you want to copy this file. + */ + +package org.cubewhy.celestial.utils; import lombok.Getter; diff --git a/src/main/java/org/cubewhy/celestial/utils/SystemUtils.java b/src/main/java/org/cubewhy/celestial/utils/SystemUtils.java index 12e0627c..bb28f7e2 100644 --- a/src/main/java/org/cubewhy/celestial/utils/SystemUtils.java +++ b/src/main/java/org/cubewhy/celestial/utils/SystemUtils.java @@ -10,14 +10,9 @@ import com.sun.tools.attach.VirtualMachine; import com.sun.tools.attach.VirtualMachineDescriptor; import lombok.extern.slf4j.Slf4j; -import org.cubewhy.celestial.Celestial; -import org.cubewhy.celestial.utils.lunar.LauncherData; -import org.jackhuang.hmcl.util.platform.ManagedProcess; import org.jetbrains.annotations.Nullable; import java.io.IOException; -import java.util.Arrays; -import java.util.List; // from hmcl launcher @Slf4j diff --git a/src/main/java/org/jackhuang/hmcl/util/platform/OperatingSystem.java b/src/main/java/org/jackhuang/hmcl/util/platform/OperatingSystem.java deleted file mode 100644 index 8990840b..00000000 --- a/src/main/java/org/jackhuang/hmcl/util/platform/OperatingSystem.java +++ /dev/null @@ -1,367 +0,0 @@ -/* - * Hello Minecraft! Launcher - * Copyright (C) 2021 huangyuhui and contributors - * - * 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 org.jackhuang.hmcl.util.platform; - -import java.io.BufferedReader; -import java.io.File; -import java.io.IOException; -import java.io.InputStreamReader; -import java.nio.charset.Charset; -import java.nio.charset.StandardCharsets; -import java.nio.charset.UnsupportedCharsetException; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.Paths; -import java.util.Arrays; -import java.util.Locale; -import java.util.Optional; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -/** - * Represents the operating system. - * - * @author huangyuhui - */ -public enum OperatingSystem { - /** - * Microsoft Windows. - */ - WINDOWS("windows"), - /** - * Linux and Unix like OS, including Solaris. - */ - LINUX("linux"), - /** - * Mac OS X. - */ - OSX("osx"), - /** - * Unknown operating system. - */ - UNKNOWN("universal"); - - private final String checkedName; - - OperatingSystem(String checkedName) { - this.checkedName = checkedName; - } - - public String getCheckedName() { - return checkedName; - } - - /** - * The current operating system. - */ - public static final OperatingSystem CURRENT_OS = parseOSName(System.getProperty("os.name")); - - /** - * The total memory/MB this computer have. - */ - public static final int TOTAL_MEMORY; - - /** - * The suggested memory size/MB for Minecraft to allocate. - */ - public static final int SUGGESTED_MEMORY; - - public static final String PATH_SEPARATOR = File.pathSeparator; - public static final String FILE_SEPARATOR = File.separator; - public static final String LINE_SEPARATOR = System.lineSeparator(); - - /** - * The system default charset. - */ - public static final Charset NATIVE_CHARSET; - - /** - * Windows system build number. - * When the version number is not recognized or on another system, the value will be -1. - */ - public static final int SYSTEM_BUILD_NUMBER; - - /** - * The name of current operating system. - */ - public static final String SYSTEM_NAME; - - /** - * The version of current operating system. - */ - public static final String SYSTEM_VERSION; - - public static final Pattern INVALID_RESOURCE_CHARACTERS; - private static final String[] INVALID_RESOURCE_BASENAMES; - private static final String[] INVALID_RESOURCE_FULLNAMES; - - private static final Pattern MEMINFO_PATTERN = Pattern.compile("^(?.*?):\\s+(?\\d+) kB?$"); - - static { - String nativeEncoding = System.getProperty("native.encoding"); - String hmclNativeEncoding = System.getProperty("hmcl.native.encoding"); - Charset nativeCharset = Charset.defaultCharset(); - - try { - if (hmclNativeEncoding != null) { - nativeCharset = Charset.forName(hmclNativeEncoding); - } else { - if (nativeEncoding != null && !nativeEncoding.equalsIgnoreCase(nativeCharset.name())) { - nativeCharset = Charset.forName(nativeEncoding); - } - - if (nativeCharset == StandardCharsets.UTF_8 || nativeCharset == StandardCharsets.US_ASCII) { - nativeCharset = StandardCharsets.UTF_8; - } else if ("GBK".equalsIgnoreCase(nativeCharset.name()) || "GB2312".equalsIgnoreCase(nativeCharset.name())) { - nativeCharset = Charset.forName("GB18030"); - } - } - } catch (UnsupportedCharsetException e) { - e.printStackTrace(); - } - NATIVE_CHARSET = nativeCharset; - - if (CURRENT_OS == WINDOWS) { - String versionNumber = null; - int buildNumber = -1; - - try { - Process process = Runtime.getRuntime().exec(new String[]{"cmd", "ver"}); - try (BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream(), NATIVE_CHARSET))) { - Matcher matcher = Pattern.compile("(?[0-9]+\\.[0-9]+\\.(?[0-9]+)(\\.[0-9]+)?)]$") - .matcher(reader.readLine().trim()); - - if (matcher.find()) { - versionNumber = matcher.group("version"); - buildNumber = Integer.parseInt(matcher.group("build")); - } - } - process.destroy(); - } catch (Throwable ignored) { - } - - if (versionNumber == null) { - versionNumber = System.getProperty("os.version"); - } - - String osName = System.getProperty("os.name"); - - // Java 17 or earlier recognizes Windows 11 as Windows 10 - if (osName.equals("Windows 10") && buildNumber >= 22000) { - osName = "Windows 11"; - } - - SYSTEM_NAME = osName; - SYSTEM_VERSION = versionNumber; - SYSTEM_BUILD_NUMBER = buildNumber; - } else { - SYSTEM_NAME = System.getProperty("os.name"); - SYSTEM_VERSION = System.getProperty("os.version"); - SYSTEM_BUILD_NUMBER = -1; - } - - TOTAL_MEMORY = getPhysicalMemoryStatus() - .map(physicalMemoryStatus -> (int) (physicalMemoryStatus.getTotal() / 1024 / 1024)) - .orElse(1024); - - SUGGESTED_MEMORY = TOTAL_MEMORY >= 32768 ? 8192 : (int) (Math.round(1.0 * TOTAL_MEMORY / 4.0 / 128.0) * 128); - - // setup the invalid names - if (CURRENT_OS == WINDOWS) { - // valid names and characters taken from http://msdn.microsoft.com/library/default.asp?url=/library/en-us/fileio/fs/naming_a_file.asp - INVALID_RESOURCE_CHARACTERS = Pattern.compile("[/\"<>|?*:\\\\]"); - INVALID_RESOURCE_BASENAMES = new String[]{"aux", "com1", "com2", "com3", "com4", - "com5", "com6", "com7", "com8", "com9", "con", "lpt1", "lpt2", - "lpt3", "lpt4", "lpt5", "lpt6", "lpt7", "lpt8", "lpt9", "nul", "prn"}; - Arrays.sort(INVALID_RESOURCE_BASENAMES); - //CLOCK$ may be used if an extension is provided - INVALID_RESOURCE_FULLNAMES = new String[]{"clock$"}; - } else { - //only front slash and null char are invalid on UNIXes - //taken from http://www.faqs.org/faqs/unix-faq/faq/part2/section-2.html - INVALID_RESOURCE_CHARACTERS = null; - INVALID_RESOURCE_BASENAMES = null; - INVALID_RESOURCE_FULLNAMES = null; - } - } - - public static OperatingSystem parseOSName(String name) { - if (name == null) { - return UNKNOWN; - } - - name = name.trim().toLowerCase(Locale.ROOT); - - if (name.contains("win")) - return WINDOWS; - else if (name.contains("mac")) - return OSX; - else if (name.contains("solaris") || name.contains("linux") || name.contains("unix") || name.contains("sunos")) - return LINUX; - else - return UNKNOWN; - } - - @SuppressWarnings("deprecation") - public static Optional getPhysicalMemoryStatus() { - if (CURRENT_OS == LINUX) { - try { - long free = 0, available = 0, total = 0; - for (String line : Files.readAllLines(Paths.get("/proc/meminfo"))) { - Matcher matcher = MEMINFO_PATTERN.matcher(line); - if (matcher.find()) { - String key = matcher.group("key"); - String value = matcher.group("value"); - if ("MemAvailable".equals(key)) { - available = Long.parseLong(value) * 1024; - } - if ("MemFree".equals(key)) { - free = Long.parseLong(value) * 1024; - } - if ("MemTotal".equals(key)) { - total = Long.parseLong(value) * 1024; - } - } - } - if (total > 0) { - return Optional.of(new PhysicalMemoryStatus(total, available > 0 ? available : free)); - } - } catch (IOException e) { - e.printStackTrace(); - } - } - - try { - java.lang.management.OperatingSystemMXBean bean = java.lang.management.ManagementFactory.getOperatingSystemMXBean(); - if (bean instanceof com.sun.management.OperatingSystemMXBean) { - com.sun.management.OperatingSystemMXBean sunBean = - (com.sun.management.OperatingSystemMXBean) - java.lang.management.ManagementFactory.getOperatingSystemMXBean(); - return Optional.of(new PhysicalMemoryStatus(sunBean.getTotalPhysicalMemorySize(), sunBean.getFreePhysicalMemorySize())); - } - } catch (NoClassDefFoundError ignored) { - } - return Optional.empty(); - } - - @SuppressWarnings("removal") - public static void forceGC() { - System.gc(); - try { - System.runFinalization(); - System.gc(); - } catch (NoSuchMethodError ignored) { - } - } - - public static Path getWorkingDirectory(String folder) { - String home = System.getProperty("user.home", "."); - switch (OperatingSystem.CURRENT_OS) { - case LINUX: - return Paths.get(home, "." + folder).toAbsolutePath(); - case WINDOWS: - String appdata = System.getenv("APPDATA"); - return Paths.get(appdata == null ? home : appdata, "." + folder).toAbsolutePath(); - case OSX: - return Paths.get(home, "Library", "Application Support", folder).toAbsolutePath(); - default: - return Paths.get(home, folder).toAbsolutePath(); - } - } - - /** - * Returns true if the given name is a valid file name on this operating system, - * and false otherwise. - */ - public static boolean isNameValid(String name) { - // empty filename is not allowed - if (name.isEmpty()) - return false; - // . and .. have special meaning on all platforms - if (name.equals(".")) - return false; - // \0 and / are forbidden on all platforms - if (name.indexOf('/') != -1 || name.indexOf('\0') != -1) - return false; - - if (CURRENT_OS == WINDOWS) { // Windows only - char lastChar = name.charAt(name.length() - 1); - // filenames ending in dot are not valid - if (lastChar == '.') - return false; - // file names ending with whitespace are truncated (bug 118997) - if (Character.isWhitespace(lastChar)) - return false; - int dot = name.indexOf('.'); - // on windows, filename suffixes are not relevant to name validity - String basename = dot == -1 ? name : name.substring(0, dot); - if (Arrays.binarySearch(INVALID_RESOURCE_BASENAMES, basename.toLowerCase(Locale.ROOT)) >= 0) - return false; - if (Arrays.binarySearch(INVALID_RESOURCE_FULLNAMES, name.toLowerCase(Locale.ROOT)) >= 0) - return false; - if (INVALID_RESOURCE_CHARACTERS.matcher(name).find()) - return false; - } - - return true; - } - - public static class PhysicalMemoryStatus { - private final long total; - private final long available; - - public PhysicalMemoryStatus(long total, long available) { - this.total = total; - this.available = available; - } - - public long getTotal() { - return total; - } - - public double getTotalGB() { - return toGigaBytes(total); - } - - public long getUsed() { - return hasAvailable() ? total - available : 0; - } - - public double getUsedGB() { - return toGigaBytes(getUsed()); - } - - public long getAvailable() { - return available; - } - - public double getAvailableGB() { - return toGigaBytes(available); - } - - public boolean hasAvailable() { - return available >= 0; - } - - public static double toGigaBytes(long bytes) { - return bytes / 1024. / 1024. / 1024.; - } - - public static final PhysicalMemoryStatus INVALID = new PhysicalMemoryStatus(0, -1); - } -}