Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Initial Mapping-IO support #463

Merged
merged 17 commits into from
Nov 28, 2023
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
3 changes: 3 additions & 0 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@ subprojects {
dependencies {
implementation 'com.google.guava:guava:32.1.2-jre'
implementation 'com.google.code.gson:gson:2.10.1'
implementation 'net.fabricmc:mapping-io:0.5.0'

compileOnly 'org.jetbrains:annotations:24.0.1'

testImplementation 'junit:junit:4.13.2'
testImplementation 'org.hamcrest:hamcrest:2.2'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@
import cuchaz.enigma.analysis.index.JarIndex;
import cuchaz.enigma.classprovider.ClasspathClassProvider;
import cuchaz.enigma.translation.mapping.EntryMapping;
import cuchaz.enigma.translation.mapping.serde.MappingFormat;
import cuchaz.enigma.translation.mapping.serde.MappingSaveParameters;
import cuchaz.enigma.translation.mapping.tree.EntryTree;
import cuchaz.enigma.translation.representation.entry.ClassEntry;
Expand Down Expand Up @@ -38,15 +37,12 @@ public void run(String... args) throws Exception {
Enigma enigma = Enigma.create();

System.out.println("Reading JAR...");

EnigmaProject project = enigma.openJar(fileJarIn, new ClasspathClassProvider(), ProgressListener.none());

System.out.println("Reading mappings...");

MappingFormat format = chooseEnigmaFormat(fileMappings);
MappingSaveParameters saveParameters = enigma.getProfile().getMappingSaveParameters();

EntryTree<EntryMapping> mappings = format.read(fileMappings, ProgressListener.none(), saveParameters);
EntryTree<EntryMapping> mappings = readMappings(fileMappings, ProgressListener.none(), saveParameters);
project.setMappings(mappings);

JarIndex idx = project.getJarIndex();
Expand Down
26 changes: 18 additions & 8 deletions enigma-cli/src/main/java/cuchaz/enigma/command/Command.java
Original file line number Diff line number Diff line change
@@ -1,18 +1,24 @@
package cuchaz.enigma.command;

import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;

import com.google.common.io.MoreFiles;
import net.fabricmc.mappingio.MappingReader;
import net.fabricmc.mappingio.tree.MemoryMappingTree;
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;
import cuchaz.enigma.translation.mapping.serde.MappingParseException;
import cuchaz.enigma.translation.mapping.serde.MappingSaveParameters;
import cuchaz.enigma.translation.mapping.tree.EntryTree;

Expand Down Expand Up @@ -41,22 +47,26 @@ protected static EnigmaProject openProject(Path fileJarIn, Path fileMappings) th
System.out.println("Reading mappings...");

MappingSaveParameters saveParameters = enigma.getProfile().getMappingSaveParameters();
EntryTree<EntryMapping> mappings = chooseEnigmaFormat(fileMappings).read(fileMappings, progress, saveParameters);
EntryTree<EntryMapping> mappings = readMappings(fileMappings, progress, saveParameters);

project.setMappings(mappings);
}

return project;
}

protected static MappingFormat chooseEnigmaFormat(Path path) {
if (Files.isDirectory(path)) {
return MappingFormat.ENIGMA_DIRECTORY;
} else if ("zip".equalsIgnoreCase(MoreFiles.getFileExtension(path))) {
return MappingFormat.ENIGMA_ZIP;
} else {
return MappingFormat.ENIGMA_FILE;
protected static EntryTree<EntryMapping> readMappings(Path path, ProgressListener progress, MappingSaveParameters saveParameters) throws IOException, MappingParseException {
// Legacy
if ("zip".equalsIgnoreCase(MoreFiles.getFileExtension(path))) {
return MappingFormat.ENIGMA_ZIP.read(path, progress, saveParameters, null);
}

net.fabricmc.mappingio.format.MappingFormat format = MappingReader.detectFormat(path);
if (format == null) throw new IllegalArgumentException("Unknown mapping format!");

VisitableMappingTree tree = new MemoryMappingTree();
MappingReader.read(path, format, tree);
return MappingIoConverter.fromMappingIo(tree, progress, null);
}

protected static File getWritableFile(String path) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,17 +1,19 @@
package cuchaz.enigma.command;

import java.io.IOException;
import java.io.UncheckedIOException;
import java.nio.file.Files;
import java.nio.file.Path;

import net.fabricmc.mappingio.MappingWriter;
import net.fabricmc.mappingio.tree.VisitableMappingTree;

import cuchaz.enigma.ProgressListener;
import cuchaz.enigma.translation.mapping.EntryMapping;
import cuchaz.enigma.translation.mapping.serde.MappingFormat;
import cuchaz.enigma.translation.mapping.serde.MappingIoConverter;
import cuchaz.enigma.translation.mapping.serde.MappingParseException;
import cuchaz.enigma.translation.mapping.serde.MappingSaveParameters;
import cuchaz.enigma.translation.mapping.serde.enigma.EnigmaMappingsReader;
import cuchaz.enigma.translation.mapping.serde.enigma.EnigmaMappingsWriter;
import cuchaz.enigma.translation.mapping.serde.tiny.TinyMappingsReader;
import cuchaz.enigma.translation.mapping.serde.tiny.TinyMappingsWriter;
import cuchaz.enigma.translation.mapping.serde.tinyv2.TinyV2Writer;
import cuchaz.enigma.translation.mapping.tree.EntryTree;
Expand All @@ -22,11 +24,11 @@ private MappingCommandsUtil() {

public static EntryTree<EntryMapping> read(String type, Path path, MappingSaveParameters saveParameters) throws MappingParseException, IOException {
if (type.equals("enigma")) {
return (Files.isDirectory(path) ? EnigmaMappingsReader.DIRECTORY : EnigmaMappingsReader.ZIP).read(path, ProgressListener.none(), saveParameters);
return (Files.isDirectory(path) ? MappingFormat.ENIGMA_DIRECTORY : MappingFormat.ENIGMA_ZIP).read(path, ProgressListener.none(), saveParameters, null);
}

if (type.equals("tiny")) {
return TinyMappingsReader.INSTANCE.read(path, ProgressListener.none(), saveParameters);
return MappingFormat.TINY_FILE.read(path, ProgressListener.none(), saveParameters, null);
}

MappingFormat format = null;
Expand All @@ -40,15 +42,15 @@ public static EntryTree<EntryMapping> read(String type, Path path, MappingSavePa
}

if (format != null) {
return format.getReader().read(path, ProgressListener.none(), saveParameters);
return format.read(path, ProgressListener.none(), saveParameters, null);
}

throw new IllegalArgumentException("no reader for " + type);
}

public static void write(EntryTree<EntryMapping> mappings, String type, Path path, MappingSaveParameters saveParameters) {
if (type.equals("enigma")) {
EnigmaMappingsWriter.DIRECTORY.write(mappings, path, ProgressListener.none(), saveParameters);
MappingFormat.ENIGMA_DIRECTORY.write(mappings, path, ProgressListener.none(), saveParameters);
return;
}

Expand All @@ -59,7 +61,18 @@ public static void write(EntryTree<EntryMapping> mappings, String type, Path pat
throw new IllegalArgumentException("specify column names as 'tinyv2:from_namespace:to_namespace'");
}

new TinyV2Writer(split[1], split[2]).write(mappings, path, ProgressListener.none(), saveParameters);
if (!System.getProperty("enigma.use_mappingio", "true").equals("true")) {
new TinyV2Writer(split[1], split[2]).write(mappings, path, ProgressListener.none(), saveParameters);
return;
}

try {
VisitableMappingTree tree = MappingIoConverter.toMappingIo(mappings, ProgressListener.none(), split[1], split[2]);
tree.accept(MappingWriter.create(path, net.fabricmc.mappingio.format.MappingFormat.TINY_2_FILE));
} catch (IOException e) {
throw new UncheckedIOException(e);
}

return;
}

Expand All @@ -70,7 +83,18 @@ public static void write(EntryTree<EntryMapping> mappings, String type, Path pat
throw new IllegalArgumentException("specify column names as 'tiny:from_column:to_column'");
}

new TinyMappingsWriter(split[1], split[2]).write(mappings, path, ProgressListener.none(), saveParameters);
if (!System.getProperty("enigma.use_mappingio", "true").equals("true")) {
new TinyMappingsWriter(split[1], split[2]).write(mappings, path, ProgressListener.none(), saveParameters);
return;
}

try {
VisitableMappingTree tree = MappingIoConverter.toMappingIo(mappings, ProgressListener.none(), split[1], split[2]);
tree.accept(MappingWriter.create(path, net.fabricmc.mappingio.format.MappingFormat.TINY_FILE));
} catch (IOException e) {
throw new UncheckedIOException(e);
}

return;
}

Expand All @@ -83,7 +107,7 @@ public static void write(EntryTree<EntryMapping> mappings, String type, Path pat
}

if (format != null) {
format.getWriter().write(mappings, path, ProgressListener.none(), saveParameters);
format.write(mappings, path, ProgressListener.none(), saveParameters);
return;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ public static void main(String[] args) {
mappingFormat = MappingFormat.ENIGMA_FILE;
}

mappings = EntryRemapper.mapped(project.getJarIndex(), mappingFormat.read(mappingsFile, ProgressListener.none(), profile.getMappingSaveParameters()));
mappings = EntryRemapper.mapped(project.getJarIndex(), mappingFormat.read(mappingsFile, ProgressListener.none(), profile.getMappingSaveParameters(), project.getJarIndex()));
}

PrintWriter log = new PrintWriter(Files.newBufferedWriter(logFile));
Expand Down
17 changes: 14 additions & 3 deletions enigma-swing/src/main/java/cuchaz/enigma/gui/GuiController.java
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
import javax.swing.SwingUtilities;

import com.google.common.collect.Lists;
import org.jetbrains.annotations.ApiStatus;

import cuchaz.enigma.Enigma;
import cuchaz.enigma.EnigmaProfile;
Expand Down Expand Up @@ -139,6 +140,12 @@ public void closeJar() {
this.gui.onCloseJar();
}

@ApiStatus.Internal
public CompletableFuture<Void> openMappings(MappingFormat format, Path path, boolean useMappingIo) {
System.getProperties().setProperty("enigma.use_mappingio", useMappingIo ? "true" : "false");
return openMappings(format, path);
}

public CompletableFuture<Void> openMappings(MappingFormat format, Path path) {
if (project == null) {
return CompletableFuture.completedFuture(null);
Expand All @@ -149,9 +156,7 @@ public CompletableFuture<Void> openMappings(MappingFormat format, Path path) {
return ProgressDialog.runOffThread(gui.getFrame(), progress -> {
try {
MappingSaveParameters saveParameters = enigma.getProfile().getMappingSaveParameters();

EntryTree<EntryMapping> mappings = format.read(path, progress, saveParameters);
project.setMappings(mappings);
project.setMappings(format.read(path, progress, saveParameters, project.getJarIndex()));

loadedMappingFormat = format;
loadedMappingPath = path;
Expand Down Expand Up @@ -179,6 +184,12 @@ public CompletableFuture<Void> saveMappings(Path path) {
return saveMappings(path, loadedMappingFormat);
}

@ApiStatus.Internal
public CompletableFuture<Void> saveMappings(Path path, MappingFormat format, boolean useMappingIo) {
System.getProperties().setProperty("enigma.use_mappingio", useMappingIo ? "true" : "false");
return saveMappings(path, format);
}

/**
* Saves the mappings, with a dialog popping up, showing the progress.
*
Expand Down
88 changes: 57 additions & 31 deletions enigma-swing/src/main/java/cuchaz/enigma/gui/elements/MenuBar.java
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ public class MenuBar {
private final JMenu fileMenu = new JMenu();
private final JMenuItem jarOpenItem = new JMenuItem();
private final JMenuItem jarCloseItem = new JMenuItem();
private final JMenu openMenu = new JMenu();
private final JMenu openMappingsMenu = new JMenu();
private final JMenuItem saveMappingsItem = new JMenuItem();
private final JMenu saveMappingsAsMenu = new JMenu();
private final JMenuItem closeMappingsItem = new JMenuItem();
Expand Down Expand Up @@ -88,7 +88,7 @@ public MenuBar(Gui gui) {

this.retranslateUi();

prepareOpenMenu(this.openMenu, gui);
prepareOpenMappingsMenu(this.openMappingsMenu, gui);
prepareSaveMappingsAsMenu(this.saveMappingsAsMenu, this.saveMappingsItem, gui);
prepareDecompilerMenu(this.decompilerMenu, gui);
prepareThemesMenu(this.themesMenu, gui);
Expand All @@ -98,7 +98,7 @@ public MenuBar(Gui gui) {
this.fileMenu.add(this.jarOpenItem);
this.fileMenu.add(this.jarCloseItem);
this.fileMenu.addSeparator();
this.fileMenu.add(this.openMenu);
this.fileMenu.add(this.openMappingsMenu);
this.fileMenu.add(this.saveMappingsItem);
this.fileMenu.add(this.saveMappingsAsMenu);
this.fileMenu.add(this.closeMappingsItem);
Expand Down Expand Up @@ -174,7 +174,7 @@ public void updateUiState() {
this.startServerItem.setText(I18n.translate(connectionState != ConnectionState.HOSTING ? "menu.collab.server.start" : "menu.collab.server.stop"));

this.jarCloseItem.setEnabled(jarOpen);
this.openMenu.setEnabled(jarOpen);
this.openMappingsMenu.setEnabled(jarOpen);
this.saveMappingsItem.setEnabled(jarOpen && this.gui.enigmaMappingsFileChooser.getSelectedFile() != null && connectionState != ConnectionState.CONNECTED);
this.saveMappingsAsMenu.setEnabled(jarOpen);
this.closeMappingsItem.setEnabled(jarOpen);
Expand All @@ -189,7 +189,7 @@ public void retranslateUi() {
this.fileMenu.setText(I18n.translate("menu.file"));
this.jarOpenItem.setText(I18n.translate("menu.file.jar.open"));
this.jarCloseItem.setText(I18n.translate("menu.file.jar.close"));
this.openMenu.setText(I18n.translate("menu.file.mappings.open"));
this.openMappingsMenu.setText(I18n.translate("menu.file.mappings.open"));
this.saveMappingsItem.setText(I18n.translate("menu.file.mappings.save"));
this.saveMappingsAsMenu.setText(I18n.translate("menu.file.mappings.save_as"));
this.closeMappingsItem.setText(I18n.translate("menu.file.mappings.close"));
Expand Down Expand Up @@ -402,45 +402,71 @@ private void onGithubClicked() {
GuiUtil.openUrl("https://github.com/FabricMC/Enigma");
}

private static void prepareOpenMenu(JMenu openMenu, Gui gui) {
private static void prepareOpenMappingsMenu(JMenu openMappingsMenu, Gui gui) {
// Mapping-IO readers
MappingFormat.getReadableFormats().stream()
.filter(format -> format.getMappingIoCounterpart() != null)
.forEach(format -> addOpenMappingsMenuEntry(I18n.translate(format.getMappingIoCounterpart().name),
format, true, openMappingsMenu, gui));
openMappingsMenu.addSeparator();

// Enigma's own readers
for (MappingFormat format : MappingFormat.values()) {
if (format.getReader() != null) {
JMenuItem item = new JMenuItem(I18n.translate("mapping_format." + format.name().toLowerCase(Locale.ROOT)));
item.addActionListener(event -> {
gui.enigmaMappingsFileChooser.setCurrentDirectory(new File(UiConfig.getLastSelectedDir()));

if (gui.enigmaMappingsFileChooser.showOpenDialog(gui.getFrame()) == JFileChooser.APPROVE_OPTION) {
File selectedFile = gui.enigmaMappingsFileChooser.getSelectedFile();
gui.getController().openMappings(format, selectedFile.toPath());
UiConfig.setLastSelectedDir(gui.enigmaMappingsFileChooser.getCurrentDirectory().toString());
}
});
openMenu.add(item);
addOpenMappingsMenuEntry(I18n.translate("mapping_format." + format.name().toLowerCase(Locale.ROOT)) + " (legacy)",
format, false, openMappingsMenu, gui);
}
}
}

private static void addOpenMappingsMenuEntry(String text, MappingFormat format, boolean mappingIo, JMenu openMappingsMenu, Gui gui) {
JMenuItem item = new JMenuItem(text);
item.addActionListener(event -> {
gui.enigmaMappingsFileChooser.setCurrentDirectory(new File(UiConfig.getLastSelectedDir()));

if (gui.enigmaMappingsFileChooser.showOpenDialog(gui.getFrame()) == JFileChooser.APPROVE_OPTION) {
File selectedFile = gui.enigmaMappingsFileChooser.getSelectedFile();
gui.getController().openMappings(format, selectedFile.toPath(), mappingIo);
UiConfig.setLastSelectedDir(gui.enigmaMappingsFileChooser.getCurrentDirectory().toString());
}
});
openMappingsMenu.add(item);
}

private static void prepareSaveMappingsAsMenu(JMenu saveMappingsAsMenu, JMenuItem saveMappingsItem, Gui gui) {
// Mapping-IO writers
MappingFormat.getWritableFormats().stream()
.filter(format -> format.hasMappingIoWriter())
.forEach(format -> addSaveMappingsAsMenuEntry(format.getMappingIoCounterpart().name,
format, true, saveMappingsAsMenu, saveMappingsItem, gui));
saveMappingsAsMenu.addSeparator();

// Enigma's own writers
for (MappingFormat format : MappingFormat.values()) {
if (format.getWriter() != null) {
JMenuItem item = new JMenuItem(I18n.translate("mapping_format." + format.name().toLowerCase(Locale.ROOT)));
item.addActionListener(event -> {
// TODO: Use a specific file chooser for it
if (gui.enigmaMappingsFileChooser.getCurrentDirectory() == null) {
gui.enigmaMappingsFileChooser.setCurrentDirectory(new File(UiConfig.getLastSelectedDir()));
}

if (gui.enigmaMappingsFileChooser.showSaveDialog(gui.getFrame()) == JFileChooser.APPROVE_OPTION) {
gui.getController().saveMappings(gui.enigmaMappingsFileChooser.getSelectedFile().toPath(), format);
saveMappingsItem.setEnabled(true);
UiConfig.setLastSelectedDir(gui.enigmaMappingsFileChooser.getCurrentDirectory().toString());
}
});
saveMappingsAsMenu.add(item);
addSaveMappingsAsMenuEntry(I18n.translate("mapping_format." + format.name().toLowerCase(Locale.ROOT)) + " (legacy)",
format, false, saveMappingsAsMenu, saveMappingsItem, gui);
}
}
}

private static void addSaveMappingsAsMenuEntry(String text, MappingFormat format, boolean mappingIo, JMenu saveMappingsAsMenu, JMenuItem saveMappingsItem, Gui gui) {
JMenuItem item = new JMenuItem(text);
item.addActionListener(event -> {
// TODO: Use a specific file chooser for it
if (gui.enigmaMappingsFileChooser.getCurrentDirectory() == null) {
gui.enigmaMappingsFileChooser.setCurrentDirectory(new File(UiConfig.getLastSelectedDir()));
}

if (gui.enigmaMappingsFileChooser.showSaveDialog(gui.getFrame()) == JFileChooser.APPROVE_OPTION) {
gui.getController().saveMappings(gui.enigmaMappingsFileChooser.getSelectedFile().toPath(), format, mappingIo);
saveMappingsItem.setEnabled(true);
UiConfig.setLastSelectedDir(gui.enigmaMappingsFileChooser.getCurrentDirectory().toString());
}
});
saveMappingsAsMenu.add(item);
}

private static void prepareDecompilerMenu(JMenu decompilerMenu, Gui gui) {
ButtonGroup decompilerGroup = new ButtonGroup();

Expand Down
Loading