From 8e4bbfcf6123d83b7918ff5cf7484a257ca5b6c4 Mon Sep 17 00:00:00 2001 From: Honfika Date: Sun, 25 Aug 2013 10:45:07 +0200 Subject: [PATCH] Show total export time, configurable method decompilation timeout --- .../jpexs/decompiler/flash/Configuration.java | 34 ++++- .../flash/abc/types/MethodBody.java | 5 +- .../jpexs/decompiler/flash/action/Action.java | 5 +- .../com/jpexs/decompiler/flash/gui/Main.java | 117 ++++++++++++------ .../jpexs/decompiler/flash/gui/MainFrame.java | 8 +- 5 files changed, 114 insertions(+), 55 deletions(-) diff --git a/trunk/src/com/jpexs/decompiler/flash/Configuration.java b/trunk/src/com/jpexs/decompiler/flash/Configuration.java index b6bc9eab2..556ca641f 100644 --- a/trunk/src/com/jpexs/decompiler/flash/Configuration.java +++ b/trunk/src/com/jpexs/decompiler/flash/Configuration.java @@ -57,11 +57,6 @@ public class Configuration { * Decompilation timeout in seconds */ public static final int DECOMPILATION_TIMEOUT = 30 * 60; - /** - * Decompilation timeout for a single method in AS3 or single action in - * AS1/2 in seconds - */ - public static final int DECOMPILATION_TIMEOUT_SINGLE_METHOD = 5; //using parameter names in decompiling may cause problems because official programs like Flash CS 5.5 inserts wrong parameter names indices public static final boolean PARAM_NAMES_ENABLE = false; private static HashMap config = new HashMap<>(); @@ -70,6 +65,27 @@ public class Configuration { */ public static java.util.List replacements = new ArrayList<>(); + private static HashMap configDefaults = new HashMap() {{ + put("decompile", true); + put("parallelSpeedUp", true); + put("autoDeobfuscate", true); + put("cacheOnDisk", true); + put("internalFlashViewer", false); + put("gotoMainClassOnStartup", false); + put("deobfuscateUsePrevTagOnly", true); + put("decompilationTimeoutSingleMethod", 60); + put("lastSaveDir", "."); + put("lastOpenDir", "."); + put("offeredAssociation", false); + put("locale", "en"); + put("lastUpdatesCheckDate", null); + put("gui.window.width", 1000); + put("gui.window.height", 700); + put("gui.window.maximized.horizontal", false); + put("gui.window.maximized.vertical", false); + put("lastRenameType", 1); + }}; + /** * Saves replacements to file for future use */ @@ -117,7 +133,13 @@ public class Configuration { } public static T getConfig(String cfg) { - return getConfig(cfg, null); + T defaultValue = null; + if (configDefaults.containsKey(cfg)) { + @SuppressWarnings("unchecked") + T def = (T)configDefaults.get(cfg); + defaultValue = def; + } + return getConfig(cfg, defaultValue); } public static T getConfig(String cfg, T defaultValue) { diff --git a/trunk/src/com/jpexs/decompiler/flash/abc/types/MethodBody.java b/trunk/src/com/jpexs/decompiler/flash/abc/types/MethodBody.java index 73d4cd6ea..52bb48453 100644 --- a/trunk/src/com/jpexs/decompiler/flash/abc/types/MethodBody.java +++ b/trunk/src/com/jpexs/decompiler/flash/abc/types/MethodBody.java @@ -123,16 +123,17 @@ public class MethodBody implements Cloneable, Serializable { } return s; } + int timeout = Configuration.getConfig("decompilationTimeoutSingleMethod", 60); try { s += Helper.timedCall(new Callable() { @Override public String call() throws Exception { return toSource(path, isStatic, scriptIndex, classIndex, abc, constants, method_info, scopeStack, isStaticInitializer, hilight, fullyQualifiedNames, initTraits); } - }, Configuration.DECOMPILATION_TIMEOUT_SINGLE_METHOD, TimeUnit.SECONDS); + }, timeout, TimeUnit.SECONDS); } catch (InterruptedException | ExecutionException | TimeoutException ex) { Logger.getLogger(Action.class.getName()).log(Level.SEVERE, "Decompilation error", ex); - s += "/*\r\n * Decompilation error\r\n * Timeout (" + Helper.formatTimeToText(Configuration.DECOMPILATION_TIMEOUT_SINGLE_METHOD) + ") was reached\r\n */"; + s += "/*\r\n * Decompilation error\r\n * Timeout (" + Helper.formatTimeToText(timeout) + ") was reached\r\n */"; } } return s; diff --git a/trunk/src/com/jpexs/decompiler/flash/action/Action.java b/trunk/src/com/jpexs/decompiler/flash/action/Action.java index d11ed449e..2b56aec03 100644 --- a/trunk/src/com/jpexs/decompiler/flash/action/Action.java +++ b/trunk/src/com/jpexs/decompiler/flash/action/Action.java @@ -716,6 +716,7 @@ public class Action implements GraphSourceItem { * @return String with Source code */ public static String actionsToSource(final List actions, final int version, final String path) { + int timeout = Configuration.getConfig("decompilationTimeoutSingleMethod", 60); try { return Helper.timedCall(new Callable() { @Override @@ -727,10 +728,10 @@ public class Action implements GraphSourceItem { return Graph.graphToString(tree); } - }, Configuration.DECOMPILATION_TIMEOUT_SINGLE_METHOD, TimeUnit.SECONDS); + }, timeout, TimeUnit.SECONDS); } catch (TimeoutException ex) { Logger.getLogger(Action.class.getName()).log(Level.SEVERE, "Decompilation error", ex); - return "/*\r\n * Decompilation error\r\n * Timeout (" + Helper.formatTimeToText(Configuration.DECOMPILATION_TIMEOUT_SINGLE_METHOD) + ") was reached\r\n */"; + return "/*\r\n * Decompilation error\r\n * Timeout (" + Helper.formatTimeToText(timeout) + ") was reached\r\n */"; } catch (Exception | OutOfMemoryError | StackOverflowError ex2) { Logger.getLogger(Action.class.getName()).log(Level.SEVERE, "Decompilation error", ex2); if (ex2 instanceof OutOfMemoryError) { diff --git a/trunk/src/com/jpexs/decompiler/flash/gui/Main.java b/trunk/src/com/jpexs/decompiler/flash/gui/Main.java index ab4d96615..4e9339288 100644 --- a/trunk/src/com/jpexs/decompiler/flash/gui/Main.java +++ b/trunk/src/com/jpexs/decompiler/flash/gui/Main.java @@ -575,16 +575,18 @@ public class Main { System.out.println(" 7) -decompress infile outfile"); System.out.println(" ...Decompress infile and save it to outfile"); System.out.println(" 8) -config key=value[,key2=value2][,key3=value3...] [other parameters]"); - System.out.print(" ...Sets configuration values. Available keys:"); + System.out.print(" ...Sets configuration values. Available keys[current setting]:"); for (String key : commandlineConfigBoolean) { - System.out.print(" " + key); + System.out.print(" " + key + "[" + Configuration.getConfig(key) + "]"); } System.out.println(""); - System.out.println(" Values are boolean, you can use 0/1, true/false or yes/no."); + System.out.println(" Values are boolean, you can use 0/1, true/false, on/off or yes/no."); System.out.println(" If no other parameters passed, configuration is saved. Otherwise it is used only once."); System.out.println(" DO NOT PUT space between comma (,) and next value."); System.out.println(" 9) -onerror (abort|retryN|ignore)"); System.out.println(" ...error handling mode. \"abort\" stops the exporting, \"retry\" tries the exporting N times, \"ignore\" ignores the current file"); + System.out.println(" 10) -timeout N"); + System.out.println(" ...decompilation timeout for a single method in AS3 or single action in AS1/2 in seconds"); System.out.println(); System.out.println("Examples:"); System.out.println("java -jar ffdec.jar myfile.swf"); @@ -751,7 +753,7 @@ public class Main { View.setLookAndFeel(); - if (Configuration.getConfig("cacheOnDisk", Boolean.TRUE)) { + if (Configuration.getConfig("cacheOnDisk", true)) { Cache.setStorageType(Cache.STORAGE_FILES); } else { Cache.setStorageType(Cache.STORAGE_MEMORY); @@ -775,42 +777,7 @@ public class Main { System.err.println("Config values expected"); badArguments(); } - String cfgStr = args[pos]; - String cfgs[]; - if (cfgStr.contains(",")) { - cfgs = cfgStr.split(","); - } else { - cfgs = new String[]{cfgStr}; - } - - for (String c : cfgs) { - String cp[]; - if (c.contains("=")) { - cp = c.split("="); - } else { - cp = new String[]{c, "1"}; - } - String key = cp[0]; - String value = cp[1]; - if (key.toLowerCase().equals("paralelSpeedUp".toLowerCase())) { - key = "parallelSpeedUp"; - } - for (String bk : commandlineConfigBoolean) { - if (key.toLowerCase().equals(bk.toLowerCase())) { - Boolean bValue = null; - if (value.equals("0") || value.toLowerCase().equals("false") || value.toLowerCase().equals("no") || value.toLowerCase().equals("off")) { - bValue = false; - } - if (value.equals("1") || value.toLowerCase().equals("true") || value.toLowerCase().equals("yes") || value.toLowerCase().equals("on")) { - bValue = true; - } - if (bValue != null) { - System.out.println("Config " + bk + " set to " + bValue); - Configuration.setConfig(bk, bValue); - } - } - } - } + setConfigurations(args[pos]); pos++; if (args.length <= pos) { saveConfig(); @@ -818,7 +785,7 @@ public class Main { return; } } - if (args[pos].equals("-onerror")) { + else if (args[pos].equals("-onerror")) { parameterProcessed = true; pos++; if (args.length <= pos) { @@ -849,6 +816,22 @@ public class Main { break; } + pos++; + } + else if (args[pos].equals("-timeout")) { + parameterProcessed = true; + pos++; + if (args.length <= pos) { + System.err.println("timeout parameter expected"); + badArguments(); + } + try { + int timeout = Integer.parseInt(args[pos]); + Configuration.setConfig("decompilationTimeoutSingleMethod", timeout); + } catch (NumberFormatException nex) { + System.err.println("Bad timeout value"); + } + pos++; } } @@ -911,6 +894,7 @@ public class Main { badArguments(); } commandLineMode = true; + long startTime = System.currentTimeMillis(); boolean exportOK; try { printHeader(); @@ -998,6 +982,9 @@ public class Main { Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex); System.exit(1); } + long stopTime = System.currentTimeMillis(); + long time = stopTime - startTime; + System.out.println("Export finished. Total export time: " + Helper.formatTimeSec(time)); if (exportOK) { System.out.println("OK"); System.exit(0); @@ -1054,6 +1041,54 @@ public class Main { } } + private static void setConfigurations(String cfgStr) { + String cfgs[]; + if (cfgStr.contains(",")) { + cfgs = cfgStr.split(","); + } else { + cfgs = new String[]{cfgStr}; + } + + for (String c : cfgs) { + String cp[]; + if (c.contains("=")) { + cp = c.split("="); + } else { + cp = new String[]{c, "1"}; + } + String key = cp[0]; + String value = cp[1]; + if (key.toLowerCase().equals("paralelSpeedUp".toLowerCase())) { + key = "parallelSpeedUp"; + } + for (String bk : commandlineConfigBoolean) { + if (key.toLowerCase().equals(bk.toLowerCase())) { + Boolean bValue = parseBooleanConfigValue(value); + if (bValue != null) { + System.out.println("Config " + bk + " set to " + bValue); + Configuration.setConfig(bk, bValue); + } + } + } + } + } + + private static Boolean parseBooleanConfigValue(String value){ + if (value == null){ + return null; + } + + Boolean bValue = null; + value = value.toLowerCase(); + if (value.equals("0") || value.equals("false") || value.equals("no") || value.equals("off")) { + bValue = false; + } + if (value.equals("1") || value.equals("true") || value.equals("yes") || value.equals("on")) { + bValue = true; + } + return bValue; + } + public static String tempFile(String url) throws IOException { File f = new File(getFFDecHome() + "saved" + File.separator); if (!f.exists()) { diff --git a/trunk/src/com/jpexs/decompiler/flash/gui/MainFrame.java b/trunk/src/com/jpexs/decompiler/flash/gui/MainFrame.java index 75806c207..2a0010d83 100644 --- a/trunk/src/com/jpexs/decompiler/flash/gui/MainFrame.java +++ b/trunk/src/com/jpexs/decompiler/flash/gui/MainFrame.java @@ -689,9 +689,9 @@ public class MainFrame extends AppRibbonFrame implements ActionListener, TreeSel menuTools.add(miSearchScript); //miInternalViewer = new JCheckBox(translate("menu.settings.internalflashviewer")); - miInternalViewer.setSelected(Configuration.getConfig("internalFlashViewer", (Boolean) (flashPanel == null))); - if (flashPanel == null) { - miInternalViewer.setSelected(true); + boolean externalFlashPlayerUnavailable = flashPanel == null; + miInternalViewer.setSelected(Configuration.getConfig("internalFlashViewer", false) || externalFlashPlayerUnavailable); + if (externalFlashPlayerUnavailable) { miInternalViewer.setEnabled(false); } miInternalViewer.setActionCommand("INTERNALVIEWERSWITCH"); @@ -2319,7 +2319,7 @@ public class MainFrame extends AppRibbonFrame implements ActionListener, TreeSel } break; case "INTERNALVIEWERSWITCH": - Configuration.setConfig("internalFlashViewer", (Boolean) miInternalViewer.isSelected()); + Configuration.setConfig("internalFlashViewer", miInternalViewer.isSelected()); reload(true); break; case "SEARCHAS":