summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar Thomas Guillemard2016-08-12 19:23:54 +0200
committerGravatar Adrian Siekierka2016-08-12 19:23:54 +0200
commitc4970cc4addedd4565cf8c3ed9ea92b6a4487e0c (patch)
treea6f00a59cd0d5bc41014768506d9c4d3aad48de8
parentAllow exporting mappings as SRG or Enigma (diff)
downloadenigma-c4970cc4addedd4565cf8c3ed9ea92b6a4487e0c.tar.gz
enigma-c4970cc4addedd4565cf8c3ed9ea92b6a4487e0c.tar.xz
enigma-c4970cc4addedd4565cf8c3ed9ea92b6a4487e0c.zip
Implement Enigma directory format (#1)
Others changes: ~ Rework File menu ~ Force UTF-8 for all I/O operations ~ Enigma now detect the original file format and use the correct one when you save a mapping
-rw-r--r--src/main/java/cuchaz/enigma/CommandMain.java4
-rw-r--r--src/main/java/cuchaz/enigma/Deobfuscator.java3
-rw-r--r--src/main/java/cuchaz/enigma/Main.java2
-rw-r--r--src/main/java/cuchaz/enigma/bytecode/accessors/ConstInfoAccessor.java7
-rw-r--r--src/main/java/cuchaz/enigma/gui/Gui.java33
-rw-r--r--src/main/java/cuchaz/enigma/gui/GuiController.java35
-rw-r--r--src/main/java/cuchaz/enigma/gui/elements/MenuBar.java85
-rw-r--r--src/main/java/cuchaz/enigma/gui/filechooser/FileChooserAny.java11
-rw-r--r--src/main/java/cuchaz/enigma/mapping/Mappings.java19
-rw-r--r--src/main/java/cuchaz/enigma/mapping/MappingsEnigmaReader.java (renamed from src/main/java/cuchaz/enigma/mapping/MappingsReaderOld.java)48
-rw-r--r--src/main/java/cuchaz/enigma/mapping/MappingsEnigmaWriter.java (renamed from src/main/java/cuchaz/enigma/mapping/MappingsOldWriter.java)61
-rw-r--r--src/main/java/cuchaz/enigma/mapping/MappingsJsonReader.java (renamed from src/main/java/cuchaz/enigma/mapping/MappingsReader.java)13
-rw-r--r--src/main/java/cuchaz/enigma/mapping/MappingsJsonWriter.java (renamed from src/main/java/cuchaz/enigma/mapping/MappingsWriter.java)9
-rw-r--r--src/main/java/cuchaz/enigma/mapping/MappingsSRGWriter.java7
-rw-r--r--src/test/java/cuchaz/enigma/TestTranslator.java10
15 files changed, 238 insertions, 109 deletions
diff --git a/src/main/java/cuchaz/enigma/CommandMain.java b/src/main/java/cuchaz/enigma/CommandMain.java
index d7967b46..4e3f4479 100644
--- a/src/main/java/cuchaz/enigma/CommandMain.java
+++ b/src/main/java/cuchaz/enigma/CommandMain.java
@@ -15,7 +15,7 @@ import java.util.jar.JarFile;
15 15
16import cuchaz.enigma.Deobfuscator.ProgressListener; 16import cuchaz.enigma.Deobfuscator.ProgressListener;
17import cuchaz.enigma.mapping.Mappings; 17import cuchaz.enigma.mapping.Mappings;
18import cuchaz.enigma.mapping.MappingsReader; 18import cuchaz.enigma.mapping.MappingsJsonReader;
19 19
20public class CommandMain { 20public class CommandMain {
21 21
@@ -119,7 +119,7 @@ public class CommandMain {
119 Deobfuscator deobfuscator = new Deobfuscator(jar); 119 Deobfuscator deobfuscator = new Deobfuscator(jar);
120 if (fileMappings != null) { 120 if (fileMappings != null) {
121 System.out.println("Reading mappings..."); 121 System.out.println("Reading mappings...");
122 Mappings mappings = new MappingsReader().read(fileMappings); 122 Mappings mappings = new MappingsJsonReader().read(fileMappings);
123 deobfuscator.setMappings(mappings); 123 deobfuscator.setMappings(mappings);
124 } 124 }
125 return deobfuscator; 125 return deobfuscator;
diff --git a/src/main/java/cuchaz/enigma/Deobfuscator.java b/src/main/java/cuchaz/enigma/Deobfuscator.java
index d22260fb..8cd80bef 100644
--- a/src/main/java/cuchaz/enigma/Deobfuscator.java
+++ b/src/main/java/cuchaz/enigma/Deobfuscator.java
@@ -10,6 +10,7 @@
10 ******************************************************************************/ 10 ******************************************************************************/
11package cuchaz.enigma; 11package cuchaz.enigma;
12 12
13import com.google.common.base.Charsets;
13import com.google.common.collect.Maps; 14import com.google.common.collect.Maps;
14import com.google.common.collect.Sets; 15import com.google.common.collect.Sets;
15 16
@@ -277,7 +278,7 @@ public class Deobfuscator {
277 // write the file 278 // write the file
278 File file = new File(dirOut, deobfClassEntry.getName().replace('.', '/') + ".java"); 279 File file = new File(dirOut, deobfClassEntry.getName().replace('.', '/') + ".java");
279 file.getParentFile().mkdirs(); 280 file.getParentFile().mkdirs();
280 try (FileWriter out = new FileWriter(file)) { 281 try (OutputStreamWriter out = new OutputStreamWriter(new FileOutputStream(file), Charsets.UTF_8)) {
281 out.write(source); 282 out.write(source);
282 } 283 }
283 } catch (Throwable t) { 284 } catch (Throwable t) {
diff --git a/src/main/java/cuchaz/enigma/Main.java b/src/main/java/cuchaz/enigma/Main.java
index d52e390a..0be1d90c 100644
--- a/src/main/java/cuchaz/enigma/Main.java
+++ b/src/main/java/cuchaz/enigma/Main.java
@@ -28,7 +28,7 @@ public class Main {
28 gui.getController().openJar(new JarFile(getFile(args[0]))); 28 gui.getController().openJar(new JarFile(getFile(args[0])));
29 } 29 }
30 if (args.length >= 2) { 30 if (args.length >= 2) {
31 gui.getController().openMappings(getFile(args[1])); 31 gui.getController().openJsonMappings(getFile(args[1]));
32 } 32 }
33 33
34 // DEBUG 34 // DEBUG
diff --git a/src/main/java/cuchaz/enigma/bytecode/accessors/ConstInfoAccessor.java b/src/main/java/cuchaz/enigma/bytecode/accessors/ConstInfoAccessor.java
index 0ea2d02b..474a3ef0 100644
--- a/src/main/java/cuchaz/enigma/bytecode/accessors/ConstInfoAccessor.java
+++ b/src/main/java/cuchaz/enigma/bytecode/accessors/ConstInfoAccessor.java
@@ -11,10 +11,13 @@
11package cuchaz.enigma.bytecode.accessors; 11package cuchaz.enigma.bytecode.accessors;
12 12
13import java.io.ByteArrayOutputStream; 13import java.io.ByteArrayOutputStream;
14import java.io.FileOutputStream;
15import java.io.OutputStreamWriter;
14import java.io.PrintWriter; 16import java.io.PrintWriter;
15import java.lang.reflect.Field; 17import java.lang.reflect.Field;
16import java.lang.reflect.Method; 18import java.lang.reflect.Method;
17 19
20import com.google.common.base.Charsets;
18import cuchaz.enigma.bytecode.InfoType; 21import cuchaz.enigma.bytecode.InfoType;
19 22
20public class ConstInfoAccessor { 23public class ConstInfoAccessor {
@@ -56,12 +59,12 @@ public class ConstInfoAccessor {
56 public String toString() { 59 public String toString() {
57 try { 60 try {
58 ByteArrayOutputStream buf = new ByteArrayOutputStream(); 61 ByteArrayOutputStream buf = new ByteArrayOutputStream();
59 PrintWriter out = new PrintWriter(buf); 62 PrintWriter out = new PrintWriter(new OutputStreamWriter(buf, Charsets.UTF_8));
60 Method print = this.item.getClass().getMethod("print", PrintWriter.class); 63 Method print = this.item.getClass().getMethod("print", PrintWriter.class);
61 print.setAccessible(true); 64 print.setAccessible(true);
62 print.invoke(this.item, out); 65 print.invoke(this.item, out);
63 out.close(); 66 out.close();
64 return buf.toString().replace("\n", ""); 67 return buf.toString("UTF-8").replace("\n", "");
65 } catch (Exception ex) { 68 } catch (Exception ex) {
66 throw new Error(ex); 69 throw new Error(ex);
67 } 70 }
diff --git a/src/main/java/cuchaz/enigma/gui/Gui.java b/src/main/java/cuchaz/enigma/gui/Gui.java
index 5b0b599f..22694760 100644
--- a/src/main/java/cuchaz/enigma/gui/Gui.java
+++ b/src/main/java/cuchaz/enigma/gui/Gui.java
@@ -34,6 +34,7 @@ import cuchaz.enigma.analysis.*;
34import cuchaz.enigma.gui.dialog.CrashDialog; 34import cuchaz.enigma.gui.dialog.CrashDialog;
35import cuchaz.enigma.gui.elements.MenuBar; 35import cuchaz.enigma.gui.elements.MenuBar;
36import cuchaz.enigma.gui.elements.PopupMenuBar; 36import cuchaz.enigma.gui.elements.PopupMenuBar;
37import cuchaz.enigma.gui.filechooser.FileChooserAny;
37import cuchaz.enigma.gui.filechooser.FileChooserFile; 38import cuchaz.enigma.gui.filechooser.FileChooserFile;
38import cuchaz.enigma.gui.filechooser.FileChooserFolder; 39import cuchaz.enigma.gui.filechooser.FileChooserFolder;
39import cuchaz.enigma.gui.highlight.DeobfuscatedHighlightPainter; 40import cuchaz.enigma.gui.highlight.DeobfuscatedHighlightPainter;
@@ -78,8 +79,8 @@ public class Gui {
78 public EntryReference<Entry, Entry> m_reference; 79 public EntryReference<Entry, Entry> m_reference;
79 80
80 public JFileChooser jarFileChooser; 81 public JFileChooser jarFileChooser;
81 public JFileChooser mappingsFileChooser; 82 public JFileChooser jsonMappingsFileChooser;
82 public JFileChooser oldMappingsFileChooser; 83 public JFileChooser enigmaMappingsFileChooser;
83 84
84 public JFileChooser exportSourceFileChooser; 85 public JFileChooser exportSourceFileChooser;
85 public JFileChooser exportJarFileChooser; 86 public JFileChooser exportJarFileChooser;
@@ -106,10 +107,10 @@ public class Gui {
106 107
107 // init file choosers 108 // init file choosers
108 this.jarFileChooser = new FileChooserFile(); 109 this.jarFileChooser = new FileChooserFile();
109 this.mappingsFileChooser = new FileChooserFolder(); 110 this.jsonMappingsFileChooser = new FileChooserFolder();
110 111
111 112
112 this.oldMappingsFileChooser = new FileChooserFile(); 113 this.enigmaMappingsFileChooser = new FileChooserAny();
113 this.exportSourceFileChooser = new FileChooserFolder(); 114 this.exportSourceFileChooser = new FileChooserFolder();
114 this.exportJarFileChooser = new FileChooserFile(); 115 this.exportJarFileChooser = new FileChooserFile();
115 116
@@ -315,11 +316,12 @@ public class Gui {
315 316
316 // update menu 317 // update menu
317 this.menuBar.closeJarMenu.setEnabled(true); 318 this.menuBar.closeJarMenu.setEnabled(true);
318 this.menuBar.openOldMappingsMenu.setEnabled(true); 319 this.menuBar.openEnigmaMappingsMenu.setEnabled(true);
319 this.menuBar.openMappingsMenu.setEnabled(true); 320 this.menuBar.openMappingsJsonMenu.setEnabled(true);
320 this.menuBar.saveMappingsMenu.setEnabled(false); 321 this.menuBar.saveMappingsMenu.setEnabled(false);
321 this.menuBar.saveMappingsAsMenu.setEnabled(true); 322 this.menuBar.saveMappingsJsonMenu.setEnabled(true);
322 this.menuBar.saveMappingsOldMenu.setEnabled(true); 323 this.menuBar.saveMappingEnigmaFileMenu.setEnabled(true);
324 this.menuBar.saveMappingEnigmaDirectoryMenu.setEnabled(true);
323 this.menuBar.saveMappingsSrgMenu.setEnabled(true); 325 this.menuBar.saveMappingsSrgMenu.setEnabled(true);
324 this.menuBar.closeMappingsMenu.setEnabled(true); 326 this.menuBar.closeMappingsMenu.setEnabled(true);
325 this.menuBar.exportSourceMenu.setEnabled(true); 327 this.menuBar.exportSourceMenu.setEnabled(true);
@@ -338,11 +340,12 @@ public class Gui {
338 340
339 // update menu 341 // update menu
340 this.menuBar.closeJarMenu.setEnabled(false); 342 this.menuBar.closeJarMenu.setEnabled(false);
341 this.menuBar.openOldMappingsMenu.setEnabled(false); 343 this.menuBar.openEnigmaMappingsMenu.setEnabled(false);
342 this.menuBar.openMappingsMenu.setEnabled(false); 344 this.menuBar.openMappingsJsonMenu.setEnabled(false);
343 this.menuBar.saveMappingsMenu.setEnabled(false); 345 this.menuBar.saveMappingsMenu.setEnabled(false);
344 this.menuBar.saveMappingsAsMenu.setEnabled(false); 346 this.menuBar.saveMappingsJsonMenu.setEnabled(false);
345 this.menuBar.saveMappingsOldMenu.setEnabled(false); 347 this.menuBar.saveMappingEnigmaFileMenu.setEnabled(false);
348 this.menuBar.saveMappingEnigmaDirectoryMenu.setEnabled(false);
346 this.menuBar.saveMappingsSrgMenu.setEnabled(false); 349 this.menuBar.saveMappingsSrgMenu.setEnabled(false);
347 this.menuBar.closeMappingsMenu.setEnabled(false); 350 this.menuBar.closeMappingsMenu.setEnabled(false);
348 this.menuBar.exportSourceMenu.setEnabled(false); 351 this.menuBar.exportSourceMenu.setEnabled(false);
@@ -360,7 +363,7 @@ public class Gui {
360 } 363 }
361 364
362 public void setMappingsFile(File file) { 365 public void setMappingsFile(File file) {
363 this.mappingsFileChooser.setSelectedFile(file); 366 this.jsonMappingsFileChooser.setSelectedFile(file);
364 this.menuBar.saveMappingsMenu.setEnabled(file != null); 367 this.menuBar.saveMappingsMenu.setEnabled(file != null);
365 } 368 }
366 369
@@ -721,9 +724,9 @@ public class Gui {
721 JOptionPane.QUESTION_MESSAGE, null, options, options[2]); 724 JOptionPane.QUESTION_MESSAGE, null, options, options[2]);
722 switch (response) { 725 switch (response) {
723 case JOptionPane.YES_OPTION: // save and exit 726 case JOptionPane.YES_OPTION: // save and exit
724 if (this.mappingsFileChooser.getSelectedFile() != null || this.mappingsFileChooser.showSaveDialog(this.frame) == JFileChooser.APPROVE_OPTION) { 727 if (this.jsonMappingsFileChooser.getSelectedFile() != null || this.jsonMappingsFileChooser.showSaveDialog(this.frame) == JFileChooser.APPROVE_OPTION) {
725 try { 728 try {
726 this.controller.saveMappings(this.mappingsFileChooser.getCurrentDirectory()); 729 this.controller.saveMappings(this.jsonMappingsFileChooser.getCurrentDirectory());
727 this.frame.dispose(); 730 this.frame.dispose();
728 } catch (IOException ex) { 731 } catch (IOException ex) {
729 throw new Error(ex); 732 throw new Error(ex);
diff --git a/src/main/java/cuchaz/enigma/gui/GuiController.java b/src/main/java/cuchaz/enigma/gui/GuiController.java
index fe7d0978..d416345b 100644
--- a/src/main/java/cuchaz/enigma/gui/GuiController.java
+++ b/src/main/java/cuchaz/enigma/gui/GuiController.java
@@ -16,7 +16,6 @@ import com.google.common.collect.Queues;
16import com.strobel.decompiler.languages.java.ast.CompilationUnit; 16import com.strobel.decompiler.languages.java.ast.CompilationUnit;
17 17
18import java.io.File; 18import java.io.File;
19import java.io.FileReader;
20import java.io.FileWriter; 19import java.io.FileWriter;
21import java.io.IOException; 20import java.io.IOException;
22import java.util.Collection; 21import java.util.Collection;
@@ -65,18 +64,16 @@ public class GuiController {
65 this.gui.onCloseJar(); 64 this.gui.onCloseJar();
66 } 65 }
67 66
68 public void openOldMappings(File file) throws IOException, MappingParseException { 67 public void openEnigmaMappings(File file) throws IOException, MappingParseException {
69 FileReader in = new FileReader(file); 68 this.deobfuscator.setMappings(new MappingsEnigmaReader().read(file));
70 this.deobfuscator.setMappings(new MappingsReaderOld().read(in));
71 in.close();
72 this.isDirty = false; 69 this.isDirty = false;
73 this.gui.setMappingsFile(file); 70 this.gui.setMappingsFile(file);
74 refreshClasses(); 71 refreshClasses();
75 refreshCurrentClass(); 72 refreshCurrentClass();
76 } 73 }
77 74
78 public void openMappings(File file) throws IOException { 75 public void openJsonMappings(File file) throws IOException {
79 this.deobfuscator.setMappings(new MappingsReader().read(file)); 76 this.deobfuscator.setMappings(new MappingsJsonReader().read(file));
80 this.isDirty = false; 77 this.isDirty = false;
81 this.gui.setMappingsFile(file); 78 this.gui.setMappingsFile(file);
82 refreshClasses(); 79 refreshClasses();
@@ -84,13 +81,29 @@ public class GuiController {
84 } 81 }
85 82
86 public void saveMappings(File file) throws IOException { 83 public void saveMappings(File file) throws IOException {
87 new MappingsWriter().write(file, this.deobfuscator.getMappings()); 84 Mappings mappings = this.deobfuscator.getMappings();
85 switch (mappings.getOriginMappingFormat())
86 {
87 case SRG_FILE:
88 saveSRGMappings(file);
89 break;
90 case JSON_DIRECTORY:
91 saveJsonMappings(file);
92 break;
93 default:
94 saveEnigmaMappings(file, Mappings.FormatType.ENIGMA_FILE != mappings.getOriginMappingFormat());
95 break;
96 }
97
98 }
99
100 public void saveJsonMappings(File file) throws IOException {
101 new MappingsJsonWriter().write(file, this.deobfuscator.getMappings());
88 this.isDirty = false; 102 this.isDirty = false;
89 } 103 }
90 104
91 public void saveOldMappings(File file) throws IOException { 105 public void saveEnigmaMappings(File file, boolean isDirectoryFormat) throws IOException {
92 FileWriter out = new FileWriter(file); 106 new MappingsEnigmaWriter().write(file, this.deobfuscator.getMappings(), isDirectoryFormat);
93 new MappingsOldWriter().write(out, this.deobfuscator.getMappings());
94 this.isDirty = false; 107 this.isDirty = false;
95 } 108 }
96 109
diff --git a/src/main/java/cuchaz/enigma/gui/elements/MenuBar.java b/src/main/java/cuchaz/enigma/gui/elements/MenuBar.java
index e79476bb..e988d74c 100644
--- a/src/main/java/cuchaz/enigma/gui/elements/MenuBar.java
+++ b/src/main/java/cuchaz/enigma/gui/elements/MenuBar.java
@@ -17,12 +17,13 @@ public class MenuBar extends JMenuBar {
17 17
18 public final JMenuItem closeJarMenu; 18 public final JMenuItem closeJarMenu;
19 19
20 public final JMenuItem openMappingsMenu; 20 public final JMenuItem openMappingsJsonMenu;
21 public final JMenuItem openOldMappingsMenu; 21 public final JMenuItem openEnigmaMappingsMenu;
22 22
23 public final JMenuItem saveMappingsMenu; 23 public final JMenuItem saveMappingsMenu;
24 public final JMenuItem saveMappingsAsMenu; 24 public final JMenuItem saveMappingsJsonMenu;
25 public final JMenuItem saveMappingsOldMenu; 25 public final JMenuItem saveMappingEnigmaFileMenu;
26 public final JMenuItem saveMappingEnigmaDirectoryMenu;
26 public final JMenuItem saveMappingsSrgMenu; 27 public final JMenuItem saveMappingsSrgMenu;
27 public final JMenuItem closeMappingsMenu; 28 public final JMenuItem closeMappingsMenu;
28 29
@@ -62,43 +63,44 @@ public class MenuBar extends JMenuBar {
62 this.closeJarMenu = item; 63 this.closeJarMenu = item;
63 } 64 }
64 menu.addSeparator(); 65 menu.addSeparator();
66 JMenu openMenu = new JMenu("Open Mappings...");
65 { 67 {
66 JMenuItem item = new JMenuItem("Open Mappings..."); 68 JMenuItem item = new JMenuItem("Enigma");
67 menu.add(item); 69 openMenu.add(item);
68 item.addActionListener(event -> { 70 item.addActionListener(event -> {
69 if (this.gui.mappingsFileChooser.showOpenDialog(this.gui.getFrame()) == JFileChooser.APPROVE_OPTION) { 71 if (this.gui.enigmaMappingsFileChooser.showOpenDialog(this.gui.getFrame()) == JFileChooser.APPROVE_OPTION) {
70 try { 72 try {
71 this.gui.getController().openMappings(this.gui.mappingsFileChooser.getSelectedFile()); 73 this.gui.getController().openEnigmaMappings(this.gui.enigmaMappingsFileChooser.getSelectedFile());
72 } catch (IOException ex) { 74 } catch (IOException ex) {
73 throw new Error(ex); 75 throw new Error(ex);
76 } catch (MappingParseException ex) {
77 JOptionPane.showMessageDialog(this.gui.getFrame(), ex.getMessage());
74 } 78 }
75 } 79 }
76 }); 80 });
77 this.openMappingsMenu = item; 81 this.openEnigmaMappingsMenu = item;
78 } 82 }
83 menu.add(openMenu);
79 { 84 {
80 JMenuItem item = new JMenuItem("Open Old Mappings..."); 85 JMenuItem item = new JMenuItem("JSON (directory)");
81 menu.add(item); 86 openMenu.add(item);
82 item.addActionListener(event -> { 87 item.addActionListener(event -> {
83 if (this.gui.oldMappingsFileChooser.showOpenDialog(this.gui.getFrame()) == JFileChooser.APPROVE_OPTION) { 88 if (this.gui.jsonMappingsFileChooser.showOpenDialog(this.gui.getFrame()) == JFileChooser.APPROVE_OPTION) {
84 try { 89 try {
85 this.gui.getController().openOldMappings(this.gui.oldMappingsFileChooser.getSelectedFile()); 90 this.gui.getController().openJsonMappings(this.gui.jsonMappingsFileChooser.getSelectedFile());
86 } catch (IOException ex) { 91 } catch (IOException ex) {
87 throw new Error(ex); 92 throw new Error(ex);
88 } catch (MappingParseException ex) {
89 JOptionPane.showMessageDialog(this.gui.getFrame(), ex.getMessage());
90 } 93 }
91 } 94 }
92 }); 95 });
93 this.openOldMappingsMenu = item; 96 this.openMappingsJsonMenu = item;
94 } 97 }
95 menu.addSeparator();
96 { 98 {
97 JMenuItem item = new JMenuItem("Save Mappings"); 99 JMenuItem item = new JMenuItem("Save Mappings");
98 menu.add(item); 100 menu.add(item);
99 item.addActionListener(event -> { 101 item.addActionListener(event -> {
100 try { 102 try {
101 this.gui.getController().saveMappings(this.gui.mappingsFileChooser.getSelectedFile()); 103 this.gui.getController().saveMappings(this.gui.jsonMappingsFileChooser.getSelectedFile());
102 } catch (IOException ex) { 104 } catch (IOException ex) {
103 throw new Error(ex); 105 throw new Error(ex);
104 } 106 }
@@ -106,29 +108,29 @@ public class MenuBar extends JMenuBar {
106 item.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_S, InputEvent.CTRL_DOWN_MASK)); 108 item.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_S, InputEvent.CTRL_DOWN_MASK));
107 this.saveMappingsMenu = item; 109 this.saveMappingsMenu = item;
108 } 110 }
111 JMenu saveMenu = new JMenu("Save Mappings As...");
109 { 112 {
110 JMenuItem item = new JMenuItem("Save Mappings As..."); 113 JMenuItem item = new JMenuItem("Enigma (single file)");
111 menu.add(item); 114 saveMenu.add(item);
112 item.addActionListener(event -> { 115 item.addActionListener(event -> {
113 if (this.gui.mappingsFileChooser.showSaveDialog(this.gui.getFrame()) == JFileChooser.APPROVE_OPTION) { 116 if (this.gui.jsonMappingsFileChooser.showSaveDialog(this.gui.getFrame()) == JFileChooser.APPROVE_OPTION) {
114 try { 117 try {
115 this.gui.getController().saveMappings(this.gui.mappingsFileChooser.getSelectedFile()); 118 this.gui.getController().saveEnigmaMappings(this.gui.jsonMappingsFileChooser.getSelectedFile(), false);
116 this.saveMappingsMenu.setEnabled(true); 119 this.saveMappingsMenu.setEnabled(true);
117 } catch (IOException ex) { 120 } catch (IOException ex) {
118 throw new Error(ex); 121 throw new Error(ex);
119 } 122 }
120 } 123 }
121 }); 124 });
122 item.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_S, InputEvent.CTRL_DOWN_MASK | InputEvent.SHIFT_DOWN_MASK)); 125 this.saveMappingEnigmaFileMenu = item;
123 this.saveMappingsAsMenu = item;
124 } 126 }
125 { 127 {
126 JMenuItem item = new JMenuItem("Save Mappings as Enigma"); 128 JMenuItem item = new JMenuItem("Enigma (directory)");
127 menu.add(item); 129 saveMenu.add(item);
128 item.addActionListener(event -> { 130 item.addActionListener(event -> {
129 if (this.gui.mappingsFileChooser.showSaveDialog(this.gui.getFrame()) == JFileChooser.APPROVE_OPTION) { 131 if (this.gui.jsonMappingsFileChooser.showSaveDialog(this.gui.getFrame()) == JFileChooser.APPROVE_OPTION) {
130 try { 132 try {
131 this.gui.getController().saveOldMappings(this.gui.mappingsFileChooser.getSelectedFile()); 133 this.gui.getController().saveEnigmaMappings(this.gui.jsonMappingsFileChooser.getSelectedFile(), true);
132 this.saveMappingsMenu.setEnabled(true); 134 this.saveMappingsMenu.setEnabled(true);
133 } catch (IOException ex) { 135 } catch (IOException ex) {
134 throw new Error(ex); 136 throw new Error(ex);
@@ -136,22 +138,37 @@ public class MenuBar extends JMenuBar {
136 } 138 }
137 }); 139 });
138 item.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_S, InputEvent.CTRL_DOWN_MASK | InputEvent.SHIFT_DOWN_MASK)); 140 item.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_S, InputEvent.CTRL_DOWN_MASK | InputEvent.SHIFT_DOWN_MASK));
139 this.saveMappingsOldMenu = item; 141 this.saveMappingEnigmaDirectoryMenu = item;
140 } 142 }
143 menu.add(saveMenu);
141 { 144 {
142 JMenuItem item = new JMenuItem("Save Mappings as SRG"); 145 JMenuItem item = new JMenuItem("JSON (directory)");
143 menu.add(item); 146 saveMenu.add(item);
144 item.addActionListener(event -> { 147 item.addActionListener(event -> {
145 if (this.gui.mappingsFileChooser.showSaveDialog(this.gui.getFrame()) == JFileChooser.APPROVE_OPTION) { 148 if (this.gui.jsonMappingsFileChooser.showSaveDialog(this.gui.getFrame()) == JFileChooser.APPROVE_OPTION) {
146 try { 149 try {
147 this.gui.getController().saveSRGMappings(this.gui.mappingsFileChooser.getSelectedFile()); 150 this.gui.getController().saveJsonMappings(this.gui.jsonMappingsFileChooser.getSelectedFile());
151 this.saveMappingsMenu.setEnabled(true);
152 } catch (IOException ex) {
153 throw new Error(ex);
154 }
155 }
156 });
157 this.saveMappingsJsonMenu = item;
158 }
159 {
160 JMenuItem item = new JMenuItem("SRG");
161 saveMenu.add(item);
162 item.addActionListener(event -> {
163 if (this.gui.jsonMappingsFileChooser.showSaveDialog(this.gui.getFrame()) == JFileChooser.APPROVE_OPTION) {
164 try {
165 this.gui.getController().saveSRGMappings(this.gui.jsonMappingsFileChooser.getSelectedFile());
148 this.saveMappingsMenu.setEnabled(true); 166 this.saveMappingsMenu.setEnabled(true);
149 } catch (IOException ex) { 167 } catch (IOException ex) {
150 throw new Error(ex); 168 throw new Error(ex);
151 } 169 }
152 } 170 }
153 }); 171 });
154 item.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_S, InputEvent.CTRL_DOWN_MASK | InputEvent.SHIFT_DOWN_MASK));
155 this.saveMappingsSrgMenu = item; 172 this.saveMappingsSrgMenu = item;
156 } 173 }
157 { 174 {
diff --git a/src/main/java/cuchaz/enigma/gui/filechooser/FileChooserAny.java b/src/main/java/cuchaz/enigma/gui/filechooser/FileChooserAny.java
new file mode 100644
index 00000000..23393347
--- /dev/null
+++ b/src/main/java/cuchaz/enigma/gui/filechooser/FileChooserAny.java
@@ -0,0 +1,11 @@
1package cuchaz.enigma.gui.filechooser;
2
3import javax.swing.*;
4
5public class FileChooserAny extends JFileChooser
6{
7 public FileChooserAny() {
8 this.setFileSelectionMode(JFileChooser.FILES_AND_DIRECTORIES);
9 this.setAcceptAllFileFilterUsed(false);
10 }
11} \ No newline at end of file
diff --git a/src/main/java/cuchaz/enigma/mapping/Mappings.java b/src/main/java/cuchaz/enigma/mapping/Mappings.java
index b51e1a4c..1f4ca02c 100644
--- a/src/main/java/cuchaz/enigma/mapping/Mappings.java
+++ b/src/main/java/cuchaz/enigma/mapping/Mappings.java
@@ -24,8 +24,15 @@ public class Mappings {
24 24
25 protected Map<String, ClassMapping> classesByObf; 25 protected Map<String, ClassMapping> classesByObf;
26 protected Map<String, ClassMapping> classesByDeobf; 26 protected Map<String, ClassMapping> classesByDeobf;
27 private final FormatType originMapping;
27 28
28 public Mappings() { 29 public Mappings()
30 {
31 this(FormatType.ENIGMA_DIRECTORY);
32 }
33
34 public Mappings(FormatType originMapping) {
35 this.originMapping = originMapping;
29 this.classesByObf = Maps.newHashMap(); 36 this.classesByObf = Maps.newHashMap();
30 this.classesByDeobf = Maps.newHashMap(); 37 this.classesByDeobf = Maps.newHashMap();
31 } 38 }
@@ -145,4 +152,14 @@ public class Mappings {
145 } 152 }
146 return mappingChain; 153 return mappingChain;
147 } 154 }
155
156 public FormatType getOriginMappingFormat()
157 {
158 return originMapping;
159 }
160
161 public enum FormatType
162 {
163 JSON_DIRECTORY, ENIGMA_FILE, ENIGMA_DIRECTORY, SRG_FILE
164 }
148} 165}
diff --git a/src/main/java/cuchaz/enigma/mapping/MappingsReaderOld.java b/src/main/java/cuchaz/enigma/mapping/MappingsEnigmaReader.java
index 776d9083..70f3f184 100644
--- a/src/main/java/cuchaz/enigma/mapping/MappingsReaderOld.java
+++ b/src/main/java/cuchaz/enigma/mapping/MappingsEnigmaReader.java
@@ -1,23 +1,49 @@
1package cuchaz.enigma.mapping; 1package cuchaz.enigma.mapping;
2 2
3import com.google.common.base.Charsets;
3import com.google.common.collect.Queues; 4import com.google.common.collect.Queues;
5import cuchaz.enigma.throwables.MappingConflict;
6import cuchaz.enigma.throwables.MappingParseException;
4 7
5import java.io.BufferedReader; 8import java.io.*;
6import java.io.IOException;
7import java.io.Reader;
8import java.util.Deque; 9import java.util.Deque;
9 10
10import cuchaz.enigma.throwables.MappingConflict; 11public class MappingsEnigmaReader
11import cuchaz.enigma.throwables.MappingParseException; 12{
12 13
13public class MappingsReaderOld { 14 public Mappings read(File file) throws IOException, MappingParseException {
15 Mappings mappings;
14 16
15 public Mappings read(Reader in) throws IOException, MappingParseException { 17 // Multiple file
16 return read(new BufferedReader(in)); 18 if (file.isDirectory())
19 {
20 mappings = new Mappings(Mappings.FormatType.ENIGMA_DIRECTORY);
21 readDirectory(mappings, file);
22 }
23 else
24 {
25 mappings = new Mappings();
26 readFile(mappings, new BufferedReader(new InputStreamReader(new FileInputStream(file), Charsets.UTF_8)));
27 }
28 return mappings;
17 } 29 }
18 30
19 public Mappings read(BufferedReader in) throws IOException, MappingParseException { 31 public void readDirectory(Mappings mappings, File directory) throws IOException, MappingParseException {
20 Mappings mappings = new Mappings(); 32 File[] files = directory.listFiles();
33 if (files != null) {
34 for (File file : files) {
35 if (file.isFile())
36 readFile(mappings, new BufferedReader(new InputStreamReader(new FileInputStream(file), Charsets.UTF_8)));
37 else if (file.isDirectory())
38 readDirectory(mappings, file.getAbsoluteFile());
39 }
40 }
41 else
42 throw new IOException("Cannot access directory" + directory.getAbsolutePath());
43 }
44
45 public Mappings readFile(Mappings mappings, BufferedReader in) throws IOException, MappingParseException {
46
21 Deque<Object> mappingStack = Queues.newArrayDeque(); 47 Deque<Object> mappingStack = Queues.newArrayDeque();
22 48
23 int lineNumber = 0; 49 int lineNumber = 0;
@@ -96,7 +122,7 @@ public class MappingsReaderOld {
96 e.printStackTrace(); 122 e.printStackTrace();
97 } 123 }
98 } 124 }
99 125 in.close();
100 return mappings; 126 return mappings;
101 } 127 }
102 128
diff --git a/src/main/java/cuchaz/enigma/mapping/MappingsOldWriter.java b/src/main/java/cuchaz/enigma/mapping/MappingsEnigmaWriter.java
index 8b766a31..a3b0616e 100644
--- a/src/main/java/cuchaz/enigma/mapping/MappingsOldWriter.java
+++ b/src/main/java/cuchaz/enigma/mapping/MappingsEnigmaWriter.java
@@ -10,17 +10,66 @@
10 ******************************************************************************/ 10 ******************************************************************************/
11package cuchaz.enigma.mapping; 11package cuchaz.enigma.mapping;
12 12
13import java.io.IOException; 13import com.google.common.base.Charsets;
14import java.io.PrintWriter; 14
15import java.io.Writer; 15import java.io.*;
16import java.util.ArrayList; 16import java.util.ArrayList;
17import java.util.Collections; 17import java.util.Collections;
18import java.util.List; 18import java.util.List;
19 19
20public class MappingsOldWriter { 20public class MappingsEnigmaWriter {
21 21
22 public void write(Writer out, Mappings mappings) throws IOException { 22 public void write(File out, Mappings mappings, boolean isDirectoryFormat) throws IOException {
23 write(new PrintWriter(out), mappings); 23 if (!isDirectoryFormat)
24 {
25 PrintWriter outputWriter = new PrintWriter(new OutputStreamWriter(new FileOutputStream(out), Charsets.UTF_8));
26 write(outputWriter, mappings);
27 outputWriter.close();
28 }
29 else
30 writeAsDirectory(out, mappings);
31 }
32
33 public void writeAsDirectory(File target, Mappings mappings) throws IOException {
34 if (!target.exists() && !target.mkdirs())
35 throw new IOException("Cannot create mapping directory!");
36
37 for (ClassMapping classMapping : sorted(mappings.classes())) {
38 File obFile = new File(target, classMapping.getObfFullName() + ".mapping");
39 File result;
40 if (classMapping.getDeobfName() == null)
41 result = obFile;
42 else
43 {
44 // Make sure that old version of the file doesn't exist
45 if (obFile.exists())
46 obFile.delete();
47 result = new File(target, classMapping.getDeobfName() + ".mapping");
48 }
49
50 if (!result.getParentFile().exists())
51 result.getParentFile().mkdirs();
52 result.createNewFile();
53 PrintWriter outputWriter = new PrintWriter(new OutputStreamWriter(new FileOutputStream(result), Charsets.UTF_8));
54 write(outputWriter, classMapping, 0);
55 outputWriter.close();
56 }
57
58 // Remove empty directories
59 File[] fileList = target.listFiles();
60 if (fileList != null)
61 {
62 for (File file : fileList)
63 {
64 if (file.isDirectory())
65 {
66 File[] childFiles = file.listFiles();
67 if (childFiles != null && childFiles.length == 0)
68 file.delete();
69 }
70 }
71 }
72
24 } 73 }
25 74
26 public void write(PrintWriter out, Mappings mappings) throws IOException { 75 public void write(PrintWriter out, Mappings mappings) throws IOException {
diff --git a/src/main/java/cuchaz/enigma/mapping/MappingsReader.java b/src/main/java/cuchaz/enigma/mapping/MappingsJsonReader.java
index b2b6d09c..8f5bde33 100644
--- a/src/main/java/cuchaz/enigma/mapping/MappingsReader.java
+++ b/src/main/java/cuchaz/enigma/mapping/MappingsJsonReader.java
@@ -10,22 +10,20 @@
10 ******************************************************************************/ 10 ******************************************************************************/
11package cuchaz.enigma.mapping; 11package cuchaz.enigma.mapping;
12 12
13import com.google.common.base.Charsets;
13import com.google.common.io.Files; 14import com.google.common.io.Files;
14import com.google.gson.Gson; 15import com.google.gson.Gson;
15import com.google.gson.GsonBuilder; 16import com.google.gson.GsonBuilder;
16 17
17import java.io.BufferedReader; 18import java.io.*;
18import java.io.File;
19import java.io.FileReader;
20import java.io.IOException;
21 19
22import cuchaz.enigma.json.JsonClass; 20import cuchaz.enigma.json.JsonClass;
23import cuchaz.enigma.throwables.MappingConflict; 21import cuchaz.enigma.throwables.MappingConflict;
24 22
25public class MappingsReader { 23public class MappingsJsonReader {
26 24
27 public Mappings read(File in) throws IOException { 25 public Mappings read(File in) throws IOException {
28 Mappings mappings = new Mappings(); 26 Mappings mappings = new Mappings(Mappings.FormatType.JSON_DIRECTORY);
29 readDirectory(mappings, in); 27 readDirectory(mappings, in);
30 return mappings; 28 return mappings;
31 } 29 }
@@ -35,7 +33,8 @@ public class MappingsReader {
35 if (fList != null) { 33 if (fList != null) {
36 for (File file : fList) { 34 for (File file : fList) {
37 if (file.isFile() && Files.getFileExtension(file.getName()).equalsIgnoreCase("json")) { 35 if (file.isFile() && Files.getFileExtension(file.getName()).equalsIgnoreCase("json")) {
38 readFile(mappings, new BufferedReader(new FileReader(file))); 36 readFile(mappings, new BufferedReader(new InputStreamReader(new FileInputStream(file),
37 Charsets.UTF_8)));
39 } else if (file.isDirectory()) { 38 } else if (file.isDirectory()) {
40 readDirectory(mappings, file.getAbsoluteFile()); 39 readDirectory(mappings, file.getAbsoluteFile());
41 } 40 }
diff --git a/src/main/java/cuchaz/enigma/mapping/MappingsWriter.java b/src/main/java/cuchaz/enigma/mapping/MappingsJsonWriter.java
index 47931662..db95322b 100644
--- a/src/main/java/cuchaz/enigma/mapping/MappingsWriter.java
+++ b/src/main/java/cuchaz/enigma/mapping/MappingsJsonWriter.java
@@ -10,19 +10,18 @@
10 ******************************************************************************/ 10 ******************************************************************************/
11package cuchaz.enigma.mapping; 11package cuchaz.enigma.mapping;
12 12
13import com.google.common.base.Charsets;
13import com.google.gson.Gson; 14import com.google.gson.Gson;
14import com.google.gson.GsonBuilder; 15import com.google.gson.GsonBuilder;
15 16
16import java.io.File; 17import java.io.*;
17import java.io.FileWriter;
18import java.io.IOException;
19import java.util.ArrayList; 18import java.util.ArrayList;
20import java.util.Collections; 19import java.util.Collections;
21import java.util.List; 20import java.util.List;
22 21
23import cuchaz.enigma.json.*; 22import cuchaz.enigma.json.*;
24 23
25public class MappingsWriter { 24public class MappingsJsonWriter {
26 25
27 public void write(File file, Mappings mappings) throws IOException { 26 public void write(File file, Mappings mappings) throws IOException {
28 if (!file.isDirectory()) { 27 if (!file.isDirectory()) {
@@ -44,7 +43,7 @@ public class MappingsWriter {
44 File f = new File(file, jsonClass.getName() + ".json"); 43 File f = new File(file, jsonClass.getName() + ".json");
45 f.getParentFile().mkdirs(); 44 f.getParentFile().mkdirs();
46 f.createNewFile(); 45 f.createNewFile();
47 FileWriter writer = new FileWriter(f); 46 PrintWriter writer = new PrintWriter(new OutputStreamWriter(new FileOutputStream(f), Charsets.UTF_8));
48 writer.write(gson.toJson(jsonClass)); 47 writer.write(gson.toJson(jsonClass));
49 writer.close(); 48 writer.close();
50 } 49 }
diff --git a/src/main/java/cuchaz/enigma/mapping/MappingsSRGWriter.java b/src/main/java/cuchaz/enigma/mapping/MappingsSRGWriter.java
index 64da7091..a05b9158 100644
--- a/src/main/java/cuchaz/enigma/mapping/MappingsSRGWriter.java
+++ b/src/main/java/cuchaz/enigma/mapping/MappingsSRGWriter.java
@@ -1,10 +1,9 @@
1package cuchaz.enigma.mapping; 1package cuchaz.enigma.mapping;
2 2
3import com.google.common.base.Charsets;
3import cuchaz.enigma.Deobfuscator; 4import cuchaz.enigma.Deobfuscator;
4 5
5import java.io.File; 6import java.io.*;
6import java.io.FileWriter;
7import java.io.IOException;
8import java.util.ArrayList; 7import java.util.ArrayList;
9import java.util.Collections; 8import java.util.Collections;
10import java.util.List; 9import java.util.List;
@@ -22,7 +21,7 @@ public class MappingsSRGWriter {
22 21
23 Mappings mappings = deobfuscator.getMappings(); 22 Mappings mappings = deobfuscator.getMappings();
24 23
25 FileWriter writer = new FileWriter(file); 24 PrintWriter writer = new PrintWriter(new OutputStreamWriter(new FileOutputStream(file), Charsets.UTF_8));
26 List<String> fieldMappings = new ArrayList<>(); 25 List<String> fieldMappings = new ArrayList<>();
27 List<String> methodMappings = new ArrayList<>(); 26 List<String> methodMappings = new ArrayList<>();
28 for (ClassMapping classMapping : sorted(mappings.classes())) { 27 for (ClassMapping classMapping : sorted(mappings.classes())) {
diff --git a/src/test/java/cuchaz/enigma/TestTranslator.java b/src/test/java/cuchaz/enigma/TestTranslator.java
index dcdced01..dddfb704 100644
--- a/src/test/java/cuchaz/enigma/TestTranslator.java
+++ b/src/test/java/cuchaz/enigma/TestTranslator.java
@@ -11,20 +11,12 @@
11package cuchaz.enigma; 11package cuchaz.enigma;
12 12
13import static cuchaz.enigma.TestEntryFactory.*; 13import static cuchaz.enigma.TestEntryFactory.*;
14import static org.hamcrest.MatcherAssert.*;
15import static org.hamcrest.Matchers.*;
16
17import java.io.InputStream;
18import java.io.InputStreamReader;
19import java.util.jar.JarFile;
20 14
21import org.junit.BeforeClass; 15import org.junit.BeforeClass;
22import org.junit.Test; 16import org.junit.Test;
23 17
24import cuchaz.enigma.mapping.Entry; 18import cuchaz.enigma.mapping.Entry;
25import cuchaz.enigma.mapping.Mappings; 19import cuchaz.enigma.mapping.Mappings;
26import cuchaz.enigma.mapping.MappingsReader;
27import cuchaz.enigma.mapping.TranslationDirection;
28import cuchaz.enigma.mapping.Translator; 20import cuchaz.enigma.mapping.Translator;
29 21
30 22
@@ -41,7 +33,7 @@ public class TestTranslator {
41 //TODO FIx 33 //TODO FIx
42 //m_deobfuscator = new Deobfuscator(new JarFile("build/test-obf/translation.jar")); 34 //m_deobfuscator = new Deobfuscator(new JarFile("build/test-obf/translation.jar"));
43 //try (InputStream in = TestTranslator.class.getResourceAsStream("/cuchaz/enigma/resources/translation.mappings")) { 35 //try (InputStream in = TestTranslator.class.getResourceAsStream("/cuchaz/enigma/resources/translation.mappings")) {
44 // m_mappings = new MappingsReader().read(new InputStreamReader(in)); 36 // m_mappings = new MappingsJsonReader().read(new InputStreamReader(in));
45 // m_deobfuscator.setMappings(m_mappings); 37 // m_deobfuscator.setMappings(m_mappings);
46 // m_deobfTranslator = m_deobfuscator.getTranslator(TranslationDirection.Deobfuscating); 38 // m_deobfTranslator = m_deobfuscator.getTranslator(TranslationDirection.Deobfuscating);
47 // m_obfTranslator = m_deobfuscator.getTranslator(TranslationDirection.Obfuscating); 39 // m_obfTranslator = m_deobfuscator.getTranslator(TranslationDirection.Obfuscating);