Skip to content

Commit 611b488

Browse files
committed
Add namespace options and improve jar remapping process
- Introduced `--from` and `--to` options for specifying source and target namespaces in the CLI. - Enhanced `RemapService` to handle namespace parameters. - Improved jar remapping by excluding signature files and ensuring output jar creation.
1 parent b0c29e1 commit 611b488

3 files changed

Lines changed: 69 additions & 6 deletions

File tree

build.gradle

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,4 +38,12 @@ jar {
3838
configurations.runtimeClasspath.collect { it.isDirectory() ? it : zipTree(it) }
3939
}
4040
duplicatesStrategy = DuplicatesStrategy.EXCLUDE
41+
42+
// Robustly exclude signature files from all merged jars
43+
exclude 'META-INF/**/*.SF', 'META-INF/**/*.DSA', 'META-INF/**/*.RSA'
44+
eachFile { file ->
45+
if (file.path ==~ /META-INF\/.*\.(SF|DSA|RSA)/) {
46+
file.exclude()
47+
}
48+
}
4149
}

src/main/java/com/threadmc/trc/Main.java

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,14 +20,32 @@ public class Main implements Callable<Integer> {
2020
@Option(names = {"--output"}, description = "Output jar file (remapped)", required = true)
2121
Path outputJar;
2222

23+
@Option(names = {"--from"}, description = "Source namespace", required = true)
24+
String fromNamespace;
25+
26+
@Option(names = {"--to"}, description = "Target namespace", required = true)
27+
String toNamespace;
28+
2329
public static void main(String[] args) {
2430
int exitCode = new CommandLine(new Main()).execute(args);
2531
System.exit(exitCode);
2632
}
2733

2834
@Override
2935
public Integer call() throws Exception {
30-
RemapService remapper = new RemapService(inputJar, mappingsFile, outputJar);
36+
if (inputJar.toString().contains("/")) {
37+
System.err.println("Error: Input jar path must use '\\' instead of '/'.");
38+
return 1;
39+
}
40+
if (mappingsFile.toString().contains("/")) {
41+
System.err.println("Error: Mappings file path must use '\\' instead of '/'.");
42+
return 1;
43+
}
44+
if (outputJar.toString().contains("/")) {
45+
System.err.println("Error: Output jar path must use '\\' instead of '/'.");
46+
return 1;
47+
}
48+
RemapService remapper = new RemapService(inputJar, mappingsFile, outputJar, fromNamespace, toNamespace);
3149
remapper.run();
3250
return 0;
3351
}

src/main/java/com/threadmc/trc/RemapService.java

Lines changed: 42 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,27 +8,33 @@
88

99
import java.io.IOException;
1010
import java.nio.file.Path;
11+
import java.util.jar.JarFile;
12+
import java.util.jar.JarEntry;
13+
import java.util.jar.JarOutputStream;
14+
import java.io.InputStream;
15+
import java.nio.file.Files;
1116

1217
public class RemapService {
1318

1419
private final Path inputJar;
1520
private final Path mappingsFile;
1621
private final Path outputJar;
22+
private final String fromNamespace;
23+
private final String toNamespace;
1724

18-
public RemapService(Path inputJar, Path mappingsFile, Path outputJar) {
25+
public RemapService(Path inputJar, Path mappingsFile, Path outputJar, String fromNamespace, String toNamespace) {
1926
this.inputJar = inputJar;
2027
this.mappingsFile = mappingsFile;
2128
this.outputJar = outputJar;
29+
this.fromNamespace = fromNamespace;
30+
this.toNamespace = toNamespace;
2231
}
2332

2433
public void run() throws IOException {
2534
System.out.println("Loading mappings...");
2635
MemoryMappingTree tree = new MemoryMappingTree();
2736
MappingReader.read(mappingsFile, tree);
2837

29-
String fromNamespace = "official";
30-
String toNamespace = "named";
31-
3238
System.out.println("Setting up TinyRemapper...");
3339

3440
TinyRemapper remapper = TinyRemapper.newRemapper()
@@ -39,12 +45,43 @@ public void run() throws IOException {
3945
.build();
4046

4147
System.out.println("Remapping jar...");
42-
try ( @SuppressWarnings("deprecation") OutputConsumerPath outputConsumer = new OutputConsumerPath(outputJar) ) {
48+
try (@SuppressWarnings("deprecation") OutputConsumerPath outputConsumer = new OutputConsumerPath(outputJar)) {
4349
outputConsumer.addNonClassFiles(inputJar);
4450
remapper.readInputs(inputJar);
4551
remapper.apply(outputConsumer);
4652
}
4753

54+
if (!Files.exists(outputJar)) {
55+
throw new IOException("Remapped output jar was not created: " + outputJar);
56+
}
57+
58+
Path tempJar = Files.createTempFile("remapped-filtered", ".jar");
59+
try (
60+
JarFile jarFile = new JarFile(outputJar.toFile());
61+
JarOutputStream jos = new JarOutputStream(Files.newOutputStream(tempJar))
62+
) {
63+
for (JarEntry entry : java.util.Collections.list(jarFile.entries())) {
64+
String n = entry.getName().replace('\\', '/');
65+
if (n.startsWith("META-INF/") && (n.endsWith(".SF") || n.endsWith(".DSA") || n.endsWith(".RSA"))) {
66+
continue;
67+
}
68+
JarEntry newEntry = new JarEntry(entry.getName());
69+
if (entry.getMethod() == JarEntry.STORED) {
70+
newEntry.setMethod(JarEntry.STORED);
71+
newEntry.setSize(entry.getSize());
72+
newEntry.setCompressedSize(entry.getCompressedSize());
73+
newEntry.setCrc(entry.getCrc());
74+
}
75+
jos.putNextEntry(newEntry);
76+
try (InputStream is = jarFile.getInputStream(entry)) {
77+
is.transferTo(jos);
78+
}
79+
jos.closeEntry();
80+
}
81+
}
82+
83+
Files.move(tempJar, outputJar, java.nio.file.StandardCopyOption.REPLACE_EXISTING);
84+
4885
remapper.finish();
4986
System.out.println("Remapped jar created at: " + outputJar.toAbsolutePath());
5087
}

0 commit comments

Comments
 (0)