From 47de69a821c6e089b01187e93f4f916aceeeea85 Mon Sep 17 00:00:00 2001 From: NebelNidas Date: Thu, 22 Sep 2022 11:59:53 +0200 Subject: [PATCH 01/16] Add initial Mapping-IO export support --- build.gradle | 2 + .../java/cuchaz/enigma/gui/GuiController.java | 45 +++++ .../cuchaz/enigma/gui/elements/MenuBar.java | 23 +++ .../mapping/serde/MappingFormat.java | 25 ++- .../mapping/serde/MappingIoConverter.java | 126 ++++++++++++ gradlew.bat | 184 +++++++++--------- 6 files changed, 304 insertions(+), 101 deletions(-) create mode 100644 enigma/src/main/java/cuchaz/enigma/translation/mapping/serde/MappingIoConverter.java diff --git a/build.gradle b/build.gradle index 08ccffe8d..e2d5edd7e 100644 --- a/build.gradle +++ b/build.gradle @@ -20,6 +20,8 @@ subprojects { implementation 'com.google.guava:guava:30.1.1-jre' implementation 'com.google.code.gson:gson:2.8.7' + implementation 'net.fabricmc:mapping-io:0.3.0' + testImplementation 'junit:junit:4.13.2' testImplementation 'org.hamcrest:hamcrest:2.2' } 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 91037b00e..e7e756699 100644 --- a/enigma-swing/src/main/java/cuchaz/enigma/gui/GuiController.java +++ b/enigma-swing/src/main/java/cuchaz/enigma/gui/GuiController.java @@ -29,6 +29,8 @@ import javax.swing.SwingUtilities; import com.google.common.collect.Lists; +import net.fabricmc.mappingio.MappingWriter; +import net.fabricmc.mappingio.tree.MemoryMappingTree; import cuchaz.enigma.Enigma; import cuchaz.enigma.EnigmaProfile; @@ -77,6 +79,7 @@ import cuchaz.enigma.translation.mapping.MappingDelta; import cuchaz.enigma.translation.mapping.ResolutionStrategy; 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; @@ -213,6 +216,48 @@ public CompletableFuture saveMappings(Path path, MappingFormat format) { }); } + public CompletableFuture saveMappings(Path path, net.fabricmc.mappingio.format.MappingFormat format) { + if (project == null) { + return CompletableFuture.completedFuture(null); + } + + return ProgressDialog.runOffThread(this.gui.getFrame(), progress -> { + EntryRemapper mapper = project.getMapper(); + MappingSaveParameters saveParameters = enigma.getProfile().getMappingSaveParameters(); + + MappingDelta delta = mapper.takeMappingDelta(); + boolean saveAll = !path.equals(loadedMappingPath); + + switch (format) { + case ENIGMA: + loadedMappingFormat = MappingFormat.ENIGMA_DIRECTORY; + loadedMappingPath = path; + break; + case PROGUARD: + loadedMappingFormat = MappingFormat.PROGUARD; + loadedMappingPath = path; + break; + case SRG: + loadedMappingFormat = MappingFormat.SRG_FILE; + loadedMappingPath = path; + break; + case TINY: + loadedMappingFormat = MappingFormat.TINY_FILE; + loadedMappingPath = path; + break; + case TINY_2: + loadedMappingFormat = MappingFormat.TINY_V2; + loadedMappingPath = path; + break; + } + + MemoryMappingTree mappingTree = MappingIoConverter.toMappingIo(mapper.getObfToDeobf()); + MappingWriter writer = MappingWriter.create(path, format); + mappingTree.accept(writer); + writer.close(); + }); + } + public void closeMappings() { if (project == null) { return; 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 1cfad5045..1d4c1ca1a 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 @@ -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; @@ -439,6 +440,28 @@ private static void prepareSaveMappingsAsMenu(JMenu saveMappingsAsMenu, JMenuIte saveMappingsAsMenu.add(item); } } + + saveMappingsAsMenu.addSeparator(); + + List writableMappingIoFormats = Arrays.asList( + net.fabricmc.mappingio.format.MappingFormat.ENIGMA, + net.fabricmc.mappingio.format.MappingFormat.TINY_2); + for (net.fabricmc.mappingio.format.MappingFormat format : writableMappingIoFormats) { + JMenuItem item = new JMenuItem(format.name + " (via mapping-io, experimental)"); + 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); + } } private static void prepareDecompilerMenu(JMenu decompilerMenu, Gui gui) { diff --git a/enigma/src/main/java/cuchaz/enigma/translation/mapping/serde/MappingFormat.java b/enigma/src/main/java/cuchaz/enigma/translation/mapping/serde/MappingFormat.java index 367af3b36..4790fee47 100644 --- a/enigma/src/main/java/cuchaz/enigma/translation/mapping/serde/MappingFormat.java +++ b/enigma/src/main/java/cuchaz/enigma/translation/mapping/serde/MappingFormat.java @@ -21,21 +21,23 @@ import cuchaz.enigma.translation.mapping.tree.EntryTree; public enum MappingFormat { - ENIGMA_FILE(EnigmaMappingsWriter.FILE, EnigmaMappingsReader.FILE), - ENIGMA_DIRECTORY(EnigmaMappingsWriter.DIRECTORY, EnigmaMappingsReader.DIRECTORY), - ENIGMA_ZIP(EnigmaMappingsWriter.ZIP, EnigmaMappingsReader.ZIP), - TINY_V2(new TinyV2Writer("intermediary", "named"), new TinyV2Reader()), - TINY_FILE(TinyMappingsWriter.INSTANCE, TinyMappingsReader.INSTANCE), - SRG_FILE(SrgMappingsWriter.INSTANCE, null), - PROGUARD(null, ProguardMappingsReader.INSTANCE), - RECAF(RecafMappingsWriter.INSTANCE, RecafMappingsReader.INSTANCE); + ENIGMA_FILE(EnigmaMappingsWriter.FILE, EnigmaMappingsReader.FILE, null), + ENIGMA_DIRECTORY(EnigmaMappingsWriter.DIRECTORY, EnigmaMappingsReader.DIRECTORY, net.fabricmc.mappingio.format.MappingFormat.ENIGMA), + ENIGMA_ZIP(EnigmaMappingsWriter.ZIP, EnigmaMappingsReader.ZIP, null), + TINY_V2(new TinyV2Writer("intermediary", "named"), new TinyV2Reader(), net.fabricmc.mappingio.format.MappingFormat.TINY_2), + TINY_FILE(TinyMappingsWriter.INSTANCE, TinyMappingsReader.INSTANCE, net.fabricmc.mappingio.format.MappingFormat.TINY), + SRG_FILE(SrgMappingsWriter.INSTANCE, null, net.fabricmc.mappingio.format.MappingFormat.SRG), + PROGUARD(null, ProguardMappingsReader.INSTANCE, net.fabricmc.mappingio.format.MappingFormat.PROGUARD), + RECAF(RecafMappingsWriter.INSTANCE, RecafMappingsReader.INSTANCE, null); private final MappingsWriter writer; private final MappingsReader reader; + private final net.fabricmc.mappingio.format.MappingFormat mappingIoCounterpart; - MappingFormat(MappingsWriter writer, MappingsReader reader) { + MappingFormat(MappingsWriter writer, MappingsReader reader, net.fabricmc.mappingio.format.MappingFormat mappingIoCounterpart) { this.writer = writer; this.reader = reader; + this.mappingIoCounterpart = mappingIoCounterpart; } public void write(EntryTree mappings, Path path, ProgressListener progressListener, MappingSaveParameters saveParameters) { @@ -67,4 +69,9 @@ public MappingsWriter getWriter() { public MappingsReader getReader() { return reader; } + + @Nullable + public net.fabricmc.mappingio.format.MappingFormat getMappingIoCounterpart() { + return mappingIoCounterpart; + } } diff --git a/enigma/src/main/java/cuchaz/enigma/translation/mapping/serde/MappingIoConverter.java b/enigma/src/main/java/cuchaz/enigma/translation/mapping/serde/MappingIoConverter.java new file mode 100644 index 000000000..3a8647669 --- /dev/null +++ b/enigma/src/main/java/cuchaz/enigma/translation/mapping/serde/MappingIoConverter.java @@ -0,0 +1,126 @@ +package cuchaz.enigma.translation.mapping.serde; + +import java.util.Deque; +import java.util.LinkedList; +import java.util.List; + +import net.fabricmc.mappingio.MappedElementKind; +import net.fabricmc.mappingio.tree.MemoryMappingTree; + +import cuchaz.enigma.translation.mapping.EntryMap; +import cuchaz.enigma.translation.mapping.EntryMapping; +import cuchaz.enigma.translation.mapping.tree.EntryTree; +import cuchaz.enigma.translation.mapping.tree.EntryTreeNode; +import cuchaz.enigma.translation.representation.entry.ClassEntry; +import cuchaz.enigma.translation.representation.entry.Entry; +import cuchaz.enigma.translation.representation.entry.FieldEntry; +import cuchaz.enigma.translation.representation.entry.LocalVariableEntry; +import cuchaz.enigma.translation.representation.entry.MethodEntry; + +public class MappingIoConverter { + public static MemoryMappingTree toMappingIo(EntryTree mappings) { + MemoryMappingTree mappingTree = new MemoryMappingTree(); + mappingTree.visitNamespaces("intermediary", List.of("named")); + + for (EntryTreeNode node : mappings) { + if (node.getEntry() instanceof ClassEntry) { + writeClass(node, mappings, mappingTree); + } + } + + mappingTree.visitEnd(); + return mappingTree; + } + + private static void writeClass(EntryTreeNode classNode, EntryMap oldMappingTree, MemoryMappingTree newMappingTree) { + ClassEntry classEntry = (ClassEntry) classNode.getEntry(); + EntryMapping mapping = oldMappingTree.get(classEntry); + Deque parts = new LinkedList<>(); + + newMappingTree.visitClass(classEntry.getFullName()); + newMappingTree.visitComment(MappedElementKind.CLASS, mapping.javadoc()); + + do { + mapping = oldMappingTree.get(classEntry); + + if (mapping != null && mapping.targetName() != null) { + parts.addFirst(mapping.targetName()); + } else { + parts.addFirst(classEntry.getName()); + } + + classEntry = classEntry.getOuterClass(); + } while (classEntry != null); + + String mappedName = String.join("$", parts); + newMappingTree.visitDstName(MappedElementKind.CLASS, 0, mappedName); + + for (EntryTreeNode child : classNode.getChildNodes()) { + Entry entry = child.getEntry(); + + if (entry instanceof FieldEntry) { + writeField(child, newMappingTree); + } else if (entry instanceof MethodEntry) { + writeMethod(child, newMappingTree); + } + } + } + + private static void writeField(EntryTreeNode fieldNode, MemoryMappingTree mappingTree) { + if (fieldNode.getValue() == null || fieldNode.getValue().equals(EntryMapping.DEFAULT)) { + return; // Shortcut + } + + FieldEntry fieldEntry = ((FieldEntry) fieldNode.getEntry()); + mappingTree.visitField(fieldEntry.getName(), fieldEntry.getDesc().toString()); + + EntryMapping fieldMapping = fieldNode.getValue(); + + if (fieldMapping == null) { + fieldMapping = EntryMapping.DEFAULT; + } + + mappingTree.visitDstName(MappedElementKind.FIELD, 0, fieldMapping.targetName()); + mappingTree.visitComment(MappedElementKind.FIELD, fieldMapping.javadoc()); + } + + private static void writeMethod(EntryTreeNode methodNode, MemoryMappingTree mappingTree) { + MethodEntry methodEntry = ((MethodEntry) methodNode.getEntry()); + mappingTree.visitMethod(methodEntry.getName(), methodEntry.getDesc().toString()); + + EntryMapping methodMapping = methodNode.getValue(); + + if (methodMapping == null) { + methodMapping = EntryMapping.DEFAULT; + } + + mappingTree.visitDstName(MappedElementKind.METHOD, 0, methodMapping.targetName()); + mappingTree.visitComment(MappedElementKind.METHOD, methodMapping.javadoc()); + + for (EntryTreeNode child : methodNode.getChildNodes()) { + Entry entry = child.getEntry(); + + if (entry instanceof LocalVariableEntry) { + writeMethodArg(child, mappingTree); + } + } + } + + private static void writeMethodArg(EntryTreeNode methodArgNode, MemoryMappingTree mappingTree) { + if (methodArgNode.getValue() == null || methodArgNode.getValue().equals(EntryMapping.DEFAULT)) { + return; // Shortcut + } + + LocalVariableEntry methodArgEntry = ((LocalVariableEntry) methodArgNode.getEntry()); + mappingTree.visitMethodArg(-1, methodArgEntry.getIndex(), methodArgEntry.getName()); + + EntryMapping methodArgMapping = methodArgNode.getValue(); + + if (methodArgMapping == null) { + methodArgMapping = EntryMapping.DEFAULT; + } + + mappingTree.visitDstName(MappedElementKind.METHOD_ARG, 0, methodArgMapping.targetName()); + mappingTree.visitComment(MappedElementKind.METHOD_ARG, methodArgMapping.javadoc()); + } +} diff --git a/gradlew.bat b/gradlew.bat index 6689b85be..93e3f59f1 100644 --- a/gradlew.bat +++ b/gradlew.bat @@ -1,92 +1,92 @@ -@rem -@rem Copyright 2015 the original author or authors. -@rem -@rem Licensed under the Apache License, Version 2.0 (the "License"); -@rem you may not use this file except in compliance with the License. -@rem You may obtain a copy of the License at -@rem -@rem https://www.apache.org/licenses/LICENSE-2.0 -@rem -@rem Unless required by applicable law or agreed to in writing, software -@rem distributed under the License is distributed on an "AS IS" BASIS, -@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -@rem See the License for the specific language governing permissions and -@rem limitations under the License. -@rem - -@if "%DEBUG%"=="" @echo off -@rem ########################################################################## -@rem -@rem Gradle startup script for Windows -@rem -@rem ########################################################################## - -@rem Set local scope for the variables with windows NT shell -if "%OS%"=="Windows_NT" setlocal - -set DIRNAME=%~dp0 -if "%DIRNAME%"=="" set DIRNAME=. -@rem This is normally unused -set APP_BASE_NAME=%~n0 -set APP_HOME=%DIRNAME% - -@rem Resolve any "." and ".." in APP_HOME to make it shorter. -for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi - -@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" - -@rem Find java.exe -if defined JAVA_HOME goto findJavaFromJavaHome - -set JAVA_EXE=java.exe -%JAVA_EXE% -version >NUL 2>&1 -if %ERRORLEVEL% equ 0 goto execute - -echo. -echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. - -goto fail - -:findJavaFromJavaHome -set JAVA_HOME=%JAVA_HOME:"=% -set JAVA_EXE=%JAVA_HOME%/bin/java.exe - -if exist "%JAVA_EXE%" goto execute - -echo. -echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. - -goto fail - -:execute -@rem Setup the command line - -set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar - - -@rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* - -:end -@rem End local scope for the variables with windows NT shell -if %ERRORLEVEL% equ 0 goto mainEnd - -:fail -rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of -rem the _cmd.exe /c_ return code! -set EXIT_CODE=%ERRORLEVEL% -if %EXIT_CODE% equ 0 set EXIT_CODE=1 -if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE% -exit /b %EXIT_CODE% - -:mainEnd -if "%OS%"=="Windows_NT" endlocal - -:omega +@rem +@rem Copyright 2015 the original author or authors. +@rem +@rem Licensed under the Apache License, Version 2.0 (the "License"); +@rem you may not use this file except in compliance with the License. +@rem You may obtain a copy of the License at +@rem +@rem https://www.apache.org/licenses/LICENSE-2.0 +@rem +@rem Unless required by applicable law or agreed to in writing, software +@rem distributed under the License is distributed on an "AS IS" BASIS, +@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +@rem See the License for the specific language governing permissions and +@rem limitations under the License. +@rem + +@if "%DEBUG%"=="" @echo off +@rem ########################################################################## +@rem +@rem Gradle startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +set DIRNAME=%~dp0 +if "%DIRNAME%"=="" set DIRNAME=. +@rem This is normally unused +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Resolve any "." and ".." in APP_HOME to make it shorter. +for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi + +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if %ERRORLEVEL% equ 0 goto execute + +echo. +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto execute + +echo. +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:execute +@rem Setup the command line + +set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar + + +@rem Execute Gradle +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* + +:end +@rem End local scope for the variables with windows NT shell +if %ERRORLEVEL% equ 0 goto mainEnd + +:fail +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of +rem the _cmd.exe /c_ return code! +set EXIT_CODE=%ERRORLEVEL% +if %EXIT_CODE% equ 0 set EXIT_CODE=1 +if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE% +exit /b %EXIT_CODE% + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega From 6c7738ca744e55e8e2ea03518a5b93000fe9a864 Mon Sep 17 00:00:00 2001 From: NebelNidas Date: Thu, 6 Oct 2022 20:03:14 +0200 Subject: [PATCH 02/16] Add Mapping-IO import support; small cleanup --- .../java/cuchaz/enigma/gui/GuiController.java | 61 +++------ .../cuchaz/enigma/gui/elements/MenuBar.java | 119 ++++++++++-------- .../mapping/serde/MappingFormat.java | 2 + .../mapping/serde/MappingIoConverter.java | 58 +++++++++ 4 files changed, 147 insertions(+), 93 deletions(-) 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 e7e756699..73472ca94 100644 --- a/enigma-swing/src/main/java/cuchaz/enigma/gui/GuiController.java +++ b/enigma-swing/src/main/java/cuchaz/enigma/gui/GuiController.java @@ -29,6 +29,7 @@ import javax.swing.SwingUtilities; import com.google.common.collect.Lists; +import net.fabricmc.mappingio.MappingReader; import net.fabricmc.mappingio.MappingWriter; import net.fabricmc.mappingio.tree.MemoryMappingTree; @@ -102,6 +103,7 @@ public class GuiController implements ClientPacketHandler { private Path loadedMappingPath; private MappingFormat loadedMappingFormat; + public boolean useMappingIo; private ClassHandleProvider chp; @@ -152,8 +154,16 @@ public CompletableFuture openMappings(MappingFormat format, Path path) { return ProgressDialog.runOffThread(gui.getFrame(), progress -> { try { MappingSaveParameters saveParameters = enigma.getProfile().getMappingSaveParameters(); + EntryTree mappings; + + if (useMappingIo) { + MemoryMappingTree mappingTree = new MemoryMappingTree(); + MappingReader.read(path, format.getMappingIoCounterpart(), mappingTree); + mappings = MappingIoConverter.fromMappingIo(mappingTree); + } else { + mappings = format.read(path, progress, saveParameters); + } - EntryTree mappings = format.read(path, progress, saveParameters); project.setMappings(mappings); loadedMappingFormat = format; @@ -208,7 +218,12 @@ public CompletableFuture saveMappings(Path path, MappingFormat format) { loadedMappingFormat = format; loadedMappingPath = path; - if (saveAll) { + if (useMappingIo) { + MemoryMappingTree mappingTree = MappingIoConverter.toMappingIo(mapper.getObfToDeobf()); + MappingWriter writer = MappingWriter.create(path, format.getMappingIoCounterpart()); + mappingTree.accept(writer); + writer.close(); + } else if (saveAll) { format.write(mapper.getObfToDeobf(), path, progress, saveParameters); } else { format.write(mapper.getObfToDeobf(), delta, path, progress, saveParameters); @@ -216,48 +231,6 @@ public CompletableFuture saveMappings(Path path, MappingFormat format) { }); } - public CompletableFuture saveMappings(Path path, net.fabricmc.mappingio.format.MappingFormat format) { - if (project == null) { - return CompletableFuture.completedFuture(null); - } - - return ProgressDialog.runOffThread(this.gui.getFrame(), progress -> { - EntryRemapper mapper = project.getMapper(); - MappingSaveParameters saveParameters = enigma.getProfile().getMappingSaveParameters(); - - MappingDelta delta = mapper.takeMappingDelta(); - boolean saveAll = !path.equals(loadedMappingPath); - - switch (format) { - case ENIGMA: - loadedMappingFormat = MappingFormat.ENIGMA_DIRECTORY; - loadedMappingPath = path; - break; - case PROGUARD: - loadedMappingFormat = MappingFormat.PROGUARD; - loadedMappingPath = path; - break; - case SRG: - loadedMappingFormat = MappingFormat.SRG_FILE; - loadedMappingPath = path; - break; - case TINY: - loadedMappingFormat = MappingFormat.TINY_FILE; - loadedMappingPath = path; - break; - case TINY_2: - loadedMappingFormat = MappingFormat.TINY_V2; - loadedMappingPath = path; - break; - } - - MemoryMappingTree mappingTree = MappingIoConverter.toMappingIo(mapper.getObfToDeobf()); - MappingWriter writer = MappingWriter.create(path, format); - mappingTree.accept(writer); - writer.close(); - }); - } - public void closeMappings() { if (project == null) { return; 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 1d4c1ca1a..3692eb3b0 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 @@ -46,7 +46,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(); @@ -89,7 +89,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); @@ -99,7 +99,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); @@ -175,7 +175,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); @@ -190,7 +190,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")); @@ -403,67 +403,88 @@ 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) { + List readableMappingIoFormats = Arrays.asList( + MappingFormat.ENIGMA_DIRECTORY, + MappingFormat.TINY_FILE, + MappingFormat.TINY_V2, + MappingFormat.SRG_FILE, + MappingFormat.TSRG_FILE, + MappingFormat.TSRG_2_FILE, + MappingFormat.PROGUARD); + + // 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)), + format, false, openMappingsMenu, gui); } } + + openMappingsMenu.addSeparator(); + + // Mapping-IO readers + for (MappingFormat format : readableMappingIoFormats) { + addOpenMappingsMenuEntry(I18n.translate(format.getMappingIoCounterpart().name + " (via Mapping-IO, experimental)"), + format, true, 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().useMappingIo = mappingIo; + gui.getController().openMappings(format, selectedFile.toPath()); + UiConfig.setLastSelectedDir(gui.enigmaMappingsFileChooser.getCurrentDirectory().toString()); + } + }); + openMappingsMenu.add(item); } private static void prepareSaveMappingsAsMenu(JMenu saveMappingsAsMenu, JMenuItem saveMappingsItem, Gui gui) { + List writableMappingIoFormats = Arrays.asList( + MappingFormat.ENIGMA_DIRECTORY, + MappingFormat.TINY_V2); + + // 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)), + format, false, saveMappingsAsMenu, saveMappingsItem, gui); } } saveMappingsAsMenu.addSeparator(); - List writableMappingIoFormats = Arrays.asList( - net.fabricmc.mappingio.format.MappingFormat.ENIGMA, - net.fabricmc.mappingio.format.MappingFormat.TINY_2); - for (net.fabricmc.mappingio.format.MappingFormat format : writableMappingIoFormats) { - JMenuItem item = new JMenuItem(format.name + " (via mapping-io, experimental)"); - 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); + // Mapping-IO writers + for (MappingFormat format : writableMappingIoFormats) { + addSaveMappingsAsMenuEntry(format.getMappingIoCounterpart().name + " (via Mapping-IO, experimental)", + format, true, 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().useMappingIo = mappingIo; + gui.getController().saveMappings(gui.enigmaMappingsFileChooser.getSelectedFile().toPath(), format); + saveMappingsItem.setEnabled(true); + UiConfig.setLastSelectedDir(gui.enigmaMappingsFileChooser.getCurrentDirectory().toString()); + } + }); + saveMappingsAsMenu.add(item); + } + private static void prepareDecompilerMenu(JMenu decompilerMenu, Gui gui) { ButtonGroup decompilerGroup = new ButtonGroup(); diff --git a/enigma/src/main/java/cuchaz/enigma/translation/mapping/serde/MappingFormat.java b/enigma/src/main/java/cuchaz/enigma/translation/mapping/serde/MappingFormat.java index 4790fee47..5bad92985 100644 --- a/enigma/src/main/java/cuchaz/enigma/translation/mapping/serde/MappingFormat.java +++ b/enigma/src/main/java/cuchaz/enigma/translation/mapping/serde/MappingFormat.java @@ -27,6 +27,8 @@ public enum MappingFormat { TINY_V2(new TinyV2Writer("intermediary", "named"), new TinyV2Reader(), net.fabricmc.mappingio.format.MappingFormat.TINY_2), TINY_FILE(TinyMappingsWriter.INSTANCE, TinyMappingsReader.INSTANCE, net.fabricmc.mappingio.format.MappingFormat.TINY), SRG_FILE(SrgMappingsWriter.INSTANCE, null, net.fabricmc.mappingio.format.MappingFormat.SRG), + TSRG_FILE(null, null, net.fabricmc.mappingio.format.MappingFormat.TSRG), + TSRG_2_FILE(null, null, net.fabricmc.mappingio.format.MappingFormat.TSRG2), PROGUARD(null, ProguardMappingsReader.INSTANCE, net.fabricmc.mappingio.format.MappingFormat.PROGUARD), RECAF(RecafMappingsWriter.INSTANCE, RecafMappingsReader.INSTANCE, null); diff --git a/enigma/src/main/java/cuchaz/enigma/translation/mapping/serde/MappingIoConverter.java b/enigma/src/main/java/cuchaz/enigma/translation/mapping/serde/MappingIoConverter.java index 3a8647669..d3fd341f1 100644 --- a/enigma/src/main/java/cuchaz/enigma/translation/mapping/serde/MappingIoConverter.java +++ b/enigma/src/main/java/cuchaz/enigma/translation/mapping/serde/MappingIoConverter.java @@ -6,11 +6,18 @@ import net.fabricmc.mappingio.MappedElementKind; import net.fabricmc.mappingio.tree.MemoryMappingTree; +import net.fabricmc.mappingio.tree.MappingTree.ClassMapping; +import net.fabricmc.mappingio.tree.MappingTree.FieldMapping; +import net.fabricmc.mappingio.tree.MappingTree.MethodArgMapping; +import net.fabricmc.mappingio.tree.MappingTree.MethodMapping; import cuchaz.enigma.translation.mapping.EntryMap; import cuchaz.enigma.translation.mapping.EntryMapping; import cuchaz.enigma.translation.mapping.tree.EntryTree; import cuchaz.enigma.translation.mapping.tree.EntryTreeNode; +import cuchaz.enigma.translation.mapping.tree.HashEntryTree; +import cuchaz.enigma.translation.representation.MethodDescriptor; +import cuchaz.enigma.translation.representation.TypeDescriptor; import cuchaz.enigma.translation.representation.entry.ClassEntry; import cuchaz.enigma.translation.representation.entry.Entry; import cuchaz.enigma.translation.representation.entry.FieldEntry; @@ -123,4 +130,55 @@ private static void writeMethodArg(EntryTreeNode methodArgNode, Me mappingTree.visitDstName(MappedElementKind.METHOD_ARG, 0, methodArgMapping.targetName()); mappingTree.visitComment(MappedElementKind.METHOD_ARG, methodArgMapping.javadoc()); } + + public static EntryTree fromMappingIo(MemoryMappingTree mappingTree) { + EntryTree dstMappingTree = new HashEntryTree<>(); + + for (ClassMapping classMapping : mappingTree.getClasses()) { + readClass(classMapping, dstMappingTree); + } + + return dstMappingTree; + } + + private static void readClass(ClassMapping classMapping, EntryTree mappingTree) { + ClassEntry currentClass = new ClassEntry(classMapping.getSrcName()); + String dstName = classMapping.getDstName(0); + + if (dstName != null) { + dstName = dstName.substring(dstName.lastIndexOf('$') + 1); + } + + mappingTree.insert(currentClass, new EntryMapping(dstName)); + + for (FieldMapping fieldMapping : classMapping.getFields()) { + readField(fieldMapping, currentClass, mappingTree); + } + + for (MethodMapping methodMapping : classMapping.getMethods()) { + readMethod(methodMapping, currentClass, mappingTree); + } + } + + private static void readField(FieldMapping fieldMapping, ClassEntry parent, EntryTree mappingTree) { + mappingTree.insert(new FieldEntry(parent, fieldMapping.getSrcName(), new TypeDescriptor(fieldMapping.getSrcDesc())), + new EntryMapping(fieldMapping.getDstName(0))); + } + + private static void readMethod(MethodMapping methodMapping, ClassEntry parent, EntryTree mappingTree) { + MethodEntry currentMethod; + mappingTree.insert(currentMethod = new MethodEntry(parent, methodMapping.getSrcName(), new MethodDescriptor(methodMapping.getSrcDesc())), + new EntryMapping(methodMapping.getDstName(0))); + + for (MethodArgMapping methodArgMapping : methodMapping.getArgs()) { + readMethodArg(methodArgMapping, currentMethod, mappingTree); + } + } + + private static void readMethodArg(MethodArgMapping methodArgMapping, MethodEntry parent, EntryTree mappingTree) { + String methodArgSrcName = methodArgMapping.getSrcName() != null ? methodArgMapping.getSrcName() : ""; + + mappingTree.insert(new LocalVariableEntry(parent, methodArgMapping.getLvIndex(), methodArgSrcName, true, null), + new EntryMapping(methodArgMapping.getDstName(0))); + } } From cc4154d610adf7aee7816279171a50fe074aa675 Mon Sep 17 00:00:00 2001 From: NebelNidas Date: Mon, 10 Oct 2022 13:25:02 +0200 Subject: [PATCH 03/16] Add progress listener to Mapping-IO conversion; deduplicate lang files --- .../java/cuchaz/enigma/gui/GuiController.java | 16 +++++++++++-- .../mapping/serde/MappingIoConverter.java | 24 ++++++++++++++----- .../serde/enigma/EnigmaMappingsReader.java | 8 +++---- .../serde/enigma/EnigmaMappingsWriter.java | 6 ++--- .../mapping/serde/srg/SrgMappingsWriter.java | 4 ++-- .../serde/tiny/TinyMappingsReader.java | 2 +- .../mapping/serde/tinyv2/TinyV2Reader.java | 2 +- enigma/src/main/resources/lang/en_us.json | 16 ++++++------- enigma/src/main/resources/lang/fr_fr.json | 14 ++++------- enigma/src/main/resources/lang/ja_jp.json | 13 ++++------ enigma/src/main/resources/lang/zh_cn.json | 13 ++++------ 11 files changed, 62 insertions(+), 56 deletions(-) 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 73472ca94..5b04f3cfa 100644 --- a/enigma-swing/src/main/java/cuchaz/enigma/gui/GuiController.java +++ b/enigma-swing/src/main/java/cuchaz/enigma/gui/GuiController.java @@ -157,9 +157,18 @@ public CompletableFuture openMappings(MappingFormat format, Path path) { EntryTree mappings; if (useMappingIo) { + String loadingMessage; + + if (format.getMappingIoCounterpart().hasSingleFile()) { + loadingMessage = I18n.translate("progress.mappings.loading_file"); + } else { + loadingMessage = I18n.translate("progress.mappings.loading_directory"); + } + + progress.init(1, loadingMessage); MemoryMappingTree mappingTree = new MemoryMappingTree(); MappingReader.read(path, format.getMappingIoCounterpart(), mappingTree); - mappings = MappingIoConverter.fromMappingIo(mappingTree); + mappings = MappingIoConverter.fromMappingIo(mappingTree, progress); } else { mappings = format.read(path, progress, saveParameters); } @@ -219,10 +228,13 @@ public CompletableFuture saveMappings(Path path, MappingFormat format) { loadedMappingPath = path; if (useMappingIo) { - MemoryMappingTree mappingTree = MappingIoConverter.toMappingIo(mapper.getObfToDeobf()); + MemoryMappingTree mappingTree = MappingIoConverter.toMappingIo(mapper.getObfToDeobf(), progress); + + progress.init(1, I18n.translate("progress.mappings.writing")); MappingWriter writer = MappingWriter.create(path, format.getMappingIoCounterpart()); mappingTree.accept(writer); writer.close(); + progress.step(1, I18n.translate("progress.done")); } else if (saveAll) { format.write(mapper.getObfToDeobf(), path, progress, saveParameters); } else { diff --git a/enigma/src/main/java/cuchaz/enigma/translation/mapping/serde/MappingIoConverter.java b/enigma/src/main/java/cuchaz/enigma/translation/mapping/serde/MappingIoConverter.java index d3fd341f1..171f25266 100644 --- a/enigma/src/main/java/cuchaz/enigma/translation/mapping/serde/MappingIoConverter.java +++ b/enigma/src/main/java/cuchaz/enigma/translation/mapping/serde/MappingIoConverter.java @@ -3,6 +3,7 @@ import java.util.Deque; import java.util.LinkedList; import java.util.List; +import java.util.stream.StreamSupport; import net.fabricmc.mappingio.MappedElementKind; import net.fabricmc.mappingio.tree.MemoryMappingTree; @@ -11,6 +12,7 @@ import net.fabricmc.mappingio.tree.MappingTree.MethodArgMapping; import net.fabricmc.mappingio.tree.MappingTree.MethodMapping; +import cuchaz.enigma.ProgressListener; import cuchaz.enigma.translation.mapping.EntryMap; import cuchaz.enigma.translation.mapping.EntryMapping; import cuchaz.enigma.translation.mapping.tree.EntryTree; @@ -23,16 +25,23 @@ import cuchaz.enigma.translation.representation.entry.FieldEntry; import cuchaz.enigma.translation.representation.entry.LocalVariableEntry; import cuchaz.enigma.translation.representation.entry.MethodEntry; +import cuchaz.enigma.utils.I18n; public class MappingIoConverter { - public static MemoryMappingTree toMappingIo(EntryTree mappings) { + public static MemoryMappingTree toMappingIo(EntryTree mappings, ProgressListener progress) { + List> classes = StreamSupport.stream(mappings.spliterator(), false) + .filter(node -> node.getEntry() instanceof ClassEntry) + .toList(); + + progress.init(classes.size(), I18n.translate("progress.mappings.converting.to_mappingio")); + int steps = 0; + MemoryMappingTree mappingTree = new MemoryMappingTree(); mappingTree.visitNamespaces("intermediary", List.of("named")); - for (EntryTreeNode node : mappings) { - if (node.getEntry() instanceof ClassEntry) { - writeClass(node, mappings, mappingTree); - } + for (EntryTreeNode classNode : classes) { + progress.step(steps++, classNode.getEntry().getFullName()); + writeClass(classNode, mappings, mappingTree); } mappingTree.visitEnd(); @@ -131,10 +140,13 @@ private static void writeMethodArg(EntryTreeNode methodArgNode, Me mappingTree.visitComment(MappedElementKind.METHOD_ARG, methodArgMapping.javadoc()); } - public static EntryTree fromMappingIo(MemoryMappingTree mappingTree) { + public static EntryTree fromMappingIo(MemoryMappingTree mappingTree, ProgressListener progress) { EntryTree dstMappingTree = new HashEntryTree<>(); + progress.init(mappingTree.getClasses().size(), I18n.translate("progress.mappings.converting.from_mappingio")); + int steps = 0; for (ClassMapping classMapping : mappingTree.getClasses()) { + progress.step(steps++, classMapping.getDstName(0) != null ? classMapping.getDstName(0) : classMapping.getSrcName()); readClass(classMapping, dstMappingTree); } diff --git a/enigma/src/main/java/cuchaz/enigma/translation/mapping/serde/enigma/EnigmaMappingsReader.java b/enigma/src/main/java/cuchaz/enigma/translation/mapping/serde/enigma/EnigmaMappingsReader.java index 546134263..d5570e986 100644 --- a/enigma/src/main/java/cuchaz/enigma/translation/mapping/serde/enigma/EnigmaMappingsReader.java +++ b/enigma/src/main/java/cuchaz/enigma/translation/mapping/serde/enigma/EnigmaMappingsReader.java @@ -40,12 +40,12 @@ public enum EnigmaMappingsReader implements MappingsReader { FILE { @Override public EntryTree read(Path path, ProgressListener progress, MappingSaveParameters saveParameters) throws IOException, MappingParseException { - progress.init(1, I18n.translate("progress.mappings.enigma_file.loading")); + progress.init(1, I18n.translate("progress.mappings.loading_file")); EntryTree mappings = new HashEntryTree<>(); readFile(path, mappings); - progress.step(1, I18n.translate("progress.mappings.enigma_file.done")); + progress.step(1, I18n.translate("progress.done")); return mappings; } @@ -60,7 +60,7 @@ public EntryTree read(Path root, ProgressListener progress, Mappin EntryTree mappings = new HashEntryTree<>(); List files = Files.walk(root).filter(f -> !Files.isDirectory(f)).filter(f -> f.toString().endsWith(".mapping")).toList(); - progress.init(files.size(), I18n.translate("progress.mappings.enigma_directory.loading")); + progress.init(files.size(), I18n.translate("progress.mappings.loading_directory")); int step = 0; for (Path file : files) { @@ -102,7 +102,7 @@ public static EntryTree readFiles(ProgressListener progress, Path. throw new IllegalArgumentException("No paths to read mappings from"); } - progress.init(paths.length, I18n.translate("progress.mappings.enigma_directory.loading")); + progress.init(paths.length, I18n.translate("progress.mappings.loading_directory")); int step = 0; for (Path file : paths) { diff --git a/enigma/src/main/java/cuchaz/enigma/translation/mapping/serde/enigma/EnigmaMappingsWriter.java b/enigma/src/main/java/cuchaz/enigma/translation/mapping/serde/enigma/EnigmaMappingsWriter.java index df1af9120..73f29a169 100644 --- a/enigma/src/main/java/cuchaz/enigma/translation/mapping/serde/enigma/EnigmaMappingsWriter.java +++ b/enigma/src/main/java/cuchaz/enigma/translation/mapping/serde/enigma/EnigmaMappingsWriter.java @@ -58,7 +58,7 @@ public enum EnigmaMappingsWriter implements MappingsWriter { public void write(EntryTree mappings, MappingDelta delta, Path path, ProgressListener progress, MappingSaveParameters saveParameters) { Collection classes = mappings.getRootNodes().filter(entry -> entry.getEntry() instanceof ClassEntry).map(entry -> (ClassEntry) entry.getEntry()).toList(); - progress.init(classes.size(), I18n.translate("progress.mappings.enigma_file.writing")); + progress.init(classes.size(), I18n.translate("progress.mappings.writing")); int steps = 0; @@ -78,11 +78,9 @@ public void write(EntryTree mappings, MappingDelta d Collection changedClasses = delta.getChangedRoots().filter(entry -> entry instanceof ClassEntry).map(entry -> (ClassEntry) entry).toList(); applyDeletions(path, changedClasses, mappings, delta.getBaseMappings(), saveParameters.getFileNameFormat()); - changedClasses = changedClasses.stream().filter(entry -> !isClassEmpty(mappings, entry)).collect(Collectors.toList()); - progress.init(changedClasses.size(), I18n.translate("progress.mappings.enigma_directory.writing")); - + progress.init(changedClasses.size(), I18n.translate("progress.mappings.writing")); AtomicInteger steps = new AtomicInteger(); Translator translator = new MappingTranslator(mappings, VoidEntryResolver.INSTANCE); diff --git a/enigma/src/main/java/cuchaz/enigma/translation/mapping/serde/srg/SrgMappingsWriter.java b/enigma/src/main/java/cuchaz/enigma/translation/mapping/serde/srg/SrgMappingsWriter.java index 4621efef9..5addcade4 100644 --- a/enigma/src/main/java/cuchaz/enigma/translation/mapping/serde/srg/SrgMappingsWriter.java +++ b/enigma/src/main/java/cuchaz/enigma/translation/mapping/serde/srg/SrgMappingsWriter.java @@ -45,7 +45,7 @@ public void write(EntryTree mappings, MappingDelta d List methodLines = new ArrayList<>(); List> rootEntries = Lists.newArrayList(mappings).stream().map(EntryTreeNode::getEntry).toList(); - progress.init(rootEntries.size(), I18n.translate("progress.mappings.srg_file.generating")); + progress.init(rootEntries.size(), I18n.translate("progress.mappings.converting")); int steps = 0; @@ -54,7 +54,7 @@ public void write(EntryTree mappings, MappingDelta d writeEntry(classLines, fieldLines, methodLines, mappings, entry); } - progress.init(3, I18n.translate("progress.mappings.srg_file.writing")); + progress.init(3, I18n.translate("progress.mappings.writing")); try (PrintWriter writer = new LfPrintWriter(Files.newBufferedWriter(path))) { progress.step(0, I18n.translate("type.classes")); diff --git a/enigma/src/main/java/cuchaz/enigma/translation/mapping/serde/tiny/TinyMappingsReader.java b/enigma/src/main/java/cuchaz/enigma/translation/mapping/serde/tiny/TinyMappingsReader.java index 534a567cb..1575f4689 100644 --- a/enigma/src/main/java/cuchaz/enigma/translation/mapping/serde/tiny/TinyMappingsReader.java +++ b/enigma/src/main/java/cuchaz/enigma/translation/mapping/serde/tiny/TinyMappingsReader.java @@ -35,7 +35,7 @@ private EntryTree read(Path path, List lines, ProgressList EntryTree mappings = new HashEntryTree<>(); lines.remove(0); - progress.init(lines.size(), I18n.translate("progress.mappings.tiny_file.loading")); + progress.init(lines.size(), I18n.translate("progress.mappings.loading_file")); for (int lineNumber = 0; lineNumber < lines.size(); lineNumber++) { progress.step(lineNumber, ""); diff --git a/enigma/src/main/java/cuchaz/enigma/translation/mapping/serde/tinyv2/TinyV2Reader.java b/enigma/src/main/java/cuchaz/enigma/translation/mapping/serde/tinyv2/TinyV2Reader.java index eecbc35ba..28185f585 100644 --- a/enigma/src/main/java/cuchaz/enigma/translation/mapping/serde/tinyv2/TinyV2Reader.java +++ b/enigma/src/main/java/cuchaz/enigma/translation/mapping/serde/tinyv2/TinyV2Reader.java @@ -46,7 +46,7 @@ public EntryTree read(Path path, ProgressListener progress, Mappin private EntryTree read(Path path, List lines, ProgressListener progress) throws MappingParseException { EntryTree mappings = new HashEntryTree<>(); - progress.init(lines.size(), "progress.mappings.tiny_v2.loading"); + progress.init(lines.size(), "progress.mappings.loading_file"); BitSet state = new BitSet(STATE_SIZE); @SuppressWarnings({"unchecked", "rawtypes"}) MappingPair, RawEntryMapping>[] holds = new MappingPair[STATE_SIZE]; diff --git a/enigma/src/main/resources/lang/en_us.json b/enigma/src/main/resources/lang/en_us.json index 421620e93..2a3cfb2d3 100644 --- a/enigma/src/main/resources/lang/en_us.json +++ b/enigma/src/main/resources/lang/en_us.json @@ -137,6 +137,7 @@ "log_panel.messages": "Messages", "log_panel.users": "Users", + "progress.done": "Done!", "progress.operation": "%s - Operation in progress", "progress.jar.indexing": "Indexing jar", "progress.jar.indexing.entries": "Entries...", @@ -147,15 +148,12 @@ "progress.sources.writing": "Writing sources...", "progress.classes.deobfuscating": "Deobfuscating classes...", "progress.classes.decompiling": "Decompiling classes...", - "progress.mappings.enigma_file.loading": "Loading mapping file", - "progress.mappings.enigma_file.done": "Done!", - "progress.mappings.enigma_file.writing": "Writing classes", - "progress.mappings.enigma_directory.loading": "Loading mapping files", - "progress.mappings.enigma_directory.writing": "Writing classes", - "progress.mappings.tiny_file.loading": "Loading mapping file", - "progress.mappings.tiny_v2.loading": "Loading mapping file", - "progress.mappings.srg_file.generating": "Generating mappings", - "progress.mappings.srg_file.writing": "Writing mappings", + "progress.mappings.loading_file": "Loading mapping file", + "progress.mappings.loading_directory": "Loading mapping files", + "progress.mappings.writing": "Writing classes", + "progress.mappings.converting": "Converting mappings", + "progress.mappings.converting.to_mappingio": "Converting to Mapping-IO", + "progress.mappings.converting.from_mappingio": "Converting from Mapping-IO", "progress.stats": "Generating stats", "progress.stats.data": "Generating data", diff --git a/enigma/src/main/resources/lang/fr_fr.json b/enigma/src/main/resources/lang/fr_fr.json index d3d0c2976..520dd32e6 100644 --- a/enigma/src/main/resources/lang/fr_fr.json +++ b/enigma/src/main/resources/lang/fr_fr.json @@ -131,6 +131,7 @@ "log_panel.messages": "Messages", "log_panel.users": "Utilisateurs", + "progress.done": "Terminé !", "progress.operation": "%s - Opération en cours", "progress.jar.indexing": "Indexation du jar", "progress.jar.indexing.entries": "Entrées...", @@ -141,15 +142,10 @@ "progress.sources.writing": "Écriture des sources...", "progress.classes.deobfuscating": "Déobfuscation des classes...", "progress.classes.decompiling": "Décompilation des classes...", - "progress.mappings.enigma_file.loading": "Chargement du fichier de mappings", - "progress.mappings.enigma_file.done": "Terminé !", - "progress.mappings.enigma_file.writing": "Écriture des classes", - "progress.mappings.enigma_directory.loading": "Chargement des fichiers de mappings", - "progress.mappings.enigma_directory.writing": "Écriture des classes", - "progress.mappings.tiny_file.loading": "Chargement du fichier de mappings", - "progress.mappings.tiny_v2.loading": "Chargement du fichier de mappings", - "progress.mappings.srg_file.generating": "Génération des mappings", - "progress.mappings.srg_file.writing": "Écriture des mappings", + "progress.mappings.loading_file": "Chargement du fichier de mappings", + "progress.mappings.loading_directory": "Chargement des fichiers de mappings", + "progress.mappings.writing": "Écriture des mappings", + "progress.mappings.converting": "Conversion des mappings", "progress.stats": "Génération des statistiques", "progress.stats.data": "Génération des données", diff --git a/enigma/src/main/resources/lang/ja_jp.json b/enigma/src/main/resources/lang/ja_jp.json index 09e7ee08b..b4d519987 100644 --- a/enigma/src/main/resources/lang/ja_jp.json +++ b/enigma/src/main/resources/lang/ja_jp.json @@ -132,6 +132,7 @@ "log_panel.messages": "メッセージ", "log_panel.users": "ユーザー", + "progress.done": "完了しました!", "progress.operation": "%s - 処理中", "progress.jar.indexing": "jarのインデックス中", "progress.jar.indexing.entries": "エントリー...", @@ -142,15 +143,9 @@ "progress.sources.writing": "ソースコードを書き出し中...", "progress.classes.deobfuscating": "クラスを難読化解除中...", "progress.classes.decompiling": "クラスのデコンパイル中...", - "progress.mappings.enigma_file.loading": "マッピングファイルをロード", - "progress.mappings.enigma_file.done": "完了しました!", - "progress.mappings.enigma_file.writing": "クラスの書き出し中", - "progress.mappings.enigma_directory.loading": "マッピングファイルの読込中", - "progress.mappings.enigma_directory.writing": "クラスの書き出し中", - "progress.mappings.tiny_file.loading": "マッピングファイルの読込中", - "progress.mappings.tiny_v2.loading": "マッピングファイルの読込中", - "progress.mappings.srg_file.generating": "マッピングの作成中", - "progress.mappings.srg_file.writing": "マッピングの書き出し中", + "progress.mappings.loading_file": "マッピングファイルをロード", + "progress.mappings.loading_directory": "マッピングファイルの読込中", + "progress.mappings.writing": "マッピングの書き出し中", "progress.stats": "統計情報を作成中", "progress.stats.data": "データの作成中", diff --git a/enigma/src/main/resources/lang/zh_cn.json b/enigma/src/main/resources/lang/zh_cn.json index fe806fb37..dbc6dd33d 100644 --- a/enigma/src/main/resources/lang/zh_cn.json +++ b/enigma/src/main/resources/lang/zh_cn.json @@ -75,6 +75,7 @@ "info_panel.tree.implementations": "实现", "info_panel.tree.calls": "调用图", + "progress.done": "完成!", "progress.operation": "%s - 进行中", "progress.jar.indexing": "索引 Jar", "progress.jar.indexing.entries": "条目...", @@ -85,15 +86,9 @@ "progress.sources.writing": "写出源码中...", "progress.classes.deobfuscating": "反混淆类中...", "progress.classes.decompiling": "反编译类中...", - "progress.mappings.enigma_file.loading": "加载映射文件", - "progress.mappings.enigma_file.done": "完成!", - "progress.mappings.enigma_file.writing": "写入类", - "progress.mappings.enigma_directory.loading": "加载映射文件", - "progress.mappings.enigma_directory.writing": "写入类", - "progress.mappings.tiny_file.loading": "加载映射文件", - "progress.mappings.tiny_v2.loading": "加载映射文件", - "progress.mappings.srg_file.generating": "生成映射", - "progress.mappings.srg_file.writing": "写出映射", + "progress.mappings.loading_file": "加载映射文件", + "progress.mappings.loading_directory": "加载映射文件", + "progress.mappings.writing": "写出映射", "progress.stats": "生成统计范围", "progress.stats.data": "生成数据", From 59aadb3c543da883acc1d29c7180cf889f03ba24 Mon Sep 17 00:00:00 2001 From: NebelNidas Date: Sat, 17 Jun 2023 11:50:56 +0200 Subject: [PATCH 04/16] Update to latest Mapping IO commit --- build.gradle | 2 +- .../java/cuchaz/enigma/gui/GuiController.java | 3 ++- .../java/cuchaz/enigma/gui/elements/MenuBar.java | 6 +++++- .../translation/mapping/serde/MappingFormat.java | 16 ++++++++-------- 4 files changed, 16 insertions(+), 11 deletions(-) diff --git a/build.gradle b/build.gradle index e2d5edd7e..e9fd4a250 100644 --- a/build.gradle +++ b/build.gradle @@ -20,7 +20,7 @@ subprojects { implementation 'com.google.guava:guava:30.1.1-jre' implementation 'com.google.code.gson:gson:2.8.7' - implementation 'net.fabricmc:mapping-io:0.3.0' + implementation 'net.fabricmc:mapping-io:0.5.0-SNAPSHOT' testImplementation 'junit:junit:4.13.2' testImplementation 'org.hamcrest:hamcrest:2.2' 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 5b04f3cfa..e6d4096ca 100644 --- a/enigma-swing/src/main/java/cuchaz/enigma/gui/GuiController.java +++ b/enigma-swing/src/main/java/cuchaz/enigma/gui/GuiController.java @@ -32,6 +32,7 @@ import net.fabricmc.mappingio.MappingReader; import net.fabricmc.mappingio.MappingWriter; import net.fabricmc.mappingio.tree.MemoryMappingTree; +import net.fabricmc.mappingio.tree.VisitOrder; import cuchaz.enigma.Enigma; import cuchaz.enigma.EnigmaProfile; @@ -232,7 +233,7 @@ public CompletableFuture saveMappings(Path path, MappingFormat format) { progress.init(1, I18n.translate("progress.mappings.writing")); MappingWriter writer = MappingWriter.create(path, format.getMappingIoCounterpart()); - mappingTree.accept(writer); + mappingTree.accept(writer, VisitOrder.createByName()); writer.close(); progress.step(1, I18n.translate("progress.done")); } else if (saveAll) { 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 3692eb3b0..ca3067c8b 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 @@ -406,6 +406,7 @@ private void onGithubClicked() { private static void prepareOpenMappingsMenu(JMenu openMappingsMenu, Gui gui) { List readableMappingIoFormats = Arrays.asList( MappingFormat.ENIGMA_DIRECTORY, + MappingFormat.ENIGMA_FILE, MappingFormat.TINY_FILE, MappingFormat.TINY_V2, MappingFormat.SRG_FILE, @@ -448,7 +449,10 @@ private static void addOpenMappingsMenuEntry(String text, MappingFormat format, private static void prepareSaveMappingsAsMenu(JMenu saveMappingsAsMenu, JMenuItem saveMappingsItem, Gui gui) { List writableMappingIoFormats = Arrays.asList( MappingFormat.ENIGMA_DIRECTORY, - MappingFormat.TINY_V2); + MappingFormat.ENIGMA_FILE, + MappingFormat.TINY_FILE, + MappingFormat.TINY_V2, + MappingFormat.PROGUARD); // Enigma's own writers for (MappingFormat format : MappingFormat.values()) { diff --git a/enigma/src/main/java/cuchaz/enigma/translation/mapping/serde/MappingFormat.java b/enigma/src/main/java/cuchaz/enigma/translation/mapping/serde/MappingFormat.java index 5bad92985..f402c1938 100644 --- a/enigma/src/main/java/cuchaz/enigma/translation/mapping/serde/MappingFormat.java +++ b/enigma/src/main/java/cuchaz/enigma/translation/mapping/serde/MappingFormat.java @@ -21,15 +21,15 @@ import cuchaz.enigma.translation.mapping.tree.EntryTree; public enum MappingFormat { - ENIGMA_FILE(EnigmaMappingsWriter.FILE, EnigmaMappingsReader.FILE, null), - ENIGMA_DIRECTORY(EnigmaMappingsWriter.DIRECTORY, EnigmaMappingsReader.DIRECTORY, net.fabricmc.mappingio.format.MappingFormat.ENIGMA), + ENIGMA_FILE(EnigmaMappingsWriter.FILE, EnigmaMappingsReader.FILE, net.fabricmc.mappingio.format.MappingFormat.ENIGMA_FILE), + ENIGMA_DIRECTORY(EnigmaMappingsWriter.DIRECTORY, EnigmaMappingsReader.DIRECTORY, net.fabricmc.mappingio.format.MappingFormat.ENIGMA_DIR), ENIGMA_ZIP(EnigmaMappingsWriter.ZIP, EnigmaMappingsReader.ZIP, null), - TINY_V2(new TinyV2Writer("intermediary", "named"), new TinyV2Reader(), net.fabricmc.mappingio.format.MappingFormat.TINY_2), - TINY_FILE(TinyMappingsWriter.INSTANCE, TinyMappingsReader.INSTANCE, net.fabricmc.mappingio.format.MappingFormat.TINY), - SRG_FILE(SrgMappingsWriter.INSTANCE, null, net.fabricmc.mappingio.format.MappingFormat.SRG), - TSRG_FILE(null, null, net.fabricmc.mappingio.format.MappingFormat.TSRG), - TSRG_2_FILE(null, null, net.fabricmc.mappingio.format.MappingFormat.TSRG2), - PROGUARD(null, ProguardMappingsReader.INSTANCE, net.fabricmc.mappingio.format.MappingFormat.PROGUARD), + TINY_V2(new TinyV2Writer("intermediary", "named"), new TinyV2Reader(), net.fabricmc.mappingio.format.MappingFormat.TINY_2_FILE), + TINY_FILE(TinyMappingsWriter.INSTANCE, TinyMappingsReader.INSTANCE, net.fabricmc.mappingio.format.MappingFormat.TINY_FILE), + SRG_FILE(SrgMappingsWriter.INSTANCE, null, net.fabricmc.mappingio.format.MappingFormat.SRG_FILE), + TSRG_FILE(null, null, net.fabricmc.mappingio.format.MappingFormat.TSRG_FILE), + TSRG_2_FILE(null, null, net.fabricmc.mappingio.format.MappingFormat.TSRG_2_FILE), + PROGUARD(null, ProguardMappingsReader.INSTANCE, net.fabricmc.mappingio.format.MappingFormat.PROGUARD_FILE), RECAF(RecafMappingsWriter.INSTANCE, RecafMappingsReader.INSTANCE, null); private final MappingsWriter writer; From 58b67c0e8e8fa802b98f9ed43f2f38d9d4a35e2b Mon Sep 17 00:00:00 2001 From: NebelNidas Date: Sat, 17 Jun 2023 11:58:02 +0200 Subject: [PATCH 05/16] Add support for method vars and arg/var comments --- .../mapping/serde/MappingIoConverter.java | 76 ++++++++++++++----- 1 file changed, 56 insertions(+), 20 deletions(-) diff --git a/enigma/src/main/java/cuchaz/enigma/translation/mapping/serde/MappingIoConverter.java b/enigma/src/main/java/cuchaz/enigma/translation/mapping/serde/MappingIoConverter.java index 171f25266..05d862a63 100644 --- a/enigma/src/main/java/cuchaz/enigma/translation/mapping/serde/MappingIoConverter.java +++ b/enigma/src/main/java/cuchaz/enigma/translation/mapping/serde/MappingIoConverter.java @@ -11,6 +11,7 @@ import net.fabricmc.mappingio.tree.MappingTree.FieldMapping; import net.fabricmc.mappingio.tree.MappingTree.MethodArgMapping; import net.fabricmc.mappingio.tree.MappingTree.MethodMapping; +import net.fabricmc.mappingio.tree.MappingTree.MethodVarMapping; import cuchaz.enigma.ProgressListener; import cuchaz.enigma.translation.mapping.EntryMap; @@ -116,28 +117,50 @@ private static void writeMethod(EntryTreeNode methodNode, MemoryMa for (EntryTreeNode child : methodNode.getChildNodes()) { Entry entry = child.getEntry(); - if (entry instanceof LocalVariableEntry) { - writeMethodArg(child, mappingTree); + if (entry instanceof LocalVariableEntry local) { + if (local.isArgument()) { + writeMethodArg(child, mappingTree); + } else { + writeMethodVar(child, mappingTree); + } } } } - private static void writeMethodArg(EntryTreeNode methodArgNode, MemoryMappingTree mappingTree) { - if (methodArgNode.getValue() == null || methodArgNode.getValue().equals(EntryMapping.DEFAULT)) { + private static void writeMethodArg(EntryTreeNode argNode, MemoryMappingTree mappingTree) { + if (argNode.getValue() == null || argNode.getValue().equals(EntryMapping.DEFAULT)) { return; // Shortcut } - LocalVariableEntry methodArgEntry = ((LocalVariableEntry) methodArgNode.getEntry()); - mappingTree.visitMethodArg(-1, methodArgEntry.getIndex(), methodArgEntry.getName()); + LocalVariableEntry argEntry = ((LocalVariableEntry) argNode.getEntry()); + mappingTree.visitMethodArg(-1, argEntry.getIndex(), argEntry.getName()); - EntryMapping methodArgMapping = methodArgNode.getValue(); + EntryMapping argMapping = argNode.getValue(); - if (methodArgMapping == null) { - methodArgMapping = EntryMapping.DEFAULT; + if (argMapping == null) { + argMapping = EntryMapping.DEFAULT; } - mappingTree.visitDstName(MappedElementKind.METHOD_ARG, 0, methodArgMapping.targetName()); - mappingTree.visitComment(MappedElementKind.METHOD_ARG, methodArgMapping.javadoc()); + mappingTree.visitDstName(MappedElementKind.METHOD_ARG, 0, argMapping.targetName()); + mappingTree.visitComment(MappedElementKind.METHOD_ARG, argMapping.javadoc()); + } + + private static void writeMethodVar(EntryTreeNode varNode, MemoryMappingTree mappingTree) { + if (varNode.getValue() == null || varNode.getValue().equals(EntryMapping.DEFAULT)) { + return; // Shortcut + } + + LocalVariableEntry varEntry = ((LocalVariableEntry) varNode.getEntry()); + mappingTree.visitMethodVar(-1, varEntry.getIndex(), -1, -1, varEntry.getName()); + + EntryMapping varMapping = varNode.getValue(); + + if (varMapping == null) { + varMapping = EntryMapping.DEFAULT; + } + + mappingTree.visitDstName(MappedElementKind.METHOD_VAR, 0, varMapping.targetName()); + mappingTree.visitComment(MappedElementKind.METHOD_VAR, varMapping.javadoc()); } public static EntryTree fromMappingIo(MemoryMappingTree mappingTree, ProgressListener progress) { @@ -161,7 +184,7 @@ private static void readClass(ClassMapping classMapping, EntryTree dstName = dstName.substring(dstName.lastIndexOf('$') + 1); } - mappingTree.insert(currentClass, new EntryMapping(dstName)); + mappingTree.insert(currentClass, new EntryMapping(dstName, classMapping.getComment())); for (FieldMapping fieldMapping : classMapping.getFields()) { readField(fieldMapping, currentClass, mappingTree); @@ -174,23 +197,36 @@ private static void readClass(ClassMapping classMapping, EntryTree private static void readField(FieldMapping fieldMapping, ClassEntry parent, EntryTree mappingTree) { mappingTree.insert(new FieldEntry(parent, fieldMapping.getSrcName(), new TypeDescriptor(fieldMapping.getSrcDesc())), - new EntryMapping(fieldMapping.getDstName(0))); + new EntryMapping(fieldMapping.getDstName(0), fieldMapping.getComment())); } private static void readMethod(MethodMapping methodMapping, ClassEntry parent, EntryTree mappingTree) { MethodEntry currentMethod; mappingTree.insert(currentMethod = new MethodEntry(parent, methodMapping.getSrcName(), new MethodDescriptor(methodMapping.getSrcDesc())), - new EntryMapping(methodMapping.getDstName(0))); + new EntryMapping(methodMapping.getDstName(0), methodMapping.getComment())); + + for (MethodArgMapping argMapping : methodMapping.getArgs()) { + readMethodArg(argMapping, currentMethod, mappingTree); + } - for (MethodArgMapping methodArgMapping : methodMapping.getArgs()) { - readMethodArg(methodArgMapping, currentMethod, mappingTree); + for (MethodVarMapping varMapping : methodMapping.getVars()) { + readMethodVar(varMapping, currentMethod, mappingTree); } } - private static void readMethodArg(MethodArgMapping methodArgMapping, MethodEntry parent, EntryTree mappingTree) { - String methodArgSrcName = methodArgMapping.getSrcName() != null ? methodArgMapping.getSrcName() : ""; + private static void readMethodArg(MethodArgMapping argMapping, MethodEntry parent, EntryTree mappingTree) { + String srcName = argMapping.getSrcName() != null ? argMapping.getSrcName() : ""; + + mappingTree.insert( + new LocalVariableEntry(parent, argMapping.getLvIndex(), srcName, true, null), + new EntryMapping(argMapping.getDstName(0), argMapping.getComment())); + } + + private static void readMethodVar(MethodVarMapping varMapping, MethodEntry parent, EntryTree mappingTree) { + String srcName = varMapping.getSrcName() != null ? varMapping.getSrcName() : ""; - mappingTree.insert(new LocalVariableEntry(parent, methodArgMapping.getLvIndex(), methodArgSrcName, true, null), - new EntryMapping(methodArgMapping.getDstName(0))); + mappingTree.insert( + new LocalVariableEntry(parent, varMapping.getLvIndex(), srcName, false, null), + new EntryMapping(varMapping.getDstName(0), varMapping.getComment())); } } From e32dfa11e892e12577a9fef50675d52e16c6d73d Mon Sep 17 00:00:00 2001 From: NebelNidas Date: Sun, 18 Jun 2023 19:54:02 +0200 Subject: [PATCH 06/16] Make Mapping-IO the default --- .../java/cuchaz/enigma/gui/GuiController.java | 2 +- .../cuchaz/enigma/gui/elements/MenuBar.java | 36 +++++++++---------- 2 files changed, 19 insertions(+), 19 deletions(-) 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 e6d4096ca..0eecc7bac 100644 --- a/enigma-swing/src/main/java/cuchaz/enigma/gui/GuiController.java +++ b/enigma-swing/src/main/java/cuchaz/enigma/gui/GuiController.java @@ -104,7 +104,7 @@ public class GuiController implements ClientPacketHandler { private Path loadedMappingPath; private MappingFormat loadedMappingFormat; - public boolean useMappingIo; + public boolean useMappingIo = true; private ClassHandleProvider chp; 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 ca3067c8b..59362e52f 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 @@ -414,21 +414,21 @@ private static void prepareOpenMappingsMenu(JMenu openMappingsMenu, Gui gui) { MappingFormat.TSRG_2_FILE, MappingFormat.PROGUARD); + // Mapping-IO readers + for (MappingFormat format : readableMappingIoFormats) { + 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) { - addOpenMappingsMenuEntry(I18n.translate("mapping_format." + format.name().toLowerCase(Locale.ROOT)), + addOpenMappingsMenuEntry(I18n.translate("mapping_format." + format.name().toLowerCase(Locale.ROOT)) + " (legacy)", format, false, openMappingsMenu, gui); } } - - openMappingsMenu.addSeparator(); - - // Mapping-IO readers - for (MappingFormat format : readableMappingIoFormats) { - addOpenMappingsMenuEntry(I18n.translate(format.getMappingIoCounterpart().name + " (via Mapping-IO, experimental)"), - format, true, openMappingsMenu, gui); - } } private static void addOpenMappingsMenuEntry(String text, MappingFormat format, boolean mappingIo, JMenu openMappingsMenu, Gui gui) { @@ -454,21 +454,21 @@ private static void prepareSaveMappingsAsMenu(JMenu saveMappingsAsMenu, JMenuIte MappingFormat.TINY_V2, MappingFormat.PROGUARD); + // Mapping-IO writers + for (MappingFormat format : writableMappingIoFormats) { + addSaveMappingsAsMenuEntry(format.getMappingIoCounterpart().name, + format, true, saveMappingsAsMenu, saveMappingsItem, gui); + } + + saveMappingsAsMenu.addSeparator(); + // Enigma's own writers for (MappingFormat format : MappingFormat.values()) { if (format.getWriter() != null) { - addSaveMappingsAsMenuEntry(I18n.translate("mapping_format." + format.name().toLowerCase(Locale.ROOT)), + addSaveMappingsAsMenuEntry(I18n.translate("mapping_format." + format.name().toLowerCase(Locale.ROOT)) + " (legacy)", format, false, saveMappingsAsMenu, saveMappingsItem, gui); } } - - saveMappingsAsMenu.addSeparator(); - - // Mapping-IO writers - for (MappingFormat format : writableMappingIoFormats) { - addSaveMappingsAsMenuEntry(format.getMappingIoCounterpart().name + " (via Mapping-IO, experimental)", - format, true, saveMappingsAsMenu, saveMappingsItem, gui); - } } private static void addSaveMappingsAsMenuEntry(String text, MappingFormat format, boolean mappingIo, JMenu saveMappingsAsMenu, JMenuItem saveMappingsItem, Gui gui) { From 9cc9988a4d035a80b5535bc6126eac5dbe9652b2 Mon Sep 17 00:00:00 2001 From: NebelNidas Date: Mon, 9 Oct 2023 11:19:30 +0200 Subject: [PATCH 07/16] Update to latest Mapping-IO release --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index e9fd4a250..27ea120e3 100644 --- a/build.gradle +++ b/build.gradle @@ -20,7 +20,7 @@ subprojects { implementation 'com.google.guava:guava:30.1.1-jre' implementation 'com.google.code.gson:gson:2.8.7' - implementation 'net.fabricmc:mapping-io:0.5.0-SNAPSHOT' + implementation 'net.fabricmc:mapping-io:0.5.0-beta.1' testImplementation 'junit:junit:4.13.2' testImplementation 'org.hamcrest:hamcrest:2.2' From 4681411ca1f9fcbe5eba5c4009175033e76c865c Mon Sep 17 00:00:00 2001 From: NebelNidas Date: Mon, 9 Oct 2023 12:29:35 +0200 Subject: [PATCH 08/16] Use `VisitableMappingTree` where possible --- .../java/cuchaz/enigma/gui/GuiController.java | 5 +- .../mapping/serde/MappingIoConverter.java | 47 +++++++++++-------- 2 files changed, 30 insertions(+), 22 deletions(-) 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 0eecc7bac..2c1530507 100644 --- a/enigma-swing/src/main/java/cuchaz/enigma/gui/GuiController.java +++ b/enigma-swing/src/main/java/cuchaz/enigma/gui/GuiController.java @@ -33,6 +33,7 @@ import net.fabricmc.mappingio.MappingWriter; import net.fabricmc.mappingio.tree.MemoryMappingTree; import net.fabricmc.mappingio.tree.VisitOrder; +import net.fabricmc.mappingio.tree.VisitableMappingTree; import cuchaz.enigma.Enigma; import cuchaz.enigma.EnigmaProfile; @@ -167,7 +168,7 @@ public CompletableFuture openMappings(MappingFormat format, Path path) { } progress.init(1, loadingMessage); - MemoryMappingTree mappingTree = new MemoryMappingTree(); + VisitableMappingTree mappingTree = new MemoryMappingTree(); MappingReader.read(path, format.getMappingIoCounterpart(), mappingTree); mappings = MappingIoConverter.fromMappingIo(mappingTree, progress); } else { @@ -229,7 +230,7 @@ public CompletableFuture saveMappings(Path path, MappingFormat format) { loadedMappingPath = path; if (useMappingIo) { - MemoryMappingTree mappingTree = MappingIoConverter.toMappingIo(mapper.getObfToDeobf(), progress); + VisitableMappingTree mappingTree = MappingIoConverter.toMappingIo(mapper.getObfToDeobf(), progress); progress.init(1, I18n.translate("progress.mappings.writing")); MappingWriter writer = MappingWriter.create(path, format.getMappingIoCounterpart()); diff --git a/enigma/src/main/java/cuchaz/enigma/translation/mapping/serde/MappingIoConverter.java b/enigma/src/main/java/cuchaz/enigma/translation/mapping/serde/MappingIoConverter.java index 05d862a63..a0912fafb 100644 --- a/enigma/src/main/java/cuchaz/enigma/translation/mapping/serde/MappingIoConverter.java +++ b/enigma/src/main/java/cuchaz/enigma/translation/mapping/serde/MappingIoConverter.java @@ -1,5 +1,7 @@ package cuchaz.enigma.translation.mapping.serde; +import java.io.IOException; +import java.io.UncheckedIOException; import java.util.Deque; import java.util.LinkedList; import java.util.List; @@ -7,6 +9,7 @@ import net.fabricmc.mappingio.MappedElementKind; import net.fabricmc.mappingio.tree.MemoryMappingTree; +import net.fabricmc.mappingio.tree.VisitableMappingTree; import net.fabricmc.mappingio.tree.MappingTree.ClassMapping; import net.fabricmc.mappingio.tree.MappingTree.FieldMapping; import net.fabricmc.mappingio.tree.MappingTree.MethodArgMapping; @@ -29,27 +32,31 @@ import cuchaz.enigma.utils.I18n; public class MappingIoConverter { - public static MemoryMappingTree toMappingIo(EntryTree mappings, ProgressListener progress) { - List> classes = StreamSupport.stream(mappings.spliterator(), false) - .filter(node -> node.getEntry() instanceof ClassEntry) - .toList(); + public static VisitableMappingTree toMappingIo(EntryTree mappings, ProgressListener progress) { + try { + List> classes = StreamSupport.stream(mappings.spliterator(), false) + .filter(node -> node.getEntry() instanceof ClassEntry) + .toList(); - progress.init(classes.size(), I18n.translate("progress.mappings.converting.to_mappingio")); - int steps = 0; + progress.init(classes.size(), I18n.translate("progress.mappings.converting.to_mappingio")); + int steps = 0; - MemoryMappingTree mappingTree = new MemoryMappingTree(); - mappingTree.visitNamespaces("intermediary", List.of("named")); + MemoryMappingTree mappingTree = new MemoryMappingTree(); + mappingTree.visitNamespaces("intermediary", List.of("named")); - for (EntryTreeNode classNode : classes) { - progress.step(steps++, classNode.getEntry().getFullName()); - writeClass(classNode, mappings, mappingTree); - } + for (EntryTreeNode classNode : classes) { + progress.step(steps++, classNode.getEntry().getFullName()); + writeClass(classNode, mappings, mappingTree); + } - mappingTree.visitEnd(); - return mappingTree; + mappingTree.visitEnd(); + return mappingTree; + } catch (IOException e) { + throw new UncheckedIOException(e); + } } - private static void writeClass(EntryTreeNode classNode, EntryMap oldMappingTree, MemoryMappingTree newMappingTree) { + private static void writeClass(EntryTreeNode classNode, EntryMap oldMappingTree, VisitableMappingTree newMappingTree) throws IOException { ClassEntry classEntry = (ClassEntry) classNode.getEntry(); EntryMapping mapping = oldMappingTree.get(classEntry); Deque parts = new LinkedList<>(); @@ -83,7 +90,7 @@ private static void writeClass(EntryTreeNode classNode, EntryMap fieldNode, MemoryMappingTree mappingTree) { + private static void writeField(EntryTreeNode fieldNode, VisitableMappingTree mappingTree) throws IOException { if (fieldNode.getValue() == null || fieldNode.getValue().equals(EntryMapping.DEFAULT)) { return; // Shortcut } @@ -101,7 +108,7 @@ private static void writeField(EntryTreeNode fieldNode, MemoryMapp mappingTree.visitComment(MappedElementKind.FIELD, fieldMapping.javadoc()); } - private static void writeMethod(EntryTreeNode methodNode, MemoryMappingTree mappingTree) { + private static void writeMethod(EntryTreeNode methodNode, VisitableMappingTree mappingTree) throws IOException { MethodEntry methodEntry = ((MethodEntry) methodNode.getEntry()); mappingTree.visitMethod(methodEntry.getName(), methodEntry.getDesc().toString()); @@ -127,7 +134,7 @@ private static void writeMethod(EntryTreeNode methodNode, MemoryMa } } - private static void writeMethodArg(EntryTreeNode argNode, MemoryMappingTree mappingTree) { + private static void writeMethodArg(EntryTreeNode argNode, VisitableMappingTree mappingTree) throws IOException { if (argNode.getValue() == null || argNode.getValue().equals(EntryMapping.DEFAULT)) { return; // Shortcut } @@ -145,7 +152,7 @@ private static void writeMethodArg(EntryTreeNode argNode, MemoryMa mappingTree.visitComment(MappedElementKind.METHOD_ARG, argMapping.javadoc()); } - private static void writeMethodVar(EntryTreeNode varNode, MemoryMappingTree mappingTree) { + private static void writeMethodVar(EntryTreeNode varNode, VisitableMappingTree mappingTree) throws IOException { if (varNode.getValue() == null || varNode.getValue().equals(EntryMapping.DEFAULT)) { return; // Shortcut } @@ -163,7 +170,7 @@ private static void writeMethodVar(EntryTreeNode varNode, MemoryMa mappingTree.visitComment(MappedElementKind.METHOD_VAR, varMapping.javadoc()); } - public static EntryTree fromMappingIo(MemoryMappingTree mappingTree, ProgressListener progress) { + public static EntryTree fromMappingIo(VisitableMappingTree mappingTree, ProgressListener progress) { EntryTree dstMappingTree = new HashEntryTree<>(); progress.init(mappingTree.getClasses().size(), I18n.translate("progress.mappings.converting.from_mappingio")); int steps = 0; From 75c6da42ca360084b57f7a384cd4a7bf93bdea0a Mon Sep 17 00:00:00 2001 From: NebelNidas Date: Mon, 9 Oct 2023 14:22:40 +0200 Subject: [PATCH 09/16] Use System Property for Mapping-IO --- .../enigma/command/CheckMappingsCommand.java | 6 +- .../java/cuchaz/enigma/command/Command.java | 26 +++-- .../enigma/command/MappingCommandsUtil.java | 35 ++++-- .../java/cuchaz/enigma/gui/GuiController.java | 48 ++------ .../cuchaz/enigma/gui/elements/MenuBar.java | 42 ++----- .../mapping/serde/MappingFormat.java | 107 +++++++++++++++--- .../mapping/serde/MappingIoConverter.java | 10 +- .../mapping/TestReadWriteCycle.java | 6 + 8 files changed, 168 insertions(+), 112 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 922d66884..5e64b2c13 100644 --- a/enigma-cli/src/main/java/cuchaz/enigma/command/CheckMappingsCommand.java +++ b/enigma-cli/src/main/java/cuchaz/enigma/command/CheckMappingsCommand.java @@ -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; @@ -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 mappings = format.read(fileMappings, ProgressListener.none(), saveParameters); + EntryTree mappings = readMappings(fileMappings, ProgressListener.none(), saveParameters); project.setMappings(mappings); JarIndex idx = project.getJarIndex(); 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 04d49f2fa..ef7cfaa50 100644 --- a/enigma-cli/src/main/java/cuchaz/enigma/command/Command.java +++ b/enigma-cli/src/main/java/cuchaz/enigma/command/Command.java @@ -1,11 +1,15 @@ 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; @@ -13,6 +17,8 @@ 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; @@ -41,7 +47,7 @@ protected static EnigmaProject openProject(Path fileJarIn, Path fileMappings) th System.out.println("Reading mappings..."); MappingSaveParameters saveParameters = enigma.getProfile().getMappingSaveParameters(); - EntryTree mappings = chooseEnigmaFormat(fileMappings).read(fileMappings, progress, saveParameters); + EntryTree mappings = readMappings(fileMappings, progress, saveParameters); project.setMappings(mappings); } @@ -49,14 +55,18 @@ protected static EnigmaProject openProject(Path fileJarIn, Path fileMappings) th 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 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); } + + 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); } protected static File getWritableFile(String path) { diff --git a/enigma-cli/src/main/java/cuchaz/enigma/command/MappingCommandsUtil.java b/enigma-cli/src/main/java/cuchaz/enigma/command/MappingCommandsUtil.java index 787625b61..c452d8ca4 100644 --- a/enigma-cli/src/main/java/cuchaz/enigma/command/MappingCommandsUtil.java +++ b/enigma-cli/src/main/java/cuchaz/enigma/command/MappingCommandsUtil.java @@ -4,14 +4,15 @@ 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; @@ -22,11 +23,11 @@ private MappingCommandsUtil() { public static EntryTree 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); } if (type.equals("tiny")) { - return TinyMappingsReader.INSTANCE.read(path, ProgressListener.none(), saveParameters); + return MappingFormat.TINY_FILE.read(path, ProgressListener.none(), saveParameters); } MappingFormat format = null; @@ -40,15 +41,15 @@ public static EntryTree read(String type, Path path, MappingSavePa } if (format != null) { - return format.getReader().read(path, ProgressListener.none(), saveParameters); + return format.read(path, ProgressListener.none(), saveParameters); } throw new IllegalArgumentException("no reader for " + type); } - public static void write(EntryTree mappings, String type, Path path, MappingSaveParameters saveParameters) { + public static void write(EntryTree mappings, String type, Path path, MappingSaveParameters saveParameters) throws IOException { if (type.equals("enigma")) { - EnigmaMappingsWriter.DIRECTORY.write(mappings, path, ProgressListener.none(), saveParameters); + MappingFormat.ENIGMA_DIRECTORY.write(mappings, path, ProgressListener.none(), saveParameters); return; } @@ -59,7 +60,13 @@ public static void write(EntryTree 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; + } + + VisitableMappingTree tree = MappingIoConverter.toMappingIo(mappings, ProgressListener.none(), split[1], split[2]); + tree.accept(MappingWriter.create(path, net.fabricmc.mappingio.format.MappingFormat.TINY_2_FILE)); return; } @@ -70,7 +77,13 @@ public static void write(EntryTree 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; + } + + VisitableMappingTree tree = MappingIoConverter.toMappingIo(mappings, ProgressListener.none(), split[1], split[2]); + tree.accept(MappingWriter.create(path, net.fabricmc.mappingio.format.MappingFormat.TINY_FILE)); return; } @@ -83,7 +96,7 @@ public static void write(EntryTree mappings, String type, Path pat } if (format != null) { - format.getWriter().write(mappings, path, ProgressListener.none(), saveParameters); + format.write(mappings, path, ProgressListener.none(), saveParameters); return; } 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 2c1530507..88dc070d3 100644 --- a/enigma-swing/src/main/java/cuchaz/enigma/gui/GuiController.java +++ b/enigma-swing/src/main/java/cuchaz/enigma/gui/GuiController.java @@ -29,11 +29,6 @@ import javax.swing.SwingUtilities; import com.google.common.collect.Lists; -import net.fabricmc.mappingio.MappingReader; -import net.fabricmc.mappingio.MappingWriter; -import net.fabricmc.mappingio.tree.MemoryMappingTree; -import net.fabricmc.mappingio.tree.VisitOrder; -import net.fabricmc.mappingio.tree.VisitableMappingTree; import cuchaz.enigma.Enigma; import cuchaz.enigma.EnigmaProfile; @@ -82,7 +77,6 @@ import cuchaz.enigma.translation.mapping.MappingDelta; import cuchaz.enigma.translation.mapping.ResolutionStrategy; 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; @@ -105,7 +99,6 @@ public class GuiController implements ClientPacketHandler { private Path loadedMappingPath; private MappingFormat loadedMappingFormat; - public boolean useMappingIo = true; private ClassHandleProvider chp; @@ -146,6 +139,11 @@ public void closeJar() { this.gui.onCloseJar(); } + public CompletableFuture openMappings(MappingFormat format, Path path, boolean useMappingIo) { + System.getProperties().setProperty("enigma.use_mappingio", useMappingIo ? "true" : "false"); + return openMappings(format, path); + } + public CompletableFuture openMappings(MappingFormat format, Path path) { if (project == null) { return CompletableFuture.completedFuture(null); @@ -156,26 +154,7 @@ public CompletableFuture openMappings(MappingFormat format, Path path) { return ProgressDialog.runOffThread(gui.getFrame(), progress -> { try { MappingSaveParameters saveParameters = enigma.getProfile().getMappingSaveParameters(); - EntryTree mappings; - - if (useMappingIo) { - String loadingMessage; - - if (format.getMappingIoCounterpart().hasSingleFile()) { - loadingMessage = I18n.translate("progress.mappings.loading_file"); - } else { - loadingMessage = I18n.translate("progress.mappings.loading_directory"); - } - - progress.init(1, loadingMessage); - VisitableMappingTree mappingTree = new MemoryMappingTree(); - MappingReader.read(path, format.getMappingIoCounterpart(), mappingTree); - mappings = MappingIoConverter.fromMappingIo(mappingTree, progress); - } else { - mappings = format.read(path, progress, saveParameters); - } - - project.setMappings(mappings); + project.setMappings(format.read(path, progress, saveParameters)); loadedMappingFormat = format; loadedMappingPath = path; @@ -203,6 +182,11 @@ public CompletableFuture saveMappings(Path path) { return saveMappings(path, loadedMappingFormat); } + public CompletableFuture 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. * @@ -229,15 +213,7 @@ public CompletableFuture saveMappings(Path path, MappingFormat format) { loadedMappingFormat = format; loadedMappingPath = path; - if (useMappingIo) { - VisitableMappingTree mappingTree = MappingIoConverter.toMappingIo(mapper.getObfToDeobf(), progress); - - progress.init(1, I18n.translate("progress.mappings.writing")); - MappingWriter writer = MappingWriter.create(path, format.getMappingIoCounterpart()); - mappingTree.accept(writer, VisitOrder.createByName()); - writer.close(); - progress.step(1, I18n.translate("progress.done")); - } else if (saveAll) { + if (saveAll) { format.write(mapper.getObfToDeobf(), path, progress, saveParameters); } else { format.write(mapper.getObfToDeobf(), delta, path, progress, saveParameters); 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 59362e52f..30e35861e 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 @@ -7,7 +7,6 @@ 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; @@ -404,22 +403,11 @@ private void onGithubClicked() { } private static void prepareOpenMappingsMenu(JMenu openMappingsMenu, Gui gui) { - List readableMappingIoFormats = Arrays.asList( - MappingFormat.ENIGMA_DIRECTORY, - MappingFormat.ENIGMA_FILE, - MappingFormat.TINY_FILE, - MappingFormat.TINY_V2, - MappingFormat.SRG_FILE, - MappingFormat.TSRG_FILE, - MappingFormat.TSRG_2_FILE, - MappingFormat.PROGUARD); - // Mapping-IO readers - for (MappingFormat format : readableMappingIoFormats) { - addOpenMappingsMenuEntry(I18n.translate(format.getMappingIoCounterpart().name), - format, true, openMappingsMenu, gui); - } - + 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 @@ -438,8 +426,7 @@ private static void addOpenMappingsMenuEntry(String text, MappingFormat format, if (gui.enigmaMappingsFileChooser.showOpenDialog(gui.getFrame()) == JFileChooser.APPROVE_OPTION) { File selectedFile = gui.enigmaMappingsFileChooser.getSelectedFile(); - gui.getController().useMappingIo = mappingIo; - gui.getController().openMappings(format, selectedFile.toPath()); + gui.getController().openMappings(format, selectedFile.toPath(), mappingIo); UiConfig.setLastSelectedDir(gui.enigmaMappingsFileChooser.getCurrentDirectory().toString()); } }); @@ -447,19 +434,11 @@ private static void addOpenMappingsMenuEntry(String text, MappingFormat format, } private static void prepareSaveMappingsAsMenu(JMenu saveMappingsAsMenu, JMenuItem saveMappingsItem, Gui gui) { - List writableMappingIoFormats = Arrays.asList( - MappingFormat.ENIGMA_DIRECTORY, - MappingFormat.ENIGMA_FILE, - MappingFormat.TINY_FILE, - MappingFormat.TINY_V2, - MappingFormat.PROGUARD); - // Mapping-IO writers - for (MappingFormat format : writableMappingIoFormats) { - addSaveMappingsAsMenuEntry(format.getMappingIoCounterpart().name, - format, true, saveMappingsAsMenu, saveMappingsItem, gui); - } - + MappingFormat.getWritableFormats().stream() + .filter(format -> format.hasMappingIoWriter()) + .forEach(format -> addSaveMappingsAsMenuEntry(format.getMappingIoCounterpart().name, + format, true, saveMappingsAsMenu, saveMappingsItem, gui)); saveMappingsAsMenu.addSeparator(); // Enigma's own writers @@ -480,8 +459,7 @@ private static void addSaveMappingsAsMenuEntry(String text, MappingFormat format } if (gui.enigmaMappingsFileChooser.showSaveDialog(gui.getFrame()) == JFileChooser.APPROVE_OPTION) { - gui.getController().useMappingIo = mappingIo; - gui.getController().saveMappings(gui.enigmaMappingsFileChooser.getSelectedFile().toPath(), format); + gui.getController().saveMappings(gui.enigmaMappingsFileChooser.getSelectedFile().toPath(), format, mappingIo); saveMappingsItem.setEnabled(true); UiConfig.setLastSelectedDir(gui.enigmaMappingsFileChooser.getCurrentDirectory().toString()); } diff --git a/enigma/src/main/java/cuchaz/enigma/translation/mapping/serde/MappingFormat.java b/enigma/src/main/java/cuchaz/enigma/translation/mapping/serde/MappingFormat.java index f402c1938..4d3472071 100644 --- a/enigma/src/main/java/cuchaz/enigma/translation/mapping/serde/MappingFormat.java +++ b/enigma/src/main/java/cuchaz/enigma/translation/mapping/serde/MappingFormat.java @@ -1,10 +1,19 @@ package cuchaz.enigma.translation.mapping.serde; import java.io.IOException; +import java.io.UncheckedIOException; import java.nio.file.Path; +import java.util.Arrays; +import java.util.List; import javax.annotation.Nullable; +import net.fabricmc.mappingio.MappingReader; +import net.fabricmc.mappingio.MappingWriter; +import net.fabricmc.mappingio.tree.MemoryMappingTree; +import net.fabricmc.mappingio.tree.VisitOrder; +import net.fabricmc.mappingio.tree.VisitableMappingTree; + import cuchaz.enigma.ProgressListener; import cuchaz.enigma.translation.mapping.EntryMapping; import cuchaz.enigma.translation.mapping.MappingDelta; @@ -19,27 +28,30 @@ import cuchaz.enigma.translation.mapping.serde.tinyv2.TinyV2Reader; import cuchaz.enigma.translation.mapping.serde.tinyv2.TinyV2Writer; import cuchaz.enigma.translation.mapping.tree.EntryTree; +import cuchaz.enigma.utils.I18n; public enum MappingFormat { - ENIGMA_FILE(EnigmaMappingsWriter.FILE, EnigmaMappingsReader.FILE, net.fabricmc.mappingio.format.MappingFormat.ENIGMA_FILE), - ENIGMA_DIRECTORY(EnigmaMappingsWriter.DIRECTORY, EnigmaMappingsReader.DIRECTORY, net.fabricmc.mappingio.format.MappingFormat.ENIGMA_DIR), - ENIGMA_ZIP(EnigmaMappingsWriter.ZIP, EnigmaMappingsReader.ZIP, null), - TINY_V2(new TinyV2Writer("intermediary", "named"), new TinyV2Reader(), net.fabricmc.mappingio.format.MappingFormat.TINY_2_FILE), - TINY_FILE(TinyMappingsWriter.INSTANCE, TinyMappingsReader.INSTANCE, net.fabricmc.mappingio.format.MappingFormat.TINY_FILE), - SRG_FILE(SrgMappingsWriter.INSTANCE, null, net.fabricmc.mappingio.format.MappingFormat.SRG_FILE), - TSRG_FILE(null, null, net.fabricmc.mappingio.format.MappingFormat.TSRG_FILE), - TSRG_2_FILE(null, null, net.fabricmc.mappingio.format.MappingFormat.TSRG_2_FILE), - PROGUARD(null, ProguardMappingsReader.INSTANCE, net.fabricmc.mappingio.format.MappingFormat.PROGUARD_FILE), - RECAF(RecafMappingsWriter.INSTANCE, RecafMappingsReader.INSTANCE, null); + ENIGMA_FILE(EnigmaMappingsWriter.FILE, EnigmaMappingsReader.FILE, net.fabricmc.mappingio.format.MappingFormat.ENIGMA_FILE, true), + ENIGMA_DIRECTORY(EnigmaMappingsWriter.DIRECTORY, EnigmaMappingsReader.DIRECTORY, net.fabricmc.mappingio.format.MappingFormat.ENIGMA_DIR, true), + ENIGMA_ZIP(EnigmaMappingsWriter.ZIP, EnigmaMappingsReader.ZIP, null, false), + TINY_V2(new TinyV2Writer("intermediary", "named"), new TinyV2Reader(), net.fabricmc.mappingio.format.MappingFormat.TINY_2_FILE, true), + TINY_FILE(TinyMappingsWriter.INSTANCE, TinyMappingsReader.INSTANCE, net.fabricmc.mappingio.format.MappingFormat.TINY_FILE, true), + SRG_FILE(SrgMappingsWriter.INSTANCE, null, net.fabricmc.mappingio.format.MappingFormat.SRG_FILE, false), + TSRG_FILE(null, null, net.fabricmc.mappingio.format.MappingFormat.TSRG_FILE, false), + TSRG_2_FILE(null, null, net.fabricmc.mappingio.format.MappingFormat.TSRG_2_FILE, false), + PROGUARD(null, ProguardMappingsReader.INSTANCE, net.fabricmc.mappingio.format.MappingFormat.PROGUARD_FILE, true), + RECAF(RecafMappingsWriter.INSTANCE, RecafMappingsReader.INSTANCE, null, false); private final MappingsWriter writer; private final MappingsReader reader; private final net.fabricmc.mappingio.format.MappingFormat mappingIoCounterpart; + private final boolean hasMappingIoWriter; - MappingFormat(MappingsWriter writer, MappingsReader reader, net.fabricmc.mappingio.format.MappingFormat mappingIoCounterpart) { + MappingFormat(MappingsWriter writer, MappingsReader reader, net.fabricmc.mappingio.format.MappingFormat mappingIoCounterpart, boolean hasMappingIoWriter) { this.writer = writer; this.reader = reader; this.mappingIoCounterpart = mappingIoCounterpart; + this.hasMappingIoWriter = hasMappingIoWriter; } public void write(EntryTree mappings, Path path, ProgressListener progressListener, MappingSaveParameters saveParameters) { @@ -47,19 +59,49 @@ public void write(EntryTree mappings, Path path, ProgressListener } public void write(EntryTree mappings, MappingDelta delta, Path path, ProgressListener progressListener, MappingSaveParameters saveParameters) { - if (writer == null) { - throw new IllegalStateException(name() + " does not support writing"); + if (!hasMappingIoWriter || !useMappingIo()) { + if (writer == null) { + throw new IllegalStateException(name() + " does not support writing"); + } + + writer.write(mappings, delta, path, progressListener, saveParameters); + return; } - writer.write(mappings, delta, path, progressListener, saveParameters); + try { + VisitableMappingTree tree = MappingIoConverter.toMappingIo(mappings, progressListener); + progressListener.init(1, I18n.translate("progress.mappings.writing")); + progressListener.step(1, null); // Reset message + + tree.accept(MappingWriter.create(path, mappingIoCounterpart), VisitOrder.createByName()); + progressListener.step(1, I18n.translate("progress.done")); + } catch (IOException e) { + throw new UncheckedIOException(e); + } } public EntryTree read(Path path, ProgressListener progressListener, MappingSaveParameters saveParameters) throws IOException, MappingParseException { - if (reader == null) { - throw new IllegalStateException(name() + " does not support reading"); + if (!useMappingIo()) { + if (reader == null) { + throw new IllegalStateException(name() + " does not support reading"); + } + + return reader.read(path, progressListener, saveParameters); } - return reader.read(path, progressListener, saveParameters); + String loadingMessage; + + if (mappingIoCounterpart.hasSingleFile()) { + loadingMessage = I18n.translate("progress.mappings.loading_file"); + } else { + loadingMessage = I18n.translate("progress.mappings.loading_directory"); + } + + progressListener.init(1, loadingMessage); + + VisitableMappingTree mappingTree = new MemoryMappingTree(); + MappingReader.read(path, mappingIoCounterpart, mappingTree); + return MappingIoConverter.fromMappingIo(mappingTree, progressListener); } @Nullable @@ -76,4 +118,35 @@ public MappingsReader getReader() { public net.fabricmc.mappingio.format.MappingFormat getMappingIoCounterpart() { return mappingIoCounterpart; } + + public boolean hasMappingIoWriter() { + return hasMappingIoWriter; + } + + public boolean isReadable() { + return reader != null || mappingIoCounterpart != null; + } + + public boolean isWritable() { + return writer != null || hasMappingIoWriter; + } + + private boolean useMappingIo() { + if (mappingIoCounterpart == null) return false; + return System.getProperty("enigma.use_mappingio", "true").equals("true"); + } + + public static List getReadableFormats() { + return Arrays.asList(values()) + .stream() + .filter(MappingFormat::isReadable) + .toList(); + } + + public static List getWritableFormats() { + return Arrays.asList(values()) + .stream() + .filter(MappingFormat::isWritable) + .toList(); + } } diff --git a/enigma/src/main/java/cuchaz/enigma/translation/mapping/serde/MappingIoConverter.java b/enigma/src/main/java/cuchaz/enigma/translation/mapping/serde/MappingIoConverter.java index a0912fafb..437258516 100644 --- a/enigma/src/main/java/cuchaz/enigma/translation/mapping/serde/MappingIoConverter.java +++ b/enigma/src/main/java/cuchaz/enigma/translation/mapping/serde/MappingIoConverter.java @@ -33,19 +33,23 @@ public class MappingIoConverter { public static VisitableMappingTree toMappingIo(EntryTree mappings, ProgressListener progress) { + return toMappingIo(mappings, progress, "intermediary", "named"); + } + + public static VisitableMappingTree toMappingIo(EntryTree mappings, ProgressListener progress, String fromNs, String toNs) { try { List> classes = StreamSupport.stream(mappings.spliterator(), false) .filter(node -> node.getEntry() instanceof ClassEntry) .toList(); progress.init(classes.size(), I18n.translate("progress.mappings.converting.to_mappingio")); - int steps = 0; + int stepsDone = 0; MemoryMappingTree mappingTree = new MemoryMappingTree(); - mappingTree.visitNamespaces("intermediary", List.of("named")); + mappingTree.visitNamespaces(fromNs, List.of(toNs)); for (EntryTreeNode classNode : classes) { - progress.step(steps++, classNode.getEntry().getFullName()); + progress.step(++stepsDone, classNode.getEntry().getFullName()); writeClass(classNode, mappings, mappingTree); } diff --git a/enigma/src/test/java/cuchaz/enigma/translation/mapping/TestReadWriteCycle.java b/enigma/src/test/java/cuchaz/enigma/translation/mapping/TestReadWriteCycle.java index 681fd3f21..34d5a6ea4 100644 --- a/enigma/src/test/java/cuchaz/enigma/translation/mapping/TestReadWriteCycle.java +++ b/enigma/src/test/java/cuchaz/enigma/translation/mapping/TestReadWriteCycle.java @@ -4,6 +4,7 @@ import java.io.IOException; import org.junit.Assert; +import org.junit.BeforeClass; import org.junit.Test; import cuchaz.enigma.ProgressListener; @@ -87,6 +88,11 @@ private void testReadWriteCycle(MappingFormat mappingFormat, boolean supportsJav tempFile.delete(); } + @BeforeClass + public static void setup() { + System.getProperties().setProperty("enigma.use_mappingio", "false"); + } + @Test public void testEnigmaFile() throws IOException, MappingParseException { testReadWriteCycle(MappingFormat.ENIGMA_FILE, true, ".enigma"); From dd11b478b3fba3a25b712f2c93221c0fefb5dbda Mon Sep 17 00:00:00 2001 From: NebelNidas Date: Wed, 15 Nov 2023 20:34:45 +0100 Subject: [PATCH 10/16] Update Mapping-IO to full release of 0.5 --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index 27ea120e3..3b90781af 100644 --- a/build.gradle +++ b/build.gradle @@ -20,7 +20,7 @@ subprojects { implementation 'com.google.guava:guava:30.1.1-jre' implementation 'com.google.code.gson:gson:2.8.7' - implementation 'net.fabricmc:mapping-io:0.5.0-beta.1' + implementation 'net.fabricmc:mapping-io:0.5.0' testImplementation 'junit:junit:4.13.2' testImplementation 'org.hamcrest:hamcrest:2.2' From 2964590e594a757386558df577fd366eac045143 Mon Sep 17 00:00:00 2001 From: NebelNidas Date: Thu, 16 Nov 2023 13:43:18 +0100 Subject: [PATCH 11/16] Allow XSRG and CSRG to be imported --- .../enigma/translation/mapping/serde/MappingFormat.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/enigma/src/main/java/cuchaz/enigma/translation/mapping/serde/MappingFormat.java b/enigma/src/main/java/cuchaz/enigma/translation/mapping/serde/MappingFormat.java index 4d3472071..bbbf36973 100644 --- a/enigma/src/main/java/cuchaz/enigma/translation/mapping/serde/MappingFormat.java +++ b/enigma/src/main/java/cuchaz/enigma/translation/mapping/serde/MappingFormat.java @@ -36,7 +36,9 @@ public enum MappingFormat { ENIGMA_ZIP(EnigmaMappingsWriter.ZIP, EnigmaMappingsReader.ZIP, null, false), TINY_V2(new TinyV2Writer("intermediary", "named"), new TinyV2Reader(), net.fabricmc.mappingio.format.MappingFormat.TINY_2_FILE, true), TINY_FILE(TinyMappingsWriter.INSTANCE, TinyMappingsReader.INSTANCE, net.fabricmc.mappingio.format.MappingFormat.TINY_FILE, true), - SRG_FILE(SrgMappingsWriter.INSTANCE, null, net.fabricmc.mappingio.format.MappingFormat.SRG_FILE, false), + SRG_FILE(SrgMappingsWriter.INSTANCE, null, net.fabricmc.mappingio.format.MappingFormat.SRG_FILE, true), + XSRG_FILE(null, null, net.fabricmc.mappingio.format.MappingFormat.XSRG_FILE, true), + CSRG_FILE(null, null, net.fabricmc.mappingio.format.MappingFormat.CSRG_FILE, false), TSRG_FILE(null, null, net.fabricmc.mappingio.format.MappingFormat.TSRG_FILE, false), TSRG_2_FILE(null, null, net.fabricmc.mappingio.format.MappingFormat.TSRG_2_FILE, false), PROGUARD(null, ProguardMappingsReader.INSTANCE, net.fabricmc.mappingio.format.MappingFormat.PROGUARD_FILE, true), From 423f5cf98c6d419942301cca0c7c8169db8d4b30 Mon Sep 17 00:00:00 2001 From: NebelNidas Date: Thu, 16 Nov 2023 13:51:03 +0100 Subject: [PATCH 12/16] Fix importing mappings without field source descriptors --- build.gradle | 3 +- .../java/cuchaz/enigma/command/Command.java | 4 +- .../enigma/command/MappingCommandsUtil.java | 6 +-- .../enigma/network/DedicatedEnigmaServer.java | 2 +- .../java/cuchaz/enigma/gui/GuiController.java | 2 +- .../mapping/serde/MappingFormat.java | 8 ++- .../mapping/serde/MappingIoConverter.java | 50 ++++++++++++++++--- .../mapping/TestReadWriteCycle.java | 2 +- 8 files changed, 60 insertions(+), 17 deletions(-) diff --git a/build.gradle b/build.gradle index 3b90781af..8cbe0cd62 100644 --- a/build.gradle +++ b/build.gradle @@ -19,8 +19,9 @@ subprojects { dependencies { implementation 'com.google.guava:guava:30.1.1-jre' implementation 'com.google.code.gson:gson:2.8.7' - 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' 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 ef7cfaa50..de06fa6e4 100644 --- a/enigma-cli/src/main/java/cuchaz/enigma/command/Command.java +++ b/enigma-cli/src/main/java/cuchaz/enigma/command/Command.java @@ -58,7 +58,7 @@ protected static EnigmaProject openProject(Path fileJarIn, Path fileMappings) th protected static EntryTree 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); + return MappingFormat.ENIGMA_ZIP.read(path, progress, saveParameters, null); } net.fabricmc.mappingio.format.MappingFormat format = MappingReader.detectFormat(path); @@ -66,7 +66,7 @@ protected static EntryTree readMappings(Path path, ProgressListene VisitableMappingTree tree = new MemoryMappingTree(); MappingReader.read(path, format, tree); - return MappingIoConverter.fromMappingIo(tree, progress); + return MappingIoConverter.fromMappingIo(tree, progress, null); } protected static File getWritableFile(String path) { diff --git a/enigma-cli/src/main/java/cuchaz/enigma/command/MappingCommandsUtil.java b/enigma-cli/src/main/java/cuchaz/enigma/command/MappingCommandsUtil.java index c452d8ca4..2c6c9fdb8 100644 --- a/enigma-cli/src/main/java/cuchaz/enigma/command/MappingCommandsUtil.java +++ b/enigma-cli/src/main/java/cuchaz/enigma/command/MappingCommandsUtil.java @@ -23,11 +23,11 @@ private MappingCommandsUtil() { public static EntryTree read(String type, Path path, MappingSaveParameters saveParameters) throws MappingParseException, IOException { if (type.equals("enigma")) { - return (Files.isDirectory(path) ? MappingFormat.ENIGMA_DIRECTORY : MappingFormat.ENIGMA_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 MappingFormat.TINY_FILE.read(path, ProgressListener.none(), saveParameters); + return MappingFormat.TINY_FILE.read(path, ProgressListener.none(), saveParameters, null); } MappingFormat format = null; @@ -41,7 +41,7 @@ public static EntryTree read(String type, Path path, MappingSavePa } if (format != null) { - return format.read(path, ProgressListener.none(), saveParameters); + return format.read(path, ProgressListener.none(), saveParameters, null); } throw new IllegalArgumentException("no reader for " + type); 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 eb22a506e..fbee40d0b 100644 --- a/enigma-server/src/main/java/cuchaz/enigma/network/DedicatedEnigmaServer.java +++ b/enigma-server/src/main/java/cuchaz/enigma/network/DedicatedEnigmaServer.java @@ -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)); 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 88dc070d3..6eab0f86e 100644 --- a/enigma-swing/src/main/java/cuchaz/enigma/gui/GuiController.java +++ b/enigma-swing/src/main/java/cuchaz/enigma/gui/GuiController.java @@ -154,7 +154,7 @@ public CompletableFuture openMappings(MappingFormat format, Path path) { return ProgressDialog.runOffThread(gui.getFrame(), progress -> { try { MappingSaveParameters saveParameters = enigma.getProfile().getMappingSaveParameters(); - project.setMappings(format.read(path, progress, saveParameters)); + project.setMappings(format.read(path, progress, saveParameters, project.getJarIndex())); loadedMappingFormat = format; loadedMappingPath = path; diff --git a/enigma/src/main/java/cuchaz/enigma/translation/mapping/serde/MappingFormat.java b/enigma/src/main/java/cuchaz/enigma/translation/mapping/serde/MappingFormat.java index bbbf36973..530aff40e 100644 --- a/enigma/src/main/java/cuchaz/enigma/translation/mapping/serde/MappingFormat.java +++ b/enigma/src/main/java/cuchaz/enigma/translation/mapping/serde/MappingFormat.java @@ -15,6 +15,7 @@ import net.fabricmc.mappingio.tree.VisitableMappingTree; import cuchaz.enigma.ProgressListener; +import cuchaz.enigma.analysis.index.JarIndex; import cuchaz.enigma.translation.mapping.EntryMapping; import cuchaz.enigma.translation.mapping.MappingDelta; import cuchaz.enigma.translation.mapping.serde.enigma.EnigmaMappingsReader; @@ -82,7 +83,12 @@ public void write(EntryTree mappings, MappingDelta d } } + @Deprecated public EntryTree read(Path path, ProgressListener progressListener, MappingSaveParameters saveParameters) throws IOException, MappingParseException { + return read(path, progressListener, saveParameters, null); + } + + public EntryTree read(Path path, ProgressListener progressListener, MappingSaveParameters saveParameters, JarIndex index) throws IOException, MappingParseException { if (!useMappingIo()) { if (reader == null) { throw new IllegalStateException(name() + " does not support reading"); @@ -103,7 +109,7 @@ public EntryTree read(Path path, ProgressListener progressListener VisitableMappingTree mappingTree = new MemoryMappingTree(); MappingReader.read(path, mappingIoCounterpart, mappingTree); - return MappingIoConverter.fromMappingIo(mappingTree, progressListener); + return MappingIoConverter.fromMappingIo(mappingTree, progressListener, index); } @Nullable diff --git a/enigma/src/main/java/cuchaz/enigma/translation/mapping/serde/MappingIoConverter.java b/enigma/src/main/java/cuchaz/enigma/translation/mapping/serde/MappingIoConverter.java index 437258516..3843d8e45 100644 --- a/enigma/src/main/java/cuchaz/enigma/translation/mapping/serde/MappingIoConverter.java +++ b/enigma/src/main/java/cuchaz/enigma/translation/mapping/serde/MappingIoConverter.java @@ -7,6 +7,9 @@ import java.util.List; import java.util.stream.StreamSupport; +import javax.annotation.Nullable; + +import org.jetbrains.annotations.ApiStatus; import net.fabricmc.mappingio.MappedElementKind; import net.fabricmc.mappingio.tree.MemoryMappingTree; import net.fabricmc.mappingio.tree.VisitableMappingTree; @@ -17,6 +20,7 @@ import net.fabricmc.mappingio.tree.MappingTree.MethodVarMapping; import cuchaz.enigma.ProgressListener; +import cuchaz.enigma.analysis.index.JarIndex; import cuchaz.enigma.translation.mapping.EntryMap; import cuchaz.enigma.translation.mapping.EntryMapping; import cuchaz.enigma.translation.mapping.tree.EntryTree; @@ -31,6 +35,7 @@ import cuchaz.enigma.translation.representation.entry.MethodEntry; import cuchaz.enigma.utils.I18n; +@ApiStatus.Internal public class MappingIoConverter { public static VisitableMappingTree toMappingIo(EntryTree mappings, ProgressListener progress) { return toMappingIo(mappings, progress, "intermediary", "named"); @@ -174,20 +179,20 @@ private static void writeMethodVar(EntryTreeNode varNode, Visitabl mappingTree.visitComment(MappedElementKind.METHOD_VAR, varMapping.javadoc()); } - public static EntryTree fromMappingIo(VisitableMappingTree mappingTree, ProgressListener progress) { + public static EntryTree fromMappingIo(VisitableMappingTree mappingTree, ProgressListener progress, @Nullable JarIndex index) { EntryTree dstMappingTree = new HashEntryTree<>(); progress.init(mappingTree.getClasses().size(), I18n.translate("progress.mappings.converting.from_mappingio")); int steps = 0; for (ClassMapping classMapping : mappingTree.getClasses()) { progress.step(steps++, classMapping.getDstName(0) != null ? classMapping.getDstName(0) : classMapping.getSrcName()); - readClass(classMapping, dstMappingTree); + readClass(classMapping, dstMappingTree, index); } return dstMappingTree; } - private static void readClass(ClassMapping classMapping, EntryTree mappingTree) { + private static void readClass(ClassMapping classMapping, EntryTree mappingTree, JarIndex index) { ClassEntry currentClass = new ClassEntry(classMapping.getSrcName()); String dstName = classMapping.getDstName(0); @@ -198,7 +203,7 @@ private static void readClass(ClassMapping classMapping, EntryTree mappingTree.insert(currentClass, new EntryMapping(dstName, classMapping.getComment())); for (FieldMapping fieldMapping : classMapping.getFields()) { - readField(fieldMapping, currentClass, mappingTree); + readField(fieldMapping, currentClass, mappingTree, index); } for (MethodMapping methodMapping : classMapping.getMethods()) { @@ -206,9 +211,40 @@ private static void readClass(ClassMapping classMapping, EntryTree } } - private static void readField(FieldMapping fieldMapping, ClassEntry parent, EntryTree mappingTree) { - mappingTree.insert(new FieldEntry(parent, fieldMapping.getSrcName(), new TypeDescriptor(fieldMapping.getSrcDesc())), - new EntryMapping(fieldMapping.getDstName(0), fieldMapping.getComment())); + private static void readField(FieldMapping fieldMapping, ClassEntry parent, EntryTree mappingTree, JarIndex index) { + String srcDesc = fieldMapping.getSrcDesc(); + FieldEntry[] fieldEntries; + + if (srcDesc != null) { + fieldEntries = new FieldEntry[] { new FieldEntry(parent, fieldMapping.getSrcName(), new TypeDescriptor(fieldMapping.getSrcDesc())) }; + } else { + if (index == null) return; // Enigma requires source descriptors, and without an index we can't look them up + + fieldEntries = index.getChildrenByClass().get(parent).stream() + .filter(entry -> entry instanceof FieldEntry) + .filter(entry -> entry.getName().equals(fieldMapping.getSrcName())) + .toArray(FieldEntry[]::new); + + if (fieldEntries.length == 0) { // slow path for synthetics + fieldEntries = index.getEntryIndex().getFields().stream() + .filter(entry -> entry.getParent().getFullName().equals(parent.getFullName())) + .filter(entry -> { + if (entry.getName().equals(fieldMapping.getSrcName())) { + return true; + } else { + System.out.println("Entry name: " + entry.getName() + ", mapping name: " + fieldMapping.getSrcName()); + return false; + } + }) + .toArray(FieldEntry[]::new); + } + + if (fieldEntries.length == 0) return; // No target found, invalid mapping + } + + for (FieldEntry fieldEntry : fieldEntries) { + mappingTree.insert(fieldEntry, new EntryMapping(fieldMapping.getDstName(0), fieldMapping.getComment())); + } } private static void readMethod(MethodMapping methodMapping, ClassEntry parent, EntryTree mappingTree) { diff --git a/enigma/src/test/java/cuchaz/enigma/translation/mapping/TestReadWriteCycle.java b/enigma/src/test/java/cuchaz/enigma/translation/mapping/TestReadWriteCycle.java index 34d5a6ea4..25f11fbca 100644 --- a/enigma/src/test/java/cuchaz/enigma/translation/mapping/TestReadWriteCycle.java +++ b/enigma/src/test/java/cuchaz/enigma/translation/mapping/TestReadWriteCycle.java @@ -63,7 +63,7 @@ private void testReadWriteCycle(MappingFormat mappingFormat, boolean supportsJav mappingFormat.write(testMappings, tempFile.toPath(), ProgressListener.none(), parameters); Assert.assertTrue("Written file not created", tempFile.exists()); - EntryTree loadedMappings = mappingFormat.read(tempFile.toPath(), ProgressListener.none(), parameters); + EntryTree loadedMappings = mappingFormat.read(tempFile.toPath(), ProgressListener.none(), parameters, null); Assert.assertTrue("Loaded mappings don't contain testClazz", loadedMappings.contains(testClazz.a)); Assert.assertTrue("Loaded mappings don't contain testField1", loadedMappings.contains(testField1.a)); From edeeb253c9143b3cf53311e1c156fb9f1b2fe4db Mon Sep 17 00:00:00 2001 From: NebelNidas Date: Thu, 16 Nov 2023 14:40:57 +0100 Subject: [PATCH 13/16] Don't only write diffs when MIO writer was last used --- .../src/main/java/cuchaz/enigma/gui/GuiController.java | 3 +++ .../enigma/translation/mapping/serde/MappingFormat.java | 5 ++++- 2 files changed, 7 insertions(+), 1 deletion(-) 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 6eab0f86e..c57990196 100644 --- a/enigma-swing/src/main/java/cuchaz/enigma/gui/GuiController.java +++ b/enigma-swing/src/main/java/cuchaz/enigma/gui/GuiController.java @@ -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; @@ -139,6 +140,7 @@ public void closeJar() { this.gui.onCloseJar(); } + @ApiStatus.Internal public CompletableFuture openMappings(MappingFormat format, Path path, boolean useMappingIo) { System.getProperties().setProperty("enigma.use_mappingio", useMappingIo ? "true" : "false"); return openMappings(format, path); @@ -182,6 +184,7 @@ public CompletableFuture saveMappings(Path path) { return saveMappings(path, loadedMappingFormat); } + @ApiStatus.Internal public CompletableFuture saveMappings(Path path, MappingFormat format, boolean useMappingIo) { System.getProperties().setProperty("enigma.use_mappingio", useMappingIo ? "true" : "false"); return saveMappings(path, format); diff --git a/enigma/src/main/java/cuchaz/enigma/translation/mapping/serde/MappingFormat.java b/enigma/src/main/java/cuchaz/enigma/translation/mapping/serde/MappingFormat.java index 530aff40e..88f722c9e 100644 --- a/enigma/src/main/java/cuchaz/enigma/translation/mapping/serde/MappingFormat.java +++ b/enigma/src/main/java/cuchaz/enigma/translation/mapping/serde/MappingFormat.java @@ -49,6 +49,7 @@ public enum MappingFormat { private final MappingsReader reader; private final net.fabricmc.mappingio.format.MappingFormat mappingIoCounterpart; private final boolean hasMappingIoWriter; + private boolean lastUsedMappingIoWriter; MappingFormat(MappingsWriter writer, MappingsReader reader, net.fabricmc.mappingio.format.MappingFormat mappingIoCounterpart, boolean hasMappingIoWriter) { this.writer = writer; @@ -67,7 +68,8 @@ public void write(EntryTree mappings, MappingDelta d throw new IllegalStateException(name() + " does not support writing"); } - writer.write(mappings, delta, path, progressListener, saveParameters); + writer.write(mappings, lastUsedMappingIoWriter ? MappingDelta.added(mappings) : delta, path, progressListener, saveParameters); + lastUsedMappingIoWriter = false; return; } @@ -78,6 +80,7 @@ public void write(EntryTree mappings, MappingDelta d tree.accept(MappingWriter.create(path, mappingIoCounterpart), VisitOrder.createByName()); progressListener.step(1, I18n.translate("progress.done")); + lastUsedMappingIoWriter = true; } catch (IOException e) { throw new UncheckedIOException(e); } From b327ba0b31c2229bb49240e456cd7cb604b8e2fa Mon Sep 17 00:00:00 2001 From: NebelNidas Date: Thu, 16 Nov 2023 14:48:13 +0100 Subject: [PATCH 14/16] Keep API compatibility --- .../enigma/command/MappingCommandsUtil.java | 21 ++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/enigma-cli/src/main/java/cuchaz/enigma/command/MappingCommandsUtil.java b/enigma-cli/src/main/java/cuchaz/enigma/command/MappingCommandsUtil.java index 2c6c9fdb8..3a00aecbb 100644 --- a/enigma-cli/src/main/java/cuchaz/enigma/command/MappingCommandsUtil.java +++ b/enigma-cli/src/main/java/cuchaz/enigma/command/MappingCommandsUtil.java @@ -1,6 +1,7 @@ package cuchaz.enigma.command; import java.io.IOException; +import java.io.UncheckedIOException; import java.nio.file.Files; import java.nio.file.Path; @@ -47,7 +48,7 @@ public static EntryTree read(String type, Path path, MappingSavePa throw new IllegalArgumentException("no reader for " + type); } - public static void write(EntryTree mappings, String type, Path path, MappingSaveParameters saveParameters) throws IOException { + public static void write(EntryTree mappings, String type, Path path, MappingSaveParameters saveParameters) { if (type.equals("enigma")) { MappingFormat.ENIGMA_DIRECTORY.write(mappings, path, ProgressListener.none(), saveParameters); return; @@ -64,9 +65,14 @@ public static void write(EntryTree mappings, String type, Path pat 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); + } - VisitableMappingTree tree = MappingIoConverter.toMappingIo(mappings, ProgressListener.none(), split[1], split[2]); - tree.accept(MappingWriter.create(path, net.fabricmc.mappingio.format.MappingFormat.TINY_2_FILE)); return; } @@ -82,8 +88,13 @@ public static void write(EntryTree mappings, String type, Path pat return; } - VisitableMappingTree tree = MappingIoConverter.toMappingIo(mappings, ProgressListener.none(), split[1], split[2]); - tree.accept(MappingWriter.create(path, net.fabricmc.mappingio.format.MappingFormat.TINY_FILE)); + 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; } From 2d365a382db47a3503fb8007b16887d412eaa8dd Mon Sep 17 00:00:00 2001 From: NebelNidas Date: Thu, 16 Nov 2023 14:57:22 +0100 Subject: [PATCH 15/16] Mark MIO-related methods as internal --- .../enigma/translation/mapping/serde/MappingFormat.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/enigma/src/main/java/cuchaz/enigma/translation/mapping/serde/MappingFormat.java b/enigma/src/main/java/cuchaz/enigma/translation/mapping/serde/MappingFormat.java index 88f722c9e..4521591ec 100644 --- a/enigma/src/main/java/cuchaz/enigma/translation/mapping/serde/MappingFormat.java +++ b/enigma/src/main/java/cuchaz/enigma/translation/mapping/serde/MappingFormat.java @@ -13,6 +13,7 @@ import net.fabricmc.mappingio.tree.MemoryMappingTree; import net.fabricmc.mappingio.tree.VisitOrder; import net.fabricmc.mappingio.tree.VisitableMappingTree; +import org.jetbrains.annotations.ApiStatus; import cuchaz.enigma.ProgressListener; import cuchaz.enigma.analysis.index.JarIndex; @@ -126,10 +127,12 @@ public MappingsReader getReader() { } @Nullable + @ApiStatus.Internal public net.fabricmc.mappingio.format.MappingFormat getMappingIoCounterpart() { return mappingIoCounterpart; } + @ApiStatus.Internal public boolean hasMappingIoWriter() { return hasMappingIoWriter; } @@ -142,6 +145,7 @@ public boolean isWritable() { return writer != null || hasMappingIoWriter; } + @ApiStatus.Internal private boolean useMappingIo() { if (mappingIoCounterpart == null) return false; return System.getProperty("enigma.use_mappingio", "true").equals("true"); From 1d89bed16bd708bdc5ad8921b7a6f0b7a5e7de83 Mon Sep 17 00:00:00 2001 From: NebelNidas Date: Thu, 16 Nov 2023 14:57:32 +0100 Subject: [PATCH 16/16] Fix checkstyle --- .../main/java/cuchaz/enigma/command/MappingCommandsUtil.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/enigma-cli/src/main/java/cuchaz/enigma/command/MappingCommandsUtil.java b/enigma-cli/src/main/java/cuchaz/enigma/command/MappingCommandsUtil.java index 3a00aecbb..e1e216a5c 100644 --- a/enigma-cli/src/main/java/cuchaz/enigma/command/MappingCommandsUtil.java +++ b/enigma-cli/src/main/java/cuchaz/enigma/command/MappingCommandsUtil.java @@ -65,7 +65,7 @@ public static void write(EntryTree mappings, String type, Path pat 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));