Skip to content

Commit 3d829ec

Browse files
committed
feat: 支持JarInJar
1 parent 85d0c82 commit 3d829ec

1 file changed

Lines changed: 46 additions & 15 deletions

File tree

src/main/java/i18nupdatemod/I18nUpdateMod.java

Lines changed: 46 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -11,15 +11,16 @@
1111
import i18nupdatemod.util.Log;
1212
import org.jetbrains.annotations.NotNull;
1313

14-
import java.io.File;
15-
import java.io.InputStream;
16-
import java.io.InputStreamReader;
14+
import java.io.*;
1715
import java.nio.file.Files;
1816
import java.nio.file.Path;
1917
import java.nio.file.Paths;
20-
import java.util.*;
18+
import java.util.ArrayList;
19+
import java.util.HashSet;
20+
import java.util.List;
21+
import java.util.Objects;
2122
import java.util.jar.JarEntry;
22-
import java.util.jar.JarFile;
23+
import java.util.jar.JarInputStream;
2324
import java.util.stream.Collectors;
2425
import java.util.stream.Stream;
2526

@@ -138,27 +139,57 @@ private static HashSet<String> getModDomainsFromModsFolder(Path minecraftPath, S
138139
String[] modsNamesList = modsPath.toFile().list((dir, name) -> name.endsWith(".jar"));
139140
if (modsNamesList != null) {
140141
for (String name : modsNamesList) {
141-
modDomainSet.addAll(getModDomainFromAsset(modsPath.resolve(name).toFile()));
142+
modDomainSet.addAll(getModDomainFromJar(modsPath.resolve(name).toFile()));
142143
}
143144
}
144145
return modDomainSet;
145146
}
146147

147-
private static HashSet<String> getModDomainFromAsset(File modsPath) {
148+
private static HashSet<String> getModDomainFromJar(File modPath) {
149+
Log.debug(String.format("Get mod domain from %s", modPath));
148150
HashSet<String> modList = new HashSet<>();
149-
try (JarFile jarFile = new JarFile(modsPath)) {
150-
Enumeration<JarEntry> entries = jarFile.entries();
151-
while (entries.hasMoreElements()) {
152-
JarEntry entry = entries.nextElement();
151+
try (FileInputStream fis = new FileInputStream(modPath)) {
152+
modList.addAll(getModDomainFromStream(fis, modPath.getName()));
153+
} catch (Exception e) {
154+
Log.warning(String.format("Failed to read jar %s: %s", modPath, e));
155+
}
156+
return modList;
157+
}
158+
159+
private static HashSet<String> getModDomainFromStream(InputStream input, String sourceName) throws IOException {
160+
HashSet<String> modList = new HashSet<>();
161+
try (JarInputStream jis = new JarInputStream(input)) {
162+
JarEntry entry;
163+
byte[] buffer = new byte[8192];
164+
while ((entry = jis.getNextJarEntry()) != null) {
153165
String path = entry.getName();
154-
// 匹配 assets/xxx/
155-
if (path.startsWith("assets/") && path.split("/").length >= 2) {
156-
modList.add(path.split("/")[1]);
166+
167+
// 匹配 assets/<domain>/
168+
if (path.startsWith("assets/")) {
169+
String[] parts = path.split("/");
170+
if (parts.length >= 2) {
171+
modList.add(parts[1]);
172+
}
173+
} else if (path.endsWith(".jar")) {
174+
try {
175+
ByteArrayOutputStream baos = new ByteArrayOutputStream();
176+
int bytesRead;
177+
while ((bytesRead = jis.read(buffer)) != -1) {
178+
baos.write(buffer, 0, bytesRead);
179+
}
180+
181+
byte[] innerJarBytes = baos.toByteArray();
182+
try (ByteArrayInputStream innerStream = new ByteArrayInputStream(innerJarBytes)) {
183+
modList.addAll(getModDomainFromStream(innerStream, path));
184+
}
185+
} catch (Exception innerEx) {
186+
Log.warning(String.format("Failed to parse nested jar %s inside %s: %s", path, sourceName, innerEx));
187+
}
157188
}
158189
}
159-
} catch (Exception ignored) {
160190
}
161191
return modList;
162192
}
163193

194+
164195
}

0 commit comments

Comments
 (0)