From f8c7b8497e9687e15123caca7d4fde54f5bf067a Mon Sep 17 00:00:00 2001 From: Joe Date: Thu, 11 Sep 2025 17:35:30 +0100 Subject: Allow you to specify the libraries in the program args rather than always using the runtime classpath --- .../cuchaz/enigma/command/CheckMappingsCommand.java | 7 ++++--- .../src/main/java/cuchaz/enigma/command/Command.java | 17 ++++++++++++++--- .../java/cuchaz/enigma/command/DecompileCommand.java | 6 ++++-- .../java/cuchaz/enigma/command/DeobfuscateCommand.java | 4 +++- .../cuchaz/enigma/network/DedicatedEnigmaServer.java | 5 +++-- .../src/main/java/cuchaz/enigma/gui/GuiController.java | 8 ++++---- enigma-swing/src/main/java/cuchaz/enigma/gui/Main.java | 4 +++- .../main/java/cuchaz/enigma/gui/elements/MenuBar.java | 2 +- enigma/src/main/java/cuchaz/enigma/Enigma.java | 15 ++++++++------- enigma/src/main/java/cuchaz/enigma/EnigmaProject.java | 8 +++++++- enigma/src/test/java/cuchaz/enigma/TestDeobfed.java | 6 +++--- .../src/test/java/cuchaz/enigma/TestDeobfuscator.java | 4 ++-- .../translation/mapping/TestTinyV2InnerClasses.java | 4 ++-- 13 files changed, 58 insertions(+), 32 deletions(-) diff --git a/enigma-cli/src/main/java/cuchaz/enigma/command/CheckMappingsCommand.java b/enigma-cli/src/main/java/cuchaz/enigma/command/CheckMappingsCommand.java index 5e64b2c1..fc187f1b 100644 --- a/enigma-cli/src/main/java/cuchaz/enigma/command/CheckMappingsCommand.java +++ b/enigma-cli/src/main/java/cuchaz/enigma/command/CheckMappingsCommand.java @@ -1,6 +1,7 @@ package cuchaz.enigma.command; import java.nio.file.Path; +import java.util.List; import java.util.Set; import java.util.stream.Collectors; @@ -8,7 +9,6 @@ import cuchaz.enigma.Enigma; import cuchaz.enigma.EnigmaProject; import cuchaz.enigma.ProgressListener; import cuchaz.enigma.analysis.index.JarIndex; -import cuchaz.enigma.classprovider.ClasspathClassProvider; import cuchaz.enigma.translation.mapping.EntryMapping; import cuchaz.enigma.translation.mapping.serde.MappingSaveParameters; import cuchaz.enigma.translation.mapping.tree.EntryTree; @@ -21,7 +21,7 @@ public class CheckMappingsCommand extends Command { @Override public String getUsage() { - return " "; + return " [ ...]"; } @Override @@ -33,11 +33,12 @@ public class CheckMappingsCommand extends Command { public void run(String... args) throws Exception { Path fileJarIn = getReadableFile(getArg(args, 0, "in jar", true)).toPath(); Path fileMappings = getReadablePath(getArg(args, 1, "mappings file", true)); + List libraries = getReadablePaths(args, 2); Enigma enigma = Enigma.create(); System.out.println("Reading JAR..."); - EnigmaProject project = enigma.openJar(fileJarIn, new ClasspathClassProvider(), ProgressListener.none()); + EnigmaProject project = enigma.openJar(fileJarIn, libraries, ProgressListener.none()); System.out.println("Reading mappings..."); MappingSaveParameters saveParameters = enigma.getProfile().getMappingSaveParameters(); diff --git a/enigma-cli/src/main/java/cuchaz/enigma/command/Command.java b/enigma-cli/src/main/java/cuchaz/enigma/command/Command.java index 53b277f6..7f42f3aa 100644 --- a/enigma-cli/src/main/java/cuchaz/enigma/command/Command.java +++ b/enigma-cli/src/main/java/cuchaz/enigma/command/Command.java @@ -5,6 +5,8 @@ import java.io.IOException; 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.Locale; import net.fabricmc.mappingio.MappingReader; @@ -14,7 +16,6 @@ import net.fabricmc.mappingio.tree.VisitableMappingTree; import cuchaz.enigma.Enigma; import cuchaz.enigma.EnigmaProject; import cuchaz.enigma.ProgressListener; -import cuchaz.enigma.classprovider.ClasspathClassProvider; import cuchaz.enigma.translation.mapping.EntryMapping; import cuchaz.enigma.translation.mapping.serde.MappingFormat; import cuchaz.enigma.translation.mapping.serde.MappingIoConverter; @@ -35,13 +36,13 @@ public abstract class Command { public abstract void run(String... args) throws Exception; - protected static EnigmaProject openProject(Path fileJarIn, Path fileMappings) throws Exception { + protected static EnigmaProject openProject(Path fileJarIn, Path fileMappings, List libraries) throws Exception { ProgressListener progress = new ConsoleProgressListener(); Enigma enigma = Enigma.create(); System.out.println("Reading jar..."); - EnigmaProject project = enigma.openJar(fileJarIn, new ClasspathClassProvider(), progress); + EnigmaProject project = enigma.openJar(fileJarIn, libraries, progress); if (fileMappings != null) { System.out.println("Reading mappings..."); @@ -143,6 +144,16 @@ public abstract class Command { return args[i]; } + protected static List getReadablePaths(String[] args, int startingFrom) { + List paths = new ArrayList<>(); + + for (int i = startingFrom; i < args.length; i++) { + paths.add(getReadablePath(args[i])); + } + + return paths; + } + public static class ConsoleProgressListener implements ProgressListener { private static final int ReportTime = 5000; // 5s diff --git a/enigma-cli/src/main/java/cuchaz/enigma/command/DecompileCommand.java b/enigma-cli/src/main/java/cuchaz/enigma/command/DecompileCommand.java index baed29a6..b1c54989 100644 --- a/enigma-cli/src/main/java/cuchaz/enigma/command/DecompileCommand.java +++ b/enigma-cli/src/main/java/cuchaz/enigma/command/DecompileCommand.java @@ -2,6 +2,7 @@ package cuchaz.enigma.command; import java.lang.reflect.Field; import java.nio.file.Path; +import java.util.List; import java.util.Locale; import cuchaz.enigma.EnigmaProject; @@ -17,7 +18,7 @@ public class DecompileCommand extends Command { @Override public String getUsage() { - return " []"; + return " [] [ ...]"; } @Override @@ -31,6 +32,7 @@ public class DecompileCommand extends Command { Path fileJarIn = getReadableFile(getArg(args, 1, "in jar", true)).toPath(); Path fileJarOut = getWritableFolder(getArg(args, 2, "out folder", true)).toPath(); Path fileMappings = getReadablePath(getArg(args, 3, "mappings file", false)); + List libraries = getReadablePaths(args, 4); DecompilerService decompilerService; @@ -42,7 +44,7 @@ public class DecompileCommand extends Command { return; } - EnigmaProject project = openProject(fileJarIn, fileMappings); + EnigmaProject project = openProject(fileJarIn, fileMappings, libraries); ProgressListener progress = new ConsoleProgressListener(); diff --git a/enigma-cli/src/main/java/cuchaz/enigma/command/DeobfuscateCommand.java b/enigma-cli/src/main/java/cuchaz/enigma/command/DeobfuscateCommand.java index c8e62008..1ea13b50 100644 --- a/enigma-cli/src/main/java/cuchaz/enigma/command/DeobfuscateCommand.java +++ b/enigma-cli/src/main/java/cuchaz/enigma/command/DeobfuscateCommand.java @@ -1,6 +1,7 @@ package cuchaz.enigma.command; import java.nio.file.Path; +import java.util.List; import cuchaz.enigma.EnigmaProject; import cuchaz.enigma.ProgressListener; @@ -25,8 +26,9 @@ public class DeobfuscateCommand extends Command { Path fileJarIn = getReadablePath(getArg(args, 0, "in jar", true)); Path fileJarOut = getWritableFile(getArg(args, 1, "out jar", true)).toPath(); Path fileMappings = getReadablePath(getArg(args, 2, "mappings file", false)); + List libraries = getReadablePaths(args, 3); - EnigmaProject project = openProject(fileJarIn, fileMappings); + EnigmaProject project = openProject(fileJarIn, fileMappings, libraries); ProgressListener progress = new ConsoleProgressListener(); diff --git a/enigma-server/src/main/java/cuchaz/enigma/network/DedicatedEnigmaServer.java b/enigma-server/src/main/java/cuchaz/enigma/network/DedicatedEnigmaServer.java index a3c38824..24fd9ff3 100644 --- a/enigma-server/src/main/java/cuchaz/enigma/network/DedicatedEnigmaServer.java +++ b/enigma-server/src/main/java/cuchaz/enigma/network/DedicatedEnigmaServer.java @@ -21,7 +21,6 @@ import cuchaz.enigma.Enigma; import cuchaz.enigma.EnigmaProfile; import cuchaz.enigma.EnigmaProject; import cuchaz.enigma.ProgressListener; -import cuchaz.enigma.classprovider.ClasspathClassProvider; import cuchaz.enigma.translation.mapping.EntryRemapper; import cuchaz.enigma.translation.mapping.serde.MappingFormat; import cuchaz.enigma.translation.mapping.serde.MappingParseException; @@ -58,6 +57,8 @@ public class DedicatedEnigmaServer extends EnigmaServer { OptionSpec jarOpt = parser.accepts("jar", "Jar file to open at startup; if there are multiple jars, the order must be the same between the server and all clients").withRequiredArg().required().withValuesConvertedBy(PathConverter.INSTANCE); + OptionSpec librariesOpt = parser.accepts("library", "Library file used by the jar").withRequiredArg().withValuesConvertedBy(PathConverter.INSTANCE); + OptionSpec mappingsOpt = parser.accepts("mappings", "Mappings file to open at startup").withRequiredArg().required().withValuesConvertedBy(PathConverter.INSTANCE); OptionSpec profileOpt = parser.accepts("profile", "Profile json to apply at startup").withRequiredArg().withValuesConvertedBy(PathConverter.INSTANCE); @@ -91,7 +92,7 @@ public class DedicatedEnigmaServer extends EnigmaServer { EnigmaProfile profile = EnigmaProfile.read(profileFile); Enigma enigma = Enigma.builder().setProfile(profile).build(); System.out.println("Indexing Jar..."); - EnigmaProject project = enigma.openJars(jars, new ClasspathClassProvider(), ProgressListener.none()); + EnigmaProject project = enigma.openJars(jars, parsedArgs.valuesOf(librariesOpt), ProgressListener.none()); MappingFormat mappingFormat = MappingFormat.ENIGMA_DIRECTORY; EntryRemapper mappings; diff --git a/enigma-swing/src/main/java/cuchaz/enigma/gui/GuiController.java b/enigma-swing/src/main/java/cuchaz/enigma/gui/GuiController.java index 5ea9ab1c..1853a9fc 100644 --- a/enigma-swing/src/main/java/cuchaz/enigma/gui/GuiController.java +++ b/enigma-swing/src/main/java/cuchaz/enigma/gui/GuiController.java @@ -55,7 +55,6 @@ import cuchaz.enigma.api.view.GuiView; import cuchaz.enigma.api.view.entry.EntryReferenceView; import cuchaz.enigma.classhandle.ClassHandle; import cuchaz.enigma.classhandle.ClassHandleProvider; -import cuchaz.enigma.classprovider.ClasspathClassProvider; import cuchaz.enigma.gui.config.NetConfig; import cuchaz.enigma.gui.config.UiConfig; import cuchaz.enigma.gui.dialog.ProgressDialog; @@ -136,11 +135,11 @@ public class GuiController implements ClientPacketHandler, GuiView, DataInvalida return project != null && project.getMapper().isDirty(); } - public CompletableFuture openJar(final List jarPaths) { + public CompletableFuture openJar(final List jarPaths, final List libraries) { this.gui.onStartOpenJar(); return ProgressDialog.runOffThread(gui.getFrame(), progress -> { - project = enigma.openJars(jarPaths, new ClasspathClassProvider(), progress, false); + project = enigma.openJars(jarPaths, libraries, progress, false); project.addDataInvalidationListener(this); indexTreeBuilder = new IndexTreeBuilder(project.getJarIndex()); chp = new ClassHandleProvider(project, UiConfig.getDecompiler().service); @@ -275,11 +274,12 @@ public class GuiController implements ClientPacketHandler, GuiView, DataInvalida public void reloadAll() { List jarPaths = this.project.getJarPaths(); + List libraryPaths = this.project.getLibraryPaths(); MappingFormat loadedMappingFormat = this.loadedMappingFormat; Path loadedMappingPath = this.loadedMappingPath; this.closeJar(); - CompletableFuture f = this.openJar(jarPaths); + CompletableFuture f = this.openJar(jarPaths, libraryPaths); if (loadedMappingFormat != null && loadedMappingPath != null) { f.whenComplete((v, t) -> this.openMappings(loadedMappingFormat, loadedMappingPath)); diff --git a/enigma-swing/src/main/java/cuchaz/enigma/gui/Main.java b/enigma-swing/src/main/java/cuchaz/enigma/gui/Main.java index 66402ad8..b9ad19e8 100644 --- a/enigma-swing/src/main/java/cuchaz/enigma/gui/Main.java +++ b/enigma-swing/src/main/java/cuchaz/enigma/gui/Main.java @@ -40,6 +40,7 @@ public class Main { OptionParser parser = new OptionParser(); OptionSpec jar = parser.accepts("jar", "Jar file to open at startup; if there are multiple jars, the order must be the same between all collab session members").withRequiredArg().withValuesConvertedBy(PathConverter.INSTANCE); + OptionSpec library = parser.accepts("library", "The libraries for the input jar files").withRequiredArg().withValuesConvertedBy(PathConverter.INSTANCE); OptionSpec mappings = parser.accepts("mappings", "Mappings file to open at startup").withRequiredArg().withValuesConvertedBy(PathConverter.INSTANCE); @@ -140,7 +141,8 @@ public class Main { if (options.has(jar)) { List jarPaths = options.valuesOf(jar); - controller.openJar(jarPaths).whenComplete((v, t) -> { + List libraryPaths = options.valuesOf(library); + controller.openJar(jarPaths, libraryPaths).whenComplete((v, t) -> { if (options.has(mappings)) { Path mappingsPath = options.valueOf(mappings); diff --git a/enigma-swing/src/main/java/cuchaz/enigma/gui/elements/MenuBar.java b/enigma-swing/src/main/java/cuchaz/enigma/gui/elements/MenuBar.java index 1789def1..02fa9e36 100644 --- a/enigma-swing/src/main/java/cuchaz/enigma/gui/elements/MenuBar.java +++ b/enigma-swing/src/main/java/cuchaz/enigma/gui/elements/MenuBar.java @@ -244,7 +244,7 @@ public class MenuBar { // checks if the file name corresponds to an existing file if (paths.stream().allMatch(Files::exists)) { - this.gui.getController().openJar(paths); + this.gui.getController().openJar(paths, gui.getController().project.getLibraryPaths()); } UiConfig.setLastSelectedDir(d.getCurrentDirectory().getAbsolutePath()); diff --git a/enigma/src/main/java/cuchaz/enigma/Enigma.java b/enigma/src/main/java/cuchaz/enigma/Enigma.java index 4483ab7a..7f1faa96 100644 --- a/enigma/src/main/java/cuchaz/enigma/Enigma.java +++ b/enigma/src/main/java/cuchaz/enigma/Enigma.java @@ -39,6 +39,7 @@ import cuchaz.enigma.api.service.JarIndexerService; import cuchaz.enigma.api.service.ProjectService; import cuchaz.enigma.classprovider.CachingClassProvider; import cuchaz.enigma.classprovider.ClassProvider; +import cuchaz.enigma.classprovider.ClasspathClassProvider; import cuchaz.enigma.classprovider.CombiningClassProvider; import cuchaz.enigma.classprovider.JarClassProvider; import cuchaz.enigma.utils.I18n; @@ -67,24 +68,24 @@ public class Enigma { return new Builder(); } - public EnigmaProject openJar(Path path, ClassProvider libraryClassProvider, ProgressListener progress) throws IOException { - return openJars(List.of(path), libraryClassProvider, progress); + public EnigmaProject openJar(Path path, List libraries, ProgressListener progress) throws IOException { + return openJars(List.of(path), libraries, progress); } - public EnigmaProject openJars(List paths, ClassProvider libraryClassProvider, ProgressListener progress) throws IOException { - return openJars(paths, libraryClassProvider, progress, true); + public EnigmaProject openJars(List paths, List libraries, ProgressListener progress) throws IOException { + return openJars(paths, libraries, progress, true); } - public EnigmaProject openJars(List paths, ClassProvider libraryClassProvider, ProgressListener progress, boolean callServices) throws IOException { + public EnigmaProject openJars(List paths, List libraries, ProgressListener progress, boolean callServices) throws IOException { ClassProvider jarClassProvider = getJarClassProvider(paths); - ClassProvider classProvider = new CachingClassProvider(new CombiningClassProvider(jarClassProvider, libraryClassProvider)); + ClassProvider classProvider = new CachingClassProvider(new CombiningClassProvider(jarClassProvider, getJarClassProvider(libraries), new ClasspathClassProvider())); Set scope = Set.copyOf(jarClassProvider.getClassNames()); JarIndex index = JarIndex.empty(); ClassProvider classProviderWithFrames = index.indexJar(scope, classProvider, progress); services.get(JarIndexerService.TYPE).forEach(indexer -> indexer.acceptJar(scope, classProviderWithFrames, index)); - EnigmaProject project = new EnigmaProject(this, paths, classProvider, scope, index, Utils.zipSha1(paths.toArray(new Path[0]))); + EnigmaProject project = new EnigmaProject(this, paths, libraries, classProvider, scope, index, Utils.zipSha1(paths.toArray(new Path[0]))); if (callServices) { for (ProjectService projectService : services.get(ProjectService.TYPE)) { diff --git a/enigma/src/main/java/cuchaz/enigma/EnigmaProject.java b/enigma/src/main/java/cuchaz/enigma/EnigmaProject.java index 86a70372..ab0ce304 100644 --- a/enigma/src/main/java/cuchaz/enigma/EnigmaProject.java +++ b/enigma/src/main/java/cuchaz/enigma/EnigmaProject.java @@ -59,6 +59,7 @@ public class EnigmaProject implements ProjectView { private final Enigma enigma; private final List jarPaths; + private final List libraryPaths; private final ClassProvider classProvider; private final JarIndex jarIndex; private final byte[] jarChecksum; @@ -71,13 +72,14 @@ public class EnigmaProject implements ProjectView { private final List dataInvalidationListeners = new ArrayList<>(); - public EnigmaProject(Enigma enigma, List jarPaths, ClassProvider classProvider, Set projectClasses, JarIndex jarIndex, byte[] jarChecksum) { + public EnigmaProject(Enigma enigma, List jarPaths, List libraryPaths, ClassProvider classProvider, Set projectClasses, JarIndex jarIndex, byte[] jarChecksum) { if (jarChecksum.length != 20) { throw new IllegalArgumentException(); } this.enigma = enigma; this.jarPaths = List.copyOf(jarPaths); + this.libraryPaths = List.copyOf(libraryPaths); this.classProvider = classProvider; this.jarIndex = jarIndex; this.jarChecksum = jarChecksum; @@ -109,6 +111,10 @@ public class EnigmaProject implements ProjectView { return jarPaths; } + public List getLibraryPaths() { + return libraryPaths; + } + public ClassProvider getClassProvider() { return classProvider; } diff --git a/enigma/src/test/java/cuchaz/enigma/TestDeobfed.java b/enigma/src/test/java/cuchaz/enigma/TestDeobfed.java index b19aa77e..024f2bba 100644 --- a/enigma/src/test/java/cuchaz/enigma/TestDeobfed.java +++ b/enigma/src/test/java/cuchaz/enigma/TestDeobfed.java @@ -18,11 +18,11 @@ import static org.hamcrest.Matchers.containsInAnyOrder; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; +import java.util.List; import org.junit.BeforeClass; import org.junit.Test; -import cuchaz.enigma.classprovider.ClasspathClassProvider; import cuchaz.enigma.source.Decompiler; import cuchaz.enigma.source.Decompilers; import cuchaz.enigma.source.SourceSettings; @@ -37,10 +37,10 @@ public class TestDeobfed { Enigma enigma = Enigma.create(); Files.createDirectories(DEOBF.getParent()); - EnigmaProject obfProject = enigma.openJar(OBF, new ClasspathClassProvider(), ProgressListener.none()); + EnigmaProject obfProject = enigma.openJar(OBF, List.of(), ProgressListener.none()); obfProject.exportRemappedJar(ProgressListener.none()).write(DEOBF, ProgressListener.none()); - deobfProject = enigma.openJar(DEOBF, new ClasspathClassProvider(), ProgressListener.none()); + deobfProject = enigma.openJar(DEOBF, List.of(), ProgressListener.none()); } @Test diff --git a/enigma/src/test/java/cuchaz/enigma/TestDeobfuscator.java b/enigma/src/test/java/cuchaz/enigma/TestDeobfuscator.java index 587494e6..4eb09f6a 100644 --- a/enigma/src/test/java/cuchaz/enigma/TestDeobfuscator.java +++ b/enigma/src/test/java/cuchaz/enigma/TestDeobfuscator.java @@ -13,10 +13,10 @@ package cuchaz.enigma; import java.io.IOException; import java.nio.file.Paths; +import java.util.List; import org.junit.Test; -import cuchaz.enigma.classprovider.ClasspathClassProvider; import cuchaz.enigma.source.Decompiler; import cuchaz.enigma.source.Decompilers; import cuchaz.enigma.source.SourceSettings; @@ -24,7 +24,7 @@ import cuchaz.enigma.source.SourceSettings; public class TestDeobfuscator { private EnigmaProject openProject() throws IOException { Enigma enigma = Enigma.create(); - return enigma.openJar(Paths.get("build/test-obf/loneClass.jar"), new ClasspathClassProvider(), ProgressListener.none()); + return enigma.openJar(Paths.get("build/test-obf/loneClass.jar"), List.of(), ProgressListener.none()); } @Test diff --git a/enigma/src/test/java/cuchaz/enigma/translation/mapping/TestTinyV2InnerClasses.java b/enigma/src/test/java/cuchaz/enigma/translation/mapping/TestTinyV2InnerClasses.java index 659ac53d..9164abe7 100644 --- a/enigma/src/test/java/cuchaz/enigma/translation/mapping/TestTinyV2InnerClasses.java +++ b/enigma/src/test/java/cuchaz/enigma/translation/mapping/TestTinyV2InnerClasses.java @@ -13,11 +13,11 @@ package cuchaz.enigma.translation.mapping; import java.nio.file.Path; import java.nio.file.Paths; +import java.util.List; import cuchaz.enigma.Enigma; import cuchaz.enigma.EnigmaProject; import cuchaz.enigma.ProgressListener; -import cuchaz.enigma.classprovider.ClasspathClassProvider; import cuchaz.enigma.translation.mapping.serde.enigma.EnigmaMappingsReader; public final class TestTinyV2InnerClasses { @@ -31,7 +31,7 @@ public final class TestTinyV2InnerClasses { // @Test public void testMappings() throws Exception { - EnigmaProject project = Enigma.create().openJar(jar, new ClasspathClassProvider(), ProgressListener.none()); + EnigmaProject project = Enigma.create().openJar(jar, List.of(), ProgressListener.none()); project.setMappings(EnigmaMappingsReader.DIRECTORY.read(mappings, ProgressListener.none(), project.getEnigma().getProfile().getMappingSaveParameters())); } } -- cgit v1.2.3