From c4970cc4addedd4565cf8c3ed9ea92b6a4487e0c Mon Sep 17 00:00:00 2001 From: Thomas Guillemard Date: Fri, 12 Aug 2016 19:23:54 +0200 Subject: 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--- src/main/java/cuchaz/enigma/mapping/Mappings.java | 19 ++- .../enigma/mapping/MappingsEnigmaReader.java | 153 +++++++++++++++++++++ .../enigma/mapping/MappingsEnigmaWriter.java | 137 ++++++++++++++++++ .../cuchaz/enigma/mapping/MappingsJsonReader.java | 120 ++++++++++++++++ .../cuchaz/enigma/mapping/MappingsJsonWriter.java | 101 ++++++++++++++ .../cuchaz/enigma/mapping/MappingsOldWriter.java | 88 ------------ .../java/cuchaz/enigma/mapping/MappingsReader.java | 121 ---------------- .../cuchaz/enigma/mapping/MappingsReaderOld.java | 127 ----------------- .../cuchaz/enigma/mapping/MappingsSRGWriter.java | 7 +- .../java/cuchaz/enigma/mapping/MappingsWriter.java | 102 -------------- 10 files changed, 532 insertions(+), 443 deletions(-) create mode 100644 src/main/java/cuchaz/enigma/mapping/MappingsEnigmaReader.java create mode 100644 src/main/java/cuchaz/enigma/mapping/MappingsEnigmaWriter.java create mode 100644 src/main/java/cuchaz/enigma/mapping/MappingsJsonReader.java create mode 100644 src/main/java/cuchaz/enigma/mapping/MappingsJsonWriter.java delete mode 100644 src/main/java/cuchaz/enigma/mapping/MappingsOldWriter.java delete mode 100644 src/main/java/cuchaz/enigma/mapping/MappingsReader.java delete mode 100644 src/main/java/cuchaz/enigma/mapping/MappingsReaderOld.java delete mode 100644 src/main/java/cuchaz/enigma/mapping/MappingsWriter.java (limited to 'src/main/java/cuchaz/enigma/mapping') diff --git a/src/main/java/cuchaz/enigma/mapping/Mappings.java b/src/main/java/cuchaz/enigma/mapping/Mappings.java index b51e1a4..1f4ca02 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 { protected Map classesByObf; protected Map classesByDeobf; + private final FormatType originMapping; - public Mappings() { + public Mappings() + { + this(FormatType.ENIGMA_DIRECTORY); + } + + public Mappings(FormatType originMapping) { + this.originMapping = originMapping; this.classesByObf = Maps.newHashMap(); this.classesByDeobf = Maps.newHashMap(); } @@ -145,4 +152,14 @@ public class Mappings { } return mappingChain; } + + public FormatType getOriginMappingFormat() + { + return originMapping; + } + + public enum FormatType + { + JSON_DIRECTORY, ENIGMA_FILE, ENIGMA_DIRECTORY, SRG_FILE + } } diff --git a/src/main/java/cuchaz/enigma/mapping/MappingsEnigmaReader.java b/src/main/java/cuchaz/enigma/mapping/MappingsEnigmaReader.java new file mode 100644 index 0000000..70f3f18 --- /dev/null +++ b/src/main/java/cuchaz/enigma/mapping/MappingsEnigmaReader.java @@ -0,0 +1,153 @@ +package cuchaz.enigma.mapping; + +import com.google.common.base.Charsets; +import com.google.common.collect.Queues; +import cuchaz.enigma.throwables.MappingConflict; +import cuchaz.enigma.throwables.MappingParseException; + +import java.io.*; +import java.util.Deque; + +public class MappingsEnigmaReader +{ + + public Mappings read(File file) throws IOException, MappingParseException { + Mappings mappings; + + // Multiple file + if (file.isDirectory()) + { + mappings = new Mappings(Mappings.FormatType.ENIGMA_DIRECTORY); + readDirectory(mappings, file); + } + else + { + mappings = new Mappings(); + readFile(mappings, new BufferedReader(new InputStreamReader(new FileInputStream(file), Charsets.UTF_8))); + } + return mappings; + } + + public void readDirectory(Mappings mappings, File directory) throws IOException, MappingParseException { + File[] files = directory.listFiles(); + if (files != null) { + for (File file : files) { + if (file.isFile()) + readFile(mappings, new BufferedReader(new InputStreamReader(new FileInputStream(file), Charsets.UTF_8))); + else if (file.isDirectory()) + readDirectory(mappings, file.getAbsoluteFile()); + } + } + else + throw new IOException("Cannot access directory" + directory.getAbsolutePath()); + } + + public Mappings readFile(Mappings mappings, BufferedReader in) throws IOException, MappingParseException { + + Deque mappingStack = Queues.newArrayDeque(); + + int lineNumber = 0; + String line; + while ((line = in.readLine()) != null) { + lineNumber++; + + // strip comments + int commentPos = line.indexOf('#'); + if (commentPos >= 0) { + line = line.substring(0, commentPos); + } + + // skip blank lines + if (line.trim().length() <= 0) { + continue; + } + + // get the indent of this line + int indent = 0; + for (int i = 0; i < line.length(); i++) { + if (line.charAt(i) != '\t') { + break; + } + indent++; + } + + // handle stack pops + while (indent < mappingStack.size()) { + mappingStack.pop(); + } + + String[] parts = line.trim().split("\\s"); + try { + // read the first token + String token = parts[0]; + + if (token.equalsIgnoreCase("CLASS")) { + ClassMapping classMapping; + if (indent <= 0) { + // outer class + classMapping = readClass(parts); + mappings.addClassMapping(classMapping); + } else { + + // inner class + if (!(mappingStack.peek() instanceof ClassMapping)) { + throw new MappingParseException(lineNumber, "Unexpected CLASS entry here!"); + } + + classMapping = readClass(parts); + ((ClassMapping) mappingStack.peek()).addInnerClassMapping(classMapping); + } + mappingStack.push(classMapping); + } else if (token.equalsIgnoreCase("FIELD")) { + if (mappingStack.isEmpty() || !(mappingStack.peek() instanceof ClassMapping)) { + throw new MappingParseException(lineNumber, "Unexpected FIELD entry here!"); + } + ((ClassMapping) mappingStack.peek()).addFieldMapping(readField(parts)); + } else if (token.equalsIgnoreCase("METHOD")) { + if (mappingStack.isEmpty() || !(mappingStack.peek() instanceof ClassMapping)) { + throw new MappingParseException(lineNumber, "Unexpected METHOD entry here!"); + } + MethodMapping methodMapping = readMethod(parts); + ((ClassMapping) mappingStack.peek()).addMethodMapping(methodMapping); + mappingStack.push(methodMapping); + } else if (token.equalsIgnoreCase("ARG")) { + if (mappingStack.isEmpty() || !(mappingStack.peek() instanceof MethodMapping)) { + throw new MappingParseException(lineNumber, "Unexpected ARG entry here!"); + } + ((MethodMapping) mappingStack.peek()).addArgumentMapping(readArgument(parts)); + } + } catch (ArrayIndexOutOfBoundsException | IllegalArgumentException ex) { + throw new MappingParseException(lineNumber, "Malformed line:\n" + line); + } catch (MappingConflict e) { + e.printStackTrace(); + } + } + in.close(); + return mappings; + } + + private ArgumentMapping readArgument(String[] parts) { + return new ArgumentMapping(Integer.parseInt(parts[1]), parts[2]); + } + + private ClassMapping readClass(String[] parts) { + if (parts.length == 2) { + return new ClassMapping(parts[1]); + } else { + return new ClassMapping(parts[1], parts[2]); + } + } + + /* TEMP */ + protected FieldMapping readField(String[] parts) { + return new FieldMapping(parts[1], new Type(parts[3]), parts[2]); + } + + private MethodMapping readMethod(String[] parts) { + if (parts.length == 3) { + return new MethodMapping(parts[1], new Signature(parts[2])); + } else { + return new MethodMapping(parts[1], new Signature(parts[3]), parts[2]); + } + } +} diff --git a/src/main/java/cuchaz/enigma/mapping/MappingsEnigmaWriter.java b/src/main/java/cuchaz/enigma/mapping/MappingsEnigmaWriter.java new file mode 100644 index 0000000..a3b0616 --- /dev/null +++ b/src/main/java/cuchaz/enigma/mapping/MappingsEnigmaWriter.java @@ -0,0 +1,137 @@ +/******************************************************************************* + * Copyright (c) 2015 Jeff Martin. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the GNU Lesser General Public + * License v3.0 which accompanies this distribution, and is available at + * http://www.gnu.org/licenses/lgpl.html + * + * Contributors: + * Jeff Martin - initial API and implementation + ******************************************************************************/ +package cuchaz.enigma.mapping; + +import com.google.common.base.Charsets; + +import java.io.*; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +public class MappingsEnigmaWriter { + + public void write(File out, Mappings mappings, boolean isDirectoryFormat) throws IOException { + if (!isDirectoryFormat) + { + PrintWriter outputWriter = new PrintWriter(new OutputStreamWriter(new FileOutputStream(out), Charsets.UTF_8)); + write(outputWriter, mappings); + outputWriter.close(); + } + else + writeAsDirectory(out, mappings); + } + + public void writeAsDirectory(File target, Mappings mappings) throws IOException { + if (!target.exists() && !target.mkdirs()) + throw new IOException("Cannot create mapping directory!"); + + for (ClassMapping classMapping : sorted(mappings.classes())) { + File obFile = new File(target, classMapping.getObfFullName() + ".mapping"); + File result; + if (classMapping.getDeobfName() == null) + result = obFile; + else + { + // Make sure that old version of the file doesn't exist + if (obFile.exists()) + obFile.delete(); + result = new File(target, classMapping.getDeobfName() + ".mapping"); + } + + if (!result.getParentFile().exists()) + result.getParentFile().mkdirs(); + result.createNewFile(); + PrintWriter outputWriter = new PrintWriter(new OutputStreamWriter(new FileOutputStream(result), Charsets.UTF_8)); + write(outputWriter, classMapping, 0); + outputWriter.close(); + } + + // Remove empty directories + File[] fileList = target.listFiles(); + if (fileList != null) + { + for (File file : fileList) + { + if (file.isDirectory()) + { + File[] childFiles = file.listFiles(); + if (childFiles != null && childFiles.length == 0) + file.delete(); + } + } + } + + } + + public void write(PrintWriter out, Mappings mappings) throws IOException { + for (ClassMapping classMapping : sorted(mappings.classes())) { + write(out, classMapping, 0); + } + } + + private void write(PrintWriter out, ClassMapping classMapping, int depth) throws IOException { + if (classMapping.getDeobfName() == null) { + out.format("%sCLASS %s\n", getIndent(depth), classMapping.getObfFullName()); + } else { + out.format("%sCLASS %s %s\n", getIndent(depth), classMapping.getObfFullName(), classMapping.getDeobfName()); + } + + for (ClassMapping innerClassMapping : sorted(classMapping.innerClasses())) { + write(out, innerClassMapping, depth + 1); + } + + for (FieldMapping fieldMapping : sorted(classMapping.fields())) { + write(out, fieldMapping, depth + 1); + } + + for (MethodMapping methodMapping : sorted(classMapping.methods())) { + write(out, methodMapping, depth + 1); + } + } + + private void write(PrintWriter out, FieldMapping fieldMapping, int depth) throws IOException { + out.format("%sFIELD %s %s %s\n", getIndent(depth), fieldMapping.getObfName(), fieldMapping.getDeobfName(), fieldMapping.getObfType().toString()); + } + + private void write(PrintWriter out, MethodMapping methodMapping, int depth) throws IOException { + if (methodMapping.getDeobfName() == null) { + out.format("%sMETHOD %s %s\n", getIndent(depth), methodMapping.getObfName(), methodMapping.getObfSignature()); + } else { + out.format("%sMETHOD %s %s %s\n", getIndent(depth), methodMapping.getObfName(), methodMapping.getDeobfName(), methodMapping.getObfSignature()); + } + + for (ArgumentMapping argumentMapping : sorted(methodMapping.arguments())) { + write(out, argumentMapping, depth + 1); + } + } + + private void write(PrintWriter out, ArgumentMapping argumentMapping, int depth) throws IOException { + out.format("%sARG %d %s\n", getIndent(depth), argumentMapping.getIndex(), argumentMapping.getName()); + } + + private > List sorted(Iterable classes) { + List out = new ArrayList(); + for (T t : classes) { + out.add(t); + } + Collections.sort(out); + return out; + } + + private String getIndent(int depth) { + StringBuilder buf = new StringBuilder(); + for (int i = 0; i < depth; i++) { + buf.append("\t"); + } + return buf.toString(); + } +} diff --git a/src/main/java/cuchaz/enigma/mapping/MappingsJsonReader.java b/src/main/java/cuchaz/enigma/mapping/MappingsJsonReader.java new file mode 100644 index 0000000..8f5bde3 --- /dev/null +++ b/src/main/java/cuchaz/enigma/mapping/MappingsJsonReader.java @@ -0,0 +1,120 @@ +/******************************************************************************* + * Copyright (c) 2015 Jeff Martin. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the GNU Lesser General Public + * License v3.0 which accompanies this distribution, and is available at + * http://www.gnu.org/licenses/lgpl.html + *

+ * Contributors: + * Jeff Martin - initial API and implementation + ******************************************************************************/ +package cuchaz.enigma.mapping; + +import com.google.common.base.Charsets; +import com.google.common.io.Files; +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; + +import java.io.*; + +import cuchaz.enigma.json.JsonClass; +import cuchaz.enigma.throwables.MappingConflict; + +public class MappingsJsonReader { + + public Mappings read(File in) throws IOException { + Mappings mappings = new Mappings(Mappings.FormatType.JSON_DIRECTORY); + readDirectory(mappings, in); + return mappings; + } + + public void readDirectory(Mappings mappings, File in) throws IOException { + File[] fList = in.listFiles(); + if (fList != null) { + for (File file : fList) { + if (file.isFile() && Files.getFileExtension(file.getName()).equalsIgnoreCase("json")) { + readFile(mappings, new BufferedReader(new InputStreamReader(new FileInputStream(file), + Charsets.UTF_8))); + } else if (file.isDirectory()) { + readDirectory(mappings, file.getAbsoluteFile()); + } + } + } + } + + public void readFile(Mappings mappings, BufferedReader in) throws IOException { + StringBuilder buf = new StringBuilder(); + String line; + while ((line = in.readLine()) != null) { + buf.append(line); + } + + Gson gson = new GsonBuilder().setPrettyPrinting().create(); + JsonClass jsonClass = gson.fromJson(buf.toString(), JsonClass.class); + try { + load(null, jsonClass, mappings); + } catch (MappingConflict e) { + e.printStackTrace(); + } + in.close(); + } + + public void load(ClassMapping parent, JsonClass jsonClass, Mappings mappings) throws MappingConflict { + ClassMapping classMapping = readClass(jsonClass.getObf(), jsonClass.getName()); + if (parent != null) { + parent.addInnerClassMapping(classMapping); + } else { + mappings.addClassMapping(classMapping); + } + jsonClass.getField().forEach(jsonField -> classMapping.addFieldMapping(readField(jsonField.getObf(), jsonField.getName(), jsonField.getType()))); + + jsonClass.getConstructors().forEach(jsonConstructor -> { + MethodMapping methodMapping = readMethod(jsonConstructor.isStatics() ? "" : "", null, jsonConstructor.getSignature()); + jsonConstructor.getArgs().forEach(jsonArgument -> { + try { + methodMapping.addArgumentMapping(readArgument(jsonArgument.getIndex(), jsonArgument.getName())); + } catch (MappingConflict e) { + e.printStackTrace(); + } + }); + classMapping.addMethodMapping(methodMapping); + }); + + jsonClass.getMethod().forEach(jsonMethod -> { + MethodMapping methodMapping = readMethod(jsonMethod.getObf(), jsonMethod.getName(), jsonMethod.getSignature()); + jsonMethod.getArgs().forEach(jsonArgument -> { + try { + methodMapping.addArgumentMapping(readArgument(jsonArgument.getIndex(), jsonArgument.getName())); + } catch (MappingConflict e) { + e.printStackTrace(); + } + }); + classMapping.addMethodMapping(methodMapping); + }); + + jsonClass.getInnerClass().forEach(jsonInnerClasses -> { + try { + load(classMapping, jsonInnerClasses, mappings); + } catch (MappingConflict e) { + e.printStackTrace(); + } + }); + } + + private ArgumentMapping readArgument(int index, String name) { + return new ArgumentMapping(index, name); + } + + private ClassMapping readClass(String obf, String deobf) { + return new ClassMapping("none/" + obf, deobf); + } + + /* TEMP */ + protected FieldMapping readField(String obf, String deobf, String sig) { + return new FieldMapping(obf, new Type(sig), deobf); + } + + private MethodMapping readMethod(String obf, String deobf, String sig) { + return new MethodMapping(obf, new Signature(sig), deobf); + } +} diff --git a/src/main/java/cuchaz/enigma/mapping/MappingsJsonWriter.java b/src/main/java/cuchaz/enigma/mapping/MappingsJsonWriter.java new file mode 100644 index 0000000..db95322 --- /dev/null +++ b/src/main/java/cuchaz/enigma/mapping/MappingsJsonWriter.java @@ -0,0 +1,101 @@ +/******************************************************************************* + * Copyright (c) 2015 Jeff Martin. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the GNU Lesser General Public + * License v3.0 which accompanies this distribution, and is available at + * http://www.gnu.org/licenses/lgpl.html + *

+ * Contributors: + * Jeff Martin - initial API and implementation + ******************************************************************************/ +package cuchaz.enigma.mapping; + +import com.google.common.base.Charsets; +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; + +import java.io.*; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +import cuchaz.enigma.json.*; + +public class MappingsJsonWriter { + + public void write(File file, Mappings mappings) throws IOException { + if (!file.isDirectory()) { + return; + } + + String[] entries = file.list(); + for (String s : entries) { + File currentFile = new File(file.getPath(), s); + deleteDirectory(currentFile); + } + + Gson gson = new GsonBuilder().setPrettyPrinting().create(); + for (ClassMapping classMapping : sorted(mappings.classes())) { + if (classMapping.getDeobfName() != null && !classMapping.getDeobfName().equalsIgnoreCase("") && !classMapping.getDeobfName().equalsIgnoreCase("null")) { + JsonClass jsonClass = new JsonClass(classMapping.getObfSimpleName(), classMapping.getDeobfName()); + write(jsonClass, classMapping); + + File f = new File(file, jsonClass.getName() + ".json"); + f.getParentFile().mkdirs(); + f.createNewFile(); + PrintWriter writer = new PrintWriter(new OutputStreamWriter(new FileOutputStream(f), Charsets.UTF_8)); + writer.write(gson.toJson(jsonClass)); + writer.close(); + } + } + } + + private void write(JsonClass jsonClass, ClassMapping classMapping) { + for (ClassMapping innerClassMapping : sorted(classMapping.innerClasses())) { + JsonClass innerClass = new JsonClass(classMapping.getObfSimpleName() + "$" + innerClassMapping.getObfSimpleName().replace("nome/", ""), innerClassMapping.getDeobfName()); + write(innerClass, innerClassMapping); + jsonClass.addInnerClass(innerClass); + } + + for (FieldMapping fieldMapping : sorted(classMapping.fields())) { + jsonClass.addField(new JsonField(fieldMapping.getObfName(), fieldMapping.getDeobfName(), fieldMapping.getObfType().toString())); + } + + for (MethodMapping methodMapping : sorted(classMapping.methods())) { + List args = new ArrayList<>(); + for (ArgumentMapping argumentMapping : sorted(methodMapping.arguments())) { + args.add(new JsonArgument(argumentMapping.getIndex(), argumentMapping.getName())); + } + if (methodMapping.getObfName().contains("") || methodMapping.getObfName().contains("")) { + jsonClass.addConstructor(new JsonConstructor(methodMapping.getObfSignature().toString(), args, methodMapping.getObfName().contains(""))); + } else { + jsonClass.addMethod(new JsonMethod(methodMapping.getObfName(), methodMapping.getDeobfName(), methodMapping.getObfSignature().toString(), args)); + } + } + } + + private > List sorted(Iterable classes) { + List out = new ArrayList<>(); + for (T t : classes) { + out.add(t); + } + Collections.sort(out); + return out; + } + + public static boolean deleteDirectory(File directory) { + if (directory.exists()) { + File[] files = directory.listFiles(); + if (null != files) { + for (int i = 0; i < files.length; i++) { + if (files[i].isDirectory()) { + deleteDirectory(files[i]); + } else { + files[i].delete(); + } + } + } + } + return (directory.delete()); + } +} diff --git a/src/main/java/cuchaz/enigma/mapping/MappingsOldWriter.java b/src/main/java/cuchaz/enigma/mapping/MappingsOldWriter.java deleted file mode 100644 index 8b766a3..0000000 --- a/src/main/java/cuchaz/enigma/mapping/MappingsOldWriter.java +++ /dev/null @@ -1,88 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2015 Jeff Martin. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the GNU Lesser General Public - * License v3.0 which accompanies this distribution, and is available at - * http://www.gnu.org/licenses/lgpl.html - * - * Contributors: - * Jeff Martin - initial API and implementation - ******************************************************************************/ -package cuchaz.enigma.mapping; - -import java.io.IOException; -import java.io.PrintWriter; -import java.io.Writer; -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; - -public class MappingsOldWriter { - - public void write(Writer out, Mappings mappings) throws IOException { - write(new PrintWriter(out), mappings); - } - - public void write(PrintWriter out, Mappings mappings) throws IOException { - for (ClassMapping classMapping : sorted(mappings.classes())) { - write(out, classMapping, 0); - } - } - - private void write(PrintWriter out, ClassMapping classMapping, int depth) throws IOException { - if (classMapping.getDeobfName() == null) { - out.format("%sCLASS %s\n", getIndent(depth), classMapping.getObfFullName()); - } else { - out.format("%sCLASS %s %s\n", getIndent(depth), classMapping.getObfFullName(), classMapping.getDeobfName()); - } - - for (ClassMapping innerClassMapping : sorted(classMapping.innerClasses())) { - write(out, innerClassMapping, depth + 1); - } - - for (FieldMapping fieldMapping : sorted(classMapping.fields())) { - write(out, fieldMapping, depth + 1); - } - - for (MethodMapping methodMapping : sorted(classMapping.methods())) { - write(out, methodMapping, depth + 1); - } - } - - private void write(PrintWriter out, FieldMapping fieldMapping, int depth) throws IOException { - out.format("%sFIELD %s %s %s\n", getIndent(depth), fieldMapping.getObfName(), fieldMapping.getDeobfName(), fieldMapping.getObfType().toString()); - } - - private void write(PrintWriter out, MethodMapping methodMapping, int depth) throws IOException { - if (methodMapping.getDeobfName() == null) { - out.format("%sMETHOD %s %s\n", getIndent(depth), methodMapping.getObfName(), methodMapping.getObfSignature()); - } else { - out.format("%sMETHOD %s %s %s\n", getIndent(depth), methodMapping.getObfName(), methodMapping.getDeobfName(), methodMapping.getObfSignature()); - } - - for (ArgumentMapping argumentMapping : sorted(methodMapping.arguments())) { - write(out, argumentMapping, depth + 1); - } - } - - private void write(PrintWriter out, ArgumentMapping argumentMapping, int depth) throws IOException { - out.format("%sARG %d %s\n", getIndent(depth), argumentMapping.getIndex(), argumentMapping.getName()); - } - - private > List sorted(Iterable classes) { - List out = new ArrayList(); - for (T t : classes) { - out.add(t); - } - Collections.sort(out); - return out; - } - - private String getIndent(int depth) { - StringBuilder buf = new StringBuilder(); - for (int i = 0; i < depth; i++) { - buf.append("\t"); - } - return buf.toString(); - } -} diff --git a/src/main/java/cuchaz/enigma/mapping/MappingsReader.java b/src/main/java/cuchaz/enigma/mapping/MappingsReader.java deleted file mode 100644 index b2b6d09..0000000 --- a/src/main/java/cuchaz/enigma/mapping/MappingsReader.java +++ /dev/null @@ -1,121 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2015 Jeff Martin. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the GNU Lesser General Public - * License v3.0 which accompanies this distribution, and is available at - * http://www.gnu.org/licenses/lgpl.html - *

- * Contributors: - * Jeff Martin - initial API and implementation - ******************************************************************************/ -package cuchaz.enigma.mapping; - -import com.google.common.io.Files; -import com.google.gson.Gson; -import com.google.gson.GsonBuilder; - -import java.io.BufferedReader; -import java.io.File; -import java.io.FileReader; -import java.io.IOException; - -import cuchaz.enigma.json.JsonClass; -import cuchaz.enigma.throwables.MappingConflict; - -public class MappingsReader { - - public Mappings read(File in) throws IOException { - Mappings mappings = new Mappings(); - readDirectory(mappings, in); - return mappings; - } - - public void readDirectory(Mappings mappings, File in) throws IOException { - File[] fList = in.listFiles(); - if (fList != null) { - for (File file : fList) { - if (file.isFile() && Files.getFileExtension(file.getName()).equalsIgnoreCase("json")) { - readFile(mappings, new BufferedReader(new FileReader(file))); - } else if (file.isDirectory()) { - readDirectory(mappings, file.getAbsoluteFile()); - } - } - } - } - - public void readFile(Mappings mappings, BufferedReader in) throws IOException { - StringBuilder buf = new StringBuilder(); - String line; - while ((line = in.readLine()) != null) { - buf.append(line); - } - - Gson gson = new GsonBuilder().setPrettyPrinting().create(); - JsonClass jsonClass = gson.fromJson(buf.toString(), JsonClass.class); - try { - load(null, jsonClass, mappings); - } catch (MappingConflict e) { - e.printStackTrace(); - } - in.close(); - } - - public void load(ClassMapping parent, JsonClass jsonClass, Mappings mappings) throws MappingConflict { - ClassMapping classMapping = readClass(jsonClass.getObf(), jsonClass.getName()); - if (parent != null) { - parent.addInnerClassMapping(classMapping); - } else { - mappings.addClassMapping(classMapping); - } - jsonClass.getField().forEach(jsonField -> classMapping.addFieldMapping(readField(jsonField.getObf(), jsonField.getName(), jsonField.getType()))); - - jsonClass.getConstructors().forEach(jsonConstructor -> { - MethodMapping methodMapping = readMethod(jsonConstructor.isStatics() ? "" : "", null, jsonConstructor.getSignature()); - jsonConstructor.getArgs().forEach(jsonArgument -> { - try { - methodMapping.addArgumentMapping(readArgument(jsonArgument.getIndex(), jsonArgument.getName())); - } catch (MappingConflict e) { - e.printStackTrace(); - } - }); - classMapping.addMethodMapping(methodMapping); - }); - - jsonClass.getMethod().forEach(jsonMethod -> { - MethodMapping methodMapping = readMethod(jsonMethod.getObf(), jsonMethod.getName(), jsonMethod.getSignature()); - jsonMethod.getArgs().forEach(jsonArgument -> { - try { - methodMapping.addArgumentMapping(readArgument(jsonArgument.getIndex(), jsonArgument.getName())); - } catch (MappingConflict e) { - e.printStackTrace(); - } - }); - classMapping.addMethodMapping(methodMapping); - }); - - jsonClass.getInnerClass().forEach(jsonInnerClasses -> { - try { - load(classMapping, jsonInnerClasses, mappings); - } catch (MappingConflict e) { - e.printStackTrace(); - } - }); - } - - private ArgumentMapping readArgument(int index, String name) { - return new ArgumentMapping(index, name); - } - - private ClassMapping readClass(String obf, String deobf) { - return new ClassMapping("none/" + obf, deobf); - } - - /* TEMP */ - protected FieldMapping readField(String obf, String deobf, String sig) { - return new FieldMapping(obf, new Type(sig), deobf); - } - - private MethodMapping readMethod(String obf, String deobf, String sig) { - return new MethodMapping(obf, new Signature(sig), deobf); - } -} diff --git a/src/main/java/cuchaz/enigma/mapping/MappingsReaderOld.java b/src/main/java/cuchaz/enigma/mapping/MappingsReaderOld.java deleted file mode 100644 index 776d908..0000000 --- a/src/main/java/cuchaz/enigma/mapping/MappingsReaderOld.java +++ /dev/null @@ -1,127 +0,0 @@ -package cuchaz.enigma.mapping; - -import com.google.common.collect.Queues; - -import java.io.BufferedReader; -import java.io.IOException; -import java.io.Reader; -import java.util.Deque; - -import cuchaz.enigma.throwables.MappingConflict; -import cuchaz.enigma.throwables.MappingParseException; - -public class MappingsReaderOld { - - public Mappings read(Reader in) throws IOException, MappingParseException { - return read(new BufferedReader(in)); - } - - public Mappings read(BufferedReader in) throws IOException, MappingParseException { - Mappings mappings = new Mappings(); - Deque mappingStack = Queues.newArrayDeque(); - - int lineNumber = 0; - String line; - while ((line = in.readLine()) != null) { - lineNumber++; - - // strip comments - int commentPos = line.indexOf('#'); - if (commentPos >= 0) { - line = line.substring(0, commentPos); - } - - // skip blank lines - if (line.trim().length() <= 0) { - continue; - } - - // get the indent of this line - int indent = 0; - for (int i = 0; i < line.length(); i++) { - if (line.charAt(i) != '\t') { - break; - } - indent++; - } - - // handle stack pops - while (indent < mappingStack.size()) { - mappingStack.pop(); - } - - String[] parts = line.trim().split("\\s"); - try { - // read the first token - String token = parts[0]; - - if (token.equalsIgnoreCase("CLASS")) { - ClassMapping classMapping; - if (indent <= 0) { - // outer class - classMapping = readClass(parts); - mappings.addClassMapping(classMapping); - } else { - - // inner class - if (!(mappingStack.peek() instanceof ClassMapping)) { - throw new MappingParseException(lineNumber, "Unexpected CLASS entry here!"); - } - - classMapping = readClass(parts); - ((ClassMapping) mappingStack.peek()).addInnerClassMapping(classMapping); - } - mappingStack.push(classMapping); - } else if (token.equalsIgnoreCase("FIELD")) { - if (mappingStack.isEmpty() || !(mappingStack.peek() instanceof ClassMapping)) { - throw new MappingParseException(lineNumber, "Unexpected FIELD entry here!"); - } - ((ClassMapping) mappingStack.peek()).addFieldMapping(readField(parts)); - } else if (token.equalsIgnoreCase("METHOD")) { - if (mappingStack.isEmpty() || !(mappingStack.peek() instanceof ClassMapping)) { - throw new MappingParseException(lineNumber, "Unexpected METHOD entry here!"); - } - MethodMapping methodMapping = readMethod(parts); - ((ClassMapping) mappingStack.peek()).addMethodMapping(methodMapping); - mappingStack.push(methodMapping); - } else if (token.equalsIgnoreCase("ARG")) { - if (mappingStack.isEmpty() || !(mappingStack.peek() instanceof MethodMapping)) { - throw new MappingParseException(lineNumber, "Unexpected ARG entry here!"); - } - ((MethodMapping) mappingStack.peek()).addArgumentMapping(readArgument(parts)); - } - } catch (ArrayIndexOutOfBoundsException | IllegalArgumentException ex) { - throw new MappingParseException(lineNumber, "Malformed line:\n" + line); - } catch (MappingConflict e) { - e.printStackTrace(); - } - } - - return mappings; - } - - private ArgumentMapping readArgument(String[] parts) { - return new ArgumentMapping(Integer.parseInt(parts[1]), parts[2]); - } - - private ClassMapping readClass(String[] parts) { - if (parts.length == 2) { - return new ClassMapping(parts[1]); - } else { - return new ClassMapping(parts[1], parts[2]); - } - } - - /* TEMP */ - protected FieldMapping readField(String[] parts) { - return new FieldMapping(parts[1], new Type(parts[3]), parts[2]); - } - - private MethodMapping readMethod(String[] parts) { - if (parts.length == 3) { - return new MethodMapping(parts[1], new Signature(parts[2])); - } else { - return new MethodMapping(parts[1], new Signature(parts[3]), parts[2]); - } - } -} diff --git a/src/main/java/cuchaz/enigma/mapping/MappingsSRGWriter.java b/src/main/java/cuchaz/enigma/mapping/MappingsSRGWriter.java index 64da709..a05b915 100644 --- a/src/main/java/cuchaz/enigma/mapping/MappingsSRGWriter.java +++ b/src/main/java/cuchaz/enigma/mapping/MappingsSRGWriter.java @@ -1,10 +1,9 @@ package cuchaz.enigma.mapping; +import com.google.common.base.Charsets; import cuchaz.enigma.Deobfuscator; -import java.io.File; -import java.io.FileWriter; -import java.io.IOException; +import java.io.*; import java.util.ArrayList; import java.util.Collections; import java.util.List; @@ -22,7 +21,7 @@ public class MappingsSRGWriter { Mappings mappings = deobfuscator.getMappings(); - FileWriter writer = new FileWriter(file); + PrintWriter writer = new PrintWriter(new OutputStreamWriter(new FileOutputStream(file), Charsets.UTF_8)); List fieldMappings = new ArrayList<>(); List methodMappings = new ArrayList<>(); for (ClassMapping classMapping : sorted(mappings.classes())) { diff --git a/src/main/java/cuchaz/enigma/mapping/MappingsWriter.java b/src/main/java/cuchaz/enigma/mapping/MappingsWriter.java deleted file mode 100644 index 4793166..0000000 --- a/src/main/java/cuchaz/enigma/mapping/MappingsWriter.java +++ /dev/null @@ -1,102 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2015 Jeff Martin. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the GNU Lesser General Public - * License v3.0 which accompanies this distribution, and is available at - * http://www.gnu.org/licenses/lgpl.html - *

- * Contributors: - * Jeff Martin - initial API and implementation - ******************************************************************************/ -package cuchaz.enigma.mapping; - -import com.google.gson.Gson; -import com.google.gson.GsonBuilder; - -import java.io.File; -import java.io.FileWriter; -import java.io.IOException; -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; - -import cuchaz.enigma.json.*; - -public class MappingsWriter { - - public void write(File file, Mappings mappings) throws IOException { - if (!file.isDirectory()) { - return; - } - - String[] entries = file.list(); - for (String s : entries) { - File currentFile = new File(file.getPath(), s); - deleteDirectory(currentFile); - } - - Gson gson = new GsonBuilder().setPrettyPrinting().create(); - for (ClassMapping classMapping : sorted(mappings.classes())) { - if (classMapping.getDeobfName() != null && !classMapping.getDeobfName().equalsIgnoreCase("") && !classMapping.getDeobfName().equalsIgnoreCase("null")) { - JsonClass jsonClass = new JsonClass(classMapping.getObfSimpleName(), classMapping.getDeobfName()); - write(jsonClass, classMapping); - - File f = new File(file, jsonClass.getName() + ".json"); - f.getParentFile().mkdirs(); - f.createNewFile(); - FileWriter writer = new FileWriter(f); - writer.write(gson.toJson(jsonClass)); - writer.close(); - } - } - } - - private void write(JsonClass jsonClass, ClassMapping classMapping) { - for (ClassMapping innerClassMapping : sorted(classMapping.innerClasses())) { - JsonClass innerClass = new JsonClass(classMapping.getObfSimpleName() + "$" + innerClassMapping.getObfSimpleName().replace("nome/", ""), innerClassMapping.getDeobfName()); - write(innerClass, innerClassMapping); - jsonClass.addInnerClass(innerClass); - } - - for (FieldMapping fieldMapping : sorted(classMapping.fields())) { - jsonClass.addField(new JsonField(fieldMapping.getObfName(), fieldMapping.getDeobfName(), fieldMapping.getObfType().toString())); - } - - for (MethodMapping methodMapping : sorted(classMapping.methods())) { - List args = new ArrayList<>(); - for (ArgumentMapping argumentMapping : sorted(methodMapping.arguments())) { - args.add(new JsonArgument(argumentMapping.getIndex(), argumentMapping.getName())); - } - if (methodMapping.getObfName().contains("") || methodMapping.getObfName().contains("")) { - jsonClass.addConstructor(new JsonConstructor(methodMapping.getObfSignature().toString(), args, methodMapping.getObfName().contains(""))); - } else { - jsonClass.addMethod(new JsonMethod(methodMapping.getObfName(), methodMapping.getDeobfName(), methodMapping.getObfSignature().toString(), args)); - } - } - } - - private > List sorted(Iterable classes) { - List out = new ArrayList<>(); - for (T t : classes) { - out.add(t); - } - Collections.sort(out); - return out; - } - - public static boolean deleteDirectory(File directory) { - if (directory.exists()) { - File[] files = directory.listFiles(); - if (null != files) { - for (int i = 0; i < files.length; i++) { - if (files[i].isDirectory()) { - deleteDirectory(files[i]); - } else { - files[i].delete(); - } - } - } - } - return (directory.delete()); - } -} -- cgit v1.2.3