From a5b46254fcf1849c9a18894f440f82de6e7bddc7 Mon Sep 17 00:00:00 2001 From: 502y <53784463+502y@users.noreply.github.com> Date: Fri, 14 Feb 2025 23:30:24 +0800 Subject: [PATCH 01/13] fix(gradle): fix non-UTF-8 envrionment cause gradle command break --- build.gradle.kts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/build.gradle.kts b/build.gradle.kts index b28d5de..af61a98 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -13,6 +13,10 @@ java { targetCompatibility = JavaVersion.VERSION_1_8 } +tasks.withType { + options.encoding = "UTF-8" +} + tasks.shadowJar { manifest { attributes( From bf988816a9f6cef805a220af8fead81ee7bfe2a8 Mon Sep 17 00:00:00 2001 From: 502y <53784463+502y@users.noreply.github.com> Date: Fri, 6 Jun 2025 18:06:54 +0800 Subject: [PATCH 02/13] feat: try get modlist from modloader --- .../java/i18nupdatemod/I18nUpdateMod.java | 9 +++++- .../fabricloader/FabricLoaderMod.java | 32 ++++++++++++++++++- .../launchwrapper/LaunchWrapperTweaker.java | 3 +- .../modlauncher/ModLauncherService.java | 15 ++++++--- 4 files changed, 51 insertions(+), 8 deletions(-) diff --git a/src/main/java/i18nupdatemod/I18nUpdateMod.java b/src/main/java/i18nupdatemod/I18nUpdateMod.java index 1afd352..ad13bd0 100644 --- a/src/main/java/i18nupdatemod/I18nUpdateMod.java +++ b/src/main/java/i18nupdatemod/I18nUpdateMod.java @@ -9,6 +9,8 @@ import i18nupdatemod.entity.GameAssetDetail; import i18nupdatemod.util.FileUtil; import i18nupdatemod.util.Log; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import java.io.InputStream; import java.io.InputStreamReader; @@ -27,12 +29,17 @@ public class I18nUpdateMod { public static final Gson GSON = new Gson(); - public static void init(Path minecraftPath, String minecraftVersion, String loader) { + public static void init(Path minecraftPath, String minecraftVersion, String loader,@NotNull List modList) { try (InputStream is = I18nUpdateMod.class.getResourceAsStream("/i18nMetaData.json")) { MOD_VERSION = GSON.fromJson(new InputStreamReader(is), JsonObject.class).get("version").getAsString(); } catch (Exception e) { Log.warning("Error getting version: " + e); } + if(modList.isEmpty()){ + Log.debug("modList: " + modList); + }else{ + Log.debug("modList is null"); + } Log.info(String.format("I18nUpdate Mod %s is loaded in %s with %s", MOD_VERSION, minecraftVersion, loader)); Log.debug(String.format("Minecraft path: %s", minecraftPath)); String localStorage = getLocalStoragePos(minecraftPath); diff --git a/src/main/java/i18nupdatemod/fabricloader/FabricLoaderMod.java b/src/main/java/i18nupdatemod/fabricloader/FabricLoaderMod.java index ad740a0..0270ec5 100644 --- a/src/main/java/i18nupdatemod/fabricloader/FabricLoaderMod.java +++ b/src/main/java/i18nupdatemod/fabricloader/FabricLoaderMod.java @@ -5,8 +5,12 @@ import i18nupdatemod.util.Reflection; import net.fabricmc.api.ClientModInitializer; import net.fabricmc.loader.api.FabricLoader; +import net.fabricmc.loader.impl.ModContainerImpl; import java.nio.file.Path; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; //1.14-latest public class FabricLoaderMod implements ClientModInitializer { @@ -20,7 +24,7 @@ public void onInitializeClient() { Log.warning("Minecraft version not found"); return; } - I18nUpdateMod.init(gameDir, mcVersion, "Fabric"); + I18nUpdateMod.init(gameDir, mcVersion, "Fabric", getMods()); } private String getMcVersion() { @@ -44,4 +48,30 @@ private String getMcVersion() { } return null; } + + + private List getMods(){ + List modList = null; + try { + // Fabric + @SuppressWarnings("unchecked") + final Map instance = (Map)Reflection.clazz("net.fabricmc.loader.impl.FabricLoaderImpl") + .get("INSTANCE") + .get("modMap").get(); + modList = new ArrayList<>(instance.keySet()); + } catch (Exception ignored) { + + } + try { + // Quilt + @SuppressWarnings("unchecked") + final Map instance = (Map)Reflection.clazz("org.quiltmc.loader.impl.QuiltLoaderImpl") + .get("INSTANCE") + .get("modMap").get(); + modList = new ArrayList<>(instance.keySet()); + } catch (Exception ignored) { + + } + return modList; + } } diff --git a/src/main/java/i18nupdatemod/launchwrapper/LaunchWrapperTweaker.java b/src/main/java/i18nupdatemod/launchwrapper/LaunchWrapperTweaker.java index 72e522f..c45cbd2 100644 --- a/src/main/java/i18nupdatemod/launchwrapper/LaunchWrapperTweaker.java +++ b/src/main/java/i18nupdatemod/launchwrapper/LaunchWrapperTweaker.java @@ -7,6 +7,7 @@ import net.minecraft.launchwrapper.LaunchClassLoader; import java.io.File; +import java.util.ArrayList; import java.util.List; //1.6-1.12.2 @@ -20,7 +21,7 @@ public void acceptOptions(List args, File gameDir, File assetsDir, Strin Log.warning("Failed to get minecraft version."); return; } - I18nUpdateMod.init(gameDir.toPath(), mcVersion, "Forge"); + I18nUpdateMod.init(gameDir.toPath(), mcVersion, "Forge", new ArrayList<>()); } @Override diff --git a/src/main/java/i18nupdatemod/modlauncher/ModLauncherService.java b/src/main/java/i18nupdatemod/modlauncher/ModLauncherService.java index f8323e4..4f9865a 100644 --- a/src/main/java/i18nupdatemod/modlauncher/ModLauncherService.java +++ b/src/main/java/i18nupdatemod/modlauncher/ModLauncherService.java @@ -14,10 +14,7 @@ import java.io.InputStream; import java.io.InputStreamReader; import java.nio.file.Path; -import java.util.Collections; -import java.util.List; -import java.util.Optional; -import java.util.Set; +import java.util.*; import static i18nupdatemod.I18nUpdateMod.GSON; @@ -31,6 +28,14 @@ public class ModLauncherService implements ITransformationService { @Override public void initialize(IEnvironment environment) { Optional minecraftPath = environment.getProperty(IEnvironment.Keys.GAMEDIR.get()); + // 没法拿到i18n后面加载的模组 + List> tmp = environment.getProperty(IEnvironment.Keys.MODLIST.get()).orElse(null); + List modList = new ArrayList<>(); + if (tmp != null) { + for (Map map : tmp) { + modList.add(map.get("name")); + } + } if (!minecraftPath.isPresent()) { Log.warning("Minecraft path not found"); return; @@ -41,7 +46,7 @@ public void initialize(IEnvironment environment) { Log.warning("Minecraft version not found"); return; } - I18nUpdateMod.init(minecraftPath.get(), minecraftVersion, "Forge"); + I18nUpdateMod.init(minecraftPath.get(), minecraftVersion, "Forge", modList); } @Override From e3592ce9fa3ecf1347c3a4816a785d2597c12e03 Mon Sep 17 00:00:00 2001 From: 502y <53784463+502y@users.noreply.github.com> Date: Sun, 16 Feb 2025 15:03:10 +0800 Subject: [PATCH 03/13] =?UTF-8?q?feat(core):=20=E6=9C=AC=E5=9C=B0=E6=8C=89?= =?UTF-8?q?=E6=A8=A1=E7=BB=84=E6=89=93=E5=8C=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/i18nupdatemod/I18nUpdateMod.java | 54 +++++++++++++++---- .../core/ResourcePackConverter.java | 6 ++- .../fabricloader/FabricLoaderMod.java | 22 ++++---- .../launchwrapper/LaunchWrapperTweaker.java | 4 +- .../modlauncher/ModLauncherService.java | 10 +--- 5 files changed, 61 insertions(+), 35 deletions(-) diff --git a/src/main/java/i18nupdatemod/I18nUpdateMod.java b/src/main/java/i18nupdatemod/I18nUpdateMod.java index ad13bd0..7dcd1f8 100644 --- a/src/main/java/i18nupdatemod/I18nUpdateMod.java +++ b/src/main/java/i18nupdatemod/I18nUpdateMod.java @@ -10,16 +10,16 @@ import i18nupdatemod.util.FileUtil; import i18nupdatemod.util.Log; import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; +import java.io.File; import java.io.InputStream; import java.io.InputStreamReader; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; -import java.util.ArrayList; -import java.util.List; -import java.util.Objects; +import java.util.*; +import java.util.jar.JarEntry; +import java.util.jar.JarFile; import java.util.stream.Collectors; import java.util.stream.Stream; @@ -29,17 +29,21 @@ public class I18nUpdateMod { public static final Gson GSON = new Gson(); - public static void init(Path minecraftPath, String minecraftVersion, String loader,@NotNull List modList) { + public static void init(Path minecraftPath, String minecraftVersion, String loader, @NotNull HashSet modDomainsSet) { try (InputStream is = I18nUpdateMod.class.getResourceAsStream("/i18nMetaData.json")) { MOD_VERSION = GSON.fromJson(new InputStreamReader(is), JsonObject.class).get("version").getAsString(); } catch (Exception e) { Log.warning("Error getting version: " + e); } - if(modList.isEmpty()){ - Log.debug("modList: " + modList); - }else{ - Log.debug("modList is null"); + + Log.debug("modList from loader:" + modDomainsSet); + if ("Forge".equals(loader)) { + modDomainsSet = getModDomainsFromModsFolder(minecraftPath, minecraftVersion, loader); + Log.debug("modList from mods folder: " + modDomainsSet); + } + modDomainsSet.remove("i18nupdatemod"); + Log.info(String.format("I18nUpdate Mod %s is loaded in %s with %s", MOD_VERSION, minecraftVersion, loader)); Log.debug(String.format("Minecraft path: %s", minecraftPath)); String localStorage = getLocalStoragePos(minecraftPath); @@ -82,7 +86,7 @@ public static void init(Path minecraftPath, String minecraftVersion, String load FileUtil.setTemporaryDirPath(Paths.get(localStorage, "." + MOD_ID, minecraftVersion)); applyFileName = assets.covertFileName; ResourcePackConverter converter = new ResourcePackConverter(languagePacks, applyFileName); - converter.convert(assets.covertPackFormat, getResourcePackDescription(assets.downloads)); + converter.convert(assets.covertPackFormat, getResourcePackDescription(assets.downloads), modDomainsSet); } //Apply resource pack @@ -128,4 +132,34 @@ public static String getLocalStoragePos(Path minecraftPath) { Objects::nonNull ).findFirst().orElse(xdgDataHome); } + + private static HashSet getModDomainsFromModsFolder(Path minecraftPath, String minecraftVersion, String loader) { + HashSet modDomainSet = new HashSet<>(); + Path modsPath = minecraftPath.resolve("mods"); + String[] modsNamesList = modsPath.toFile().list((dir, name) -> name.endsWith(".jar")); + if (modsNamesList != null) { + for (String name : modsNamesList) { + modDomainSet.addAll(getModDomainFromAsset(modsPath.resolve(name).toFile())); + } + } + return modDomainSet; + } + + private static HashSet getModDomainFromAsset(File modsPath) { + HashSet modList = new HashSet<>(); + try (JarFile jarFile = new JarFile(modsPath)) { + Enumeration entries = jarFile.entries(); + while (entries.hasMoreElements()) { + JarEntry entry = entries.nextElement(); + String path = entry.getName(); + // 匹配 assets/xxx/ + if (path.startsWith("assets/") && path.split("/").length >= 2) { + modList.add(path.split("/")[1]); + } + } + } catch (Exception ignored) { + } + return modList; + } + } \ No newline at end of file diff --git a/src/main/java/i18nupdatemod/core/ResourcePackConverter.java b/src/main/java/i18nupdatemod/core/ResourcePackConverter.java index 0a97712..d6544d4 100644 --- a/src/main/java/i18nupdatemod/core/ResourcePackConverter.java +++ b/src/main/java/i18nupdatemod/core/ResourcePackConverter.java @@ -32,7 +32,7 @@ public ResourcePackConverter(List resourcePack, String filename) { this.tmpFilePath = FileUtil.getTemporaryPath(filename); } - public void convert(int packFormat, String description) throws Exception { + public void convert(int packFormat, String description, HashSet modDomainsSet) throws Exception { Set fileList = new HashSet<>(); try (ZipOutputStream zos = new ZipOutputStream( Files.newOutputStream(tmpFilePath), @@ -44,6 +44,10 @@ public void convert(int packFormat, String description) throws Exception { for (Enumeration e = zf.entries(); e.hasMoreElements(); ) { ZipEntry ze = e.nextElement(); String name = ze.getName(); + if (name.split("/").length >= 2 && !modDomainsSet.contains(name.split("/")[1])) { + continue; + } + //Log.debug(name); // Don't put same file if (fileList.contains(name)) { // Log.debug(name + ": DUPLICATE"); diff --git a/src/main/java/i18nupdatemod/fabricloader/FabricLoaderMod.java b/src/main/java/i18nupdatemod/fabricloader/FabricLoaderMod.java index 0270ec5..d27cf58 100644 --- a/src/main/java/i18nupdatemod/fabricloader/FabricLoaderMod.java +++ b/src/main/java/i18nupdatemod/fabricloader/FabricLoaderMod.java @@ -5,11 +5,9 @@ import i18nupdatemod.util.Reflection; import net.fabricmc.api.ClientModInitializer; import net.fabricmc.loader.api.FabricLoader; -import net.fabricmc.loader.impl.ModContainerImpl; import java.nio.file.Path; -import java.util.ArrayList; -import java.util.List; +import java.util.HashSet; import java.util.Map; //1.14-latest @@ -50,25 +48,23 @@ private String getMcVersion() { } - private List getMods(){ - List modList = null; - try { + private HashSet getMods() { + HashSet modList = new HashSet<>(); + try { // Fabric - @SuppressWarnings("unchecked") - final Map instance = (Map)Reflection.clazz("net.fabricmc.loader.impl.FabricLoaderImpl") + @SuppressWarnings("unchecked") final Map instance = (Map) Reflection.clazz("net.fabricmc.loader.impl.FabricLoaderImpl") .get("INSTANCE") .get("modMap").get(); - modList = new ArrayList<>(instance.keySet()); - } catch (Exception ignored) { + modList = new HashSet<>(instance.keySet()); + } catch (Exception ignored) { } try { // Quilt - @SuppressWarnings("unchecked") - final Map instance = (Map)Reflection.clazz("org.quiltmc.loader.impl.QuiltLoaderImpl") + @SuppressWarnings("unchecked") final Map instance = (Map) Reflection.clazz("org.quiltmc.loader.impl.QuiltLoaderImpl") .get("INSTANCE") .get("modMap").get(); - modList = new ArrayList<>(instance.keySet()); + modList = new HashSet<>(instance.keySet()); } catch (Exception ignored) { } diff --git a/src/main/java/i18nupdatemod/launchwrapper/LaunchWrapperTweaker.java b/src/main/java/i18nupdatemod/launchwrapper/LaunchWrapperTweaker.java index c45cbd2..45e599f 100644 --- a/src/main/java/i18nupdatemod/launchwrapper/LaunchWrapperTweaker.java +++ b/src/main/java/i18nupdatemod/launchwrapper/LaunchWrapperTweaker.java @@ -7,7 +7,7 @@ import net.minecraft.launchwrapper.LaunchClassLoader; import java.io.File; -import java.util.ArrayList; +import java.util.HashSet; import java.util.List; //1.6-1.12.2 @@ -21,7 +21,7 @@ public void acceptOptions(List args, File gameDir, File assetsDir, Strin Log.warning("Failed to get minecraft version."); return; } - I18nUpdateMod.init(gameDir.toPath(), mcVersion, "Forge", new ArrayList<>()); + I18nUpdateMod.init(gameDir.toPath(), mcVersion, "Forge", new HashSet<>()); } @Override diff --git a/src/main/java/i18nupdatemod/modlauncher/ModLauncherService.java b/src/main/java/i18nupdatemod/modlauncher/ModLauncherService.java index 4f9865a..21dcb4f 100644 --- a/src/main/java/i18nupdatemod/modlauncher/ModLauncherService.java +++ b/src/main/java/i18nupdatemod/modlauncher/ModLauncherService.java @@ -28,14 +28,6 @@ public class ModLauncherService implements ITransformationService { @Override public void initialize(IEnvironment environment) { Optional minecraftPath = environment.getProperty(IEnvironment.Keys.GAMEDIR.get()); - // 没法拿到i18n后面加载的模组 - List> tmp = environment.getProperty(IEnvironment.Keys.MODLIST.get()).orElse(null); - List modList = new ArrayList<>(); - if (tmp != null) { - for (Map map : tmp) { - modList.add(map.get("name")); - } - } if (!minecraftPath.isPresent()) { Log.warning("Minecraft path not found"); return; @@ -46,7 +38,7 @@ public void initialize(IEnvironment environment) { Log.warning("Minecraft version not found"); return; } - I18nUpdateMod.init(minecraftPath.get(), minecraftVersion, "Forge", modList); + I18nUpdateMod.init(minecraftPath.get(), minecraftVersion, "Forge", new HashSet<>()); } @Override From 438e031dd843eee92e1ff967e8dc3adc5e3150ba Mon Sep 17 00:00:00 2001 From: 502y <53784463+502y@users.noreply.github.com> Date: Mon, 9 Jun 2025 10:12:11 +0800 Subject: [PATCH 04/13] =?UTF-8?q?refactor:=20=E6=B3=A8=E9=87=8A=E8=B0=83?= =?UTF-8?q?=E8=AF=95=E6=97=A5=E5=BF=97=E8=BE=93=E5=87=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/i18nupdatemod/I18nUpdateMod.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/i18nupdatemod/I18nUpdateMod.java b/src/main/java/i18nupdatemod/I18nUpdateMod.java index 7dcd1f8..37c74af 100644 --- a/src/main/java/i18nupdatemod/I18nUpdateMod.java +++ b/src/main/java/i18nupdatemod/I18nUpdateMod.java @@ -36,10 +36,10 @@ public static void init(Path minecraftPath, String minecraftVersion, String load Log.warning("Error getting version: " + e); } - Log.debug("modList from loader:" + modDomainsSet); + //Log.debug("modList from loader:" + modDomainsSet); if ("Forge".equals(loader)) { modDomainsSet = getModDomainsFromModsFolder(minecraftPath, minecraftVersion, loader); - Log.debug("modList from mods folder: " + modDomainsSet); + //Log.debug("modList from mods folder: " + modDomainsSet); } modDomainsSet.remove("i18nupdatemod"); From 6591997d18b53be0fe806ef5a6e2870da9fd960e Mon Sep 17 00:00:00 2001 From: 502y <53784463+502y@users.noreply.github.com> Date: Tue, 10 Jun 2025 10:15:27 +0800 Subject: [PATCH 05/13] =?UTF-8?q?feat(core):=20=E6=B7=BB=E5=8A=A0=E6=B5=8B?= =?UTF-8?q?=E9=80=9F=E3=80=81=E5=B0=9D=E8=AF=95=E9=80=9A=E8=BF=87pop=20out?= =?UTF-8?q?=E6=8F=90=E5=89=8D=E7=BB=93=E6=9D=9Fconverter?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/i18nupdatemod/I18nUpdateMod.java | 3 +++ .../java/i18nupdatemod/core/ResourcePackConverter.java | 7 +++++++ 2 files changed, 10 insertions(+) diff --git a/src/main/java/i18nupdatemod/I18nUpdateMod.java b/src/main/java/i18nupdatemod/I18nUpdateMod.java index 37c74af..06465e4 100644 --- a/src/main/java/i18nupdatemod/I18nUpdateMod.java +++ b/src/main/java/i18nupdatemod/I18nUpdateMod.java @@ -30,6 +30,7 @@ public class I18nUpdateMod { public static final Gson GSON = new Gson(); public static void init(Path minecraftPath, String minecraftVersion, String loader, @NotNull HashSet modDomainsSet) { + long startTime = System.nanoTime(); try (InputStream is = I18nUpdateMod.class.getResourceAsStream("/i18nMetaData.json")) { MOD_VERSION = GSON.fromJson(new InputStreamReader(is), JsonObject.class).get("version").getAsString(); } catch (Exception e) { @@ -94,6 +95,8 @@ public static void init(Path minecraftPath, String minecraftVersion, String load config.addResourcePack("Minecraft-Mod-Language-Modpack", (minecraftMajorVersion <= 12 ? "" : "file/") + applyFileName); config.writeToFile(); + long endTime = System.nanoTime(); + Log.info(String.format("I18nUpdateMod finished in %.2f ms", (endTime - startTime) / 1000000.0)); } catch (Exception e) { Log.warning(String.format("Failed to update resource pack: %s", e)); // e.printStackTrace(); diff --git a/src/main/java/i18nupdatemod/core/ResourcePackConverter.java b/src/main/java/i18nupdatemod/core/ResourcePackConverter.java index d6544d4..2ce833c 100644 --- a/src/main/java/i18nupdatemod/core/ResourcePackConverter.java +++ b/src/main/java/i18nupdatemod/core/ResourcePackConverter.java @@ -38,6 +38,7 @@ public void convert(int packFormat, String description, HashSet modDomai Files.newOutputStream(tmpFilePath), StandardCharsets.UTF_8)) { // zos.setMethod(ZipOutputStream.STORED); + resourcePackLoop: for (Path p : sourcePath) { Log.info("Converting: " + p); try (ZipFile zf = new ZipFile(p.toFile(), StandardCharsets.UTF_8)) { @@ -45,6 +46,11 @@ public void convert(int packFormat, String description, HashSet modDomai ZipEntry ze = e.nextElement(); String name = ze.getName(); if (name.split("/").length >= 2 && !modDomainsSet.contains(name.split("/")[1])) { + modDomainsSet.remove(name.split("/")[1]); + if (name.isEmpty()) { + Log.debug(modDomainsSet.toString()); + break resourcePackLoop; + } continue; } //Log.debug(name); @@ -71,6 +77,7 @@ public void convert(int packFormat, String description, HashSet modDomai } } zos.close(); + Log.debug("unsolved mod domains" + modDomainsSet.toString()); Log.info("Converted: %s -> %s", sourcePath, tmpFilePath); FileUtil.syncTmpFile(tmpFilePath, filePath, true); } catch (Exception e) { From b9c4102b2cc92473c686629ebeb551535028a399 Mon Sep 17 00:00:00 2001 From: 502y <53784463+502y@users.noreply.github.com> Date: Tue, 22 Jul 2025 00:34:20 +0800 Subject: [PATCH 06/13] =?UTF-8?q?feat:=20=E4=BC=98=E5=8C=96=E4=BB=A3?= =?UTF-8?q?=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/i18nupdatemod/core/ResourcePackConverter.java | 9 ++++----- .../java/i18nupdatemod/fabricloader/FabricLoaderMod.java | 2 ++ 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/src/main/java/i18nupdatemod/core/ResourcePackConverter.java b/src/main/java/i18nupdatemod/core/ResourcePackConverter.java index 2ce833c..a617bf3 100644 --- a/src/main/java/i18nupdatemod/core/ResourcePackConverter.java +++ b/src/main/java/i18nupdatemod/core/ResourcePackConverter.java @@ -34,9 +34,7 @@ public ResourcePackConverter(List resourcePack, String filename) { public void convert(int packFormat, String description, HashSet modDomainsSet) throws Exception { Set fileList = new HashSet<>(); - try (ZipOutputStream zos = new ZipOutputStream( - Files.newOutputStream(tmpFilePath), - StandardCharsets.UTF_8)) { + try (ZipOutputStream zos = new ZipOutputStream(Files.newOutputStream(tmpFilePath), StandardCharsets.UTF_8)) { // zos.setMethod(ZipOutputStream.STORED); resourcePackLoop: for (Path p : sourcePath) { @@ -45,8 +43,9 @@ public void convert(int packFormat, String description, HashSet modDomai for (Enumeration e = zf.entries(); e.hasMoreElements(); ) { ZipEntry ze = e.nextElement(); String name = ze.getName(); - if (name.split("/").length >= 2 && !modDomainsSet.contains(name.split("/")[1])) { - modDomainsSet.remove(name.split("/")[1]); + String[] parts = name.split("/"); + if (parts.length >= 2 && !modDomainsSet.contains(parts[1])) { + modDomainsSet.remove(parts[1]); if (name.isEmpty()) { Log.debug(modDomainsSet.toString()); break resourcePackLoop; diff --git a/src/main/java/i18nupdatemod/fabricloader/FabricLoaderMod.java b/src/main/java/i18nupdatemod/fabricloader/FabricLoaderMod.java index d27cf58..e2bf81c 100644 --- a/src/main/java/i18nupdatemod/fabricloader/FabricLoaderMod.java +++ b/src/main/java/i18nupdatemod/fabricloader/FabricLoaderMod.java @@ -56,6 +56,7 @@ private HashSet getMods() { .get("INSTANCE") .get("modMap").get(); modList = new HashSet<>(instance.keySet()); + return modList; } catch (Exception ignored) { } @@ -65,6 +66,7 @@ private HashSet getMods() { .get("INSTANCE") .get("modMap").get(); modList = new HashSet<>(instance.keySet()); + return modList; } catch (Exception ignored) { } From 662b83a8e3de952434c96ee474079c86c5702c4d Mon Sep 17 00:00:00 2001 From: 502y <53784463+502y@users.noreply.github.com> Date: Sat, 26 Jul 2025 16:06:22 +0800 Subject: [PATCH 07/13] =?UTF-8?q?feat(convert):=E6=8F=90=E9=AB=98converter?= =?UTF-8?q?=E6=80=A7=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../core/ResourcePackConverter.java | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) diff --git a/src/main/java/i18nupdatemod/core/ResourcePackConverter.java b/src/main/java/i18nupdatemod/core/ResourcePackConverter.java index a617bf3..a1b0178 100644 --- a/src/main/java/i18nupdatemod/core/ResourcePackConverter.java +++ b/src/main/java/i18nupdatemod/core/ResourcePackConverter.java @@ -11,10 +11,7 @@ import java.nio.charset.StandardCharsets; import java.nio.file.Files; import java.nio.file.Path; -import java.util.Enumeration; -import java.util.HashSet; -import java.util.List; -import java.util.Set; +import java.util.*; import java.util.stream.Collectors; import java.util.zip.ZipEntry; import java.util.zip.ZipFile; @@ -35,8 +32,8 @@ public ResourcePackConverter(List resourcePack, String filename) { public void convert(int packFormat, String description, HashSet modDomainsSet) throws Exception { Set fileList = new HashSet<>(); try (ZipOutputStream zos = new ZipOutputStream(Files.newOutputStream(tmpFilePath), StandardCharsets.UTF_8)) { + Set loadedModDomains = new HashSet<>(); // zos.setMethod(ZipOutputStream.STORED); - resourcePackLoop: for (Path p : sourcePath) { Log.info("Converting: " + p); try (ZipFile zf = new ZipFile(p.toFile(), StandardCharsets.UTF_8)) { @@ -44,12 +41,8 @@ public void convert(int packFormat, String description, HashSet modDomai ZipEntry ze = e.nextElement(); String name = ze.getName(); String[] parts = name.split("/"); + // 正在筛选的是assets/modDomain/** && 当前的modDomain不需要 if (parts.length >= 2 && !modDomainsSet.contains(parts[1])) { - modDomainsSet.remove(parts[1]); - if (name.isEmpty()) { - Log.debug(modDomainsSet.toString()); - break resourcePackLoop; - } continue; } //Log.debug(name); @@ -59,7 +52,7 @@ public void convert(int packFormat, String description, HashSet modDomai continue; } fileList.add(name); -// Log.debug(name); + loadedModDomains.add(parts[1]); // Put file into new zip zos.putNextEntry(new ZipEntry(name)); @@ -74,6 +67,10 @@ public void convert(int packFormat, String description, HashSet modDomai zos.closeEntry(); } } + modDomainsSet.removeAll(loadedModDomains); + if (modDomainsSet.isEmpty()){ + break; + } } zos.close(); Log.debug("unsolved mod domains" + modDomainsSet.toString()); From b56e6d063d1259e2a469d8b380bb35ae028522c1 Mon Sep 17 00:00:00 2001 From: 502y <53784463+502y@users.noreply.github.com> Date: Sat, 26 Jul 2025 20:10:21 +0800 Subject: [PATCH 08/13] =?UTF-8?q?fix(convert):=20=E5=88=A0=E9=99=A4?= =?UTF-8?q?=E6=8F=90=E5=89=8D=E7=BB=93=E6=9D=9F=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/i18nupdatemod/core/ResourcePackConverter.java | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/main/java/i18nupdatemod/core/ResourcePackConverter.java b/src/main/java/i18nupdatemod/core/ResourcePackConverter.java index a1b0178..bd9cf85 100644 --- a/src/main/java/i18nupdatemod/core/ResourcePackConverter.java +++ b/src/main/java/i18nupdatemod/core/ResourcePackConverter.java @@ -32,7 +32,6 @@ public ResourcePackConverter(List resourcePack, String filename) { public void convert(int packFormat, String description, HashSet modDomainsSet) throws Exception { Set fileList = new HashSet<>(); try (ZipOutputStream zos = new ZipOutputStream(Files.newOutputStream(tmpFilePath), StandardCharsets.UTF_8)) { - Set loadedModDomains = new HashSet<>(); // zos.setMethod(ZipOutputStream.STORED); for (Path p : sourcePath) { Log.info("Converting: " + p); @@ -52,7 +51,6 @@ public void convert(int packFormat, String description, HashSet modDomai continue; } fileList.add(name); - loadedModDomains.add(parts[1]); // Put file into new zip zos.putNextEntry(new ZipEntry(name)); @@ -67,7 +65,6 @@ public void convert(int packFormat, String description, HashSet modDomai zos.closeEntry(); } } - modDomainsSet.removeAll(loadedModDomains); if (modDomainsSet.isEmpty()){ break; } From 14c2f251343c70fa7733b0888f1bad37cec09646 Mon Sep 17 00:00:00 2001 From: 502y <53784463+502y@users.noreply.github.com> Date: Sun, 5 Oct 2025 17:12:39 +0800 Subject: [PATCH 09/13] =?UTF-8?q?=E5=88=A0=E5=8E=BB=E6=97=A0=E7=94=A8Log?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/i18nupdatemod/core/ResourcePackConverter.java | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/main/java/i18nupdatemod/core/ResourcePackConverter.java b/src/main/java/i18nupdatemod/core/ResourcePackConverter.java index bd9cf85..bfb6e13 100644 --- a/src/main/java/i18nupdatemod/core/ResourcePackConverter.java +++ b/src/main/java/i18nupdatemod/core/ResourcePackConverter.java @@ -65,12 +65,9 @@ public void convert(int packFormat, String description, HashSet modDomai zos.closeEntry(); } } - if (modDomainsSet.isEmpty()){ - break; - } } zos.close(); - Log.debug("unsolved mod domains" + modDomainsSet.toString()); + //Log.debug("unsolved mod domains" + modDomainsSet.toString()); Log.info("Converted: %s -> %s", sourcePath, tmpFilePath); FileUtil.syncTmpFile(tmpFilePath, filePath, true); } catch (Exception e) { From 85d0c8289cf2919089d7b32bc0d6cd3d4db1ee58 Mon Sep 17 00:00:00 2001 From: 502y <53784463+502y@users.noreply.github.com> Date: Sun, 5 Oct 2025 20:21:58 +0800 Subject: [PATCH 10/13] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8D=E7=89=B9?= =?UTF-8?q?=E7=82=B9=E7=89=88=E6=9C=AC=E4=B8=8D=E8=BF=9B=E8=A1=8C=E8=BD=AC?= =?UTF-8?q?=E6=8D=A2=E7=9A=84=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/i18nupdatemod/I18nUpdateMod.java | 14 +++++--------- src/main/java/i18nupdatemod/core/ResourcePack.java | 8 +++----- .../i18nupdatemod/core/ResourcePackConverter.java | 7 +++++-- src/main/java/i18nupdatemod/util/FileUtil.java | 4 ++-- 4 files changed, 15 insertions(+), 18 deletions(-) diff --git a/src/main/java/i18nupdatemod/I18nUpdateMod.java b/src/main/java/i18nupdatemod/I18nUpdateMod.java index 06465e4..cdc357a 100644 --- a/src/main/java/i18nupdatemod/I18nUpdateMod.java +++ b/src/main/java/i18nupdatemod/I18nUpdateMod.java @@ -73,22 +73,18 @@ public static void init(Path minecraftPath, String minecraftVersion, String load //Update resource pack List languagePacks = new ArrayList<>(); - boolean convertNotNeed = assets.downloads.size() == 1 && assets.downloads.get(0).targetVersion.equals(minecraftVersion); - String applyFileName = assets.downloads.get(0).fileName; for (GameAssetDetail.AssetDownloadDetail it : assets.downloads) { FileUtil.setTemporaryDirPath(Paths.get(localStorage, "." + MOD_ID, it.targetVersion)); - ResourcePack languagePack = new ResourcePack(it.fileName, convertNotNeed); + ResourcePack languagePack = new ResourcePack(it.fileName); languagePack.checkUpdate(it.fileUrl, it.md5Url); languagePacks.add(languagePack); } //Convert resourcepack - if (!convertNotNeed) { - FileUtil.setTemporaryDirPath(Paths.get(localStorage, "." + MOD_ID, minecraftVersion)); - applyFileName = assets.covertFileName; - ResourcePackConverter converter = new ResourcePackConverter(languagePacks, applyFileName); - converter.convert(assets.covertPackFormat, getResourcePackDescription(assets.downloads), modDomainsSet); - } + FileUtil.setTemporaryDirPath(Paths.get(localStorage, "." + MOD_ID, minecraftVersion)); + String applyFileName = assets.covertFileName; + ResourcePackConverter converter = new ResourcePackConverter(languagePacks, applyFileName); + converter.convert(assets.covertPackFormat, getResourcePackDescription(assets.downloads), modDomainsSet); //Apply resource pack GameConfig config = new GameConfig(minecraftPath.resolve("options.txt")); diff --git a/src/main/java/i18nupdatemod/core/ResourcePack.java b/src/main/java/i18nupdatemod/core/ResourcePack.java index 6c890e5..91e1700 100644 --- a/src/main/java/i18nupdatemod/core/ResourcePack.java +++ b/src/main/java/i18nupdatemod/core/ResourcePack.java @@ -22,17 +22,15 @@ public class ResourcePack { private final String filename; private final Path filePath; private final Path tmpFilePath; - private final boolean saveToGame; private String remoteMd5; - public ResourcePack(String filename, boolean saveToGame) { + public ResourcePack(String filename) { //If target version is not current version, not save - this.saveToGame = saveToGame; this.filename = filename; this.filePath = FileUtil.getResourcePackPath(filename); this.tmpFilePath = FileUtil.getTemporaryPath(filename); try { - FileUtil.syncTmpFile(filePath, tmpFilePath, saveToGame); + FileUtil.syncTmpFile(filePath, tmpFilePath); } catch (Exception e) { Log.warning( String.format("Error while sync temp file %s <-> %s: %s", filePath, tmpFilePath, e)); @@ -89,7 +87,7 @@ private void downloadFull(String fileUrl, String md5Url) throws IOException { if (!Files.exists(tmpFilePath)) { throw new FileNotFoundException("Tmp file not found."); } - FileUtil.syncTmpFile(filePath, tmpFilePath, saveToGame); + FileUtil.syncTmpFile(filePath, tmpFilePath); } public Path getTmpFilePath() { diff --git a/src/main/java/i18nupdatemod/core/ResourcePackConverter.java b/src/main/java/i18nupdatemod/core/ResourcePackConverter.java index bfb6e13..566b020 100644 --- a/src/main/java/i18nupdatemod/core/ResourcePackConverter.java +++ b/src/main/java/i18nupdatemod/core/ResourcePackConverter.java @@ -11,7 +11,10 @@ import java.nio.charset.StandardCharsets; import java.nio.file.Files; import java.nio.file.Path; -import java.util.*; +import java.util.Enumeration; +import java.util.HashSet; +import java.util.List; +import java.util.Set; import java.util.stream.Collectors; import java.util.zip.ZipEntry; import java.util.zip.ZipFile; @@ -69,7 +72,7 @@ public void convert(int packFormat, String description, HashSet modDomai zos.close(); //Log.debug("unsolved mod domains" + modDomainsSet.toString()); Log.info("Converted: %s -> %s", sourcePath, tmpFilePath); - FileUtil.syncTmpFile(tmpFilePath, filePath, true); + FileUtil.syncTmpFile(tmpFilePath, filePath); } catch (Exception e) { throw new Exception(String.format("Error converting %s to %s: %s", sourcePath, tmpFilePath, e)); } diff --git a/src/main/java/i18nupdatemod/util/FileUtil.java b/src/main/java/i18nupdatemod/util/FileUtil.java index 6cc3410..8c5f818 100644 --- a/src/main/java/i18nupdatemod/util/FileUtil.java +++ b/src/main/java/i18nupdatemod/util/FileUtil.java @@ -37,7 +37,7 @@ public static Path getTemporaryPath(String filename) { return temporaryDirPath.resolve(filename); } - public static void syncTmpFile(Path filePath, Path tmpFilePath, boolean saveToGame) throws IOException { + public static void syncTmpFile(Path filePath, Path tmpFilePath) throws IOException { //Both temp and current file not found if (!Files.exists(filePath) && !Files.exists(tmpFilePath)) { Log.debug("Both temp and current file not found"); @@ -59,7 +59,7 @@ public static void syncTmpFile(Path filePath, Path tmpFilePath, boolean saveToGa to = filePath; } - if (!saveToGame && to == filePath) { + if (to == filePath) { //Don't save to game return; } From 3d829ecf1447776a5e225486247199e53c04fbe5 Mon Sep 17 00:00:00 2001 From: 502y <53784463+502y@users.noreply.github.com> Date: Mon, 6 Oct 2025 18:44:42 +0800 Subject: [PATCH 11/13] =?UTF-8?q?feat:=20=E6=94=AF=E6=8C=81JarInJar?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/i18nupdatemod/I18nUpdateMod.java | 61 ++++++++++++++----- 1 file changed, 46 insertions(+), 15 deletions(-) diff --git a/src/main/java/i18nupdatemod/I18nUpdateMod.java b/src/main/java/i18nupdatemod/I18nUpdateMod.java index cdc357a..8dd3a1f 100644 --- a/src/main/java/i18nupdatemod/I18nUpdateMod.java +++ b/src/main/java/i18nupdatemod/I18nUpdateMod.java @@ -11,15 +11,16 @@ import i18nupdatemod.util.Log; import org.jetbrains.annotations.NotNull; -import java.io.File; -import java.io.InputStream; -import java.io.InputStreamReader; +import java.io.*; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; -import java.util.*; +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Objects; import java.util.jar.JarEntry; -import java.util.jar.JarFile; +import java.util.jar.JarInputStream; import java.util.stream.Collectors; import java.util.stream.Stream; @@ -138,27 +139,57 @@ private static HashSet getModDomainsFromModsFolder(Path minecraftPath, S String[] modsNamesList = modsPath.toFile().list((dir, name) -> name.endsWith(".jar")); if (modsNamesList != null) { for (String name : modsNamesList) { - modDomainSet.addAll(getModDomainFromAsset(modsPath.resolve(name).toFile())); + modDomainSet.addAll(getModDomainFromJar(modsPath.resolve(name).toFile())); } } return modDomainSet; } - private static HashSet getModDomainFromAsset(File modsPath) { + private static HashSet getModDomainFromJar(File modPath) { + Log.debug(String.format("Get mod domain from %s", modPath)); HashSet modList = new HashSet<>(); - try (JarFile jarFile = new JarFile(modsPath)) { - Enumeration entries = jarFile.entries(); - while (entries.hasMoreElements()) { - JarEntry entry = entries.nextElement(); + try (FileInputStream fis = new FileInputStream(modPath)) { + modList.addAll(getModDomainFromStream(fis, modPath.getName())); + } catch (Exception e) { + Log.warning(String.format("Failed to read jar %s: %s", modPath, e)); + } + return modList; + } + + private static HashSet getModDomainFromStream(InputStream input, String sourceName) throws IOException { + HashSet modList = new HashSet<>(); + try (JarInputStream jis = new JarInputStream(input)) { + JarEntry entry; + byte[] buffer = new byte[8192]; + while ((entry = jis.getNextJarEntry()) != null) { String path = entry.getName(); - // 匹配 assets/xxx/ - if (path.startsWith("assets/") && path.split("/").length >= 2) { - modList.add(path.split("/")[1]); + + // 匹配 assets// + if (path.startsWith("assets/")) { + String[] parts = path.split("/"); + if (parts.length >= 2) { + modList.add(parts[1]); + } + } else if (path.endsWith(".jar")) { + try { + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + int bytesRead; + while ((bytesRead = jis.read(buffer)) != -1) { + baos.write(buffer, 0, bytesRead); + } + + byte[] innerJarBytes = baos.toByteArray(); + try (ByteArrayInputStream innerStream = new ByteArrayInputStream(innerJarBytes)) { + modList.addAll(getModDomainFromStream(innerStream, path)); + } + } catch (Exception innerEx) { + Log.warning(String.format("Failed to parse nested jar %s inside %s: %s", path, sourceName, innerEx)); + } } } - } catch (Exception ignored) { } return modList; } + } \ No newline at end of file From 20027cb3cade2feb70ab5d2d1c0dbd059c562ba0 Mon Sep 17 00:00:00 2001 From: 502y <53784463+502y@users.noreply.github.com> Date: Fri, 17 Oct 2025 21:42:06 +0800 Subject: [PATCH 12/13] =?UTF-8?q?=E5=88=A0=E5=8E=BB=E6=97=A0=E7=94=A8Log?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/i18nupdatemod/core/ResourcePackConverter.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/i18nupdatemod/core/ResourcePackConverter.java b/src/main/java/i18nupdatemod/core/ResourcePackConverter.java index 566b020..d1dd051 100644 --- a/src/main/java/i18nupdatemod/core/ResourcePackConverter.java +++ b/src/main/java/i18nupdatemod/core/ResourcePackConverter.java @@ -47,7 +47,7 @@ public void convert(int packFormat, String description, HashSet modDomai if (parts.length >= 2 && !modDomainsSet.contains(parts[1])) { continue; } - //Log.debug(name); + // Don't put same file if (fileList.contains(name)) { // Log.debug(name + ": DUPLICATE"); From 01749bc676abb1fc29220415cd46e4883ae3bbf1 Mon Sep 17 00:00:00 2001 From: 502y <53784463+502y@users.noreply.github.com> Date: Sat, 18 Oct 2025 10:10:45 +0800 Subject: [PATCH 13/13] =?UTF-8?q?=E7=A7=BB=E5=8A=A8mod=20domain=E6=8F=90?= =?UTF-8?q?=E5=8F=96=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/i18nupdatemod/I18nUpdateMod.java | 67 ------------------- .../launchwrapper/LaunchWrapperTweaker.java | 4 +- .../modlauncher/ModLauncherService.java | 3 +- src/main/java/i18nupdatemod/util/ModUtil.java | 67 +++++++++++++++++++ 4 files changed, 71 insertions(+), 70 deletions(-) create mode 100644 src/main/java/i18nupdatemod/util/ModUtil.java diff --git a/src/main/java/i18nupdatemod/I18nUpdateMod.java b/src/main/java/i18nupdatemod/I18nUpdateMod.java index 8dd3a1f..b891c9e 100644 --- a/src/main/java/i18nupdatemod/I18nUpdateMod.java +++ b/src/main/java/i18nupdatemod/I18nUpdateMod.java @@ -19,8 +19,6 @@ import java.util.HashSet; import java.util.List; import java.util.Objects; -import java.util.jar.JarEntry; -import java.util.jar.JarInputStream; import java.util.stream.Collectors; import java.util.stream.Stream; @@ -38,12 +36,6 @@ public static void init(Path minecraftPath, String minecraftVersion, String load Log.warning("Error getting version: " + e); } - //Log.debug("modList from loader:" + modDomainsSet); - if ("Forge".equals(loader)) { - modDomainsSet = getModDomainsFromModsFolder(minecraftPath, minecraftVersion, loader); - //Log.debug("modList from mods folder: " + modDomainsSet); - - } modDomainsSet.remove("i18nupdatemod"); Log.info(String.format("I18nUpdate Mod %s is loaded in %s with %s", MOD_VERSION, minecraftVersion, loader)); @@ -133,63 +125,4 @@ public static String getLocalStoragePos(Path minecraftPath) { ).findFirst().orElse(xdgDataHome); } - private static HashSet getModDomainsFromModsFolder(Path minecraftPath, String minecraftVersion, String loader) { - HashSet modDomainSet = new HashSet<>(); - Path modsPath = minecraftPath.resolve("mods"); - String[] modsNamesList = modsPath.toFile().list((dir, name) -> name.endsWith(".jar")); - if (modsNamesList != null) { - for (String name : modsNamesList) { - modDomainSet.addAll(getModDomainFromJar(modsPath.resolve(name).toFile())); - } - } - return modDomainSet; - } - - private static HashSet getModDomainFromJar(File modPath) { - Log.debug(String.format("Get mod domain from %s", modPath)); - HashSet modList = new HashSet<>(); - try (FileInputStream fis = new FileInputStream(modPath)) { - modList.addAll(getModDomainFromStream(fis, modPath.getName())); - } catch (Exception e) { - Log.warning(String.format("Failed to read jar %s: %s", modPath, e)); - } - return modList; - } - - private static HashSet getModDomainFromStream(InputStream input, String sourceName) throws IOException { - HashSet modList = new HashSet<>(); - try (JarInputStream jis = new JarInputStream(input)) { - JarEntry entry; - byte[] buffer = new byte[8192]; - while ((entry = jis.getNextJarEntry()) != null) { - String path = entry.getName(); - - // 匹配 assets// - if (path.startsWith("assets/")) { - String[] parts = path.split("/"); - if (parts.length >= 2) { - modList.add(parts[1]); - } - } else if (path.endsWith(".jar")) { - try { - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - int bytesRead; - while ((bytesRead = jis.read(buffer)) != -1) { - baos.write(buffer, 0, bytesRead); - } - - byte[] innerJarBytes = baos.toByteArray(); - try (ByteArrayInputStream innerStream = new ByteArrayInputStream(innerJarBytes)) { - modList.addAll(getModDomainFromStream(innerStream, path)); - } - } catch (Exception innerEx) { - Log.warning(String.format("Failed to parse nested jar %s inside %s: %s", path, sourceName, innerEx)); - } - } - } - } - return modList; - } - - } \ No newline at end of file diff --git a/src/main/java/i18nupdatemod/launchwrapper/LaunchWrapperTweaker.java b/src/main/java/i18nupdatemod/launchwrapper/LaunchWrapperTweaker.java index 45e599f..dab5b80 100644 --- a/src/main/java/i18nupdatemod/launchwrapper/LaunchWrapperTweaker.java +++ b/src/main/java/i18nupdatemod/launchwrapper/LaunchWrapperTweaker.java @@ -2,12 +2,12 @@ import i18nupdatemod.I18nUpdateMod; import i18nupdatemod.util.Log; +import i18nupdatemod.util.ModUtil; import i18nupdatemod.util.Reflection; import net.minecraft.launchwrapper.ITweaker; import net.minecraft.launchwrapper.LaunchClassLoader; import java.io.File; -import java.util.HashSet; import java.util.List; //1.6-1.12.2 @@ -21,7 +21,7 @@ public void acceptOptions(List args, File gameDir, File assetsDir, Strin Log.warning("Failed to get minecraft version."); return; } - I18nUpdateMod.init(gameDir.toPath(), mcVersion, "Forge", new HashSet<>()); + I18nUpdateMod.init(gameDir.toPath(), mcVersion, "Forge", ModUtil.getModDomainsFromModsFolder(gameDir.toPath(), mcVersion, "Forge")); } @Override diff --git a/src/main/java/i18nupdatemod/modlauncher/ModLauncherService.java b/src/main/java/i18nupdatemod/modlauncher/ModLauncherService.java index 21dcb4f..33e0421 100644 --- a/src/main/java/i18nupdatemod/modlauncher/ModLauncherService.java +++ b/src/main/java/i18nupdatemod/modlauncher/ModLauncherService.java @@ -8,6 +8,7 @@ import cpw.mods.modlauncher.api.IncompatibleEnvironmentException; import i18nupdatemod.I18nUpdateMod; import i18nupdatemod.util.Log; +import i18nupdatemod.util.ModUtil; import i18nupdatemod.util.Reflection; import org.jetbrains.annotations.NotNull; @@ -38,7 +39,7 @@ public void initialize(IEnvironment environment) { Log.warning("Minecraft version not found"); return; } - I18nUpdateMod.init(minecraftPath.get(), minecraftVersion, "Forge", new HashSet<>()); + I18nUpdateMod.init(minecraftPath.get(), minecraftVersion, "Forge", ModUtil.getModDomainsFromModsFolder(minecraftPath.get(), minecraftVersion, "Forge")); } @Override diff --git a/src/main/java/i18nupdatemod/util/ModUtil.java b/src/main/java/i18nupdatemod/util/ModUtil.java new file mode 100644 index 0000000..b798c82 --- /dev/null +++ b/src/main/java/i18nupdatemod/util/ModUtil.java @@ -0,0 +1,67 @@ +package i18nupdatemod.util; + +import java.io.*; +import java.nio.file.Path; +import java.util.HashSet; +import java.util.jar.JarEntry; +import java.util.jar.JarInputStream; + +public class ModUtil { + public static HashSet getModDomainsFromModsFolder(Path minecraftPath, String minecraftVersion, String loader) { + HashSet modDomainSet = new HashSet<>(); + Path modsPath = minecraftPath.resolve("mods"); + String[] modsNamesList = modsPath.toFile().list((dir, name) -> name.endsWith(".jar")); + if (modsNamesList != null) { + for (String name : modsNamesList) { + modDomainSet.addAll(getModDomainFromJar(modsPath.resolve(name).toFile())); + } + } + return modDomainSet; + } + + private static HashSet getModDomainFromJar(File modPath) { + Log.debug(String.format("Get mod domain from %s", modPath)); + HashSet modList = new HashSet<>(); + try (FileInputStream fis = new FileInputStream(modPath)) { + modList.addAll(getModDomainFromStream(fis, modPath.getName())); + } catch (Exception e) { + Log.warning(String.format("Failed to read jar %s: %s", modPath, e)); + } + return modList; + } + + private static HashSet getModDomainFromStream(InputStream input, String sourceName) throws IOException { + HashSet modList = new HashSet<>(); + try (JarInputStream jis = new JarInputStream(input)) { + JarEntry entry; + byte[] buffer = new byte[8192]; + while ((entry = jis.getNextJarEntry()) != null) { + String path = entry.getName(); + + // 匹配 assets// + if (path.startsWith("assets/")) { + String[] parts = path.split("/"); + if (parts.length >= 2) { + modList.add(parts[1]); + } + } else if (path.endsWith(".jar")) { + try { + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + int bytesRead; + while ((bytesRead = jis.read(buffer)) != -1) { + baos.write(buffer, 0, bytesRead); + } + + byte[] innerJarBytes = baos.toByteArray(); + try (ByteArrayInputStream innerStream = new ByteArrayInputStream(innerJarBytes)) { + modList.addAll(getModDomainFromStream(innerStream, path)); + } + } catch (Exception innerEx) { + Log.warning(String.format("Failed to parse nested jar %s inside %s: %s", path, sourceName, innerEx)); + } + } + } + } + return modList; + } +}