Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.Executors;
import java.util.concurrent.LinkedBlockingDeque;
Expand Down Expand Up @@ -55,7 +56,7 @@ public void log(String message) {
public static void main(String[] args) {
OptionParser parser = new OptionParser();

OptionSpec<Path> jarOpt = parser.accepts("jar", "Jar file to open at startup").withRequiredArg().required().withValuesConvertedBy(PathConverter.INSTANCE);
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);

OptionSpec<Path> mappingsOpt = parser.accepts("mappings", "Mappings file to open at startup").withRequiredArg().required().withValuesConvertedBy(PathConverter.INSTANCE);

Expand All @@ -68,7 +69,7 @@ public static void main(String[] args) {
OptionSpec<Path> logFileOpt = parser.accepts("log", "The log file to write to").withRequiredArg().withValuesConvertedBy(PathConverter.INSTANCE).defaultsTo(Paths.get("log.txt"));

OptionSet parsedArgs = parser.parse(args);
Path jar = parsedArgs.valueOf(jarOpt);
List<Path> jars = parsedArgs.valuesOf(jarOpt);
Path mappingsFile = parsedArgs.valueOf(mappingsOpt);
Path profileFile = parsedArgs.valueOf(profileOpt);
int port = parsedArgs.valueOf(portOpt);
Expand All @@ -85,12 +86,12 @@ public static void main(String[] args) {
DedicatedEnigmaServer server;

try {
byte[] checksum = Utils.zipSha1(parsedArgs.valueOf(jarOpt));
byte[] checksum = Utils.zipSha1(jars.toArray(new Path[0]));

EnigmaProfile profile = EnigmaProfile.read(profileFile);
Enigma enigma = Enigma.builder().setProfile(profile).build();
System.out.println("Indexing Jar...");
EnigmaProject project = enigma.openJar(jar, new ClasspathClassProvider(), ProgressListener.none());
EnigmaProject project = enigma.openJars(jars, new ClasspathClassProvider(), ProgressListener.none());

MappingFormat mappingFormat = MappingFormat.ENIGMA_DIRECTORY;
EntryRemapper mappings;
Expand Down
1 change: 1 addition & 0 deletions enigma-swing/src/main/java/cuchaz/enigma/gui/Gui.java
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,7 @@ public Gui(EnigmaProfile profile, Set<EditableType> editableTypes) {

private void setupUi() {
this.jarFileChooser.setFileSelectionMode(JFileChooser.FILES_ONLY);
this.jarFileChooser.setMultiSelectionEnabled(true);

this.exportSourceFileChooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
this.exportSourceFileChooser.setAcceptAllFileFilterUsed(false);
Expand Down
26 changes: 16 additions & 10 deletions enigma-swing/src/main/java/cuchaz/enigma/gui/GuiController.java
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
import java.util.Set;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import javax.swing.JOptionPane;
Expand Down Expand Up @@ -119,20 +120,27 @@ public boolean isDirty() {
return project != null && project.getMapper().isDirty();
}

public CompletableFuture<Void> openJar(final Path jarPath) {
public CompletableFuture<Void> openJar(final List<Path> jarPaths) {
this.gui.onStartOpenJar();

return ProgressDialog.runOffThread(gui.getFrame(), progress -> {
project = enigma.openJar(jarPath, new ClasspathClassProvider(), progress);
project = enigma.openJars(jarPaths, new ClasspathClassProvider(), progress);
indexTreeBuilder = new IndexTreeBuilder(project.getJarIndex());
chp = new ClassHandleProvider(project, UiConfig.getDecompiler().service);
SwingUtilities.invokeLater(() -> {
gui.onFinishOpenJar(jarPath.getFileName().toString());
gui.onFinishOpenJar(getFileNames(jarPaths));
refreshClasses();
});
});
}

private static String getFileNames(List<Path> jarPaths) {
return jarPaths.stream()
.map(Path::getFileName)
.map(Object::toString)
.collect(Collectors.joining(", "));
}

public void closeJar() {
this.chp.destroy();
this.chp = null;
Expand Down Expand Up @@ -241,17 +249,15 @@ public void closeMappings() {
}

public void reloadAll() {
Path jarPath = this.project.getJarPath();
List<Path> jarPaths = this.project.getJarPaths();
MappingFormat loadedMappingFormat = this.loadedMappingFormat;
Path loadedMappingPath = this.loadedMappingPath;

if (jarPath != null) {
this.closeJar();
CompletableFuture<Void> f = this.openJar(jarPath);
this.closeJar();
CompletableFuture<Void> f = this.openJar(jarPaths);

if (loadedMappingFormat != null && loadedMappingPath != null) {
f.whenComplete((v, t) -> this.openMappings(loadedMappingFormat, loadedMappingPath));
}
if (loadedMappingFormat != null && loadedMappingPath != null) {
f.whenComplete((v, t) -> this.openMappings(loadedMappingFormat, loadedMappingPath));
}
}

Expand Down
6 changes: 3 additions & 3 deletions enigma-swing/src/main/java/cuchaz/enigma/gui/Main.java
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ public class Main {
public static void main(String[] args) throws IOException {
OptionParser parser = new OptionParser();

OptionSpec<Path> jar = parser.accepts("jar", "Jar file to open at startup").withRequiredArg().withValuesConvertedBy(PathConverter.INSTANCE);
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);

OptionSpec<Path> mappings = parser.accepts("mappings", "Mappings file to open at startup").withRequiredArg().withValuesConvertedBy(PathConverter.INSTANCE);

Expand Down Expand Up @@ -137,8 +137,8 @@ public static void main(String[] args) throws IOException {
}

if (options.has(jar)) {
Path jarPath = options.valueOf(jar);
controller.openJar(jarPath).whenComplete((v, t) -> {
List<Path> jarPaths = options.valuesOf(jar);
controller.openJar(jarPaths).whenComplete((v, t) -> {
if (options.has(mappings)) {
Path mappingsPath = options.valueOf(mappings);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Arrays;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.stream.Collectors;
Expand Down Expand Up @@ -235,15 +236,15 @@ private void onOpenJarClicked() {
return;
}

File file = d.getSelectedFile();
File[] files = d.getSelectedFiles();

// checks if the file name is not empty
if (file != null) {
Path path = file.toPath();
if (files.length >= 1) {
List<Path> paths = Arrays.stream(files).map(File::toPath).toList();

// checks if the file name corresponds to an existing file
if (Files.exists(path)) {
this.gui.getController().openJar(path);
if (paths.stream().allMatch(Files::exists)) {
this.gui.getController().openJar(paths);
}

UiConfig.setLastSelectedDir(d.getCurrentDirectory().getAbsolutePath());
Expand Down
24 changes: 21 additions & 3 deletions enigma/src/main/java/cuchaz/enigma/Enigma.java
Original file line number Diff line number Diff line change
Expand Up @@ -57,15 +57,33 @@ public static Builder builder() {
}

public EnigmaProject openJar(Path path, ClassProvider libraryClassProvider, ProgressListener progress) throws IOException {
JarClassProvider jarClassProvider = new JarClassProvider(path);
return openJars(List.of(path), libraryClassProvider, progress);
}

public EnigmaProject openJars(List<Path> paths, ClassProvider libraryClassProvider, ProgressListener progress) throws IOException {
ClassProvider jarClassProvider = getJarClassProvider(paths);
ClassProvider classProvider = new CachingClassProvider(new CombiningClassProvider(jarClassProvider, libraryClassProvider));
Set<String> scope = jarClassProvider.getClassNames();
Set<String> 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));

return new EnigmaProject(this, path, classProvider, index, Utils.zipSha1(path));
return new EnigmaProject(this, paths, classProvider, index, Utils.zipSha1(paths.toArray(new Path[0])));
}

private ClassProvider getJarClassProvider(List<Path> jars) throws IOException {
if (jars.size() == 1) {
return new JarClassProvider(jars.get(0));
}

var classProviders = new ClassProvider[jars.size()];

for (int i = 0; i < jars.size(); i++) {
classProviders[i] = new JarClassProvider(jars.get(i));
}

return new CombiningClassProvider(classProviders);
}

public EnigmaProfile getProfile() {
Expand Down
10 changes: 5 additions & 5 deletions enigma/src/main/java/cuchaz/enigma/EnigmaProject.java
Original file line number Diff line number Diff line change
Expand Up @@ -48,17 +48,17 @@
public class EnigmaProject {
private final Enigma enigma;

private final Path jarPath;
private final List<Path> jarPaths;
private final ClassProvider classProvider;
private final JarIndex jarIndex;
private final byte[] jarChecksum;

private EntryRemapper mapper;

public EnigmaProject(Enigma enigma, Path jarPath, ClassProvider classProvider, JarIndex jarIndex, byte[] jarChecksum) {
public EnigmaProject(Enigma enigma, List<Path> jarPaths, ClassProvider classProvider, JarIndex jarIndex, byte[] jarChecksum) {
Preconditions.checkArgument(jarChecksum.length == 20);
this.enigma = enigma;
this.jarPath = jarPath;
this.jarPaths = List.copyOf(jarPaths);
this.classProvider = classProvider;
this.jarIndex = jarIndex;
this.jarChecksum = jarChecksum;
Expand All @@ -78,8 +78,8 @@ public Enigma getEnigma() {
return enigma;
}

public Path getJarPath() {
return jarPath;
public List<Path> getJarPaths() {
return jarPaths;
}

public ClassProvider getClassProvider() {
Expand Down
14 changes: 11 additions & 3 deletions enigma/src/main/java/cuchaz/enigma/utils/Utils.java
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;

import com.google.common.base.Preconditions;
import com.google.common.io.CharStreams;

public class Utils {
Expand All @@ -53,7 +54,8 @@ public static void delete(Path path) throws IOException {
}
}

public static byte[] zipSha1(Path path) throws IOException {
public static byte[] zipSha1(Path... paths) throws IOException {
Preconditions.checkArgument(paths.length >= 1, "Must provide at least one zip");
MessageDigest digest;

try {
Expand All @@ -63,6 +65,14 @@ public static byte[] zipSha1(Path path) throws IOException {
throw new RuntimeException(e);
}

for (Path path : paths) {
appendZipSha1(digest, path);
}

return digest.digest();
}

private static void appendZipSha1(MessageDigest digest, Path path) throws IOException {
try (ZipFile zip = new ZipFile(path.toFile())) {
List<? extends ZipEntry> entries = Collections.list(zip.entries());
// only compare classes (some implementations may not generate directory entries)
Expand All @@ -83,8 +93,6 @@ public static byte[] zipSha1(Path path) throws IOException {
}
}
}

return digest.digest();
}

public static void withLock(Lock l, Runnable op) {
Expand Down