mirror of
https://git.huckle.dev/Huckles-Minecraft-Archive/jpexs-decompiler.git
synced 2026-09-28 06:00:46 +00:00
Debugging in the browser WIP
This commit is contained in:
@@ -495,7 +495,7 @@ public class DebugPanel extends JPanel {
|
||||
|
||||
SelectedTab oldSel = selectedTab;
|
||||
localsTable = null;
|
||||
SWF swf = Main.getMainFrame().getPanel().getCurrentSwf();
|
||||
SWF swf = Main.getDebuggedSWF();
|
||||
if (swf == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -31,7 +31,9 @@ import com.jpexs.debugger.flash.messages.in.InCallFunction;
|
||||
import com.jpexs.debugger.flash.messages.in.InConstantPool;
|
||||
import com.jpexs.debugger.flash.messages.in.InContinue;
|
||||
import com.jpexs.debugger.flash.messages.in.InErrorException;
|
||||
import com.jpexs.debugger.flash.messages.in.InExit;
|
||||
import com.jpexs.debugger.flash.messages.in.InFrame;
|
||||
import com.jpexs.debugger.flash.messages.in.InGetSwf;
|
||||
import com.jpexs.debugger.flash.messages.in.InGetVariable;
|
||||
import com.jpexs.debugger.flash.messages.in.InNumScript;
|
||||
import com.jpexs.debugger.flash.messages.in.InPlaceObject;
|
||||
@@ -43,6 +45,7 @@ import com.jpexs.debugger.flash.messages.in.InTrace;
|
||||
import com.jpexs.debugger.flash.messages.in.InVersion;
|
||||
import com.jpexs.debugger.flash.messages.out.OutAddWatch2;
|
||||
import com.jpexs.debugger.flash.messages.out.OutGetBreakReason;
|
||||
import com.jpexs.debugger.flash.messages.out.OutGetSwf;
|
||||
import com.jpexs.debugger.flash.messages.out.OutPlay;
|
||||
import com.jpexs.debugger.flash.messages.out.OutProcessedTag;
|
||||
import com.jpexs.debugger.flash.messages.out.OutRewind;
|
||||
@@ -51,7 +54,11 @@ import com.jpexs.debugger.flash.messages.out.OutSwfInfo;
|
||||
import com.jpexs.decompiler.flash.SWF;
|
||||
import com.jpexs.decompiler.flash.configuration.Configuration;
|
||||
import com.jpexs.decompiler.graph.DottedChain;
|
||||
import com.jpexs.helpers.Helper;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.security.MessageDigest;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
@@ -72,7 +79,7 @@ import java.util.regex.Pattern;
|
||||
* @author JPEXS
|
||||
*/
|
||||
public class DebuggerHandler implements DebugConnectionListener {
|
||||
|
||||
|
||||
private boolean connected = false;
|
||||
|
||||
private DebuggerCommands commands = null;
|
||||
@@ -586,15 +593,13 @@ public class DebuggerHandler implements DebugConnectionListener {
|
||||
}
|
||||
}
|
||||
|
||||
public void disconnect() {
|
||||
|
||||
private void disconnected() {
|
||||
frame = null;
|
||||
pool = null;
|
||||
breakInfo = null;
|
||||
breakReason = null;
|
||||
connected = false;
|
||||
if (commands != null) {
|
||||
commands.disconnect();
|
||||
}
|
||||
commands = null;
|
||||
synchronized (this) {
|
||||
for (SWF debuggedSwf : debuggedSwfs) {
|
||||
@@ -630,6 +635,18 @@ public class DebuggerHandler implements DebugConnectionListener {
|
||||
}
|
||||
debuggedSwfs.clear();
|
||||
}
|
||||
|
||||
public void disconnect() {
|
||||
frame = null;
|
||||
pool = null;
|
||||
breakInfo = null;
|
||||
breakReason = null;
|
||||
connected = false;
|
||||
if (commands != null) {
|
||||
commands.disconnect();
|
||||
}
|
||||
disconnected();
|
||||
}
|
||||
|
||||
public synchronized boolean isConnected() {
|
||||
return connected;
|
||||
@@ -659,10 +676,6 @@ public class DebuggerHandler implements DebugConnectionListener {
|
||||
|
||||
@Override
|
||||
public void connected(DebuggerConnection con) {
|
||||
/*for (SWF debuggedSwf : debuggedSwfs) {
|
||||
makeBreakPointsUnconfirmed(debuggedSwf);
|
||||
}*/
|
||||
|
||||
Main.startWork(AppStrings.translate("work.debugging"), null);
|
||||
|
||||
synchronized (this) {
|
||||
@@ -701,7 +714,7 @@ public class DebuggerHandler implements DebugConnectionListener {
|
||||
final Pattern patAS3 = Pattern.compile("^(.*);(.*);(.*)\\.as$");
|
||||
final Pattern patAS3PCode = Pattern.compile("^(?<hash>[0-9a-z_]+):#PCODE abc:(?<abc>[0-9]+),script:(?<script>[0-9]+),class:(?<class>-?[0-9]+),trait:(?<trait>-?[0-9]+),method:(?<method>[0-9]+),body:(?<body>[0-9]+);(.*)$");
|
||||
|
||||
boolean isAS3 = Main.getRunningSWF().isAS3();
|
||||
//boolean isAS3 = Main.getRunningSWF().isAS3();
|
||||
try {
|
||||
|
||||
con.addMessageListener(new DebugMessageListener<InErrorException>() {
|
||||
@@ -811,16 +824,26 @@ public class DebuggerHandler implements DebugConnectionListener {
|
||||
commands.setGetterTimeout(1500);
|
||||
commands.setSetterTimeout(5000);
|
||||
|
||||
con.isAS3 = isAS3;
|
||||
|
||||
//Widelines - only AS3, it hangs in AS1/2 and SWD does not support UI32 lines
|
||||
if (isAS3) {
|
||||
con.wideLines = commands.getOption("wide_line_player", "false").equals("true");
|
||||
if (con.wideLines) {
|
||||
commands.setOption("wide_line_debugger", "on");
|
||||
}
|
||||
}
|
||||
/*if (isAS3) {
|
||||
|
||||
}*/
|
||||
commands.squelch(true);
|
||||
|
||||
con.addMessageListener(new DebugMessageListener<InExit>() {
|
||||
@Override
|
||||
public void message(InExit t) {
|
||||
Logger.getLogger(DebuggerHandler.class.getName()).fine("Handling inExit");
|
||||
//con.dropMessage(t);
|
||||
synchronized (DebuggerHandler.this) {
|
||||
paused = false;
|
||||
connected = false;
|
||||
}
|
||||
Logger.getLogger(DebuggerHandler.class.getName()).fine("Calling disconnected");
|
||||
disconnected();
|
||||
Logger.getLogger(DebuggerHandler.class.getName()).fine("Disconnected called");
|
||||
}
|
||||
});
|
||||
|
||||
con.writeMessage(new OutSwfInfo(con, 0));
|
||||
con.addMessageListener(new DebugMessageListener<InSwfInfo>() {
|
||||
@@ -840,6 +863,57 @@ public class DebuggerHandler implements DebugConnectionListener {
|
||||
});
|
||||
}*/
|
||||
con.dropMessage(t);
|
||||
View.execInEventDispatch(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
for (InSwfInfo.SwfInfo s : t.swfInfos) {
|
||||
try {
|
||||
/*try {
|
||||
con.sendMessageWithTimeout(new OutGetSwf(con, (int) s.index), InGetSwf.class);
|
||||
con.sendMessageWithTimeout(new OutGetSwd(con, (int) s.index), InGetSwd.class);
|
||||
} catch (IOException ex) {
|
||||
//ignore
|
||||
}*/
|
||||
InGetSwf inGetSwf = con.sendMessageWithTimeout(new OutGetSwf(con, (int) s.index), InGetSwf.class);
|
||||
System.err.println("Received SWF");
|
||||
String sha256 = Helper.byteArrayToHex(MessageDigest.getInstance("SHA-256").digest(inGetSwf.swfData));
|
||||
Main.findDebuggedSwf(sha256);
|
||||
|
||||
SWF debuggedSwf = Main.getDebuggedSWF();
|
||||
if (debuggedSwf == null) {
|
||||
con.disconnect();
|
||||
synchronized (DebuggerHandler.this) {
|
||||
paused = false;
|
||||
connected = false;
|
||||
}
|
||||
disconnected();
|
||||
} else {
|
||||
con.isAS3 = debuggedSwf.isAS3();
|
||||
if (debuggedSwf.isAS3()) {
|
||||
con.wideLines = commands.getOption("wide_line_player", "false").equals("true");
|
||||
if (con.wideLines) {
|
||||
commands.setOption("wide_line_debugger", "on");
|
||||
}
|
||||
} else {
|
||||
Logger.getLogger(DebuggerHandler.class.getName()).log(Level.FINER, "End of connect - sending continue");
|
||||
con.writeMessage(new OutRewind(con));
|
||||
con.writeMessage(new OutPlay(con));
|
||||
commands.sendContinue();
|
||||
}
|
||||
}
|
||||
} catch (IOException | NoSuchAlgorithmException ex) {
|
||||
//ignore
|
||||
|
||||
con.disconnect();
|
||||
synchronized (DebuggerHandler.this) {
|
||||
paused = false;
|
||||
connected = false;
|
||||
}
|
||||
disconnected();
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
@@ -998,17 +1072,16 @@ public class DebuggerHandler implements DebugConnectionListener {
|
||||
}
|
||||
});
|
||||
|
||||
if (!isAS3) {
|
||||
Logger.getLogger(DebuggerHandler.class.getName()).log(Level.FINER, "End of connect - sending continue");
|
||||
con.writeMessage(new OutRewind(con));
|
||||
con.writeMessage(new OutPlay(con));
|
||||
commands.sendContinue();
|
||||
}
|
||||
/* if (!isAS3) {
|
||||
|
||||
}*/
|
||||
|
||||
} catch (IOException ex) {
|
||||
synchronized (this) {
|
||||
paused = false;
|
||||
connected = false;
|
||||
}
|
||||
disconnected();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1026,7 +1099,7 @@ public class DebuggerHandler implements DebugConnectionListener {
|
||||
SWF debuggedSwf = debuggedSwfs.get(swfIndex);
|
||||
String hash = Main.getSwfHash(debuggedSwf);
|
||||
|
||||
Logger.getLogger(DebuggerHandler.class.getName()).log(Level.FINEST, "sending breakpoints of ", hash);
|
||||
Logger.getLogger(DebuggerHandler.class.getName()).log(Level.FINEST, "sending breakpoints of {0}", hash);
|
||||
|
||||
if (toRemoveBPointMap.containsKey(debuggedSwf)) {
|
||||
for (String scriptName : toRemoveBPointMap.get(debuggedSwf).keySet()) {
|
||||
|
||||
@@ -120,6 +120,8 @@ import java.nio.file.StandardWatchEventKinds;
|
||||
import java.nio.file.WatchEvent;
|
||||
import java.nio.file.WatchKey;
|
||||
import java.nio.file.WatchService;
|
||||
import java.security.MessageDigest;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
@@ -139,6 +141,7 @@ import java.util.Timer;
|
||||
import java.util.TimerTask;
|
||||
import java.util.concurrent.CancellationException;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.logging.ConsoleHandler;
|
||||
import java.util.logging.FileHandler;
|
||||
import java.util.logging.Formatter;
|
||||
@@ -228,13 +231,49 @@ public class Main {
|
||||
public static String currentDebuggerPackage = null;
|
||||
|
||||
private static SWF runningSWF = null;
|
||||
|
||||
private static SWF debuggedSWF = null;
|
||||
|
||||
private static String preparedHashSha256 = null;
|
||||
|
||||
private static SwfPreparation runningPreparation = null;
|
||||
|
||||
private static boolean loggingFileLoaded = false;
|
||||
|
||||
private static boolean debugListening = false;
|
||||
|
||||
public static SWF getDebuggedSWF() {
|
||||
return debuggedSWF;
|
||||
}
|
||||
|
||||
|
||||
public static void findDebuggedSwf(String hashSha256) {
|
||||
|
||||
System.err.println("Searching for hash " + hashSha256 + "...");
|
||||
|
||||
for (SWF swf : mainFrame.getPanel().getAllSwfs()) {
|
||||
System.err.println("Checking " + swf +" with hash " + swf.getHashSha256());
|
||||
if (Objects.equals(hashSha256, swf.getHashSha256())) {
|
||||
Main.debuggedSWF = swf;
|
||||
System.err.println("RECEIVED SWF FOUND");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (preparedHashSha256 != null && hashSha256.equals(preparedHashSha256)) {
|
||||
System.err.println("RECEIVED SWF IS ONE THAT WAS PREPARED FOR RUN...");
|
||||
Main.debuggedSWF = runningSWF;
|
||||
return;
|
||||
}
|
||||
|
||||
System.err.println("RECEIVED SWF IS NOT ANY OF OURS");
|
||||
Main.debuggedSWF = null;
|
||||
}
|
||||
|
||||
public static SWF getRunningSWF() {
|
||||
return runningSWF;
|
||||
//System.err.println("debuggedSWF: " + (debuggedSWF == null ? "NOT SET" : debuggedSWF));
|
||||
//return runningSWF;
|
||||
return debuggedSWF;
|
||||
}
|
||||
|
||||
public static WatchService getWatcher() {
|
||||
@@ -276,6 +315,7 @@ public class Main {
|
||||
if (runTempFile != null) {
|
||||
deleteCookiesAfterRun(runTempFile);
|
||||
runTempFile.delete();
|
||||
System.err.println("deleted " + runTempFile);
|
||||
runTempFile = null;
|
||||
}
|
||||
for (File f : runTempFiles) {
|
||||
@@ -296,11 +336,11 @@ public class Main {
|
||||
}
|
||||
|
||||
public static synchronized boolean isDebugPaused() {
|
||||
return runProcess != null && runProcessDebug && getDebugHandler().isPaused();
|
||||
return (runProcess != null && runProcessDebug || !flashDebugger.isStopped()) && getDebugHandler().isPaused();
|
||||
}
|
||||
|
||||
public static synchronized boolean isDebugRunning() {
|
||||
return runProcess != null && runProcessDebug;
|
||||
return (runProcess != null && runProcessDebug) || !flashDebugger.isStopped();
|
||||
}
|
||||
|
||||
public static synchronized boolean isDebugPCode() {
|
||||
@@ -401,7 +441,7 @@ public class Main {
|
||||
} catch (InterruptedException ex) {
|
||||
if (proc != null) {
|
||||
try {
|
||||
proc.destroy();
|
||||
proc.destroyForcibly();
|
||||
} catch (Exception ex2) {
|
||||
//ignore
|
||||
}
|
||||
@@ -425,6 +465,9 @@ public class Main {
|
||||
if (runProcess != null) {
|
||||
try {
|
||||
runProcess.destroy();
|
||||
if (!runProcess.waitFor(5, TimeUnit.SECONDS)) {
|
||||
runProcess.destroyForcibly();
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
//ignored
|
||||
}
|
||||
@@ -445,10 +488,18 @@ public class Main {
|
||||
synchronized (Main.class) {
|
||||
if (runProcess != null) {
|
||||
runProcess.destroy();
|
||||
try {
|
||||
if (!runProcess.waitFor(5, TimeUnit.SECONDS)) {
|
||||
runProcess.destroyForcibly();
|
||||
}
|
||||
} catch (InterruptedException ex) {
|
||||
//ignore
|
||||
}
|
||||
}
|
||||
}
|
||||
freeRun();
|
||||
stopDebugger();
|
||||
stopWork();
|
||||
mainFrame.getMenu().updateComponents();
|
||||
}
|
||||
|
||||
@@ -596,9 +647,23 @@ public class Main {
|
||||
try (FileOutputStream fos = new FileOutputStream(toPrepareFile)) {
|
||||
instrSWF.saveTo(fos);
|
||||
}
|
||||
}
|
||||
if ("main".equals(swfHash)) {
|
||||
preparedHashSha256 = instrSWF.getHashSha256();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static void prepareForDebug(SWF swf, File fTempFile, File tempRunDir, List<File> tempFiles, boolean doPCode) throws IOException, InterruptedException {
|
||||
SWF swfToSave = swf;
|
||||
if (swf.gfx) {
|
||||
swfToSave = new GfxConvertor().convertSwf(swf);
|
||||
}
|
||||
try (OutputStream fos = new BufferedOutputStream(new FileOutputStream(fTempFile))) {
|
||||
swfToSave.saveTo(fos, false, swf.gfx);
|
||||
}
|
||||
prepareSwf("main", new SwfDebugPrepare(doPCode), fTempFile, swf.getFile() == null ? null : new File(swf.getFile()), tempRunDir, tempFiles);
|
||||
}
|
||||
|
||||
private static File createTempFileInDir(File tempFilesDir, String prefix, String suffix) throws IOException {
|
||||
if (tempFilesDir == null || !tempFilesDir.isDirectory()) {
|
||||
return File.createTempFile(prefix, suffix);
|
||||
@@ -776,7 +841,16 @@ public class Main {
|
||||
SharedObjectsStorage.addChangedListener(tempFile, runCookieListener);
|
||||
}
|
||||
|
||||
public static void runDebug(SWF swf, final boolean doPCode) {
|
||||
public static void startDebugListening() {
|
||||
debugListening = true;
|
||||
Main.stopWork();
|
||||
Main.startWork(AppStrings.translate("work.debugging.start") + "...", null, true);
|
||||
Main.startDebugger();
|
||||
Main.startWork(AppStrings.translate("work.debugging.listening"), null);
|
||||
mainFrame.getMenu().hilightPath("/debugging");
|
||||
}
|
||||
|
||||
public static void runDebug(SWF swf, final boolean doPCode) {
|
||||
String flashVars = ""; //key=val&key2=val2
|
||||
String playerLocation = Configuration.playerDebugLocation.get();
|
||||
if (playerLocation.isEmpty() || (!new File(playerLocation).exists())) {
|
||||
@@ -2932,9 +3006,15 @@ public class Main {
|
||||
|
||||
@Override
|
||||
public void disconnected() {
|
||||
if (Main.mainFrame != null) {
|
||||
Main.mainFrame.getMenu().updateComponents();
|
||||
}
|
||||
if (Main.mainFrame != null && Main.mainFrame.getPanel() != null) {
|
||||
Main.mainFrame.getPanel().refreshBreakPoints();
|
||||
}
|
||||
if (debugListening) {
|
||||
Main.startWork(AppStrings.translate("work.debugging.listening"), null, true);
|
||||
}
|
||||
}
|
||||
});
|
||||
flashDebugger.addConnectionListener(debugHandler);
|
||||
@@ -2948,7 +3028,7 @@ public class Main {
|
||||
}
|
||||
|
||||
public static void startDebugger() {
|
||||
flashDebugger.startDebugger();
|
||||
flashDebugger.startDebugger();
|
||||
}
|
||||
|
||||
public static void stopDebugger() {
|
||||
@@ -3759,6 +3839,9 @@ public class Main {
|
||||
|
||||
public static void showBreakpointsList() {
|
||||
SWF swf = getMainFrame().getPanel().getCurrentSwf();
|
||||
if (swf == null) {
|
||||
return;
|
||||
}
|
||||
getMainFrame().getPanel().showBreakpointlistDialog(swf);
|
||||
}
|
||||
|
||||
|
||||
@@ -1175,6 +1175,7 @@ public abstract class MainFrameMenu implements MenuBuilder {
|
||||
setMenuEnabled("/file/start/run", swfSelected && !isRunningOrDebugging);
|
||||
setMenuEnabled("/file/start/debug", swfSelected && !isRunningOrDebugging);
|
||||
setMenuEnabled("/file/start/debugpcode", swfSelected && !isRunningOrDebugging);
|
||||
setMenuEnabled("/file/start/debuglisten", !isDebugRunning);
|
||||
|
||||
setMenuEnabled("/file/start/stop", isRunningOrDebugging);
|
||||
setMenuEnabled("/debugging/debug/stop", isRunningOrDebugging); //same as previous
|
||||
@@ -1298,6 +1299,7 @@ public abstract class MainFrameMenu implements MenuBuilder {
|
||||
addMenuItem("/file/start/stop", translate("menu.file.start.stop"), "stop32", this::stopActionPerformed, PRIORITY_TOP, null, true, null, false);
|
||||
addMenuItem("/file/start/debug", translate("menu.file.start.debug"), "debug32", this::debugActionPerformed, PRIORITY_MEDIUM, null, true, new HotKey("CTRL+F5"), false);
|
||||
addMenuItem("/file/start/debugpcode", translate("menu.file.start.debugpcode"), "debug32", this::debugPCodeActionPerformed, PRIORITY_MEDIUM, null, true, null, false);
|
||||
addMenuItem("/file/start/debuglisten", translate("menu.file.start.debuglisten"), "listen32", this::debugListenActionPerformed, PRIORITY_MEDIUM, null, true, null, false);
|
||||
finishMenu("/file/start");
|
||||
|
||||
addMenuItem("/file/view", translate("menu.view"), null, null, 0, null, false, null, false);
|
||||
@@ -1736,6 +1738,11 @@ public abstract class MainFrameMenu implements MenuBuilder {
|
||||
Main.runDebug((SWF) openable, false);
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean debugListenActionPerformed(ActionEvent evt) {
|
||||
Main.startDebugListening();
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean debugPCodeActionPerformed(ActionEvent evt) {
|
||||
Main.runDebug((SWF) openable, true);
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 1.7 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 3.1 KiB |
@@ -1105,4 +1105,10 @@ contextmenu.normalizeFonts = Normalize fonts
|
||||
|
||||
#after 24.1.1
|
||||
contextmenu.saveSwc = Save as Swc...
|
||||
work.generating.swc = Generating Swc...
|
||||
work.generating.swc = Generating Swc...
|
||||
|
||||
#after 25.0.0
|
||||
menu.file.start.debuglisten = Debug listen...
|
||||
work.debugging.listening = Listening for incoming connections...
|
||||
contextmenu.prepareDebug.injectDebug = Prepare file for debugging (+ inject debug info)
|
||||
contextmenu.prepareDebug.generateSwd = Prepare file for debugging (+ generate SWD)
|
||||
|
||||
@@ -381,7 +381,11 @@ public class TagTreeContextMenu extends JPopupMenu {
|
||||
private JMenuItem convertPlaceObjectTypeMenuItem;
|
||||
|
||||
private JMenuItem normalizeFontsMenuItem;
|
||||
|
||||
|
||||
private JMenuItem prepareDebugInject;
|
||||
|
||||
private JMenuItem prepareDebugSwd;
|
||||
|
||||
private List<TreeItem> items = new ArrayList<>();
|
||||
|
||||
private static final int KIND_TAG_MOVETO = 0;
|
||||
@@ -653,6 +657,17 @@ public class TagTreeContextMenu extends JPopupMenu {
|
||||
|
||||
addSeparator();
|
||||
|
||||
prepareDebugInject = new JMenuItem(mainPanel.translate("contextmenu.prepareDebug.injectDebug"));
|
||||
prepareDebugInject.addActionListener(this::prepareDebugActionPerformed);
|
||||
prepareDebugInject.setIcon(View.getIcon("debug16"));
|
||||
add(prepareDebugInject);
|
||||
|
||||
prepareDebugSwd = new JMenuItem(mainPanel.translate("contextmenu.prepareDebug.generateSwd"));
|
||||
prepareDebugSwd.addActionListener(this::prepareDebugActionPerformed);
|
||||
prepareDebugSwd.setIcon(View.getIcon("debug16"));
|
||||
add(prepareDebugSwd);
|
||||
|
||||
|
||||
gotoDocumentClassMenuItem = new JMenuItem(mainPanel.translate("menu.tools.gotoDocumentClass"));
|
||||
gotoDocumentClassMenuItem.addActionListener(this::gotoDocumentClassActionPerformed);
|
||||
gotoDocumentClassMenuItem.setIcon(View.getIcon("gotomainclass16"));
|
||||
@@ -1354,6 +1369,8 @@ public class TagTreeContextMenu extends JPopupMenu {
|
||||
|
||||
boolean hasExportableNodes = tree.hasExportableNodes();
|
||||
|
||||
prepareDebugInject.setVisible(false);
|
||||
prepareDebugSwd.setVisible(false);
|
||||
gotoDocumentClassMenuItem.setVisible(false);
|
||||
setAsLinkageMenuItem.setVisible(false);
|
||||
setAs3ClassLinkageMenuItem.setVisible(false);
|
||||
@@ -1549,7 +1566,7 @@ public class TagTreeContextMenu extends JPopupMenu {
|
||||
if ("__Packages".equals(firstPkg)) {
|
||||
addAs12ClassMenuItem.setVisible(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (firstItem instanceof ClassesListTreeModel) {
|
||||
addAs3ClassMenuItem.setVisible(true);
|
||||
if (firstItem.getOpenable() instanceof SWF) {
|
||||
@@ -1586,6 +1603,9 @@ public class TagTreeContextMenu extends JPopupMenu {
|
||||
if (firstItem instanceof SWF) {
|
||||
if (((SWF) firstItem).isAS3()) {
|
||||
gotoDocumentClassMenuItem.setVisible(true);
|
||||
prepareDebugInject.setVisible(true);
|
||||
} else {
|
||||
prepareDebugSwd.setVisible(true);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3055,6 +3075,45 @@ public class TagTreeContextMenu extends JPopupMenu {
|
||||
mainPanel.showGenericTag((Tag) itemr);
|
||||
}
|
||||
|
||||
private void prepareDebugActionPerformed(ActionEvent evt) {
|
||||
TreeItem item = getCurrentItem();
|
||||
SWF swf = (SWF) item.getOpenable();
|
||||
File dir = null;
|
||||
String newName = "debug.swf";
|
||||
if (swf.getFile() != null) {
|
||||
dir = new File(swf.getFile()).getParentFile();
|
||||
String name = new File(swf.getFile()).getName();
|
||||
newName = name.substring(0, name.lastIndexOf(".")) + "_debug" + name.substring(name.lastIndexOf("."));
|
||||
}
|
||||
JFileChooser chooser = View.getFileChooserWithIcon("debug");
|
||||
chooser.setCurrentDirectory(dir);
|
||||
chooser.setSelectedFile(new File(dir, newName));
|
||||
chooser.setFileFilter(new FileFilter() {
|
||||
@Override
|
||||
public boolean accept(File f) {
|
||||
return f.getAbsolutePath().toLowerCase().endsWith(".swf") || f.isDirectory();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDescription() {
|
||||
return AppStrings.translate("filter.swf");
|
||||
}
|
||||
});
|
||||
if (chooser.showSaveDialog(this) != JFileChooser.APPROVE_OPTION) {
|
||||
return;
|
||||
}
|
||||
File selFile = Helper.fixDialogFile(chooser.getSelectedFile());
|
||||
|
||||
boolean doPCode = false;
|
||||
List<File> tempFiles = new ArrayList<>();
|
||||
try {
|
||||
Main.prepareForDebug(swf, selFile, selFile.getParentFile(), tempFiles, doPCode);
|
||||
} catch (IOException | InterruptedException ex) {
|
||||
ViewMessages.showMessageDialog(mainPanel, ex.toString(), AppStrings.translate("error"), JOptionPane.ERROR_MESSAGE);
|
||||
}
|
||||
Main.stopWork();
|
||||
}
|
||||
|
||||
private void gotoDocumentClassActionPerformed(ActionEvent evt) {
|
||||
TreeItem item = getCurrentItem();
|
||||
item.getOpenable();
|
||||
|
||||
Reference in New Issue
Block a user