/******************************************************************************* * 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; import java.io.File; import java.io.FileReader; import java.util.jar.JarFile; import cuchaz.enigma.Deobfuscator.ProgressListener; import cuchaz.enigma.mapping.Mappings; import cuchaz.enigma.mapping.MappingsReader; public class CommandMain { public static class ConsoleProgressListener implements ProgressListener { private static final int ReportTime = 5000; // 5s private int m_totalWork; private long m_startTime; private long m_lastReportTime; @Override public void init(int totalWork, String title) { m_totalWork = totalWork; m_startTime = System.currentTimeMillis(); m_lastReportTime = m_startTime; System.out.println(title); } @Override public void onProgress(int numDone, String message) { long now = System.currentTimeMillis(); boolean isLastUpdate = numDone == m_totalWork; boolean shouldReport = isLastUpdate || now - m_lastReportTime > ReportTime; if (shouldReport) { int percent = numDone*100/m_totalWork; System.out.println(String.format("\tProgress: %3d%%", percent)); m_lastReportTime = now; } if (isLastUpdate) { double elapsedSeconds = (now - m_startTime)/1000; System.out.println(String.format("Finished in %.1f seconds", elapsedSeconds)); } } } public static void main(String[] args) throws Exception { try { // process the command String command = getArg(args, 0, "command", true); if (command.equalsIgnoreCase("deobfuscate")) { deobfuscate(args); } else if (command.equalsIgnoreCase("decompile")) { decompile(args); } else if (command.equalsIgnoreCase("protectify")) { protectify(args); } else if (command.equalsIgnoreCase("publify")) { publify(args); } else { throw new IllegalArgumentException("Command not recognized: " + command); } } catch (IllegalArgumentException ex) { System.out.println(ex.getMessage()); printHelp(); } } private static void printHelp() { System.out.println(String.format("%s - %s", Constants.Name, Constants.Version)); System.out.println("Usage:"); System.out.println("\tjava -cp enigma.jar cuchaz.enigma.CommandMain "); System.out.println("\twhere is one of:"); System.out.println("\t\tdeobfuscate []"); System.out.println("\t\tdecompile []"); System.out.println("\t\tprotectify "); } private static void decompile(String[] args) throws Exception { File fileJarIn = getReadableFile(getArg(args, 1, "in jar", true)); File fileJarOut = getWritableFolder(getArg(args, 2, "out folder", true)); File fileMappings = getReadableFile(getArg(args, 3, "mappings file", false)); Deobfuscator deobfuscator = getDeobfuscator(fileMappings, new JarFile(fileJarIn)); deobfuscator.writeSources(fileJarOut, new ConsoleProgressListener()); } private static void deobfuscate(String[] args) throws Exception { File fileJarIn = getReadableFile(getArg(args, 1, "in jar", true)); File fileJarOut = getWritableFile(getArg(args, 2, "out jar", true)); File fileMappings = getReadableFile(getArg(args, 3, "mappings file", false)); Deobfuscator deobfuscator = getDeobfuscator(fileMappings, new JarFile(fileJarIn)); deobfuscator.writeJar(fileJarOut, new ConsoleProgressListener()); } private static void protectify(String[] args) throws Exception { File fileJarIn = getReadableFile(getArg(args, 1, "in jar", true)); File fileJarOut = getWritableFile(getArg(args, 2, "out jar", true)); Deobfuscator deobfuscator = getDeobfuscator(null, new JarFile(fileJarIn)); deobfuscator.protectifyJar(fileJarOut, new ConsoleProgressListener()); } private static void publify(String[] args) throws Exception { File fileJarIn = getReadableFile(getArg(args, 1, "in jar", true)); File fileJarOut = getWritableFile(getArg(args, 2, "out jar", true)); Deobfuscator deobfuscator = getDeobfuscator(null, new JarFile(fileJarIn)); deobfuscator.publifyJar(fileJarOut, new ConsoleProgressListener()); } private static Deobfuscator getDeobfuscator(File fileMappings, JarFile jar) throws Exception { System.out.println("Reading jar..."); Deobfuscator deobfuscator = new Deobfuscator(jar); if (fileMappings != null) { System.out.println("Reading mappings..."); Mappings mappings = new MappingsReader().read(new FileReader(fileMappings)); deobfuscator.setMappings(mappings); } return deobfuscator; } private static String getArg(String[] args, int i, String name, boolean required) { if (i >= args.length) { if (required) { throw new IllegalArgumentException(name + " is required"); } else { return null; } } return args[i]; } private static File getWritableFile(String path) { if (path == null) { return null; } File file = new File(path).getAbsoluteFile(); File dir = file.getParentFile(); if (dir == null || !dir.exists()) { throw new IllegalArgumentException("Cannot write to folder: " + file); } return file; } private static File getWritableFolder(String path) { if (path == null) { return null; } File dir = new File(path).getAbsoluteFile(); if (!dir.exists()) { throw new IllegalArgumentException("Cannot write to folder: " + dir); } return dir; } private static File getReadableFile(String path) { if (path == null) { return null; } File file = new File(path).getAbsoluteFile(); if (!file.exists()) { throw new IllegalArgumentException("Cannot find file: " + file.getAbsolutePath()); } return file; } }