diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/ScriptPack.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/ScriptPack.java index 91130da18..f855e3ef0 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/ScriptPack.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/ScriptPack.java @@ -379,7 +379,7 @@ public class ScriptPack extends AS3ClassTreeItem { //String filepath = path.toString().replace('.', '/') + ".as"; String pkg = path.packageStr.toString(); String cls = path.className; - String filename = new File(directoryPath, path.packageStr.toFilePath()) + ";" + pkg + ";" + cls + ".as"; + String filename = new File(directoryPath, path.packageStr.toFilePath()) + ";" + pkg.replace(".", File.separator) + ";" + cls + ".as"; for (int bodyIndex : bodyToPosToLine.keySet()) { MethodBody b = abc.bodies.get(bodyIndex); diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/configuration/Configuration.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/configuration/Configuration.java index c1bdf2c98..72f682e09 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/configuration/Configuration.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/configuration/Configuration.java @@ -234,12 +234,15 @@ public class Configuration { public static final ConfigurationItem lastRenameType = null; @ConfigurationDefaultString(".") + @ConfigurationDirectory public static final ConfigurationItem lastSaveDir = null; @ConfigurationDefaultString(".") + @ConfigurationDirectory public static final ConfigurationItem lastOpenDir = null; @ConfigurationDefaultString(".") + @ConfigurationDirectory public static final ConfigurationItem lastExportDir = null; @ConfigurationDefaultString("en") @@ -502,6 +505,21 @@ public class Configuration { @ConfigurationCategory("ui") public static final ConfigurationItem autoOpenLoadedSWFs = null; + @ConfigurationDefaultString("") + @ConfigurationCategory("paths") + @ConfigurationFile + public static final ConfigurationItem playerLocation = null; + + @ConfigurationDefaultString("") + @ConfigurationCategory("paths") + @ConfigurationFile + public static final ConfigurationItem playerDebugLocation = null; + + @ConfigurationDefaultString("") + @ConfigurationCategory("paths") + @ConfigurationFile(".*\\.swc$") + public static final ConfigurationItem playerLibLocation = null; + private enum OSId { WINDOWS, OSX, UNIX @@ -761,6 +779,12 @@ public class Configuration { } catch (IOException ex) { Logger.getLogger(Configuration.class.getName()).log(Level.SEVERE, null, ex); } + if (playerLibLocation.get("").isEmpty()) { + File swcFile = getPlayerSwcOld(); + if (swcFile != null) { + playerLibLocation.set(swcFile.getAbsolutePath()); + } + } } public static Object getDefaultValue(Field field) { @@ -838,7 +862,7 @@ public class Configuration { String proxyAddress = Configuration.updateProxyAddress.get(); URL url = new URL(urlString); - URLConnection uc = null; + URLConnection uc; if (proxyAddress != null && !proxyAddress.isEmpty()) { int port = 8080; if (proxyAddress.contains(":")) { @@ -900,6 +924,21 @@ public class Configuration { } public static File getPlayerSWC() { + String libLocation = playerLibLocation.get(""); + File ret = null; + if (!libLocation.isEmpty()) { + ret = new File(libLocation); + } + if (ret == null || !ret.exists()) { + ret = getPlayerSwcOld(); + if (ret != null) { + playerLibLocation.set(ret.getAbsolutePath()); + } + } + return ret; + } + + private static File getPlayerSwcOld() { File libsDir = getFlashLibPath(); if (libsDir != null && libsDir.exists()) { File[] libs = libsDir.listFiles(new FilenameFilter() { diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/configuration/ConfigurationDirectory.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/configuration/ConfigurationDirectory.java new file mode 100644 index 000000000..cc9516634 --- /dev/null +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/configuration/ConfigurationDirectory.java @@ -0,0 +1,32 @@ +/* + * Copyright (C) 2010-2015 JPEXS, All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3.0 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. + */ +package com.jpexs.decompiler.flash.configuration; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * + * @author JPEXS + */ +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.FIELD) +public @interface ConfigurationDirectory { + +} diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/configuration/ConfigurationFile.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/configuration/ConfigurationFile.java new file mode 100644 index 000000000..14aab6068 --- /dev/null +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/configuration/ConfigurationFile.java @@ -0,0 +1,33 @@ +/* + * Copyright (C) 2010-2015 JPEXS, All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3.0 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. + */ +package com.jpexs.decompiler.flash.configuration; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * + * @author JPEXS + */ +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.FIELD) +public @interface ConfigurationFile { + + String value() default "^.*$"; +} diff --git a/src/com/jpexs/decompiler/flash/gui/AdvancedSettingsDialog.java b/src/com/jpexs/decompiler/flash/gui/AdvancedSettingsDialog.java index 064516cf7..e3e5e1e73 100644 --- a/src/com/jpexs/decompiler/flash/gui/AdvancedSettingsDialog.java +++ b/src/com/jpexs/decompiler/flash/gui/AdvancedSettingsDialog.java @@ -18,8 +18,11 @@ package com.jpexs.decompiler.flash.gui; import com.jpexs.decompiler.flash.configuration.Configuration; import com.jpexs.decompiler.flash.configuration.ConfigurationCategory; +import com.jpexs.decompiler.flash.configuration.ConfigurationDirectory; +import com.jpexs.decompiler.flash.configuration.ConfigurationFile; import com.jpexs.decompiler.flash.configuration.ConfigurationItem; import com.jpexs.decompiler.flash.gui.helpers.SpringUtilities; +import com.jpexs.helpers.Helper; import java.awt.BorderLayout; import java.awt.Color; import java.awt.Component; @@ -28,8 +31,11 @@ import java.awt.Dimension; import java.awt.FlowLayout; import java.awt.Graphics; import java.awt.Graphics2D; +import java.awt.Insets; import java.awt.RenderingHints; import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.io.File; import java.lang.reflect.Field; import java.lang.reflect.ParameterizedType; import java.text.ParseException; @@ -47,6 +53,8 @@ import javax.swing.Icon; import javax.swing.JButton; import javax.swing.JCheckBox; import javax.swing.JComboBox; +import javax.swing.JFileChooser; +import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JList; import javax.swing.JOptionPane; @@ -56,6 +64,7 @@ import javax.swing.JTabbedPane; import javax.swing.JTextField; import javax.swing.SpringLayout; import javax.swing.WindowConstants; +import javax.swing.filechooser.FileFilter; import javax.swing.table.DefaultTableModel; import org.pushingpixels.substance.api.ColorSchemeAssociationKind; import org.pushingpixels.substance.api.ComponentState; @@ -241,7 +250,7 @@ public class AdvancedSettingsDialog extends AppDialog { Map tabs = new HashMap<>(); getCategories(componentsMap, tabs, skinComboBox, getResourceBundle()); - String catOrder[] = new String[]{"ui", "display", "decompilation", "script", "format", "export", "import", "limit", "update", "debug", "other"}; + String catOrder[] = new String[]{"ui", "display", "decompilation", "script", "format", "export", "import", "paths", "limit", "update", "debug", "other"}; for (String cat : catOrder) { if (!tabs.containsKey(cat)) { @@ -256,6 +265,40 @@ public class AdvancedSettingsDialog extends AppDialog { pack(); } + public static String selectConfigFile(ConfigurationItem config, String current, String pattern) { + JFileChooser fc = new JFileChooser(); + fc.setSelectedFile(new File(current)); + fc.setMultiSelectionEnabled(false); + fc.setCurrentDirectory(new File((String) config.get())); + FileFilter allSupportedFilter = new FileFilter() { + private final String[] supportedExtensions = new String[]{".swf", ".gfx", ".swc", ".zip"}; + + @Override + public boolean accept(File f) { + if (f.isDirectory()) { + return true; + } + return f.getName().matches(pattern); + } + + @Override + public String getDescription() { + return ""; + } + }; + fc.setFileFilter(allSupportedFilter); + + fc.setAcceptAllFileFilterUsed(false); + JFrame f = new JFrame(); + View.setWindowIcon(f); + int returnVal = fc.showOpenDialog(f); + if (returnVal == JFileChooser.APPROVE_OPTION) { + return Helper.fixDialogFile(fc.getSelectedFile()).getAbsolutePath(); + } else { + return (String) config.get(); + } + } + public static void getCategories(Map componentsMap, Map tabs, JComboBox skinComboBox, ResourceBundle resourceBundle) { Map> categorized = new HashMap<>(); @@ -315,11 +358,15 @@ public class AdvancedSettingsDialog extends AppDialog { l.setToolTipText(description); configPanel.add(l); Component c = null; + Component addComponent = null; if (name.equals("gui.skin")) { skinComboBox.setToolTipText(description); skinComboBox.setMaximumSize(new Dimension(Integer.MAX_VALUE, skinComboBox.getPreferredSize().height)); c = skinComboBox; } else if ((itemType == String.class) || (itemType == Integer.class) || (itemType == Long.class) || (itemType == Double.class) || (itemType == Float.class) || (itemType == Calendar.class)) { + ConfigurationFile confFile = field.getAnnotation(ConfigurationFile.class); + ConfigurationDirectory confDirectory = field.getAnnotation(ConfigurationDirectory.class); + JTextField tf = new JTextField(); Object val = item.get(); if (val == null) { @@ -332,7 +379,21 @@ public class AdvancedSettingsDialog extends AppDialog { } tf.setToolTipText(description); tf.setMaximumSize(new Dimension(Integer.MAX_VALUE, tf.getPreferredSize().height)); + c = tf; + if (confFile != null) { //|| confDirectory != null) { + JPanel p = new JPanel(new BorderLayout()); + p.setMaximumSize(new Dimension(Integer.MAX_VALUE, tf.getPreferredSize().height)); + p.add(tf, BorderLayout.CENTER); + JButton butSelect = new JButton(View.getIcon("folderopen16")); + butSelect.setToolTipText(AppStrings.translate("FileChooser.openButtonText")); + butSelect.setMargin(new Insets(2, 2, 2, 2)); + butSelect.addActionListener((ActionEvent e) -> { + tf.setText(selectConfigFile(item, tf.getText(), confFile.value())); + }); + p.add(butSelect, BorderLayout.EAST); + addComponent = p; + } } else if (itemType == Boolean.class) { JCheckBox cb = new JCheckBox(); cb.setSelected((Boolean) item.get()); @@ -362,8 +423,11 @@ public class AdvancedSettingsDialog extends AppDialog { } componentsMap.put(name, c); + if (addComponent == null) { + addComponent = c; + } l.setLabelFor(c); - configPanel.add(c); + configPanel.add(addComponent); } catch (IllegalArgumentException | IllegalAccessException ex) { // Reflection exceptions. This should never happen throw new Error(ex.getMessage()); diff --git a/src/com/jpexs/decompiler/flash/gui/DebuggerHandler.java b/src/com/jpexs/decompiler/flash/gui/DebuggerHandler.java index 058f3f615..d9055876d 100644 --- a/src/com/jpexs/decompiler/flash/gui/DebuggerHandler.java +++ b/src/com/jpexs/decompiler/flash/gui/DebuggerHandler.java @@ -27,8 +27,8 @@ import com.jpexs.debugger.flash.messages.in.InNumScript; import com.jpexs.debugger.flash.messages.in.InScript; import com.jpexs.debugger.flash.messages.in.InSwfInfo; import com.jpexs.decompiler.flash.abc.ClassPath; -import com.jpexs.decompiler.flash.abc.ScriptPack; import com.jpexs.decompiler.graph.DottedChain; +import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -38,10 +38,26 @@ import java.util.logging.Logger; /** * - * @author Jindra + * @author JPEXS */ public class DebuggerHandler implements DebugConnectionListener { + private boolean connected = false; + private DebuggerCommands commands = null; + private List swfs = new ArrayList<>(); + + public List getSwfs() { + return swfs; + } + + public boolean isConnected() { + return connected; + } + + public DebuggerCommands getCommands() { + return commands; + } + @Override public void connected(DebuggerConnection con) { @@ -54,17 +70,17 @@ public class DebuggerHandler implements DebugConnectionListener { rootLog.addHandler(ch); //rootLog.getHandlers()[0].setLevel(level); - final DebuggerCommands dc = new DebuggerCommands(con); - dc.stopWarning(); - dc.setStopOnFault(); - dc.setEnumerateOverride(); - dc.setNotifyFailure(); - dc.setInvokeSetters(); - dc.setSwfLoadNotify(); - dc.setGetterTimeout(1500); - dc.setSetterTimeout(5000); - dc.squelch(true); - List swfs = dc.getSwfInfo(1); + commands = new DebuggerCommands(con); + commands.stopWarning(); + commands.setStopOnFault(); + commands.setEnumerateOverride(); + commands.setNotifyFailure(); + commands.setInvokeSetters(); + commands.setSwfLoadNotify(); + commands.setGetterTimeout(1500); + commands.setSetterTimeout(5000); + commands.squelch(true); + swfs = commands.getSwfInfo(1); int numScript = con.getMessage(InNumScript.class).num; final Map moduleNames = new HashMap<>(); for (int i = 0; i < numScript; i++) { @@ -81,24 +97,26 @@ public class DebuggerHandler implements DebugConnectionListener { if (parts.length == 3) { String clsName = parts[2].replace(".as", ""); - String pkg = parts[1]; + String pkg = parts[1].replace("/", "\\").replace("\\", "."); modulePaths.put(mname, new ClassPath(DottedChain.parse(pkg), clsName)); } } con.getMessage(InAskBreakpoints.class); - //dc.addBreakPoint(15, 14); - dc.addBreakPoint(9, 26); con.addMessageListener(new DebugMessageListener() { @Override public void message(InBreakAt message) { - Logger.getLogger(DebuggerHandler.class.getName()).log(Level.WARNING, "break at {0}:{1}", new Object[]{moduleNames.get(message.file), message.line}); + Logger.getLogger(DebuggerHandler.class.getName()).log(Level.INFO, "break at {0}:{1}", new Object[]{moduleNames.get(message.file), message.line}); + if (!modulePaths.containsKey(message.file)) { + return; + } String cls = modulePaths.get(message.file).toString(); Main.getMainFrame().getPanel().debuggerBreakAt(Main.getMainFrame().getPanel().getCurrentSwf(), cls, message.line); //dc.sendContinue(); } }); - dc.sendContinue(); + commands.sendContinue(); + connected = true; } } diff --git a/src/com/jpexs/decompiler/flash/gui/Main.java b/src/com/jpexs/decompiler/flash/gui/Main.java index 6b41bd7fe..7016ca3bc 100644 --- a/src/com/jpexs/decompiler/flash/gui/Main.java +++ b/src/com/jpexs/decompiler/flash/gui/Main.java @@ -151,6 +151,12 @@ public class Main { private static Debugger flashDebugger; + private static DebuggerHandler debugHandler = null; + + public static DebuggerHandler getDebugHandler() { + return debugHandler; + } + public static void ensureMainFrame() { if (mainFrame == null) { synchronized (Main.class) { @@ -1025,10 +1031,11 @@ public class Main { rootLog.getHandlers()[0].setLevel(level); */ flashDebugger = new Debugger(); - flashDebugger.addConnectionListener(new DebuggerHandler()); + debugHandler = new DebuggerHandler(); + flashDebugger.addConnectionListener(debugHandler); flashDebugger.start(); } catch (IOException ex) { - Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex); + //ignore } } diff --git a/src/com/jpexs/decompiler/flash/gui/MainFrameMenu.java b/src/com/jpexs/decompiler/flash/gui/MainFrameMenu.java index 015d6699c..b138eee1d 100644 --- a/src/com/jpexs/decompiler/flash/gui/MainFrameMenu.java +++ b/src/com/jpexs/decompiler/flash/gui/MainFrameMenu.java @@ -16,6 +16,7 @@ */ package com.jpexs.decompiler.flash.gui; +import com.jpexs.debugger.flash.DebuggerCommands; import com.jpexs.decompiler.flash.ApplicationInfo; import com.jpexs.decompiler.flash.SWF; import com.jpexs.decompiler.flash.SWFBundle; @@ -41,13 +42,19 @@ import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.KeyEvent; import java.awt.event.WindowEvent; +import java.io.BufferedOutputStream; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; import java.io.IOException; +import java.io.OutputStream; import java.io.PrintStream; import java.util.List; import java.util.Timer; import java.util.TimerTask; +import java.util.concurrent.atomic.AtomicBoolean; import java.util.logging.Level; import java.util.logging.Logger; import javax.swing.AbstractButton; @@ -635,6 +642,10 @@ public abstract class MainFrameMenu implements MenuBuilder { public void updateComponents(SWF swf) { this.swf = swf; + boolean isRunning = isRunning(); + boolean isDebugRunning = isDebugRunning(); + boolean isRunningOrDebugging = isRunning || isDebugRunning; + boolean swfSelected = swf != null; boolean isWorking = Main.isWorking(); List abcList = swf != null ? swf.getAbcList() : null; @@ -692,6 +703,19 @@ public abstract class MainFrameMenu implements MenuBuilder { setMenuEnabled("/help/homePage", !isWorking); setMenuEnabled("_/about", !isWorking); setMenuEnabled("/help/about", !isWorking); + + setMenuEnabled("/execution/start/run", !isRunningOrDebugging); + setMenuEnabled("/execution/start/debug", !isRunningOrDebugging); + setMenuEnabled("/execution/start/stop", isRunningOrDebugging); + setMenuEnabled("/execution/debug", isDebugRunning); + setMenuEnabled("/execution/debug/pause", isDebugRunning); + setMenuEnabled("/execution/debug/stepOver", isDebugRunning); + setMenuEnabled("/execution/debug/stepInto", isDebugRunning); + setMenuEnabled("/execution/debug/stepOut", isDebugRunning); + setMenuEnabled("/execution/debug/continue", isDebugRunning); + setMenuEnabled("/execution/debug/stack", isDebugRunning); + setMenuEnabled("/execution/debug/watch", isDebugRunning); + } private void registerHotKeys() { @@ -774,6 +798,37 @@ public abstract class MainFrameMenu implements MenuBuilder { setGroupSelection("view", "/file/view/viewResources"); } + /* + menu.execution = Execution + menu.execution.start.run = Run + menu.execution.start.debug = Debug + menu.execution.start.stop = Stop + menu.execution.debug.pause = Pause + menu.execution.debug.stepOver = Step over + menu.execution.debug.stepInto = Step into + menu.execution.debug.stepOut = Step out + menu.execution.debug.continue = Continue + menu.execution.debug.stack = Stack... + menu.execution.debug.watch = New watch... + */ + addMenuItem("/execution", translate("menu.execution"), null, null, 0, null, false); + addMenuItem("/execution/start", translate("menu.execution.start"), null, null, 0, null, false); + addMenuItem("/execution/start/run", translate("menu.execution.start.run"), "play32", this::runActionPerformed, PRIORITY_TOP, null, true); + addMenuItem("/execution/start/debug", translate("menu.execution.start.debug"), "debug32", this::debugActionPerformed, PRIORITY_TOP, null, true); + addMenuItem("/execution/start/stop", translate("menu.execution.start.stop"), "stop32", this::stopActionPerformed, PRIORITY_TOP, null, true); + finishMenu("/execution/start"); + + addMenuItem("/execution/debug", translate("menu.execution.debug"), null, null, 0, null, false); + addMenuItem("/execution/debug/pause", translate("menu.execution.debug.pause"), "pause32", this::pauseActionPerformed, PRIORITY_TOP, null, true); + addMenuItem("/execution/debug/continue", translate("menu.execution.debug.continue"), "continue32", this::continueActionPerformed, PRIORITY_TOP, null, true); + addMenuItem("/execution/debug/stepOver", translate("menu.execution.debug.stepOver"), "stepover32", this::stepOverActionPerformed, PRIORITY_MEDIUM, null, true); + addMenuItem("/execution/debug/stepInto", translate("menu.execution.debug.stepInto"), "stepinto32", this::stepIntoActionPerformed, PRIORITY_MEDIUM, null, true); + addMenuItem("/execution/debug/stepOut", translate("menu.execution.debug.stepOut"), "stepout32", this::stepOutActionPerformed, PRIORITY_MEDIUM, null, true); + addMenuItem("/execution/debug/stack", translate("menu.execution.debug.stack"), "stack32", this::stackActionPerformed, PRIORITY_MEDIUM, null, true); + addMenuItem("/execution/debug/watch", translate("menu.execution.debug.watch"), "watch32", this::watchActionPerformed, PRIORITY_MEDIUM, null, true); + finishMenu("/execution/debug"); + finishMenu("/execution"); + addMenuItem("/tools", translate("menu.tools"), null, null, 0, null, false); addMenuItem("/tools/search", translate("menu.tools.search"), "search16", this::searchActionPerformed, PRIORITY_TOP, null, true); @@ -1017,10 +1072,216 @@ public abstract class MainFrameMenu implements MenuBuilder { manager.removeKeyEventDispatcher(keyEventDispatcher); } + private Process runProcess; + private boolean runProcessDebug; + private File runTempFile; + + public synchronized boolean isDebugRunning() { + return runProcess != null && runProcessDebug; + } + + public synchronized boolean isRunning() { + return runProcess != null && !runProcessDebug; + } + + private synchronized void setProcess(Process p) { + this.runProcess = p; + } + + private synchronized void freeRun() { + if (runTempFile != null) { + runTempFile.delete(); + runTempFile = null; + } + runProcess = null; + } + + private void runPlayer(String exePath, String file, String flashVars) { + if (!new File(file).exists()) { + return; + } + final Process proc; + if (flashVars != null && !flashVars.isEmpty()) { + file += "?" + flashVars; + } + try { + proc = Runtime.getRuntime().exec("\"" + exePath + "\" \"file://" + file + "\""); + + } catch (IOException ex) { + Logger.getLogger(MainFrameMenu.class + .getName()).log(Level.SEVERE, null, ex); + + return; + } + Thread t = new Thread() { + + @Override + public void run() { + try { + proc.waitFor(); + + } catch (InterruptedException ex) { + Logger.getLogger(MainFrameMenu.class + .getName()).log(Level.SEVERE, null, ex); + } + freeRun(); + updateComponents(); + } + + }; + t.start(); + synchronized (this) { + runProcess = proc; + } + updateComponents(); + } + + public boolean runActionPerformed(ActionEvent evt) { + String flashVars = "";//key=val&key2=val2 + String playerLocation = Configuration.playerLocation.get(); + if (playerLocation.isEmpty() || (!new File(playerLocation).exists())) { + View.showMessageDialog(null, AppStrings.translate("message.playerpath.notset"), AppStrings.translate("error"), JOptionPane.ERROR_MESSAGE); + return true; + } + if (swf == null) { + return true; + } + File tempFile; + try { + tempFile = File.createTempFile("ffdec_run_", ".swf"); + + try (OutputStream fos = new BufferedOutputStream(new FileOutputStream(tempFile))) { + swf.saveTo(fos); + } + } catch (IOException ex) { + return true; + + } + if (tempFile != null) { + synchronized (this) { + runTempFile = tempFile; + runProcessDebug = false; + } + runPlayer(playerLocation, tempFile.getAbsolutePath(), flashVars); + } + return true; + } + + public boolean debugActionPerformed(ActionEvent evt) { + String flashVars = "";//key=val&key2=val2 + String playerLocation = Configuration.playerDebugLocation.get(); + if (playerLocation.isEmpty() || (!new File(playerLocation).exists())) { + View.showMessageDialog(null, AppStrings.translate("message.playerpath.debug.notset"), AppStrings.translate("error"), JOptionPane.ERROR_MESSAGE); + return true; + } + if (swf == null) { + return true; + } + File tempFile; + try { + tempFile = File.createTempFile("ffdec_debug_", ".swf"); + + try (OutputStream fos = new BufferedOutputStream(new FileOutputStream(tempFile))) { + swf.saveTo(fos); + } + //Inject Loader + SWF instrSWF = null; + try (FileInputStream fis = new FileInputStream(tempFile)) { + instrSWF = new SWF(fis, false, false); + + } catch (InterruptedException ex) { + Logger.getLogger(MainFrameMenu.class + .getName()).log(Level.SEVERE, null, ex); + } + if (instrSWF != null) { + instrSWF.enableDebugging(true, new File(".")); + try (OutputStream fos = new BufferedOutputStream(new FileOutputStream(tempFile))) { + instrSWF.saveTo(fos); + + } + } + + } catch (IOException ex) { + Logger.getLogger(MainFrameMenu.class + .getName()).log(Level.SEVERE, "Cannot inject debug info", ex); + + return true; + } + synchronized (this) { + runTempFile = tempFile; + runProcessDebug = true; + } + runPlayer(playerLocation, tempFile.getAbsolutePath(), flashVars); + return true; + } + + public boolean stopActionPerformed(ActionEvent evt) { + + synchronized (this) { + if (runProcess != null) { + runProcess.destroy(); + } + } + freeRun(); + + updateComponents(); + return true; + } + + public boolean pauseActionPerformed(ActionEvent evt) { + DebuggerCommands cmd = Main.getDebugHandler().getCommands(); + if (cmd != null) { + //TODO + } + return true; + } + + public boolean stepOverActionPerformed(ActionEvent evt) { + DebuggerCommands cmd = Main.getDebugHandler().getCommands(); + if (cmd != null) { + cmd.stepOver(); + } + return true; + } + + public boolean stepIntoActionPerformed(ActionEvent evt) { + DebuggerCommands cmd = Main.getDebugHandler().getCommands(); + if (cmd != null) { + cmd.stepInto(); + } + return true; + } + + public boolean stepOutActionPerformed(ActionEvent evt) { + DebuggerCommands cmd = Main.getDebugHandler().getCommands(); + if (cmd != null) { + cmd.stepOut(); + } + return true; + } + + public boolean continueActionPerformed(ActionEvent evt) { + DebuggerCommands cmd = Main.getDebugHandler().getCommands(); + if (cmd != null) { + cmd.stepContinue(); + } + return true; + } + + public boolean stackActionPerformed(ActionEvent evt) { + //TODO + return true; + } + + public boolean watchActionPerformed(ActionEvent evt) { + //TODO + return true; + } + public boolean dispatchKeyEvent(KeyEvent e) { if (((JFrame) mainFrame).isActive() && e.getID() == KeyEvent.KEY_PRESSED) { int code = e.getKeyCode(); - if (e.isControlDown() && e.isShiftDown()) { + if (e.isControlDown() && e.isShiftDown()) { //CTRL+SHIFT switch (code) { case KeyEvent.VK_O: return openActionPerformed(null); @@ -1041,13 +1302,28 @@ public abstract class MainFrameMenu implements MenuBuilder { case KeyEvent.VK_E: return export(false); } - } else if (e.isControlDown() && !e.isShiftDown()) { + } else if (e.isControlDown() && !e.isShiftDown()) { //CTRL switch (code) { + case KeyEvent.VK_F7: + return stepOutActionPerformed(null); + case KeyEvent.VK_F5: + return debugActionPerformed(null); case KeyEvent.VK_UP: return previousTag(); case KeyEvent.VK_DOWN: return nextTag(); } + } else if (!e.isControlDown() && !e.isShiftDown()) { //no modifier + switch (code) { + case KeyEvent.VK_F5: + return continueActionPerformed(null); + case KeyEvent.VK_F6: + return runActionPerformed(null); + case KeyEvent.VK_F7: + return stepIntoActionPerformed(null); + case KeyEvent.VK_F8: + return stepOverActionPerformed(null); + } } } diff --git a/src/com/jpexs/decompiler/flash/gui/graphics/continue16.png b/src/com/jpexs/decompiler/flash/gui/graphics/continue16.png new file mode 100644 index 000000000..184be2312 Binary files /dev/null and b/src/com/jpexs/decompiler/flash/gui/graphics/continue16.png differ diff --git a/src/com/jpexs/decompiler/flash/gui/graphics/continue32.png b/src/com/jpexs/decompiler/flash/gui/graphics/continue32.png new file mode 100644 index 000000000..a1f7345f3 Binary files /dev/null and b/src/com/jpexs/decompiler/flash/gui/graphics/continue32.png differ diff --git a/src/com/jpexs/decompiler/flash/gui/graphics/debug16.png b/src/com/jpexs/decompiler/flash/gui/graphics/debug16.png new file mode 100644 index 000000000..03e5eb2b4 Binary files /dev/null and b/src/com/jpexs/decompiler/flash/gui/graphics/debug16.png differ diff --git a/src/com/jpexs/decompiler/flash/gui/graphics/debug32.png b/src/com/jpexs/decompiler/flash/gui/graphics/debug32.png new file mode 100644 index 000000000..a8f268677 Binary files /dev/null and b/src/com/jpexs/decompiler/flash/gui/graphics/debug32.png differ diff --git a/src/com/jpexs/decompiler/flash/gui/graphics/pause32.png b/src/com/jpexs/decompiler/flash/gui/graphics/pause32.png new file mode 100644 index 000000000..3ab8b69db Binary files /dev/null and b/src/com/jpexs/decompiler/flash/gui/graphics/pause32.png differ diff --git a/src/com/jpexs/decompiler/flash/gui/graphics/play32.png b/src/com/jpexs/decompiler/flash/gui/graphics/play32.png new file mode 100644 index 000000000..a1f7345f3 Binary files /dev/null and b/src/com/jpexs/decompiler/flash/gui/graphics/play32.png differ diff --git a/src/com/jpexs/decompiler/flash/gui/graphics/stack16.png b/src/com/jpexs/decompiler/flash/gui/graphics/stack16.png new file mode 100644 index 000000000..6d659e177 Binary files /dev/null and b/src/com/jpexs/decompiler/flash/gui/graphics/stack16.png differ diff --git a/src/com/jpexs/decompiler/flash/gui/graphics/stack32.png b/src/com/jpexs/decompiler/flash/gui/graphics/stack32.png new file mode 100644 index 000000000..3ae41eff2 Binary files /dev/null and b/src/com/jpexs/decompiler/flash/gui/graphics/stack32.png differ diff --git a/src/com/jpexs/decompiler/flash/gui/graphics/stepinto16.png b/src/com/jpexs/decompiler/flash/gui/graphics/stepinto16.png new file mode 100644 index 000000000..691f6e0c7 Binary files /dev/null and b/src/com/jpexs/decompiler/flash/gui/graphics/stepinto16.png differ diff --git a/src/com/jpexs/decompiler/flash/gui/graphics/stepinto32.png b/src/com/jpexs/decompiler/flash/gui/graphics/stepinto32.png new file mode 100644 index 000000000..2aa47f51c Binary files /dev/null and b/src/com/jpexs/decompiler/flash/gui/graphics/stepinto32.png differ diff --git a/src/com/jpexs/decompiler/flash/gui/graphics/stepout16.png b/src/com/jpexs/decompiler/flash/gui/graphics/stepout16.png new file mode 100644 index 000000000..6a7c9bc18 Binary files /dev/null and b/src/com/jpexs/decompiler/flash/gui/graphics/stepout16.png differ diff --git a/src/com/jpexs/decompiler/flash/gui/graphics/stepout32.png b/src/com/jpexs/decompiler/flash/gui/graphics/stepout32.png new file mode 100644 index 000000000..c03843653 Binary files /dev/null and b/src/com/jpexs/decompiler/flash/gui/graphics/stepout32.png differ diff --git a/src/com/jpexs/decompiler/flash/gui/graphics/stepover16.png b/src/com/jpexs/decompiler/flash/gui/graphics/stepover16.png new file mode 100644 index 000000000..a588266dc Binary files /dev/null and b/src/com/jpexs/decompiler/flash/gui/graphics/stepover16.png differ diff --git a/src/com/jpexs/decompiler/flash/gui/graphics/stepover32.png b/src/com/jpexs/decompiler/flash/gui/graphics/stepover32.png new file mode 100644 index 000000000..be4f8e927 Binary files /dev/null and b/src/com/jpexs/decompiler/flash/gui/graphics/stepover32.png differ diff --git a/src/com/jpexs/decompiler/flash/gui/graphics/stop32.png b/src/com/jpexs/decompiler/flash/gui/graphics/stop32.png new file mode 100644 index 000000000..f15bf6921 Binary files /dev/null and b/src/com/jpexs/decompiler/flash/gui/graphics/stop32.png differ diff --git a/src/com/jpexs/decompiler/flash/gui/graphics/watch16.png b/src/com/jpexs/decompiler/flash/gui/graphics/watch16.png new file mode 100644 index 000000000..b81b18de1 Binary files /dev/null and b/src/com/jpexs/decompiler/flash/gui/graphics/watch16.png differ diff --git a/src/com/jpexs/decompiler/flash/gui/graphics/watch32.png b/src/com/jpexs/decompiler/flash/gui/graphics/watch32.png new file mode 100644 index 000000000..9cbc3618f Binary files /dev/null and b/src/com/jpexs/decompiler/flash/gui/graphics/watch32.png differ diff --git a/src/com/jpexs/decompiler/flash/gui/locales/AdvancedSettingsDialog.properties b/src/com/jpexs/decompiler/flash/gui/locales/AdvancedSettingsDialog.properties index 699fd58c7..90b3ecb88 100644 --- a/src/com/jpexs/decompiler/flash/gui/locales/AdvancedSettingsDialog.properties +++ b/src/com/jpexs/decompiler/flash/gui/locales/AdvancedSettingsDialog.properties @@ -383,3 +383,15 @@ config.description.autoOpenLoadedSWFs = Opens automatically all SWFs loaded by A config.name.lastSessionFileTitles = Last session file titles config.description.lastSessionFileTitles = Contains the opened file titles from the last session (for example when loaded from URL etc.) +config.group.name.paths = Paths +config.group.description.paths = Location of needed files + +config.name.playerLocation = Flash player executable path +config.description.playerLocation = Location of standalone flash player executable + +config.name.playerDebugLocation = Flash player debug executable path +config.description.playerDebugLocation = Location of standalone debug flash player executable + +config.name.playerLibLocation = Playerglobal.swc library path +config.description.playerLibLocation = Location of playerglobal.swc flash player library. It is used mostly for AS3 compilation. + diff --git a/src/com/jpexs/decompiler/flash/gui/locales/AdvancedSettingsDialog_cs.properties b/src/com/jpexs/decompiler/flash/gui/locales/AdvancedSettingsDialog_cs.properties index c44d9cb0c..1eec726be 100644 --- a/src/com/jpexs/decompiler/flash/gui/locales/AdvancedSettingsDialog_cs.properties +++ b/src/com/jpexs/decompiler/flash/gui/locales/AdvancedSettingsDialog_cs.properties @@ -359,3 +359,19 @@ config.description.swfSpecificConfigs = Obsahuje konfigurace pro jednotliv\u00e1 config.name.autoOpenLoadedSWFs = Otev\u00edrat na\u010d\u00edtan\u00e1 SWF b\u011bhem p\u0159ehr\u00e1v\u00e1n\u00ed (Extern\u00ed p\u0159ehr\u00e1va\u010d = jen WIN) config.description.autoOpenLoadedSWFs = Otev\u00edr\u00e1 automaticky v\u0161echna SWF na\u010d\u00edtan\u00e1 AS3 t\u0159\u00eddou Loader b\u011bhem p\u0159ehr\u00e1v\u00e1n\u00ed v extern\u00edm p\u0159ehr\u00e1va\u010di v FFDec. Toto funguje pouze ve Windows. + +config.name.lastSessionFileTitles = Titulky soubor\u016f z posledn\u00ed session +config.description.lastSessionFileTitles = Obsahuje titulky souboru z naposledy otev\u0159en\u00e9 session (nap\u0159\u00edklad kdy\u017e byly otev\u0159eny z URL apod.) + +config.group.name.paths = Cesty +config.group.description.paths = Um\u00edst\u011bn\u00ed pot\u0159ebn\u00fdch soubor\u016f + +config.name.playerLocation = Cesta k Flash playeru +config.description.playerLocation = Um\u00edst\u011bn\u00ed spustiteln\u00e9ho standalone Flash playeru + +config.name.playerDebugLocation = Cesta k Degug Flash playeru +config.description.playerDebugLocation = Um\u00edst\u011bn\u00ed spustiteln\u00e9ho standalone debug Flash playeru + +config.name.playerLibLocation = Cesta ke knihovn\u011b Playerglobal.swc +config.description.playerLibLocation = Um\u00edst\u011bn\u00ed knihovny playerglobal.swc, pou\u017e\u00edv\u00e1 se hlavn\u011b pro AS3 kompilaci. + diff --git a/src/com/jpexs/decompiler/flash/gui/locales/MainFrame.properties b/src/com/jpexs/decompiler/flash/gui/locales/MainFrame.properties index c6a18ea39..d29a5a3fd 100644 --- a/src/com/jpexs/decompiler/flash/gui/locales/MainFrame.properties +++ b/src/com/jpexs/decompiler/flash/gui/locales/MainFrame.properties @@ -630,4 +630,23 @@ error.image.alpha.invalid = Invalid alpha channel data. #after version 6.0.2 contextmenu.saveUncompressedToFile = Save to Uncompressed File abc.traitslist.scriptinitializer = script initializer -menu.settings.autoOpenLoadedSWFs = Open loaded SWFs while playing \ No newline at end of file +menu.settings.autoOpenLoadedSWFs = Open loaded SWFs while playing + +#after version 6.1.1 +menu.execution = Execution +menu.execution.start = Start +menu.execution.start.run = Run +menu.execution.start.debug = Debug +menu.execution.start.stop = Stop +menu.execution.debug = Debugging +menu.execution.debug.pause = Pause +menu.execution.debug.stepOver = Step over +menu.execution.debug.stepInto = Step into +menu.execution.debug.stepOut = Step out +menu.execution.debug.continue = Continue +menu.execution.debug.stack = Stack... +menu.execution.debug.watch = New watch... + + +message.playerpath.notset = Player executable not found. Please configure Flash Player path in Advanced Settings / Paths. +message.playerpath.debug.notset = Debug player executable not found. Please configure Debug Flash Player path in Advanced Settings / Paths. \ No newline at end of file