Issue #707 Debugger for logging messages
@@ -0,0 +1,114 @@
|
||||
/*
|
||||
* Copyright (C) 2014 JPEXS
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.jpexs.decompiler.flash.gui;
|
||||
|
||||
import com.jpexs.decompiler.flash.gui.debugger.DebugListener;
|
||||
import com.jpexs.decompiler.flash.gui.debugger.Debugger;
|
||||
import java.awt.BorderLayout;
|
||||
import java.awt.Color;
|
||||
import java.awt.Container;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.FlowLayout;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
import javax.swing.DefaultListModel;
|
||||
import javax.swing.JButton;
|
||||
import javax.swing.JList;
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.JScrollPane;
|
||||
import javax.swing.JTextArea;
|
||||
import javax.swing.ListModel;
|
||||
import javax.swing.text.BadLocationException;
|
||||
import javax.swing.text.Document;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public class DebugLogDialog extends AppDialog implements ActionListener {
|
||||
|
||||
private JTextArea logTextArea = new JTextArea();
|
||||
private final String ACTION_CLOSE = "CLOSE";
|
||||
private final String ACTION_CLEAR = "CLEAR";
|
||||
private Debugger debug;
|
||||
|
||||
public DebugLogDialog(Debugger debug) {
|
||||
setSize(800, 600);
|
||||
this.debug = debug;
|
||||
setTitle(translate("dialog.title"));
|
||||
logTextArea.setBackground(Color.white);
|
||||
logTextArea.setEditable(false);
|
||||
JScrollPane spane = new JScrollPane(logTextArea);
|
||||
spane.setPreferredSize(new Dimension(800,500));
|
||||
|
||||
debug.addMessageListener(new DebugListener() {
|
||||
|
||||
@Override
|
||||
public void onMessage(String clientId, String msg) {
|
||||
log(translate("msg.header").replace("%clientid%", clientId)+msg);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFinish(String clientId) {
|
||||
|
||||
}
|
||||
});
|
||||
Container cnt = getContentPane();
|
||||
cnt.setLayout(new BorderLayout());
|
||||
cnt.add(spane,BorderLayout.CENTER);
|
||||
|
||||
JPanel buttonsPanel = new JPanel(new FlowLayout());
|
||||
JButton clearButton = new JButton(translate("button.clear"));
|
||||
clearButton.setActionCommand(ACTION_CLEAR);
|
||||
clearButton.addActionListener(this);
|
||||
|
||||
JButton closeButton = new JButton(translate("button.close"));
|
||||
closeButton.setActionCommand(ACTION_CLOSE);
|
||||
closeButton.addActionListener(this);
|
||||
|
||||
buttonsPanel.add(clearButton);
|
||||
buttonsPanel.add(closeButton);
|
||||
cnt.add(buttonsPanel,BorderLayout.SOUTH);
|
||||
View.setWindowIcon(this);
|
||||
View.centerScreen(this);
|
||||
}
|
||||
|
||||
public void log(String msg){
|
||||
Document d = logTextArea.getDocument();
|
||||
try {
|
||||
d.insertString(d.getLength(), msg+"\r\n", null);
|
||||
} catch (BadLocationException ex) {
|
||||
//ignore
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
switch(e.getActionCommand()){
|
||||
case ACTION_CLEAR:
|
||||
logTextArea.setText("");
|
||||
break;
|
||||
case ACTION_CLOSE:
|
||||
setVisible(false);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -23,12 +23,22 @@ import com.jpexs.decompiler.flash.SWFBundle;
|
||||
import com.jpexs.decompiler.flash.SWFSourceInfo;
|
||||
import com.jpexs.decompiler.flash.SearchMode;
|
||||
import com.jpexs.decompiler.flash.Version;
|
||||
import com.jpexs.decompiler.flash.abc.ABC;
|
||||
import com.jpexs.decompiler.flash.abc.ClassPath;
|
||||
import com.jpexs.decompiler.flash.abc.ScriptPack;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.AVM2Code;
|
||||
import com.jpexs.decompiler.flash.abc.types.Multiname;
|
||||
import com.jpexs.decompiler.flash.abc.types.Namespace;
|
||||
import com.jpexs.decompiler.flash.configuration.Configuration;
|
||||
import com.jpexs.decompiler.flash.console.CommandLineArgumentParser;
|
||||
import com.jpexs.decompiler.flash.console.ContextMenuTools;
|
||||
import com.jpexs.decompiler.flash.gui.debugger.DebugListener;
|
||||
import com.jpexs.decompiler.flash.gui.debugger.Debugger;
|
||||
import com.jpexs.decompiler.flash.gui.proxy.ProxyFrame;
|
||||
import com.jpexs.decompiler.flash.helpers.SWFDecompilerPlugin;
|
||||
import com.jpexs.decompiler.flash.helpers.collections.MyEntry;
|
||||
import com.jpexs.decompiler.flash.tags.ABCContainerTag;
|
||||
import com.jpexs.decompiler.flash.tags.Tag;
|
||||
import com.jpexs.decompiler.flash.tags.base.FontTag;
|
||||
import com.jpexs.decompiler.flash.treeitems.SWFList;
|
||||
import com.jpexs.helpers.Cache;
|
||||
@@ -70,6 +80,7 @@ import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.Random;
|
||||
import java.util.logging.ConsoleHandler;
|
||||
import java.util.logging.FileHandler;
|
||||
import java.util.logging.Formatter;
|
||||
@@ -106,6 +117,39 @@ public class Main {
|
||||
public static LoadFromMemoryFrame loadFromMemoryFrame;
|
||||
public static LoadFromCacheFrame loadFromCacheFrame;
|
||||
private static final Logger logger = Logger.getLogger(Main.class.getName());
|
||||
private static Debugger debugger;
|
||||
public static DebugLogDialog debugDialog;
|
||||
public static final String DEBUGGER_PACKAGE = "com.jpexs.decompiler.flash.debugger";
|
||||
|
||||
private static ABCContainerTag getDebuggerABCTag(SWF swf) {
|
||||
for (ABCContainerTag ac : swf.abcList) {
|
||||
ABC a = ac.getABC();
|
||||
for (MyEntry<ClassPath, ScriptPack> m : a.getScriptPacks()) {
|
||||
if (isDebuggerClass(m.getKey().packageStr, null)) {
|
||||
return ac;
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private static String getDebuggerPackage(SWF swf) {
|
||||
ABCContainerTag ac = getDebuggerABCTag(swf);
|
||||
if (ac == null) {
|
||||
return null;
|
||||
}
|
||||
ABC a = ac.getABC();
|
||||
for (MyEntry<ClassPath, ScriptPack> m : a.getScriptPacks()) {
|
||||
if (isDebuggerClass(m.getKey().packageStr, null)) {
|
||||
return m.getKey().packageStr;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static boolean hasDebugger(SWF swf) {
|
||||
return getDebuggerABCTag(swf) != null;
|
||||
}
|
||||
|
||||
public static void ensureMainFrame() {
|
||||
if (mainFrame == null) {
|
||||
@@ -448,6 +492,10 @@ public class Main {
|
||||
}
|
||||
|
||||
public static void reloadApp() {
|
||||
if (debugDialog != null) {
|
||||
debugDialog.setVisible(false);
|
||||
debugDialog = null;
|
||||
}
|
||||
if (loadingDialog != null) {
|
||||
loadingDialog.setVisible(false);
|
||||
loadingDialog = null;
|
||||
@@ -878,7 +926,7 @@ public class Main {
|
||||
* @throws IOException
|
||||
*/
|
||||
public static void main(String[] args) throws IOException {
|
||||
|
||||
|
||||
String pluginPath = Configuration.pluginPath.get();
|
||||
if (pluginPath != null && !pluginPath.isEmpty()) {
|
||||
try {
|
||||
@@ -1030,6 +1078,124 @@ public class Main {
|
||||
(new AdvancedSettingsDialog()).setVisible(true);
|
||||
}
|
||||
|
||||
private static boolean isDebuggerClass(String tested, String cls) {
|
||||
if (tested == null) {
|
||||
return false;
|
||||
}
|
||||
if (cls == null) {
|
||||
cls = "";
|
||||
} else {
|
||||
cls = "\\." + Pattern.quote(cls);
|
||||
}
|
||||
return tested.matches(Pattern.quote(DEBUGGER_PACKAGE) + "\\.pkg[a-f0-9]+" + cls);
|
||||
}
|
||||
|
||||
private static String byteArrayToHex(byte[] a) {
|
||||
StringBuilder sb = new StringBuilder(a.length * 2);
|
||||
for (byte b : a) {
|
||||
sb.append(String.format("%02x", b & 0xff));
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
public static void replaceTraceCalls(String fname) {
|
||||
SWF swf = getMainFrame().getPanel().getCurrentSwf();
|
||||
if (hasDebugger(swf)) {
|
||||
String debuggerPkg = getDebuggerPackage(swf);
|
||||
//change trace to fname
|
||||
for (ABCContainerTag ct : swf.abcList) {
|
||||
ABC a = ct.getABC();
|
||||
for (int i = 1; i < a.constants.constant_multiname.size(); i++) {
|
||||
Multiname m = a.constants.constant_multiname.get(i);
|
||||
if ("trace".equals(m.getNameWithNamespace(a.constants, true))) {
|
||||
m.namespace_index = a.constants.getNamespaceId(new Namespace(Namespace.KIND_PACKAGE, a.constants.getStringId(debuggerPkg, true)), 0, true);
|
||||
m.name_index = a.constants.getStringId(fname, true);
|
||||
((Tag) ct).setModified(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void switchDebugger() {
|
||||
int port = Configuration.debuggerPort.get();
|
||||
SWF swf = getMainFrame().getPanel().getCurrentSwf();
|
||||
ABCContainerTag found = getDebuggerABCTag(swf);
|
||||
if (found != null) {
|
||||
swf.tags.remove((Tag) found);
|
||||
swf.abcList.remove(found);
|
||||
|
||||
//Change all debugger calls to normal trace
|
||||
for (ABCContainerTag ct : swf.abcList) {
|
||||
ABC a = ct.getABC();
|
||||
for (int i = 1; i < a.constants.constant_multiname.size(); i++) {
|
||||
Multiname m = a.constants.constant_multiname.get(i);
|
||||
if (isDebuggerClass(m.getNameWithNamespace(a.constants, true), "debugTrace")
|
||||
|| isDebuggerClass(m.getNameWithNamespace(a.constants, true), "debugAlert")
|
||||
|| isDebuggerClass(m.getNameWithNamespace(a.constants, true), "debugSocket")
|
||||
|| isDebuggerClass(m.getNameWithNamespace(a.constants, true), "debugConsole")) {
|
||||
m.name_index = a.constants.getStringId("trace", true);
|
||||
m.namespace_index = a.constants.getNamespaceId(new Namespace(Namespace.KIND_PACKAGE, a.constants.getStringId("", true)), 0, true);
|
||||
((Tag) ct).setModified(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
Random rnd = new Random();
|
||||
byte rb[] = new byte[16];
|
||||
rnd.nextBytes(rb);
|
||||
String rhex = byteArrayToHex(rb);
|
||||
try {
|
||||
//load debug swf
|
||||
SWF debugSWF = new SWF(Main.class.getClassLoader().getResourceAsStream("com/jpexs/decompiler/flash/gui/debugger/debug.swf"), false);
|
||||
|
||||
ABCContainerTag firstAbc = swf.abcList.get(0);
|
||||
String newdebuggerpkg = DEBUGGER_PACKAGE + ".pkg" + rhex;
|
||||
//add debug ABC tags to main SWF
|
||||
for (ABCContainerTag ds : debugSWF.abcList) {
|
||||
ABC a = ds.getABC();
|
||||
//Append random hex to Debugger package name
|
||||
for (int i = 1; i < a.constants.constant_namespace.size(); i++) {
|
||||
if (a.constants.constant_namespace.get(i).hasName(DEBUGGER_PACKAGE, a.constants)) {
|
||||
a.constants.constant_namespace.get(i).name_index = a.constants.getStringId(newdebuggerpkg, true);
|
||||
}
|
||||
}
|
||||
//Set debugger port to actually set port
|
||||
for (int i = 0; i < a.constants.constant_int.size(); i++) {
|
||||
if (a.constants.constant_int.get(i) == 123456L) {
|
||||
a.constants.constant_int.set(i, (long) port);
|
||||
}
|
||||
}
|
||||
//Add to target SWF
|
||||
((Tag) ds).setSwf(swf);
|
||||
swf.tags.add(swf.tags.indexOf(firstAbc), (Tag) ds);
|
||||
swf.abcList.add(swf.abcList.indexOf(firstAbc), ds);
|
||||
((Tag) ds).setModified(true);
|
||||
}
|
||||
|
||||
} catch (Exception ex) {
|
||||
//ignore
|
||||
}
|
||||
|
||||
}
|
||||
initDebugger();
|
||||
}
|
||||
|
||||
private static void initDebugger() {
|
||||
if (debugger == null) {
|
||||
debugger = new Debugger(Configuration.debuggerPort.get());
|
||||
debugger.start();
|
||||
}
|
||||
}
|
||||
|
||||
public static void debuggerShowLog() {
|
||||
initDebugger();
|
||||
if (debugDialog == null) {
|
||||
debugDialog = new DebugLogDialog(debugger);
|
||||
}
|
||||
debugDialog.setVisible(true);
|
||||
}
|
||||
|
||||
public static void autoCheckForUpdates() {
|
||||
if (Configuration.checkForUpdatesAuto.get()) {
|
||||
Calendar lastUpdatesCheckDate = Configuration.lastUpdatesCheckDate.get();
|
||||
|
||||
@@ -93,6 +93,9 @@ public class MainFrameRibbonMenu implements MainFrameMenu, ActionListener {
|
||||
static final String ACTION_TIMELINE = "TIMELINE";
|
||||
static final String ACTION_AUTO_DEOBFUSCATE = "AUTODEOBFUSCATE";
|
||||
static final String ACTION_EXIT = "EXIT";
|
||||
static final String ACTION_DEBUGGER_SWITCH = "DEBUGGER_SWITCH";
|
||||
static final String ACTION_DEBUGGER_REPLACE_TRACE = "DEBUGGER_REPLACE_TRACE";
|
||||
static final String ACTION_DEBUGGER_LOG = "DEBUGGER_LOG";
|
||||
|
||||
static final String ACTION_RENAME_ONE_IDENTIFIER = "RENAMEONEIDENTIFIER";
|
||||
static final String ACTION_ABOUT = "ABOUT";
|
||||
@@ -158,6 +161,10 @@ public class MainFrameRibbonMenu implements MainFrameMenu, ActionListener {
|
||||
private CommandToggleButtonGroup timeLineToggleGroup;
|
||||
private JCommandButton gotoDocumentClassCommandButton;
|
||||
private JCommandButton clearRecentFilesCommandButton;
|
||||
private JCommandToggleButton debuggerSwitchCommandButton;
|
||||
private CommandToggleButtonGroup debuggerSwitchGroup;
|
||||
private JCommandButton debuggerReplaceTraceCommandButton;
|
||||
private JCommandButton debuggerLogCommandButton;
|
||||
|
||||
private CommandToggleButtonGroup viewModeToggleGroup;
|
||||
|
||||
@@ -385,13 +392,43 @@ public class MainFrameRibbonMenu implements MainFrameMenu, ActionListener {
|
||||
}
|
||||
|
||||
private RibbonTask createToolsRibbonTask() {
|
||||
|
||||
|
||||
JRibbonBand debuggerBand = new JRibbonBand(translate("menu.debugger"), null);
|
||||
debuggerBand.setResizePolicies(getResizePolicies(debuggerBand));
|
||||
|
||||
debuggerSwitchCommandButton = new JCommandToggleButton(translate("menu.debugger.switch"),View.getResizableIcon("debugger32"));
|
||||
assignListener(debuggerSwitchCommandButton, ACTION_DEBUGGER_SWITCH);
|
||||
|
||||
//debuggerDetachCommandButton = new JCommandButton("Detach debugger",View.getResizableIcon("debuggerremove16"));
|
||||
//assignListener(debuggerDetachCommandButton, ACTION_DEBUGGER_DETACH);
|
||||
|
||||
debuggerReplaceTraceCommandButton = new JCommandButton(translate("menu.debugger.replacetrace"), View.getResizableIcon("debuggerreplace16"));
|
||||
assignListener(debuggerReplaceTraceCommandButton, ACTION_DEBUGGER_REPLACE_TRACE);
|
||||
|
||||
debuggerLogCommandButton = new JCommandButton(translate("menu.debugger.showlog"), View.getResizableIcon("debuggerlog16"));
|
||||
assignListener(debuggerLogCommandButton, ACTION_DEBUGGER_LOG);
|
||||
|
||||
debuggerSwitchGroup = new CommandToggleButtonGroup();
|
||||
debuggerSwitchGroup.add(debuggerSwitchCommandButton);
|
||||
|
||||
debuggerSwitchCommandButton.setEnabled(false);
|
||||
|
||||
debuggerReplaceTraceCommandButton.setEnabled(false);
|
||||
|
||||
debuggerBand.addCommandButton(debuggerSwitchCommandButton, RibbonElementPriority.TOP);
|
||||
debuggerBand.addCommandButton(debuggerReplaceTraceCommandButton, RibbonElementPriority.MEDIUM);
|
||||
debuggerBand.addCommandButton(debuggerLogCommandButton, RibbonElementPriority.MEDIUM);
|
||||
|
||||
|
||||
|
||||
//----------------------------------------- TOOLS -----------------------------------
|
||||
|
||||
JRibbonBand toolsBand = new JRibbonBand(translate("menu.tools"), null);
|
||||
toolsBand.setResizePolicies(getResizePolicies(toolsBand));
|
||||
|
||||
searchCommandButton = new JCommandButton(fixCommandTitle(translate("menu.tools.search")), View.getResizableIcon("search32"));
|
||||
assignListener(searchCommandButton, ACTION_SEARCH);
|
||||
assignListener(searchCommandButton, ACTION_SEARCH);
|
||||
|
||||
timeLineToggleButton = new JCommandToggleButton(fixCommandTitle(translate("menu.tools.timeline")), View.getResizableIcon("timeline32"));
|
||||
assignListener(timeLineToggleButton, ACTION_TIMELINE);
|
||||
@@ -436,7 +473,7 @@ public class MainFrameRibbonMenu implements MainFrameMenu, ActionListener {
|
||||
|
||||
//JRibbonBand otherToolsBand = new JRibbonBand(translate("menu.tools.otherTools"), null);
|
||||
//otherToolsBand.setResizePolicies(getResizePolicies(otherToolsBand));
|
||||
return new RibbonTask(translate("menu.tools"), toolsBand, deobfuscationBand/*, otherToolsBand*/);
|
||||
return new RibbonTask(translate("menu.tools"), toolsBand, deobfuscationBand, debuggerBand /*, otherToolsBand*/);
|
||||
}
|
||||
|
||||
private RibbonTask createSettingsRibbonTask(boolean externalFlashPlayerUnavailable) {
|
||||
@@ -598,7 +635,8 @@ public class MainFrameRibbonMenu implements MainFrameMenu, ActionListener {
|
||||
public void updateComponents(SWF swf, List<ABCContainerTag> abcList) {
|
||||
boolean swfLoaded = swf != null;
|
||||
boolean hasAbc = swfLoaded && abcList != null && !abcList.isEmpty();
|
||||
|
||||
boolean hasDebugger = hasAbc && Main.hasDebugger(swf);
|
||||
|
||||
exportAllMenu.setEnabled(swfLoaded);
|
||||
exportFlaMenu.setEnabled(swfLoaded);
|
||||
exportSelMenu.setEnabled(swfLoaded);
|
||||
@@ -625,6 +663,12 @@ public class MainFrameRibbonMenu implements MainFrameMenu, ActionListener {
|
||||
|
||||
gotoDocumentClassCommandButton.setEnabled(hasAbc);
|
||||
deobfuscationCommandButton.setEnabled(hasAbc);
|
||||
debuggerSwitchCommandButton.setEnabled(hasAbc);
|
||||
debuggerSwitchGroup.setSelected(debuggerSwitchCommandButton, hasDebugger);
|
||||
//debuggerSwitchCommandButton.
|
||||
//debuggerDetachCommandButton.setEnabled(hasDebugger);
|
||||
debuggerReplaceTraceCommandButton.setEnabled(hasAbc && hasDebugger);
|
||||
|
||||
}
|
||||
|
||||
private boolean saveAs(SWF swf, SaveFileMode mode) {
|
||||
@@ -640,6 +684,28 @@ public class MainFrameRibbonMenu implements MainFrameMenu, ActionListener {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
switch (e.getActionCommand()) {
|
||||
case ACTION_DEBUGGER_SWITCH:
|
||||
if(debuggerSwitchGroup.getSelected()==null || View.showConfirmDialog(mainFrame, translate("message.debugger"), translate("dialog.message.title"),JOptionPane.OK_CANCEL_OPTION,JOptionPane.INFORMATION_MESSAGE, Configuration.displayDebuggerInfo,JOptionPane.OK_OPTION)==JOptionPane.OK_OPTION){
|
||||
Main.switchDebugger();
|
||||
mainFrame.panel.refreshDecompiled();
|
||||
}else{
|
||||
if(debuggerSwitchGroup.getSelected()==debuggerSwitchCommandButton){
|
||||
debuggerSwitchGroup.setSelected(debuggerSwitchCommandButton, false);
|
||||
}
|
||||
}
|
||||
debuggerReplaceTraceCommandButton.setEnabled(debuggerSwitchGroup.getSelected()==debuggerSwitchCommandButton);
|
||||
break;
|
||||
case ACTION_DEBUGGER_LOG:
|
||||
Main.debuggerShowLog();
|
||||
break;
|
||||
case ACTION_DEBUGGER_REPLACE_TRACE:
|
||||
ReplaceTraceDialog rtd = new ReplaceTraceDialog(mainFrame);
|
||||
rtd.setVisible(true);
|
||||
if(rtd.getResult()!=null){
|
||||
Main.replaceTraceCalls(rtd.getResult());
|
||||
mainFrame.panel.refreshDecompiled();
|
||||
}
|
||||
break;
|
||||
case ACTION_RELOAD:
|
||||
if (View.showConfirmDialog(null, translate("message.confirm.reload"), translate("message.warning"), JOptionPane.YES_NO_OPTION, JOptionPane.WARNING_MESSAGE) == JOptionPane.YES_OPTION) {
|
||||
Main.reloadApp();
|
||||
|
||||
@@ -1892,12 +1892,12 @@ public final class MainPanel extends JPanel implements ActionListener, TreeSelec
|
||||
}
|
||||
}
|
||||
|
||||
public void refreshDecompiled() {
|
||||
public void refreshDecompiled() {
|
||||
clearCache();
|
||||
if (abcPanel != null) {
|
||||
abcPanel.reload();
|
||||
}
|
||||
reload(true);
|
||||
reload(true);
|
||||
updateClassesList();
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,109 @@
|
||||
/*
|
||||
* Copyright (C) 2014 JPEXS
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.jpexs.decompiler.flash.gui;
|
||||
|
||||
import java.awt.Container;
|
||||
import java.awt.FlowLayout;
|
||||
import java.awt.Window;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
import javax.swing.BoxLayout;
|
||||
import javax.swing.ButtonGroup;
|
||||
import javax.swing.JButton;
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.JRadioButton;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public class ReplaceTraceDialog extends AppDialog {
|
||||
|
||||
private JRadioButton debugAlertRadio;
|
||||
private JRadioButton debugConsoleRadio;
|
||||
private JRadioButton debugProxyRadio;
|
||||
|
||||
private String result = null;
|
||||
|
||||
public String getResult() {
|
||||
return result;
|
||||
}
|
||||
|
||||
public ReplaceTraceDialog(Window owner) {
|
||||
super(owner);
|
||||
setTitle(translate("dialog.title"));
|
||||
Container cnt=getContentPane();
|
||||
cnt.setLayout(new BoxLayout(cnt, BoxLayout.Y_AXIS));
|
||||
debugAlertRadio = new JRadioButton(translate("function.debugAlert"));
|
||||
debugAlertRadio.setAlignmentX(0);
|
||||
debugConsoleRadio = new JRadioButton(translate("function.debugConsole"));
|
||||
debugConsoleRadio.setAlignmentX(0);
|
||||
debugProxyRadio = new JRadioButton(translate("function.debugSocket"));
|
||||
debugProxyRadio.setAlignmentX(0);
|
||||
|
||||
debugAlertRadio.setSelected(true);
|
||||
|
||||
ButtonGroup bg = new ButtonGroup();
|
||||
bg.add(debugAlertRadio);
|
||||
bg.add(debugConsoleRadio);
|
||||
bg.add(debugProxyRadio);
|
||||
|
||||
|
||||
|
||||
cnt.add(debugAlertRadio);
|
||||
cnt.add(debugConsoleRadio);
|
||||
cnt.add(debugProxyRadio);
|
||||
|
||||
JPanel buttonsPanel = new JPanel(new FlowLayout());
|
||||
JButton okButton=new JButton(AppStrings.translate("button.ok"));
|
||||
okButton.addActionListener(new ActionListener() {
|
||||
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
if(debugAlertRadio.isSelected()){
|
||||
result = "debugAlert";
|
||||
}
|
||||
if(debugConsoleRadio.isSelected()){
|
||||
result = "debugConsole";
|
||||
}
|
||||
if(debugProxyRadio.isSelected()){
|
||||
result = "debugSocket";
|
||||
}
|
||||
setVisible(false);
|
||||
}
|
||||
});
|
||||
JButton cancelButton=new JButton(AppStrings.translate("button.cancel"));
|
||||
cancelButton.addActionListener(new ActionListener() {
|
||||
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
result = null;
|
||||
setVisible(false);
|
||||
}
|
||||
});
|
||||
buttonsPanel.add(okButton);
|
||||
buttonsPanel.add(cancelButton);
|
||||
buttonsPanel.setAlignmentX(0);
|
||||
add(buttonsPanel);
|
||||
setModalityType(DEFAULT_MODALITY_TYPE);
|
||||
pack();
|
||||
View.setWindowIcon(this);
|
||||
View.centerScreen(this);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -333,7 +333,7 @@ public class TagTreeModel implements TreeModel {
|
||||
if (n instanceof TreeElement) {
|
||||
TreeElement te = (TreeElement) n;
|
||||
TreeElementItem it = te.getItem();
|
||||
if (obj == it) {
|
||||
if (obj.equals(it)) {
|
||||
return newPath;
|
||||
}
|
||||
}
|
||||
@@ -346,7 +346,7 @@ public class TagTreeModel implements TreeModel {
|
||||
return newPath;
|
||||
}
|
||||
} else {
|
||||
if (n.getItem() == obj) {
|
||||
if (obj.equals(n.getItem())) {
|
||||
return newPath;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -376,7 +376,7 @@ public class View {
|
||||
|
||||
public static int showConfirmDialog(final Component parentComponent, String message, final String title, final int optionType, final int messageTyp, ConfigurationItem<Boolean> showAgainConfig, int defaultOption) {
|
||||
|
||||
JLabel warLabel = new JLabel(message);
|
||||
JLabel warLabel = new JLabel("<html>"+message.replace("\r\n", "<br>")+"</html>");
|
||||
final JPanel warPanel = new JPanel(new BorderLayout());
|
||||
warPanel.add(warLabel, BorderLayout.CENTER);
|
||||
JCheckBox donotShowAgainCheckBox = new JCheckBox(AppStrings.translate("message.confirm.donotshowagain"));
|
||||
@@ -398,13 +398,37 @@ public class View {
|
||||
return ret[0];
|
||||
}
|
||||
|
||||
public static void showMessageDialog(final Component parentComponent, final Object message, final String title, final int messageType) {
|
||||
public static void showMessageDialog(final Component parentComponent, final String message, final String title, final int messageType) {
|
||||
showMessageDialog(parentComponent, message, title, messageType, null);
|
||||
}
|
||||
|
||||
public static void showMessageDialog(final Component parentComponent, final String message, final String title, final int messageType, ConfigurationItem<Boolean> showAgainConfig) {
|
||||
|
||||
Object msg = message;
|
||||
JCheckBox donotShowAgainCheckBox = new JCheckBox(AppStrings.translate("message.confirm.donotshowagain"));
|
||||
|
||||
if (showAgainConfig != null) {
|
||||
JLabel warLabel = new JLabel("<html>"+message.replace("\r\n", "<br>")+"</html>");
|
||||
final JPanel warPanel = new JPanel(new BorderLayout());
|
||||
warPanel.add(warLabel, BorderLayout.CENTER);
|
||||
donotShowAgainCheckBox.setSelected(!showAgainConfig.get());
|
||||
warPanel.add(donotShowAgainCheckBox, BorderLayout.SOUTH);
|
||||
msg = warPanel;
|
||||
if (donotShowAgainCheckBox.isSelected()) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
final Object fmsg=msg;
|
||||
|
||||
execInEventDispatch(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
JOptionPane.showMessageDialog(parentComponent, message, title, messageType);
|
||||
JOptionPane.showMessageDialog(parentComponent, fmsg, title, messageType);
|
||||
}
|
||||
});
|
||||
if (showAgainConfig != null) {
|
||||
showAgainConfig.set(!donotShowAgainCheckBox.isSelected());
|
||||
}
|
||||
}
|
||||
|
||||
public static void showMessageDialog(final Component parentComponent, final Object message) {
|
||||
|
||||
@@ -119,7 +119,7 @@ public class ABCPanel extends JPanel implements ItemListener, ActionListener, Se
|
||||
public ABC abc;
|
||||
public SWF swf;
|
||||
public JComboBox<ABCContainerTag> abcComboBox;
|
||||
public int listIndex = -1;
|
||||
public ABCContainerTag listIndex = null;
|
||||
public DecompiledEditorPane decompiledTextArea;
|
||||
public JScrollPane decompiledScrollPane;
|
||||
public JSplitPane splitPane;
|
||||
@@ -318,8 +318,8 @@ public class ABCPanel extends JPanel implements ItemListener, ActionListener, Se
|
||||
public void setSwf(SWF swf) {
|
||||
if (this.swf != swf) {
|
||||
this.swf = swf;
|
||||
listIndex = -1;
|
||||
switchAbc(0); // todo honika: do we need this?
|
||||
listIndex = null;
|
||||
switchAbc(swf.abcList.get(0)); // todo honika: do we need this?
|
||||
abcComboBox.setModel(new ABCComboBoxModel(swf.abcList));
|
||||
if (swf.abcList.size() > 0) {
|
||||
this.abc = swf.abcList.get(0).getABC();
|
||||
@@ -329,11 +329,11 @@ public class ABCPanel extends JPanel implements ItemListener, ActionListener, Se
|
||||
}
|
||||
}
|
||||
|
||||
public void switchAbc(int index) {
|
||||
public void switchAbc(ABCContainerTag index) {
|
||||
listIndex = index;
|
||||
|
||||
if (index != -1) {
|
||||
this.abc = swf.abcList.get(index).getABC();
|
||||
if (index != null) {
|
||||
this.abc = index.getABC();
|
||||
}
|
||||
updateConstList();
|
||||
}
|
||||
@@ -643,7 +643,7 @@ public class ABCPanel extends JPanel implements ItemListener, ActionListener, Se
|
||||
if (index == -1) {
|
||||
return;
|
||||
}
|
||||
switchAbc(index - 1);
|
||||
switchAbc(swf.abcList.get(index - 1));
|
||||
}
|
||||
if (e.getSource() == constantTypeList) {
|
||||
int index = ((JComboBox) e.getSource()).getSelectedIndex();
|
||||
@@ -775,15 +775,23 @@ public class ABCPanel extends JPanel implements ItemListener, ActionListener, Se
|
||||
case ACTION_SAVE_DECOMPILED:
|
||||
ScriptPack pack = decompiledTextArea.getScriptLeaf();
|
||||
int oldIndex = pack.scriptIndex;
|
||||
|
||||
decompiledTextArea.uncache(pack);
|
||||
|
||||
|
||||
try {
|
||||
String oldSp = null;
|
||||
List<MyEntry<ClassPath, ScriptPack>> packs = abc.script_info.get(oldIndex).getPacks(abc, oldIndex);
|
||||
if (!packs.isEmpty()) {
|
||||
oldSp = packs.get(0).getKey().toString();
|
||||
}
|
||||
|
||||
String as = decompiledTextArea.getText();
|
||||
abc.replaceSciptPack(pack, as);
|
||||
lastDecompiled = as;
|
||||
mainPanel.updateClassesList();
|
||||
List<MyEntry<ClassPath, ScriptPack>> packs = abc.script_info.get(oldIndex).getPacks(abc, oldIndex);
|
||||
if (!packs.isEmpty()) {
|
||||
hilightScript(swf, packs.get(0).getKey().toString());
|
||||
|
||||
if(oldSp!=null){
|
||||
hilightScript(swf, oldSp);
|
||||
}
|
||||
//decompiledTextArea.setClassIndex(-1);
|
||||
//navigator.setClassIndex(-1, oldIndex);
|
||||
|
||||
@@ -385,7 +385,7 @@ public class DecompiledEditorPane extends LineMarkedEditorPane implements CaretL
|
||||
}
|
||||
}
|
||||
|
||||
private void uncache(ScriptPack pack) {
|
||||
public void uncache(ScriptPack pack) {
|
||||
cache.remove(pack);
|
||||
}
|
||||
|
||||
|
||||
@@ -169,7 +169,9 @@ public class DetailPanel extends JPanel implements ActionListener {
|
||||
if (trait == null) {
|
||||
traitNameLabel.setText("-");
|
||||
} else {
|
||||
traitNameLabel.setText(trait.getName(abcPanel.abc).getName(abcPanel.abc.constants, new ArrayList<String>(), false));
|
||||
if(abcPanel!=null && trait.getName(abcPanel.abc)!=null && abcPanel.abc != null){
|
||||
traitNameLabel.setText(trait.getName(abcPanel.abc).getName(abcPanel.abc.constants, new ArrayList<String>(), false));
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
package com.jpexs.decompiler.flash.gui.debugger;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public interface DebugListener {
|
||||
public void onMessage(String clientId,String msg);
|
||||
public void onFinish(String clientId);
|
||||
}
|
||||
@@ -0,0 +1,181 @@
|
||||
package com.jpexs.decompiler.flash.gui.debugger;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.net.InetAddress;
|
||||
import java.net.ServerSocket;
|
||||
import java.net.Socket;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.WeakHashMap;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public class Debugger {
|
||||
|
||||
private static Set<DebugListener> listeners = new HashSet<>();
|
||||
|
||||
public synchronized void addMessageListener(DebugListener l) {
|
||||
listeners.add(l);
|
||||
}
|
||||
|
||||
public synchronized void removeMessageListener(DebugListener l) {
|
||||
listeners.remove(l);
|
||||
}
|
||||
|
||||
private static class DebugHandler extends Thread {
|
||||
|
||||
Socket s;
|
||||
int serverPort;
|
||||
static int maxid = 0;
|
||||
int id;
|
||||
public boolean finished = false;
|
||||
|
||||
public DebugHandler(int serverPort, Socket s) {
|
||||
this.s = s;
|
||||
id = maxid++;
|
||||
this.serverPort = serverPort;
|
||||
}
|
||||
|
||||
public void cancel() {
|
||||
try {
|
||||
s.close();
|
||||
} catch (IOException ex) {
|
||||
//ignore
|
||||
}
|
||||
}
|
||||
|
||||
private String readString(InputStream is) throws IOException
|
||||
{
|
||||
int len = is.read();
|
||||
if (len == -1) {
|
||||
return "";
|
||||
}
|
||||
byte buf[] = new byte[len];
|
||||
is.read(buf);
|
||||
return new String(buf, "UTF-8");
|
||||
|
||||
}
|
||||
@Override
|
||||
public void run() {
|
||||
String clientName = ""+id;
|
||||
try (InputStream is = s.getInputStream()) {
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
|
||||
int c;
|
||||
do {
|
||||
c = is.read();
|
||||
if (c != 0) {
|
||||
baos.write(c);
|
||||
}
|
||||
|
||||
} while (c > 0);
|
||||
String ret = baos.toString("UTF-8");
|
||||
|
||||
if (ret.equals("<policy-file-request/>")) {
|
||||
try (OutputStream os = s.getOutputStream()) {
|
||||
os.write(("<cross-domain-policy><allow-access-from domain=\"*\" to-ports=\"" + serverPort + "\" /></cross-domain-policy>").getBytes("UTF-8"));
|
||||
}
|
||||
} else {
|
||||
String name = readString(is);
|
||||
if(!name.equals("")){
|
||||
clientName = name;
|
||||
}
|
||||
while (true) {
|
||||
ret = readString(is);
|
||||
for (DebugListener l : listeners) {
|
||||
l.onMessage(clientName, ret);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} catch (IOException ex) {
|
||||
//ignore
|
||||
}
|
||||
try {
|
||||
s.close();
|
||||
} catch (IOException ex) {
|
||||
//ignore
|
||||
}
|
||||
finished = true;
|
||||
for (DebugListener l : listeners) {
|
||||
l.onFinish(clientName);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static class DebugServerThread extends Thread {
|
||||
|
||||
private final int port;
|
||||
private ServerSocket ss;
|
||||
private final Map<Integer, DebugHandler> handlers = new WeakHashMap<>();
|
||||
|
||||
public DebugServerThread(int port) {
|
||||
this.port = port;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
ss = new ServerSocket(port,50,InetAddress.getByName("localhost"));
|
||||
ss.setReuseAddress(true);
|
||||
while (true) {
|
||||
Socket s = ss.accept();
|
||||
if (s != null) {
|
||||
DebugHandler h = new DebugHandler(port, s);
|
||||
handlers.put(h.id, h);
|
||||
h.start();
|
||||
}
|
||||
}
|
||||
} catch (IOException ex) {
|
||||
//ignore
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private int port;
|
||||
|
||||
public Debugger(int port) {
|
||||
this.port = port;
|
||||
}
|
||||
|
||||
private DebugServerThread server = null;
|
||||
|
||||
public synchronized void start() {
|
||||
if (server == null) {
|
||||
server = new DebugServerThread(port);
|
||||
server.start();
|
||||
}
|
||||
}
|
||||
|
||||
public synchronized boolean isRunning() {
|
||||
return server != null;
|
||||
}
|
||||
|
||||
public int getPort() {
|
||||
return port;
|
||||
}
|
||||
|
||||
public synchronized void stop() {
|
||||
if (server != null) {
|
||||
try {
|
||||
server.ss.close();
|
||||
} catch (IOException ex) {
|
||||
//ignore
|
||||
}
|
||||
for (DebugHandler h : server.handlers.values()) {
|
||||
h.cancel();
|
||||
}
|
||||
server.handlers.clear();
|
||||
server = null;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
After Width: | Height: | Size: 790 B |
|
After Width: | Height: | Size: 2.0 KiB |
|
After Width: | Height: | Size: 958 B |
|
After Width: | Height: | Size: 2.3 KiB |
|
After Width: | Height: | Size: 554 B |
|
After Width: | Height: | Size: 951 B |
|
After Width: | Height: | Size: 2.3 KiB |
|
After Width: | Height: | Size: 984 B |
|
After Width: | Height: | Size: 2.3 KiB |
@@ -272,3 +272,9 @@ config.description.showMethodBodyId = Shows the id of the methodbody for command
|
||||
|
||||
config.name.export.zoom = (Internal) Export zoom
|
||||
config.description.export.zoom = Last used export zoom
|
||||
|
||||
config.name.debuggerPort = Debugger port
|
||||
config.description.debuggerPort = Port used for socket debugging
|
||||
|
||||
config.name.displayDebuggerInfo = (Internal) Display debugger info
|
||||
config.description.displayDebuggerInfo = Display info about debugger before switching it
|
||||
@@ -253,5 +253,21 @@ config.description.packJavaScripts = Spou\u0161t\u011bt komprim\u00e1tor JavaScr
|
||||
config.name.textExportExportFontFace = Pou\u017e\u00edvat font-face v SVG exportu
|
||||
config.description.textExportExportFontFace = Vkl\u00e1dat soubory p\u00edsem do SVG pou\u017eit\u00edm font-face m\u00edsto tvar\u016f
|
||||
|
||||
config.name.dumpView = Dump zobrazen\u00ed
|
||||
config.description.dumpView = Zobrazit dump raw dat
|
||||
config.name.lzmaFastBytes = LZMA fast bytes (platn\u00e9 hodnoty: 5-255)
|
||||
config.description.lzmaFastBytes = Parametr fast bytes LZMA enkoderu
|
||||
|
||||
#temporary setting, do not translate it
|
||||
config.name.pluginPath = Plugin Path
|
||||
config.description.pluginPath = -
|
||||
|
||||
config.name.deobfuscationMode = M\u00f3d deobfuskace
|
||||
config.description.deobfuscationMode = Typ deobfuskace
|
||||
|
||||
config.name.showMethodBodyId = Zobrazovat id body metod
|
||||
config.description.showMethodBodyId = Zobrazuje id body metody pro import p\u0159es p\u0159\u00edkazovou \u0159\u00e1dku
|
||||
|
||||
config.name.export.zoom = (Internal) P\u0159ibl\u00ed\u017een\u00ed exportu
|
||||
config.description.export.zoom = Naposledy pou\u017eit\u00e9 nastaven\u00ed p\u0159ibl\u00ed\u017een\u00ed
|
||||
|
||||
config.name.debuggerPort = Port Debuggeru
|
||||
config.description.debuggerPort = Port pou\u017e\u00edvan\u00fd pro lad\u011bn\u00ed p\u0159es sockety
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
# Copyright (C) 2014 JPEXS
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program 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 General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
dialog.title = Debugger Log
|
||||
button.clear = Clear
|
||||
button.close = Close
|
||||
msg.header = connection %clientid%:
|
||||
@@ -0,0 +1,19 @@
|
||||
# Copyright (C) 2014 JPEXS
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program 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 General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
dialog.title = Log Debuggeru
|
||||
button.clear = Vypr\u00e1zdnit
|
||||
button.close = Zav\u0159\u00edt
|
||||
msg.header = spojen\u00ed %clientid%:
|
||||
@@ -66,3 +66,7 @@ frames.pdf = PDF
|
||||
fonts = P\u00edsma
|
||||
fonts.ttf = TTF
|
||||
fonts.woff = WOFF
|
||||
|
||||
zoom = P\u0159ibl\u00ed\u017een\u00ed
|
||||
zoom.percent = %
|
||||
zoom.invalid = Neplatn\u00e1 hodnota velikost.
|
||||
@@ -514,4 +514,11 @@ button.snapshot.hint = Take snapshot into clipboard
|
||||
|
||||
editorTruncateWarning = Text truncated at position %chars% in debug mode.
|
||||
|
||||
font.name.intag = Font name in tag:
|
||||
font.name.intag = Font name in tag:
|
||||
|
||||
menu.debugger = Debugger
|
||||
menu.debugger.switch = Debugger
|
||||
menu.debugger.replacetrace = Replace trace calls
|
||||
menu.debugger.showlog = Show Log
|
||||
|
||||
message.debugger = This SWF Debugger can only be used to print messages to log window, browser console or alerts.\r\nIt is NOT designed for features like step code, breakpoints etc.
|
||||
|
||||
@@ -513,4 +513,11 @@ button.snapshot.hint = Sn\u00edmek do schr\u00e1nky
|
||||
|
||||
editorTruncateWarning = Text je o\u0159\u00edznut na pozici %chars% v lad\u00edc\u00edm m\u00f3du.
|
||||
|
||||
font.name.intag = N\u00e1zev p\u00edsma v tagu:
|
||||
font.name.intag = N\u00e1zev p\u00edsma v tagu:
|
||||
|
||||
menu.debugger = Debugger
|
||||
menu.debugger.switch = Debugger
|
||||
menu.debugger.replacetrace = Nahradit vol\u00e1n\u00ed trace
|
||||
menu.debugger.showlog = Zobrazit Log
|
||||
|
||||
message.debugger = Tento SWF Debugger slou\u017e\u00ed jen k pos\u00edl\u00e1n\u00ed zpr\u00e1v do okna logu, konzole prohl\u00ed\u017ee\u010de nebo alert oken.\r\nNEN\u00cd ur\u010den pro krokov\u00e1n\u00ed k\u00f3du, breakpointy atd.
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
# Copyright (C) 2014 JPEXS
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program 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 General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
dialog.title = Replace Trace function calls
|
||||
|
||||
function.debugAlert = debugAlert - web browser javascript alert
|
||||
function.debugConsole = debugConsole - web browser javascript console.log
|
||||
function.debugSocket = debugSocket - socket connection to the decompiler
|
||||
@@ -0,0 +1,20 @@
|
||||
# Copyright (C) 2014 JPEXS
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program 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 General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
dialog.title = Nahrazen\u00ed vol\u00e1n\u00ed funkce Trace
|
||||
|
||||
function.debugAlert = debugAlert - javascriptov\u00e1 funkce alert webov\u00e9ho prohl\u00ed\u017ee\u010de
|
||||
function.debugConsole = debugConsole - javascriptov\u00e1 funkce console.log webov\u00e9ho prohl\u00ed\u017ee\u010de
|
||||
function.debugSocket = debugSocket - p\u0159ipojen\u00ed sockety k dekompil\u00e1toru
|
||||
@@ -17,7 +17,10 @@
|
||||
package com.jpexs.decompiler.flash.gui.player;
|
||||
|
||||
import com.jpexs.decompiler.flash.gui.FlashUnsupportedException;
|
||||
import com.jpexs.decompiler.flash.gui.Main;
|
||||
import com.jpexs.javactivex.ActiveX;
|
||||
import com.jpexs.javactivex.ActiveXEvent;
|
||||
import com.jpexs.javactivex.ActiveXEventListener;
|
||||
import com.jpexs.javactivex.example.controls.flash.ShockwaveFlash;
|
||||
import com.sun.jna.Platform;
|
||||
import java.awt.AWTException;
|
||||
@@ -30,6 +33,8 @@ import java.awt.Robot;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.io.Closeable;
|
||||
import java.io.IOException;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/**
|
||||
*
|
||||
@@ -107,6 +112,35 @@ public class FlashPlayerPanel extends Panel implements Closeable, MediaDisplay {
|
||||
throw new FlashUnsupportedException();
|
||||
}
|
||||
flash = ActiveX.createObject(ShockwaveFlash.class, this);
|
||||
flash.setAllowScriptAccess("always");
|
||||
flash.setAllowNetworking("all");
|
||||
flash.addFlashCallListener(new ActiveXEventListener() {
|
||||
|
||||
@Override
|
||||
public void onEvent(ActiveXEvent axe) {
|
||||
String req = (String) axe.args.get("request");
|
||||
Matcher m = Pattern.compile("<invoke name=\"([^\"]+)\" returntype=\"xml\"><arguments><string>(.*)</string></arguments></invoke>").matcher(req);
|
||||
if (m.matches()) {
|
||||
String funname = m.group(1);
|
||||
String msg = m.group(2);
|
||||
if (funname.equals("alert") || funname.equals("console.log")) {
|
||||
if (Main.debugDialog != null) {
|
||||
Main.debugDialog.log(funname + ":" + msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
flash.addFSCommandListener(new ActiveXEventListener() {
|
||||
|
||||
@Override
|
||||
public void onEvent(ActiveXEvent axe) {
|
||||
System.out.println("Event:" + axe.name);
|
||||
for (String k : axe.args.keySet()) {
|
||||
System.out.println(k + "=" + axe.args.get(k));
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public synchronized void stopSWF() {
|
||||
|
||||