Skip to content
Open
Show file tree
Hide file tree
Changes from 7 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,10 @@ java {
targetCompatibility = JavaVersion.VERSION_1_8
}

tasks.withType<JavaCompile> {
options.encoding = "UTF-8"
}

tasks.shadowJar {
manifest {
attributes(
Expand Down
54 changes: 49 additions & 5 deletions src/main/java/i18nupdatemod/I18nUpdateMod.java
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,17 @@
import i18nupdatemod.entity.GameAssetDetail;
import i18nupdatemod.util.FileUtil;
import i18nupdatemod.util.Log;
import org.jetbrains.annotations.NotNull;

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;

Expand All @@ -27,12 +29,22 @@ 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 HashSet<String> 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) {
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));
Log.debug(String.format("Minecraft path: %s", minecraftPath));
String localStorage = getLocalStoragePos(minecraftPath);
Expand Down Expand Up @@ -75,14 +87,16 @@ 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
GameConfig config = new GameConfig(minecraftPath.resolve("options.txt"));
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();
Expand Down Expand Up @@ -121,4 +135,34 @@ public static String getLocalStoragePos(Path minecraftPath) {
Objects::nonNull
).findFirst().orElse(xdgDataHome);
}

private static HashSet<String> getModDomainsFromModsFolder(Path minecraftPath, String minecraftVersion, String loader) {
HashSet<String> 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<String> getModDomainFromAsset(File modsPath) {
HashSet<String> modList = new HashSet<>();
try (JarFile jarFile = new JarFile(modsPath)) {
Enumeration<JarEntry> 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;
}

}
25 changes: 16 additions & 9 deletions src/main/java/i18nupdatemod/core/ResourcePackConverter.java
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -32,25 +29,30 @@ public ResourcePackConverter(List<ResourcePack> 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<String> modDomainsSet) throws Exception {
Set<String> 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)) {
Set<String> loadedModDomains = new HashSet<>();
// zos.setMethod(ZipOutputStream.STORED);
for (Path p : sourcePath) {
Log.info("Converting: " + p);
try (ZipFile zf = new ZipFile(p.toFile(), StandardCharsets.UTF_8)) {
for (Enumeration<? extends ZipEntry> e = zf.entries(); e.hasMoreElements(); ) {
ZipEntry ze = e.nextElement();
String name = ze.getName();
String[] parts = name.split("/");
// 正在筛选的是assets/modDomain/** && 当前的modDomain不需要
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");
continue;
}
fileList.add(name);
// Log.debug(name);
loadedModDomains.add(parts[1]);

// Put file into new zip
zos.putNextEntry(new ZipEntry(name));
Expand All @@ -65,8 +67,13 @@ public void convert(int packFormat, String description) throws Exception {
zos.closeEntry();
}
}
modDomainsSet.removeAll(loadedModDomains);
if (modDomainsSet.isEmpty()){
break;
}
}
zos.close();
Log.debug("unsolved mod domains" + modDomainsSet.toString());
Log.info("Converted: %s -> %s", sourcePath, tmpFilePath);
FileUtil.syncTmpFile(tmpFilePath, filePath, true);
} catch (Exception e) {
Expand Down
30 changes: 29 additions & 1 deletion src/main/java/i18nupdatemod/fabricloader/FabricLoaderMod.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
import net.fabricmc.loader.api.FabricLoader;

import java.nio.file.Path;
import java.util.HashSet;
import java.util.Map;

//1.14-latest
public class FabricLoaderMod implements ClientModInitializer {
Expand All @@ -20,7 +22,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() {
Expand All @@ -44,4 +46,30 @@ private String getMcVersion() {
}
return null;
}


private HashSet<String> getMods() {
HashSet<String> modList = new HashSet<>();
try {
// Fabric
@SuppressWarnings("unchecked") final Map<String, Object> instance = (Map<String, Object>) Reflection.clazz("net.fabricmc.loader.impl.FabricLoaderImpl")
.get("INSTANCE")
.get("modMap").get();
modList = new HashSet<>(instance.keySet());
return modList;
} catch (Exception ignored) {

}
try {
// Quilt
@SuppressWarnings("unchecked") final Map<String, Object> instance = (Map<String, Object>) Reflection.clazz("org.quiltmc.loader.impl.QuiltLoaderImpl")
.get("INSTANCE")
.get("modMap").get();
modList = new HashSet<>(instance.keySet());
return modList;
} catch (Exception ignored) {

}
return modList;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import net.minecraft.launchwrapper.LaunchClassLoader;

import java.io.File;
import java.util.HashSet;
import java.util.List;

//1.6-1.12.2
Expand All @@ -20,7 +21,7 @@ public void acceptOptions(List<String> 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 HashSet<>());
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand All @@ -41,7 +38,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", new HashSet<>());
}

@Override
Expand Down