summaryrefslogtreecommitdiff
path: root/src/main/java/cuchaz/enigma/CommandMain.java
diff options
context:
space:
mode:
authorGravatar gegy10002019-06-10 18:23:59 +0200
committerGravatar gegy10002019-06-10 18:23:59 +0200
commit54bbafce6a72abcd740a27917b7f6f7b5947167b (patch)
treeaad1060c4c1db00d62850a00366c9b12a704774d /src/main/java/cuchaz/enigma/CommandMain.java
parentSeparate JarProcessor and EntryNameProposer (diff)
parentMethod type reference corrections (#142) (diff)
downloadenigma-fork-54bbafce6a72abcd740a27917b7f6f7b5947167b.tar.gz
enigma-fork-54bbafce6a72abcd740a27917b7f6f7b5947167b.tar.xz
enigma-fork-54bbafce6a72abcd740a27917b7f6f7b5947167b.zip
Merge remote-tracking branch 'origin/master' into proposal-tweak
Diffstat (limited to 'src/main/java/cuchaz/enigma/CommandMain.java')
-rw-r--r--src/main/java/cuchaz/enigma/CommandMain.java208
1 files changed, 53 insertions, 155 deletions
diff --git a/src/main/java/cuchaz/enigma/CommandMain.java b/src/main/java/cuchaz/enigma/CommandMain.java
index c9f8382..5b25087 100644
--- a/src/main/java/cuchaz/enigma/CommandMain.java
+++ b/src/main/java/cuchaz/enigma/CommandMain.java
@@ -11,35 +11,49 @@
11 11
12package cuchaz.enigma; 12package cuchaz.enigma;
13 13
14import cuchaz.enigma.translation.mapping.EntryMapping; 14import cuchaz.enigma.command.*;
15import cuchaz.enigma.translation.mapping.serde.MappingFormat; 15
16import cuchaz.enigma.translation.mapping.tree.EntryTree; 16import java.util.LinkedHashMap;
17
18import java.io.File;
19import java.nio.file.Files;
20import java.nio.file.Path;
21import java.nio.file.Paths;
22import java.util.Locale; 17import java.util.Locale;
23import java.util.jar.JarFile; 18import java.util.Map;
24 19
25public class CommandMain { 20public class CommandMain {
26 21
27 public static void main(String[] args) throws Exception { 22 private static final Map<String, Command> COMMANDS = new LinkedHashMap<>();
23
24 public static void main(String... args) throws Exception {
28 try { 25 try {
29 // process the command 26 // process the command
30 String command = getArg(args, 0, "command", true); 27 if (args.length < 1)
31 if (command.equalsIgnoreCase("deobfuscate")) { 28 throw new IllegalArgumentException("Requires a command");
32 deobfuscate(args); 29 String command = args[0].toLowerCase(Locale.ROOT);
33 } else if (command.equalsIgnoreCase("decompile")) { 30
34 decompile(args); 31 Command cmd = COMMANDS.get(command);
35 } else if (command.equalsIgnoreCase("convertmappings")) { 32 if (cmd == null)
36 convertMappings(args);
37 } else {
38 throw new IllegalArgumentException("Command not recognized: " + command); 33 throw new IllegalArgumentException("Command not recognized: " + command);
34
35 if (!cmd.isValidArgument(args.length - 1)) {
36 throw new CommandHelpException(cmd);
37 }
38
39 String[] cmdArgs = new String[args.length - 1];
40 System.arraycopy(args, 1, cmdArgs, 0, args.length - 1);
41
42 try {
43 cmd.run(cmdArgs);
44 } catch (Exception ex) {
45 throw new CommandHelpException(cmd, ex);
39 } 46 }
47 } catch (CommandHelpException ex) {
48 System.err.println(ex.getMessage());
49 System.out.println(String.format("%s - %s", Constants.NAME, Constants.VERSION));
50 System.out.println("Command " + ex.command.name + " has encountered an error! Usage:");
51 printHelp(ex.command);
52 System.exit(1);
40 } catch (IllegalArgumentException ex) { 53 } catch (IllegalArgumentException ex) {
41 System.out.println(ex.getMessage()); 54 System.err.println(ex.getMessage());
42 printHelp(); 55 printHelp();
56 System.exit(1);
43 } 57 }
44 } 58 }
45 59
@@ -48,157 +62,41 @@ public class CommandMain {
48 System.out.println("Usage:"); 62 System.out.println("Usage:");
49 System.out.println("\tjava -cp enigma.jar cuchaz.enigma.CommandMain <command>"); 63 System.out.println("\tjava -cp enigma.jar cuchaz.enigma.CommandMain <command>");
50 System.out.println("\twhere <command> is one of:"); 64 System.out.println("\twhere <command> is one of:");
51 System.out.println("\t\tdeobfuscate <in jar> <out jar> [<mappings file>]");
52 System.out.println("\t\tdecompile <in jar> <out folder> [<mappings file>]");
53 System.out.println("\t\tconvertmappings <enigma mappings> <converted mappings> <ENIGMA_FILE|ENIGMA_DIRECTORY|SRG_FILE>");
54 }
55
56 private static void decompile(String[] args) throws Exception {
57 File fileJarIn = getReadableFile(getArg(args, 1, "in jar", true));
58 File fileJarOut = getWritableFolder(getArg(args, 2, "out folder", true));
59 Path fileMappings = getReadablePath(getArg(args, 3, "mappings file", false));
60 Deobfuscator deobfuscator = getDeobfuscator(fileMappings, new JarFile(fileJarIn));
61 deobfuscator.writeSources(fileJarOut.toPath(), new ConsoleProgressListener());
62 }
63
64 private static void deobfuscate(String[] args) throws Exception {
65 File fileJarIn = getReadableFile(getArg(args, 1, "in jar", true));
66 File fileJarOut = getWritableFile(getArg(args, 2, "out jar", true));
67 Path fileMappings = getReadablePath(getArg(args, 3, "mappings file", false));
68 Deobfuscator deobfuscator = getDeobfuscator(fileMappings, new JarFile(fileJarIn));
69 deobfuscator.writeTransformedJar(fileJarOut, new ConsoleProgressListener());
70 }
71
72 private static Deobfuscator getDeobfuscator(Path fileMappings, JarFile jar) throws Exception {
73 System.out.println("Reading jar...");
74 Deobfuscator deobfuscator = new Deobfuscator(jar);
75 if (fileMappings != null) {
76 System.out.println("Reading mappings...");
77 EntryTree<EntryMapping> mappings = chooseEnigmaFormat(fileMappings).read(fileMappings, new ConsoleProgressListener());
78 deobfuscator.setMappings(mappings);
79 }
80 return deobfuscator;
81 }
82
83 private static void convertMappings(String[] args) throws Exception {
84 Path fileMappings = getReadablePath(getArg(args, 1, "enigma mapping", true));
85 File result = getWritableFile(getArg(args, 2, "enigma mapping", true));
86 String name = getArg(args, 3, "format desc", true);
87 MappingFormat saveFormat;
88 try {
89 saveFormat = MappingFormat.valueOf(name.toUpperCase(Locale.ROOT));
90 } catch (IllegalArgumentException e) {
91 throw new IllegalArgumentException(name + "is not a valid mapping format!");
92 }
93
94 System.out.println("Reading mappings...");
95
96 MappingFormat readFormat = chooseEnigmaFormat(fileMappings);
97 EntryTree<EntryMapping> mappings = readFormat.read(fileMappings, new ConsoleProgressListener());
98 System.out.println("Saving new mappings...");
99 65
100 saveFormat.write(mappings, result.toPath(), new ConsoleProgressListener()); 66 for (Command command : COMMANDS.values()) {
101 } 67 printHelp(command);
102
103 private static MappingFormat chooseEnigmaFormat(Path path) {
104 if (Files.isDirectory(path)) {
105 return MappingFormat.ENIGMA_DIRECTORY;
106 } else {
107 return MappingFormat.ENIGMA_FILE;
108 }
109 }
110
111 private static String getArg(String[] args, int i, String name, boolean required) {
112 if (i >= args.length) {
113 if (required) {
114 throw new IllegalArgumentException(name + " is required");
115 } else {
116 return null;
117 }
118 }
119 return args[i];
120 }
121
122 private static File getWritableFile(String path) {
123 if (path == null) {
124 return null;
125 }
126 File file = new File(path).getAbsoluteFile();
127 File dir = file.getParentFile();
128 if (dir == null) {
129 throw new IllegalArgumentException("Cannot write file: " + path);
130 } 68 }
131 // quick fix to avoid stupid stuff in Gradle code
132 if (!dir.isDirectory()) {
133 dir.mkdirs();
134 }
135 return file;
136 } 69 }
137 70
138 private static File getWritableFolder(String path) { 71 private static void printHelp(Command command) {
139 if (path == null) { 72 System.out.println("\t\t" + command.name + " " + command.getUsage());
140 return null;
141 }
142 File dir = new File(path).getAbsoluteFile();
143 if (!dir.exists()) {
144 throw new IllegalArgumentException("Cannot write to folder: " + dir);
145 }
146 return dir;
147 } 73 }
148 74
149 private static File getReadableFile(String path) { 75 private static void register(Command command) {
150 if (path == null) { 76 Command old = COMMANDS.put(command.name, command);
151 return null; 77 if (old != null) {
78 System.err.println("Command " + old + " with name " + command.name + " has been substituted by " + command);
152 } 79 }
153 File file = new File(path).getAbsoluteFile();
154 if (!file.exists()) {
155 throw new IllegalArgumentException("Cannot find file: " + file.getAbsolutePath());
156 }
157 return file;
158 } 80 }
159 81
160 private static Path getReadablePath(String path) { 82 static {
161 if (path == null) { 83 register(new DeobfuscateCommand());
162 return null; 84 register(new DecompileCommand());
163 } 85 register(new ConvertMappingsCommand());
164 Path file = Paths.get(path).toAbsolutePath(); 86 register(new CheckMappingsCommand());
165 if (!Files.exists(file)) {
166 throw new IllegalArgumentException("Cannot find file: " + file.toString());
167 }
168 return file;
169 } 87 }
170 88
171 public static class ConsoleProgressListener implements ProgressListener { 89 private static final class CommandHelpException extends IllegalArgumentException {
172
173 private static final int ReportTime = 5000; // 5s
174 90
175 private int totalWork; 91 final Command command;
176 private long startTime;
177 private long lastReportTime;
178 92
179 @Override 93 CommandHelpException(Command command) {
180 public void init(int totalWork, String title) { 94 this.command = command;
181 this.totalWork = totalWork;
182 this.startTime = System.currentTimeMillis();
183 this.lastReportTime = this.startTime;
184 System.out.println(title);
185 } 95 }
186 96
187 @Override 97 CommandHelpException(Command command, Throwable cause) {
188 public void step(int numDone, String message) { 98 super(cause);
189 long now = System.currentTimeMillis(); 99 this.command = command;
190 boolean isLastUpdate = numDone == this.totalWork;
191 boolean shouldReport = isLastUpdate || now - this.lastReportTime > ReportTime;
192
193 if (shouldReport) {
194 int percent = numDone * 100 / this.totalWork;
195 System.out.println(String.format("\tProgress: %3d%%", percent));
196 this.lastReportTime = now;
197 }
198 if (isLastUpdate) {
199 double elapsedSeconds = (now - this.startTime) / 1000.0;
200 System.out.println(String.format("Finished in %.1f seconds", elapsedSeconds));
201 }
202 } 100 }
203 } 101 }
204} 102}