summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar Joe2025-09-11 17:35:30 +0100
committerGravatar modmuss2025-09-13 09:14:23 +0100
commitf8c7b8497e9687e15123caca7d4fde54f5bf067a (patch)
tree92a9da7756e0e18cb8925c1cc01e2a2edc10e60f
parentAdd factory methods to the entry views (diff)
downloadenigma-f8c7b8497e9687e15123caca7d4fde54f5bf067a.tar.gz
enigma-f8c7b8497e9687e15123caca7d4fde54f5bf067a.tar.xz
enigma-f8c7b8497e9687e15123caca7d4fde54f5bf067a.zip
Allow you to specify the libraries in the program args rather than always using the runtime classpath
-rw-r--r--enigma-cli/src/main/java/cuchaz/enigma/command/CheckMappingsCommand.java7
-rw-r--r--enigma-cli/src/main/java/cuchaz/enigma/command/Command.java17
-rw-r--r--enigma-cli/src/main/java/cuchaz/enigma/command/DecompileCommand.java6
-rw-r--r--enigma-cli/src/main/java/cuchaz/enigma/command/DeobfuscateCommand.java4
-rw-r--r--enigma-server/src/main/java/cuchaz/enigma/network/DedicatedEnigmaServer.java5
-rw-r--r--enigma-swing/src/main/java/cuchaz/enigma/gui/GuiController.java8
-rw-r--r--enigma-swing/src/main/java/cuchaz/enigma/gui/Main.java4
-rw-r--r--enigma-swing/src/main/java/cuchaz/enigma/gui/elements/MenuBar.java2
-rw-r--r--enigma/src/main/java/cuchaz/enigma/Enigma.java15
-rw-r--r--enigma/src/main/java/cuchaz/enigma/EnigmaProject.java8
-rw-r--r--enigma/src/test/java/cuchaz/enigma/TestDeobfed.java6
-rw-r--r--enigma/src/test/java/cuchaz/enigma/TestDeobfuscator.java4
-rw-r--r--enigma/src/test/java/cuchaz/enigma/translation/mapping/TestTinyV2InnerClasses.java4
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 @@
1package cuchaz.enigma.command; 1package cuchaz.enigma.command;
2 2
3import java.nio.file.Path; 3import java.nio.file.Path;
4import java.util.List;
4import java.util.Set; 5import java.util.Set;
5import java.util.stream.Collectors; 6import java.util.stream.Collectors;
6 7
@@ -8,7 +9,6 @@ import cuchaz.enigma.Enigma;
8import cuchaz.enigma.EnigmaProject; 9import cuchaz.enigma.EnigmaProject;
9import cuchaz.enigma.ProgressListener; 10import cuchaz.enigma.ProgressListener;
10import cuchaz.enigma.analysis.index.JarIndex; 11import cuchaz.enigma.analysis.index.JarIndex;
11import cuchaz.enigma.classprovider.ClasspathClassProvider;
12import cuchaz.enigma.translation.mapping.EntryMapping; 12import cuchaz.enigma.translation.mapping.EntryMapping;
13import cuchaz.enigma.translation.mapping.serde.MappingSaveParameters; 13import cuchaz.enigma.translation.mapping.serde.MappingSaveParameters;
14import cuchaz.enigma.translation.mapping.tree.EntryTree; 14import cuchaz.enigma.translation.mapping.tree.EntryTree;
@@ -21,7 +21,7 @@ public class CheckMappingsCommand extends Command {
21 21
22 @Override 22 @Override
23 public String getUsage() { 23 public String getUsage() {
24 return "<in jar> <mappings file>"; 24 return "<in jar> <mappings file> [<libraries> ...]";
25 } 25 }
26 26
27 @Override 27 @Override
@@ -33,11 +33,12 @@ public class CheckMappingsCommand extends Command {
33 public void run(String... args) throws Exception { 33 public void run(String... args) throws Exception {
34 Path fileJarIn = getReadableFile(getArg(args, 0, "in jar", true)).toPath(); 34 Path fileJarIn = getReadableFile(getArg(args, 0, "in jar", true)).toPath();
35 Path fileMappings = getReadablePath(getArg(args, 1, "mappings file", true)); 35 Path fileMappings = getReadablePath(getArg(args, 1, "mappings file", true));
36 List<Path> libraries = getReadablePaths(args, 2);
36 37
37 Enigma enigma = Enigma.create(); 38 Enigma enigma = Enigma.create();
38 39
39 System.out.println("Reading JAR..."); 40 System.out.println("Reading JAR...");
40 EnigmaProject project = enigma.openJar(fileJarIn, new ClasspathClassProvider(), ProgressListener.none()); 41 EnigmaProject project = enigma.openJar(fileJarIn, libraries, ProgressListener.none());
41 42
42 System.out.println("Reading mappings..."); 43 System.out.println("Reading mappings...");
43 MappingSaveParameters saveParameters = enigma.getProfile().getMappingSaveParameters(); 44 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;
5import java.nio.file.Files; 5import java.nio.file.Files;
6import java.nio.file.Path; 6import java.nio.file.Path;
7import java.nio.file.Paths; 7import java.nio.file.Paths;
8import java.util.ArrayList;
9import java.util.List;
8import java.util.Locale; 10import java.util.Locale;
9 11
10import net.fabricmc.mappingio.MappingReader; 12import net.fabricmc.mappingio.MappingReader;
@@ -14,7 +16,6 @@ import net.fabricmc.mappingio.tree.VisitableMappingTree;
14import cuchaz.enigma.Enigma; 16import cuchaz.enigma.Enigma;
15import cuchaz.enigma.EnigmaProject; 17import cuchaz.enigma.EnigmaProject;
16import cuchaz.enigma.ProgressListener; 18import cuchaz.enigma.ProgressListener;
17import cuchaz.enigma.classprovider.ClasspathClassProvider;
18import cuchaz.enigma.translation.mapping.EntryMapping; 19import cuchaz.enigma.translation.mapping.EntryMapping;
19import cuchaz.enigma.translation.mapping.serde.MappingFormat; 20import cuchaz.enigma.translation.mapping.serde.MappingFormat;
20import cuchaz.enigma.translation.mapping.serde.MappingIoConverter; 21import cuchaz.enigma.translation.mapping.serde.MappingIoConverter;
@@ -35,13 +36,13 @@ public abstract class Command {
35 36
36 public abstract void run(String... args) throws Exception; 37 public abstract void run(String... args) throws Exception;
37 38
38 protected static EnigmaProject openProject(Path fileJarIn, Path fileMappings) throws Exception { 39 protected static EnigmaProject openProject(Path fileJarIn, Path fileMappings, List<Path> libraries) throws Exception {
39 ProgressListener progress = new ConsoleProgressListener(); 40 ProgressListener progress = new ConsoleProgressListener();
40 41
41 Enigma enigma = Enigma.create(); 42 Enigma enigma = Enigma.create();
42 43
43 System.out.println("Reading jar..."); 44 System.out.println("Reading jar...");
44 EnigmaProject project = enigma.openJar(fileJarIn, new ClasspathClassProvider(), progress); 45 EnigmaProject project = enigma.openJar(fileJarIn, libraries, progress);
45 46
46 if (fileMappings != null) { 47 if (fileMappings != null) {
47 System.out.println("Reading mappings..."); 48 System.out.println("Reading mappings...");
@@ -143,6 +144,16 @@ public abstract class Command {
143 return args[i]; 144 return args[i];
144 } 145 }
145 146
147 protected static List<Path> getReadablePaths(String[] args, int startingFrom) {
148 List<Path> paths = new ArrayList<>();
149
150 for (int i = startingFrom; i < args.length; i++) {
151 paths.add(getReadablePath(args[i]));
152 }
153
154 return paths;
155 }
156
146 public static class ConsoleProgressListener implements ProgressListener { 157 public static class ConsoleProgressListener implements ProgressListener {
147 private static final int ReportTime = 5000; // 5s 158 private static final int ReportTime = 5000; // 5s
148 159
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;
2 2
3import java.lang.reflect.Field; 3import java.lang.reflect.Field;
4import java.nio.file.Path; 4import java.nio.file.Path;
5import java.util.List;
5import java.util.Locale; 6import java.util.Locale;
6 7
7import cuchaz.enigma.EnigmaProject; 8import cuchaz.enigma.EnigmaProject;
@@ -17,7 +18,7 @@ public class DecompileCommand extends Command {
17 18
18 @Override 19 @Override
19 public String getUsage() { 20 public String getUsage() {
20 return "<decompiler> <in jar> <out folder> [<mappings file>]"; 21 return "<decompiler> <in jar> <out folder> [<mappings file>] [<libraries> ...]";
21 } 22 }
22 23
23 @Override 24 @Override
@@ -31,6 +32,7 @@ public class DecompileCommand extends Command {
31 Path fileJarIn = getReadableFile(getArg(args, 1, "in jar", true)).toPath(); 32 Path fileJarIn = getReadableFile(getArg(args, 1, "in jar", true)).toPath();
32 Path fileJarOut = getWritableFolder(getArg(args, 2, "out folder", true)).toPath(); 33 Path fileJarOut = getWritableFolder(getArg(args, 2, "out folder", true)).toPath();
33 Path fileMappings = getReadablePath(getArg(args, 3, "mappings file", false)); 34 Path fileMappings = getReadablePath(getArg(args, 3, "mappings file", false));
35 List<Path> libraries = getReadablePaths(args, 4);
34 36
35 DecompilerService decompilerService; 37 DecompilerService decompilerService;
36 38
@@ -42,7 +44,7 @@ public class DecompileCommand extends Command {
42 return; 44 return;
43 } 45 }
44 46
45 EnigmaProject project = openProject(fileJarIn, fileMappings); 47 EnigmaProject project = openProject(fileJarIn, fileMappings, libraries);
46 48
47 ProgressListener progress = new ConsoleProgressListener(); 49 ProgressListener progress = new ConsoleProgressListener();
48 50
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 @@
1package cuchaz.enigma.command; 1package cuchaz.enigma.command;
2 2
3import java.nio.file.Path; 3import java.nio.file.Path;
4import java.util.List;
4 5
5import cuchaz.enigma.EnigmaProject; 6import cuchaz.enigma.EnigmaProject;
6import cuchaz.enigma.ProgressListener; 7import cuchaz.enigma.ProgressListener;
@@ -25,8 +26,9 @@ public class DeobfuscateCommand extends Command {
25 Path fileJarIn = getReadablePath(getArg(args, 0, "in jar", true)); 26 Path fileJarIn = getReadablePath(getArg(args, 0, "in jar", true));
26 Path fileJarOut = getWritableFile(getArg(args, 1, "out jar", true)).toPath(); 27 Path fileJarOut = getWritableFile(getArg(args, 1, "out jar", true)).toPath();
27 Path fileMappings = getReadablePath(getArg(args, 2, "mappings file", false)); 28 Path fileMappings = getReadablePath(getArg(args, 2, "mappings file", false));
29 List<Path> libraries = getReadablePaths(args, 3);
28 30
29 EnigmaProject project = openProject(fileJarIn, fileMappings); 31 EnigmaProject project = openProject(fileJarIn, fileMappings, libraries);
30 32
31 ProgressListener progress = new ConsoleProgressListener(); 33 ProgressListener progress = new ConsoleProgressListener();
32 34
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;
21import cuchaz.enigma.EnigmaProfile; 21import cuchaz.enigma.EnigmaProfile;
22import cuchaz.enigma.EnigmaProject; 22import cuchaz.enigma.EnigmaProject;
23import cuchaz.enigma.ProgressListener; 23import cuchaz.enigma.ProgressListener;
24import cuchaz.enigma.classprovider.ClasspathClassProvider;
25import cuchaz.enigma.translation.mapping.EntryRemapper; 24import cuchaz.enigma.translation.mapping.EntryRemapper;
26import cuchaz.enigma.translation.mapping.serde.MappingFormat; 25import cuchaz.enigma.translation.mapping.serde.MappingFormat;
27import cuchaz.enigma.translation.mapping.serde.MappingParseException; 26import cuchaz.enigma.translation.mapping.serde.MappingParseException;
@@ -58,6 +57,8 @@ public class DedicatedEnigmaServer extends EnigmaServer {
58 57
59 OptionSpec<Path> 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); 58 OptionSpec<Path> 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);
60 59
60 OptionSpec<Path> librariesOpt = parser.accepts("library", "Library file used by the jar").withRequiredArg().withValuesConvertedBy(PathConverter.INSTANCE);
61
61 OptionSpec<Path> mappingsOpt = parser.accepts("mappings", "Mappings file to open at startup").withRequiredArg().required().withValuesConvertedBy(PathConverter.INSTANCE); 62 OptionSpec<Path> mappingsOpt = parser.accepts("mappings", "Mappings file to open at startup").withRequiredArg().required().withValuesConvertedBy(PathConverter.INSTANCE);
62 63
63 OptionSpec<Path> profileOpt = parser.accepts("profile", "Profile json to apply at startup").withRequiredArg().withValuesConvertedBy(PathConverter.INSTANCE); 64 OptionSpec<Path> profileOpt = parser.accepts("profile", "Profile json to apply at startup").withRequiredArg().withValuesConvertedBy(PathConverter.INSTANCE);
@@ -91,7 +92,7 @@ public class DedicatedEnigmaServer extends EnigmaServer {
91 EnigmaProfile profile = EnigmaProfile.read(profileFile); 92 EnigmaProfile profile = EnigmaProfile.read(profileFile);
92 Enigma enigma = Enigma.builder().setProfile(profile).build(); 93 Enigma enigma = Enigma.builder().setProfile(profile).build();
93 System.out.println("Indexing Jar..."); 94 System.out.println("Indexing Jar...");
94 EnigmaProject project = enigma.openJars(jars, new ClasspathClassProvider(), ProgressListener.none()); 95 EnigmaProject project = enigma.openJars(jars, parsedArgs.valuesOf(librariesOpt), ProgressListener.none());
95 96
96 MappingFormat mappingFormat = MappingFormat.ENIGMA_DIRECTORY; 97 MappingFormat mappingFormat = MappingFormat.ENIGMA_DIRECTORY;
97 EntryRemapper mappings; 98 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;
55import cuchaz.enigma.api.view.entry.EntryReferenceView; 55import cuchaz.enigma.api.view.entry.EntryReferenceView;
56import cuchaz.enigma.classhandle.ClassHandle; 56import cuchaz.enigma.classhandle.ClassHandle;
57import cuchaz.enigma.classhandle.ClassHandleProvider; 57import cuchaz.enigma.classhandle.ClassHandleProvider;
58import cuchaz.enigma.classprovider.ClasspathClassProvider;
59import cuchaz.enigma.gui.config.NetConfig; 58import cuchaz.enigma.gui.config.NetConfig;
60import cuchaz.enigma.gui.config.UiConfig; 59import cuchaz.enigma.gui.config.UiConfig;
61import cuchaz.enigma.gui.dialog.ProgressDialog; 60import cuchaz.enigma.gui.dialog.ProgressDialog;
@@ -136,11 +135,11 @@ public class GuiController implements ClientPacketHandler, GuiView, DataInvalida
136 return project != null && project.getMapper().isDirty(); 135 return project != null && project.getMapper().isDirty();
137 } 136 }
138 137
139 public CompletableFuture<Void> openJar(final List<Path> jarPaths) { 138 public CompletableFuture<Void> openJar(final List<Path> jarPaths, final List<Path> libraries) {
140 this.gui.onStartOpenJar(); 139 this.gui.onStartOpenJar();
141 140
142 return ProgressDialog.runOffThread(gui.getFrame(), progress -> { 141 return ProgressDialog.runOffThread(gui.getFrame(), progress -> {
143 project = enigma.openJars(jarPaths, new ClasspathClassProvider(), progress, false); 142 project = enigma.openJars(jarPaths, libraries, progress, false);
144 project.addDataInvalidationListener(this); 143 project.addDataInvalidationListener(this);
145 indexTreeBuilder = new IndexTreeBuilder(project.getJarIndex()); 144 indexTreeBuilder = new IndexTreeBuilder(project.getJarIndex());
146 chp = new ClassHandleProvider(project, UiConfig.getDecompiler().service); 145 chp = new ClassHandleProvider(project, UiConfig.getDecompiler().service);
@@ -275,11 +274,12 @@ public class GuiController implements ClientPacketHandler, GuiView, DataInvalida
275 274
276 public void reloadAll() { 275 public void reloadAll() {
277 List<Path> jarPaths = this.project.getJarPaths(); 276 List<Path> jarPaths = this.project.getJarPaths();
277 List<Path> libraryPaths = this.project.getLibraryPaths();
278 MappingFormat loadedMappingFormat = this.loadedMappingFormat; 278 MappingFormat loadedMappingFormat = this.loadedMappingFormat;
279 Path loadedMappingPath = this.loadedMappingPath; 279 Path loadedMappingPath = this.loadedMappingPath;
280 280
281 this.closeJar(); 281 this.closeJar();
282 CompletableFuture<Void> f = this.openJar(jarPaths); 282 CompletableFuture<Void> f = this.openJar(jarPaths, libraryPaths);
283 283
284 if (loadedMappingFormat != null && loadedMappingPath != null) { 284 if (loadedMappingFormat != null && loadedMappingPath != null) {
285 f.whenComplete((v, t) -> this.openMappings(loadedMappingFormat, loadedMappingPath)); 285 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 {
40 OptionParser parser = new OptionParser(); 40 OptionParser parser = new OptionParser();
41 41
42 OptionSpec<Path> 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); 42 OptionSpec<Path> 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);
43 OptionSpec<Path> library = parser.accepts("library", "The libraries for the input jar files").withRequiredArg().withValuesConvertedBy(PathConverter.INSTANCE);
43 44
44 OptionSpec<Path> mappings = parser.accepts("mappings", "Mappings file to open at startup").withRequiredArg().withValuesConvertedBy(PathConverter.INSTANCE); 45 OptionSpec<Path> mappings = parser.accepts("mappings", "Mappings file to open at startup").withRequiredArg().withValuesConvertedBy(PathConverter.INSTANCE);
45 46
@@ -140,7 +141,8 @@ public class Main {
140 141
141 if (options.has(jar)) { 142 if (options.has(jar)) {
142 List<Path> jarPaths = options.valuesOf(jar); 143 List<Path> jarPaths = options.valuesOf(jar);
143 controller.openJar(jarPaths).whenComplete((v, t) -> { 144 List<Path> libraryPaths = options.valuesOf(library);
145 controller.openJar(jarPaths, libraryPaths).whenComplete((v, t) -> {
144 if (options.has(mappings)) { 146 if (options.has(mappings)) {
145 Path mappingsPath = options.valueOf(mappings); 147 Path mappingsPath = options.valueOf(mappings);
146 148
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 {
244 244
245 // checks if the file name corresponds to an existing file 245 // checks if the file name corresponds to an existing file
246 if (paths.stream().allMatch(Files::exists)) { 246 if (paths.stream().allMatch(Files::exists)) {
247 this.gui.getController().openJar(paths); 247 this.gui.getController().openJar(paths, gui.getController().project.getLibraryPaths());
248 } 248 }
249 249
250 UiConfig.setLastSelectedDir(d.getCurrentDirectory().getAbsolutePath()); 250 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;
39import cuchaz.enigma.api.service.ProjectService; 39import cuchaz.enigma.api.service.ProjectService;
40import cuchaz.enigma.classprovider.CachingClassProvider; 40import cuchaz.enigma.classprovider.CachingClassProvider;
41import cuchaz.enigma.classprovider.ClassProvider; 41import cuchaz.enigma.classprovider.ClassProvider;
42import cuchaz.enigma.classprovider.ClasspathClassProvider;
42import cuchaz.enigma.classprovider.CombiningClassProvider; 43import cuchaz.enigma.classprovider.CombiningClassProvider;
43import cuchaz.enigma.classprovider.JarClassProvider; 44import cuchaz.enigma.classprovider.JarClassProvider;
44import cuchaz.enigma.utils.I18n; 45import cuchaz.enigma.utils.I18n;
@@ -67,24 +68,24 @@ public class Enigma {
67 return new Builder(); 68 return new Builder();
68 } 69 }
69 70
70 public EnigmaProject openJar(Path path, ClassProvider libraryClassProvider, ProgressListener progress) throws IOException { 71 public EnigmaProject openJar(Path path, List<Path> libraries, ProgressListener progress) throws IOException {
71 return openJars(List.of(path), libraryClassProvider, progress); 72 return openJars(List.of(path), libraries, progress);
72 } 73 }
73 74
74 public EnigmaProject openJars(List<Path> paths, ClassProvider libraryClassProvider, ProgressListener progress) throws IOException { 75 public EnigmaProject openJars(List<Path> paths, List<Path> libraries, ProgressListener progress) throws IOException {
75 return openJars(paths, libraryClassProvider, progress, true); 76 return openJars(paths, libraries, progress, true);
76 } 77 }
77 78
78 public EnigmaProject openJars(List<Path> paths, ClassProvider libraryClassProvider, ProgressListener progress, boolean callServices) throws IOException { 79 public EnigmaProject openJars(List<Path> paths, List<Path> libraries, ProgressListener progress, boolean callServices) throws IOException {
79 ClassProvider jarClassProvider = getJarClassProvider(paths); 80 ClassProvider jarClassProvider = getJarClassProvider(paths);
80 ClassProvider classProvider = new CachingClassProvider(new CombiningClassProvider(jarClassProvider, libraryClassProvider)); 81 ClassProvider classProvider = new CachingClassProvider(new CombiningClassProvider(jarClassProvider, getJarClassProvider(libraries), new ClasspathClassProvider()));
81 Set<String> scope = Set.copyOf(jarClassProvider.getClassNames()); 82 Set<String> scope = Set.copyOf(jarClassProvider.getClassNames());
82 83
83 JarIndex index = JarIndex.empty(); 84 JarIndex index = JarIndex.empty();
84 ClassProvider classProviderWithFrames = index.indexJar(scope, classProvider, progress); 85 ClassProvider classProviderWithFrames = index.indexJar(scope, classProvider, progress);
85 services.get(JarIndexerService.TYPE).forEach(indexer -> indexer.acceptJar(scope, classProviderWithFrames, index)); 86 services.get(JarIndexerService.TYPE).forEach(indexer -> indexer.acceptJar(scope, classProviderWithFrames, index));
86 87
87 EnigmaProject project = new EnigmaProject(this, paths, classProvider, scope, index, Utils.zipSha1(paths.toArray(new Path[0]))); 88 EnigmaProject project = new EnigmaProject(this, paths, libraries, classProvider, scope, index, Utils.zipSha1(paths.toArray(new Path[0])));
88 89
89 if (callServices) { 90 if (callServices) {
90 for (ProjectService projectService : services.get(ProjectService.TYPE)) { 91 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 {
59 private final Enigma enigma; 59 private final Enigma enigma;
60 60
61 private final List<Path> jarPaths; 61 private final List<Path> jarPaths;
62 private final List<Path> libraryPaths;
62 private final ClassProvider classProvider; 63 private final ClassProvider classProvider;
63 private final JarIndex jarIndex; 64 private final JarIndex jarIndex;
64 private final byte[] jarChecksum; 65 private final byte[] jarChecksum;
@@ -71,13 +72,14 @@ public class EnigmaProject implements ProjectView {
71 72
72 private final List<DataInvalidationListener> dataInvalidationListeners = new ArrayList<>(); 73 private final List<DataInvalidationListener> dataInvalidationListeners = new ArrayList<>();
73 74
74 public EnigmaProject(Enigma enigma, List<Path> jarPaths, ClassProvider classProvider, Set<String> projectClasses, JarIndex jarIndex, byte[] jarChecksum) { 75 public EnigmaProject(Enigma enigma, List<Path> jarPaths, List<Path> libraryPaths, ClassProvider classProvider, Set<String> projectClasses, JarIndex jarIndex, byte[] jarChecksum) {
75 if (jarChecksum.length != 20) { 76 if (jarChecksum.length != 20) {
76 throw new IllegalArgumentException(); 77 throw new IllegalArgumentException();
77 } 78 }
78 79
79 this.enigma = enigma; 80 this.enigma = enigma;
80 this.jarPaths = List.copyOf(jarPaths); 81 this.jarPaths = List.copyOf(jarPaths);
82 this.libraryPaths = List.copyOf(libraryPaths);
81 this.classProvider = classProvider; 83 this.classProvider = classProvider;
82 this.jarIndex = jarIndex; 84 this.jarIndex = jarIndex;
83 this.jarChecksum = jarChecksum; 85 this.jarChecksum = jarChecksum;
@@ -109,6 +111,10 @@ public class EnigmaProject implements ProjectView {
109 return jarPaths; 111 return jarPaths;
110 } 112 }
111 113
114 public List<Path> getLibraryPaths() {
115 return libraryPaths;
116 }
117
112 public ClassProvider getClassProvider() { 118 public ClassProvider getClassProvider() {
113 return classProvider; 119 return classProvider;
114 } 120 }
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;
18import java.nio.file.Files; 18import java.nio.file.Files;
19import java.nio.file.Path; 19import java.nio.file.Path;
20import java.nio.file.Paths; 20import java.nio.file.Paths;
21import java.util.List;
21 22
22import org.junit.BeforeClass; 23import org.junit.BeforeClass;
23import org.junit.Test; 24import org.junit.Test;
24 25
25import cuchaz.enigma.classprovider.ClasspathClassProvider;
26import cuchaz.enigma.source.Decompiler; 26import cuchaz.enigma.source.Decompiler;
27import cuchaz.enigma.source.Decompilers; 27import cuchaz.enigma.source.Decompilers;
28import cuchaz.enigma.source.SourceSettings; 28import cuchaz.enigma.source.SourceSettings;
@@ -37,10 +37,10 @@ public class TestDeobfed {
37 Enigma enigma = Enigma.create(); 37 Enigma enigma = Enigma.create();
38 38
39 Files.createDirectories(DEOBF.getParent()); 39 Files.createDirectories(DEOBF.getParent());
40 EnigmaProject obfProject = enigma.openJar(OBF, new ClasspathClassProvider(), ProgressListener.none()); 40 EnigmaProject obfProject = enigma.openJar(OBF, List.of(), ProgressListener.none());
41 obfProject.exportRemappedJar(ProgressListener.none()).write(DEOBF, ProgressListener.none()); 41 obfProject.exportRemappedJar(ProgressListener.none()).write(DEOBF, ProgressListener.none());
42 42
43 deobfProject = enigma.openJar(DEOBF, new ClasspathClassProvider(), ProgressListener.none()); 43 deobfProject = enigma.openJar(DEOBF, List.of(), ProgressListener.none());
44 } 44 }
45 45
46 @Test 46 @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;
13 13
14import java.io.IOException; 14import java.io.IOException;
15import java.nio.file.Paths; 15import java.nio.file.Paths;
16import java.util.List;
16 17
17import org.junit.Test; 18import org.junit.Test;
18 19
19import cuchaz.enigma.classprovider.ClasspathClassProvider;
20import cuchaz.enigma.source.Decompiler; 20import cuchaz.enigma.source.Decompiler;
21import cuchaz.enigma.source.Decompilers; 21import cuchaz.enigma.source.Decompilers;
22import cuchaz.enigma.source.SourceSettings; 22import cuchaz.enigma.source.SourceSettings;
@@ -24,7 +24,7 @@ import cuchaz.enigma.source.SourceSettings;
24public class TestDeobfuscator { 24public class TestDeobfuscator {
25 private EnigmaProject openProject() throws IOException { 25 private EnigmaProject openProject() throws IOException {
26 Enigma enigma = Enigma.create(); 26 Enigma enigma = Enigma.create();
27 return enigma.openJar(Paths.get("build/test-obf/loneClass.jar"), new ClasspathClassProvider(), ProgressListener.none()); 27 return enigma.openJar(Paths.get("build/test-obf/loneClass.jar"), List.of(), ProgressListener.none());
28 } 28 }
29 29
30 @Test 30 @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;
13 13
14import java.nio.file.Path; 14import java.nio.file.Path;
15import java.nio.file.Paths; 15import java.nio.file.Paths;
16import java.util.List;
16 17
17import cuchaz.enigma.Enigma; 18import cuchaz.enigma.Enigma;
18import cuchaz.enigma.EnigmaProject; 19import cuchaz.enigma.EnigmaProject;
19import cuchaz.enigma.ProgressListener; 20import cuchaz.enigma.ProgressListener;
20import cuchaz.enigma.classprovider.ClasspathClassProvider;
21import cuchaz.enigma.translation.mapping.serde.enigma.EnigmaMappingsReader; 21import cuchaz.enigma.translation.mapping.serde.enigma.EnigmaMappingsReader;
22 22
23public final class TestTinyV2InnerClasses { 23public final class TestTinyV2InnerClasses {
@@ -31,7 +31,7 @@ public final class TestTinyV2InnerClasses {
31 31
32 // @Test 32 // @Test
33 public void testMappings() throws Exception { 33 public void testMappings() throws Exception {
34 EnigmaProject project = Enigma.create().openJar(jar, new ClasspathClassProvider(), ProgressListener.none()); 34 EnigmaProject project = Enigma.create().openJar(jar, List.of(), ProgressListener.none());
35 project.setMappings(EnigmaMappingsReader.DIRECTORY.read(mappings, ProgressListener.none(), project.getEnigma().getProfile().getMappingSaveParameters())); 35 project.setMappings(EnigmaMappingsReader.DIRECTORY.read(mappings, ProgressListener.none(), project.getEnigma().getProfile().getMappingSaveParameters()));
36 } 36 }
37} 37}