mirror of
https://git.huckle.dev/Huckles-Minecraft-Archive/jpexs-decompiler.git
synced 2026-06-24 19:06:33 +00:00
AS1/2 debugger
debugger listening only when really debugging started fail to listen message break reason displayed
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -7,6 +7,7 @@
|
||||
*.conflict~
|
||||
*.identcache
|
||||
*.recompiled.swf
|
||||
run_test_*.swf
|
||||
Thumbs.db
|
||||
/build/
|
||||
/reports/
|
||||
|
||||
Binary file not shown.
@@ -52,7 +52,7 @@ auxiliary.show.customizer.message=<message>
|
||||
<action name="rebuild">
|
||||
<target>clean</target>
|
||||
<target>build</target>
|
||||
</action>
|
||||
</action>
|
||||
<action name="debug">
|
||||
<script>../../nbproject/ide-targets.xml</script>
|
||||
<target>debug-nb</target>
|
||||
@@ -137,7 +137,7 @@ auxiliary.show.customizer.message=<message>
|
||||
<arity>
|
||||
<one-file-only/>
|
||||
</arity>
|
||||
</context>
|
||||
</context>
|
||||
</action>
|
||||
<action name="debug.test.single">
|
||||
<script>nbproject/ide-file-targets.xml</script>
|
||||
@@ -147,7 +147,7 @@ auxiliary.show.customizer.message=<message>
|
||||
<folder>test</folder>
|
||||
<pattern>\.java$</pattern>
|
||||
<format>java-name</format>
|
||||
<arity>
|
||||
<arity>
|
||||
<one-file-only/>
|
||||
</arity>
|
||||
</context>
|
||||
@@ -181,7 +181,7 @@ auxiliary.show.customizer.message=<message>
|
||||
<one-file-only/>
|
||||
</arity>
|
||||
</context>
|
||||
</action>
|
||||
</action>
|
||||
</ide-actions>
|
||||
<export>
|
||||
<type>folder</type>
|
||||
@@ -219,7 +219,7 @@ auxiliary.show.customizer.message=<message>
|
||||
</source-file>
|
||||
<source-file>
|
||||
<location>nbproject/ide-file-targets.xml</location>
|
||||
</source-file>
|
||||
</source-file>
|
||||
</items>
|
||||
<context-menu>
|
||||
<ide-action name="build"/>
|
||||
@@ -236,7 +236,7 @@ auxiliary.show.customizer.message=<message>
|
||||
<java-data xmlns="http://www.netbeans.org/ns/freeform-project-java/4">
|
||||
<compilation-unit>
|
||||
<package-root>src</package-root>
|
||||
<classpath mode="compile">../../lib/LZMA.jar;../../lib/avi.jar;../../lib/gif.jar;../../lib/gnujpdf.jar;../../lib/jl1.0.1.jar;../../lib/jpacker.jar;../../lib/nellymoser.jar;../../lib/sfntly.jar;../../lib/ttf.jar;../../lib/cmykjpeg.jar;../../src</classpath>
|
||||
<classpath mode="compile">../../lib/LZMA.jar;../../lib/avi.jar;../../lib/gif.jar;../../lib/gnujpdf.jar;../../lib/jl1.0.1.jar;../../lib/jpacker.jar;../../lib/nellymoser.jar;../../lib/sfntly.jar;../../lib/ttf.jar;../../lib/cmykjpeg.jar;../../src;../../lib/flashdebugger.jar</classpath>
|
||||
<built-to>build</built-to>
|
||||
<built-to>reports</built-to>
|
||||
<built-to>dist</built-to>
|
||||
|
||||
@@ -18,6 +18,7 @@ package com.jpexs.decompiler.flash;
|
||||
|
||||
import SevenZip.Compression.LZMA.Decoder;
|
||||
import SevenZip.Compression.LZMA.Encoder;
|
||||
import com.jpexs.debugger.flash.SWD;
|
||||
import com.jpexs.decompiler.flash.abc.ABC;
|
||||
import com.jpexs.decompiler.flash.abc.CachedDecompilation;
|
||||
import com.jpexs.decompiler.flash.abc.ClassPath;
|
||||
@@ -77,6 +78,7 @@ import com.jpexs.decompiler.flash.helpers.SWFDecompilerPlugin;
|
||||
import com.jpexs.decompiler.flash.helpers.collections.MyEntry;
|
||||
import com.jpexs.decompiler.flash.helpers.hilight.Highlighting;
|
||||
import com.jpexs.decompiler.flash.tags.ABCContainerTag;
|
||||
import com.jpexs.decompiler.flash.tags.DebugIDTag;
|
||||
import com.jpexs.decompiler.flash.tags.DefineBinaryDataTag;
|
||||
import com.jpexs.decompiler.flash.tags.DefineSpriteTag;
|
||||
import com.jpexs.decompiler.flash.tags.DoInitActionTag;
|
||||
@@ -157,6 +159,7 @@ import java.awt.image.BufferedImage;
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
@@ -171,10 +174,15 @@ import java.util.HashSet;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Random;
|
||||
import java.util.Set;
|
||||
import java.util.Stack;
|
||||
import java.util.TreeMap;
|
||||
import java.util.TreeSet;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
import java.util.zip.DeflaterOutputStream;
|
||||
import java.util.zip.InflaterInputStream;
|
||||
|
||||
@@ -1094,12 +1102,7 @@ public final class SWF implements SWFContainerItem, Timelined {
|
||||
}
|
||||
}
|
||||
|
||||
/*preload shape tags
|
||||
for (Tag tag : tags) {
|
||||
if (tag instanceof ShapeTag) {
|
||||
((ShapeTag) tag).getShapes();
|
||||
}
|
||||
}*/
|
||||
getASMs(true); // Add scriptNames to ASMs
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -1473,11 +1476,14 @@ public final class SWF implements SWFContainerItem, Timelined {
|
||||
TreeItem realItem = treeItem instanceof TagScript ? ((TagScript) treeItem).getTag() : treeItem;
|
||||
if (realItem instanceof ASMSource && (exportAll || exportNode)) {
|
||||
String npath = path;
|
||||
String exPath = path;
|
||||
int ppos = 1;
|
||||
while (asmsToExport.containsKey(npath)) {
|
||||
ppos++;
|
||||
npath = path + (exportFileNames ? "[" + ppos + "]" : "_" + ppos);
|
||||
exPath = path + "[" + ppos + "]";
|
||||
}
|
||||
((ASMSource) realItem).setScriptName(exPath);
|
||||
asmsToExport.put(npath, (ASMSource) realItem);
|
||||
}
|
||||
|
||||
@@ -3143,6 +3149,8 @@ public final class SWF implements SWFContainerItem, Timelined {
|
||||
|
||||
int pos = 0;
|
||||
|
||||
boolean hasEnabled = false;
|
||||
|
||||
for (int i = 0; i < tags.size(); i++) {
|
||||
Tag t = tags.get(i);
|
||||
if (t instanceof MetadataTag) {
|
||||
@@ -3152,23 +3160,183 @@ public final class SWF implements SWFContainerItem, Timelined {
|
||||
pos = i + 1;
|
||||
}
|
||||
if (version >= 6 && (t instanceof EnableDebugger2Tag)) {
|
||||
return;
|
||||
hasEnabled = true;
|
||||
break;
|
||||
}
|
||||
if (version == 5 && (t instanceof EnableDebuggerTag)) {
|
||||
return;
|
||||
hasEnabled = true;
|
||||
break;
|
||||
}
|
||||
if (version < 5 && (t instanceof ProtectTag)) {
|
||||
return;
|
||||
hasEnabled = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (version >= 6) {
|
||||
tags.add(pos, new EnableDebugger2Tag(this));
|
||||
} else if (version == 5) {
|
||||
tags.add(pos, new EnableDebuggerTag(this));
|
||||
} else {
|
||||
tags.add(pos, new ProtectTag(this));
|
||||
if (!hasEnabled) {
|
||||
if (version >= 6) {
|
||||
tags.add(pos, new EnableDebugger2Tag(this));
|
||||
} else if (version == 5) {
|
||||
tags.add(pos, new EnableDebuggerTag(this));
|
||||
} else {
|
||||
tags.add(pos, new ProtectTag(this));
|
||||
}
|
||||
}
|
||||
|
||||
addDebugId();
|
||||
}
|
||||
|
||||
public DebugIDTag getDebugId() {
|
||||
for (Tag t : tags) {
|
||||
if (t instanceof DebugIDTag) {
|
||||
return (DebugIDTag) t;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public DebugIDTag addDebugId() {
|
||||
DebugIDTag r = getDebugId();
|
||||
if (r == null) {
|
||||
for (int i = 0; i < tags.size(); i++) {
|
||||
Tag t = tags.get(i);
|
||||
if ((t instanceof EnableDebuggerTag) || (t instanceof EnableDebugger2Tag)) {
|
||||
r = new DebugIDTag(this);
|
||||
tags.add(i + 1, r);
|
||||
new Random().nextBytes(r.debugId);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
public boolean generateSwdFile(File file, Map<String, Set<Integer>> breakpoints) throws IOException {
|
||||
DebugIDTag dit = getDebugId();
|
||||
if (dit == null) {
|
||||
return false;
|
||||
}
|
||||
List<SWD.DebugItem> items = new ArrayList<>();
|
||||
Map<String, ASMSource> asms = getASMs(true);
|
||||
|
||||
try {
|
||||
items.add(new SWD.DebugId(dit.debugId));
|
||||
Random rnd = new Random();
|
||||
|
||||
//Map<String, Integer> moduleIds = new HashMap<>();
|
||||
List<SWD.DebugOffset> swdOffsets = new ArrayList<>();
|
||||
List<SWD.DebugBreakpoint> swfBps = new ArrayList<>();
|
||||
int moduleId = 0;
|
||||
List<String> names = new ArrayList<>(asms.keySet());
|
||||
Collections.sort(names);
|
||||
//Collections.reverse(names);
|
||||
for (String name : names) {
|
||||
moduleId++;
|
||||
CachedScript cs;
|
||||
try {
|
||||
cs = SWF.getCached(asms.get(name), asms.get(name).getActions());
|
||||
} catch (InterruptedException ex) {
|
||||
return false;
|
||||
}
|
||||
String txt = cs.text.replace("\r", "");
|
||||
int line = 1;
|
||||
Map<Integer, Integer> lineToOffset = new HashMap<>();
|
||||
Map<Integer, String> regNames = new HashMap<>();
|
||||
|
||||
for (int pos = 0; pos < txt.length(); pos++) {
|
||||
Highlighting h = Highlighting.searchPos(cs.hilights, pos);
|
||||
if (h != null) {
|
||||
|
||||
int firstLineOffset = (int) h.getProperties().firstLineOffset;
|
||||
if (firstLineOffset != -1) {
|
||||
if (h.getProperties().declaration && h.getProperties().regIndex > -1) {
|
||||
regNames.put(h.getProperties().regIndex, h.getProperties().localName);
|
||||
|
||||
/*List<Integer> curRegIndexes = new ArrayList<>(regNames.keySet());
|
||||
List<String> curRegNames = new ArrayList<>();
|
||||
for (int i = 0; i < curRegIndexes.size(); i++) {
|
||||
curRegNames.add(regNames.get(i));
|
||||
}
|
||||
items.add(new SWD.DebugRegisters((int) h.getProperties().firstLineOffset, curRegIndexes, curRegNames));*/
|
||||
}
|
||||
}
|
||||
if (firstLineOffset != -1 && !lineToOffset.containsKey(line)) {
|
||||
lineToOffset.put(line, firstLineOffset);
|
||||
}
|
||||
}
|
||||
if (txt.charAt(pos) == '\n') {
|
||||
line++;
|
||||
}
|
||||
}
|
||||
|
||||
Map<Integer, Integer> offSetToLine = new TreeMap<>();
|
||||
for (Map.Entry<Integer, Integer> en : lineToOffset.entrySet()) {
|
||||
offSetToLine.put(en.getValue(), en.getKey());
|
||||
}
|
||||
|
||||
//final String NONAME = "[No instance name assigned]";
|
||||
String sname = name;
|
||||
int bitmap = SWD.bitmapAction;
|
||||
/* Matcher m;
|
||||
int bitmap = SWD.bitmapAction;
|
||||
m = Pattern.compile("^\\\\frame_([0-9]+)\\\\DoAction$").matcher(sname);
|
||||
if (m.matches()) {
|
||||
//TODO: scenes?, layers?
|
||||
sname = "Actions for Scene 1: Frame " + m.group(1) + " of Layer Name Layer 1";
|
||||
} else if ((m = Pattern.compile("^\\\\__Packages\\\\(.*)$").matcher(sname)).matches()) {
|
||||
sname = m.group(1).replace("\\", ".") + ": .\\" + m.group(1) + ".as";
|
||||
} else {
|
||||
continue; //FIXME!
|
||||
}
|
||||
m = Pattern.compile("^\\\\DefineSprite_([0-9])+\\\\frame_([0-9]+)\\\\DoAction$").matcher(sname);
|
||||
if (m.matches()) {
|
||||
//TODO: layers?
|
||||
//sname = "Actions for Symbol " + m.group(1) + ": Frame " + m.group(2) + " of Layer Name Layer 1";
|
||||
continue; //FIXME!
|
||||
}
|
||||
|
||||
//TODO: handle onxxx together ?
|
||||
m = Pattern.compile("^\\\\DefineButton2?_([0-9]+)\\\\on\\(.*$").matcher(sname);
|
||||
if (m.matches()) {
|
||||
//bitmap = SWD.bitmapOnAction;
|
||||
//sname = "Actions for " + NONAME + " (Symbol " + m.group(1) + ")";
|
||||
continue; //FIXME!
|
||||
}
|
||||
|
||||
//TODO: handle onClipEvent together ?
|
||||
m = Pattern.compile("^\\\\frame_([0-9]+)\\\\PlaceObject[2-3]?_([0-9]+)_[^\\\\]*\\\\onClipEvent\\(.*$").matcher(sname);
|
||||
if (m.matches()) {
|
||||
//bitmap = SWD.bitmapOnClipAction;
|
||||
//sname = "Actions for " + NONAME + " (Symbol " + m.group(2) + ")";
|
||||
continue; //FIXME!
|
||||
}//*/
|
||||
|
||||
items.add(new SWD.DebugScript(moduleId, bitmap, sname, txt));
|
||||
for (int ofs : offSetToLine.keySet()) {
|
||||
items.add(new SWD.DebugOffset(moduleId, offSetToLine.get(ofs), ofs));
|
||||
}
|
||||
if (breakpoints.containsKey(name)) {
|
||||
Set<Integer> bplines = breakpoints.get(name);
|
||||
for (int bpline : bplines) {
|
||||
if (lineToOffset.containsKey(bpline)) {
|
||||
items.add(new SWD.DebugBreakpoint(moduleId, bpline));
|
||||
}
|
||||
}
|
||||
}
|
||||
//moduleId++;
|
||||
}
|
||||
//items.addAll(swdOffsets);
|
||||
//items.addAll(swfBps);
|
||||
|
||||
} catch (Throwable t) {
|
||||
Logger.getLogger(SWF.class.getName()).log(Level.SEVERE, "message", t);
|
||||
return false;
|
||||
}
|
||||
SWD swd = new SWD(7, items);
|
||||
try (FileOutputStream fis = new FileOutputStream(file)) {
|
||||
swd.saveTo(fis);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean enableTelemetry(String password) {
|
||||
|
||||
@@ -897,7 +897,7 @@ public class SWFInputStream implements AutoCloseable {
|
||||
InflaterInputStream dis = new InflaterInputStream(new ByteArrayInputStream(data, offset, length));
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
byte[] buf = new byte[4096];
|
||||
int c = 0;
|
||||
int c;
|
||||
while ((c = dis.read(buf)) > 0) {
|
||||
baos.write(buf, 0, c);
|
||||
}
|
||||
@@ -1202,11 +1202,7 @@ public class SWFInputStream implements AutoCloseable {
|
||||
break;
|
||||
case DoActionTag.ID:
|
||||
case DoInitActionTag.ID:
|
||||
if (isAS3) {
|
||||
doParse = false;
|
||||
} else {
|
||||
doParse = true;
|
||||
}
|
||||
doParse = !isAS3;
|
||||
break;
|
||||
case ShowFrameTag.ID:
|
||||
case PlaceObjectTag.ID:
|
||||
@@ -1233,7 +1229,7 @@ public class SWFInputStream implements AutoCloseable {
|
||||
|
||||
}
|
||||
}
|
||||
if (parseTags && doParse && parallel1 && tag instanceof TagStub) {
|
||||
if (parseTags && doParse && parallel1 && tag instanceof TagStub && executor != null) {
|
||||
Future<Tag> future = executor.submit(new TagResolutionTask((TagStub) tag, di, level, parallel1, skipUnusualTags, lazy));
|
||||
futureResults.add(future);
|
||||
} else {
|
||||
@@ -1262,7 +1258,9 @@ public class SWFInputStream implements AutoCloseable {
|
||||
}
|
||||
}
|
||||
|
||||
executor.shutdown();
|
||||
if (executor != null) {
|
||||
executor.shutdown();
|
||||
}
|
||||
}
|
||||
return tags;
|
||||
}
|
||||
@@ -1670,7 +1668,7 @@ public class SWFInputStream implements AutoCloseable {
|
||||
* @throws IOException
|
||||
*/
|
||||
public Action readAction() throws IOException {
|
||||
int actionCode = -1;
|
||||
int actionCode;
|
||||
|
||||
try {
|
||||
actionCode = readUI8("actionCode");
|
||||
|
||||
@@ -61,6 +61,11 @@ public class AVM2Instruction implements Cloneable, GraphSourceItem {
|
||||
|
||||
private String file;
|
||||
|
||||
@Override
|
||||
public long getLineOffset() {
|
||||
return getOffset();
|
||||
}
|
||||
|
||||
public void setFileLine(String file, int line) {
|
||||
this.file = file;
|
||||
this.line = line;
|
||||
|
||||
@@ -21,6 +21,7 @@ import com.jpexs.decompiler.flash.BaseLocalData;
|
||||
import com.jpexs.decompiler.flash.DisassemblyListener;
|
||||
import com.jpexs.decompiler.flash.SWF;
|
||||
import com.jpexs.decompiler.flash.SWFOutputStream;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.parser.script.Reference;
|
||||
import com.jpexs.decompiler.flash.action.deobfuscation.ActionDeobfuscator;
|
||||
import com.jpexs.decompiler.flash.action.model.ActionItem;
|
||||
import com.jpexs.decompiler.flash.action.model.ConstantPool;
|
||||
@@ -109,6 +110,8 @@ public abstract class Action implements GraphSourceItem {
|
||||
|
||||
private boolean ignored = false;
|
||||
|
||||
public long fileOffset = -1;
|
||||
|
||||
/**
|
||||
* Action type identifier
|
||||
*/
|
||||
@@ -121,6 +124,11 @@ public abstract class Action implements GraphSourceItem {
|
||||
|
||||
private long address;
|
||||
|
||||
@Override
|
||||
public long getLineOffset() {
|
||||
return fileOffset;
|
||||
}
|
||||
|
||||
/**
|
||||
* Names of ActionScript properties
|
||||
*/
|
||||
@@ -937,11 +945,12 @@ public abstract class Action implements GraphSourceItem {
|
||||
this.ignored = ignored;
|
||||
}
|
||||
|
||||
public static List<GraphTargetItem> actionsPartToTree(HashMap<Integer, String> registerNames, HashMap<String, GraphTargetItem> variables, HashMap<String, GraphTargetItem> functions, TranslateStack stack, List<Action> actions, int start, int end, int version, int staticOperation, String path) throws InterruptedException {
|
||||
public static List<GraphTargetItem> actionsPartToTree(Reference<GraphSourceItem> fi, HashMap<Integer, String> registerNames, HashMap<String, GraphTargetItem> variables, HashMap<String, GraphTargetItem> functions, TranslateStack stack, List<Action> actions, int start, int end, int version, int staticOperation, String path) throws InterruptedException {
|
||||
if (start < actions.size() && (end > 0) && (start > 0)) {
|
||||
logger.log(Level.FINE, "Entering {0}-{1}{2}", new Object[]{start, end, actions.size() > 0 ? (" (" + actions.get(start).toString() + " - " + actions.get(end == actions.size() ? end - 1 : end) + ")") : ""});
|
||||
}
|
||||
ActionLocalData localData = new ActionLocalData(registerNames, variables, functions);
|
||||
localData.lineStartAction = fi.getVal();
|
||||
List<GraphTargetItem> output = new ArrayList<>();
|
||||
int ip = start;
|
||||
boolean isWhile = false;
|
||||
@@ -964,6 +973,10 @@ public abstract class Action implements GraphSourceItem {
|
||||
ip++;
|
||||
continue;
|
||||
}
|
||||
if (stack.isEmpty()) {
|
||||
localData.lineStartAction = action;
|
||||
fi.setVal(action);
|
||||
}
|
||||
if (action instanceof GraphSourceItemContainer) {
|
||||
GraphSourceItemContainer cnt = (GraphSourceItemContainer) action;
|
||||
//List<GraphTargetItem> out=actionsPartToTree(new HashMap<Integer, String>(), new HashMap<String, GraphTargetItem>(),new HashMap<String, GraphTargetItem>(), new TranslateStack(), src, ip+1,endip-1 , version);
|
||||
|
||||
@@ -79,7 +79,11 @@ public class ActionGraphSource extends GraphSource {
|
||||
|
||||
@Override
|
||||
public List<GraphTargetItem> translatePart(GraphPart part, BaseLocalData localData, TranslateStack stack, int start, int end, int staticOperation, String path) throws InterruptedException {
|
||||
return Action.actionsPartToTree(registerNames, variables, functions, stack, actions, start, end, version, staticOperation, path);
|
||||
Reference<GraphSourceItem> fi = new Reference<>(localData.lineStartInstruction);
|
||||
|
||||
List<GraphTargetItem> r = Action.actionsPartToTree(fi, registerNames, variables, functions, stack, actions, start, end, version, staticOperation, path);
|
||||
localData.lineStartInstruction = fi.getVal();
|
||||
return r;
|
||||
}
|
||||
|
||||
private List<Long> posCache = null;
|
||||
|
||||
@@ -796,6 +796,7 @@ public class ActionListReader {
|
||||
if ((a = sis.readAction()) == null) {
|
||||
break;
|
||||
}
|
||||
a.fileOffset = ip;
|
||||
|
||||
int actionLengthWithHeader = a.getTotalActionLength();
|
||||
|
||||
|
||||
@@ -524,6 +524,10 @@ public class Configuration {
|
||||
@ConfigurationName("gui.avm2.splitPane.vars.dividerLocationPercent")
|
||||
public static final ConfigurationItem<Double> guiAvm2VarsSplitPaneDividerLocationPercent = null;
|
||||
|
||||
@ConfigurationDefaultDouble(0.7)
|
||||
@ConfigurationName("gui.action.splitPane.vars.dividerLocationPercent")
|
||||
public static final ConfigurationItem<Double> guiActionVarsSplitPaneDividerLocationPercent = null;
|
||||
|
||||
@ConfigurationDefaultBoolean(true)
|
||||
@ConfigurationCategory("script")
|
||||
public static final ConfigurationItem<Boolean> debugHalt = null;
|
||||
|
||||
@@ -184,7 +184,7 @@ public class HighlightedTextWriter extends GraphTextWriter {
|
||||
ndata.merge(data);
|
||||
ndata.offset = src.getOffset() + pos;
|
||||
if (itemPos.startLineItem != null) {
|
||||
ndata.firstLineOffset = itemPos.startLineItem.getOffset();
|
||||
ndata.firstLineOffset = itemPos.startLineItem.getLineOffset();
|
||||
}
|
||||
h = new Highlighting(sb.length() - newLineCount, ndata, HighlightType.OFFSET, str);
|
||||
instructionHilights.add(h);
|
||||
|
||||
@@ -84,6 +84,13 @@ public class DefineButtonTag extends ButtonTag implements ASMSource {
|
||||
|
||||
private boolean isSingleFrame;
|
||||
|
||||
private String scriptName = "-";
|
||||
|
||||
@Override
|
||||
public String getScriptName() {
|
||||
return scriptName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
@@ -108,6 +115,11 @@ public class DefineButtonTag extends ButtonTag implements ASMSource {
|
||||
readData(sis, data, 0, false, false, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setScriptName(String scriptName) {
|
||||
this.scriptName = scriptName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void readData(SWFInputStream sis, ByteArrayRange data, int level, boolean parallel, boolean skipUnusualTags, boolean lazy) throws IOException {
|
||||
buttonId = sis.readUI16("buttonId");
|
||||
|
||||
@@ -27,6 +27,7 @@ import com.jpexs.decompiler.flash.exporters.modes.ScriptExportMode;
|
||||
import com.jpexs.decompiler.flash.helpers.GraphTextWriter;
|
||||
import com.jpexs.decompiler.flash.tags.base.ASMSource;
|
||||
import com.jpexs.decompiler.flash.types.annotations.HideInRawEdit;
|
||||
import com.jpexs.decompiler.flash.types.annotations.Internal;
|
||||
import com.jpexs.decompiler.flash.types.annotations.SWFVersion;
|
||||
import com.jpexs.helpers.ByteArrayRange;
|
||||
import com.jpexs.helpers.Helper;
|
||||
@@ -54,6 +55,14 @@ public class DoActionTag extends Tag implements ASMSource {
|
||||
@HideInRawEdit
|
||||
public ByteArrayRange actionBytes;
|
||||
|
||||
@Internal
|
||||
private String scriptName = "-";
|
||||
|
||||
@Override
|
||||
public String getScriptName() {
|
||||
return scriptName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
@@ -87,6 +96,11 @@ public class DoActionTag extends Tag implements ASMSource {
|
||||
readData(sis, data, 0, false, false, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setScriptName(String scriptName) {
|
||||
this.scriptName = scriptName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void readData(SWFInputStream sis, ByteArrayRange data, int level, boolean parallel, boolean skipUnusualTags, boolean lazy) throws IOException {
|
||||
actionBytes = sis.readByteRangeEx(sis.available(), "actionBytes");
|
||||
|
||||
@@ -29,6 +29,7 @@ import com.jpexs.decompiler.flash.tags.base.ASMSource;
|
||||
import com.jpexs.decompiler.flash.tags.base.CharacterIdTag;
|
||||
import com.jpexs.decompiler.flash.types.BasicType;
|
||||
import com.jpexs.decompiler.flash.types.annotations.HideInRawEdit;
|
||||
import com.jpexs.decompiler.flash.types.annotations.Internal;
|
||||
import com.jpexs.decompiler.flash.types.annotations.SWFType;
|
||||
import com.jpexs.decompiler.flash.types.annotations.SWFVersion;
|
||||
import com.jpexs.helpers.ByteArrayRange;
|
||||
@@ -61,6 +62,14 @@ public class DoInitActionTag extends Tag implements CharacterIdTag, ASMSource {
|
||||
@HideInRawEdit
|
||||
public ByteArrayRange actionBytes;
|
||||
|
||||
@Internal
|
||||
private String scriptName = "-";
|
||||
|
||||
@Override
|
||||
public String getScriptName() {
|
||||
return scriptName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
@@ -71,6 +80,11 @@ public class DoInitActionTag extends Tag implements CharacterIdTag, ASMSource {
|
||||
actionBytes = ByteArrayRange.EMPTY;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setScriptName(String scriptName) {
|
||||
this.scriptName = scriptName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
|
||||
@@ -91,4 +91,8 @@ public interface ASMSource extends Exportable {
|
||||
public Tag getSourceTag();
|
||||
|
||||
public void setSourceTag(Tag t);
|
||||
|
||||
public String getScriptName();
|
||||
|
||||
public void setScriptName(String scriptName);
|
||||
}
|
||||
|
||||
@@ -47,6 +47,13 @@ public class BUTTONCONDACTION implements ASMSource, Serializable {
|
||||
|
||||
private Tag tag;
|
||||
|
||||
private String scriptName = "-";
|
||||
|
||||
@Override
|
||||
public String getScriptName() {
|
||||
return scriptName;
|
||||
}
|
||||
|
||||
// Constructor for Generic tag editor.
|
||||
public BUTTONCONDACTION() {
|
||||
swf = null;
|
||||
@@ -54,6 +61,11 @@ public class BUTTONCONDACTION implements ASMSource, Serializable {
|
||||
actionBytes = new ByteArrayRange(SWFInputStream.BYTE_ARRAY_EMPTY);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setScriptName(String scriptName) {
|
||||
this.scriptName = scriptName;
|
||||
}
|
||||
|
||||
public BUTTONCONDACTION(SWF swf, SWFInputStream sis, Tag tag) throws IOException {
|
||||
this.swf = swf;
|
||||
this.tag = tag;
|
||||
|
||||
@@ -42,6 +42,13 @@ import java.util.List;
|
||||
*/
|
||||
public class CLIPACTIONRECORD implements ASMSource, Serializable {
|
||||
|
||||
private String scriptName = "-";
|
||||
|
||||
@Override
|
||||
public String getScriptName() {
|
||||
return scriptName;
|
||||
}
|
||||
|
||||
public static String keyToString(int key) {
|
||||
if ((key < CLIPACTIONRECORD.KEYNAMES.length) && (key > 0) && (CLIPACTIONRECORD.KEYNAMES[key] != null)) {
|
||||
return CLIPACTIONRECORD.KEYNAMES[key];
|
||||
@@ -100,6 +107,11 @@ public class CLIPACTIONRECORD implements ASMSource, Serializable {
|
||||
actionBytes = ByteArrayRange.EMPTY;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setScriptName(String scriptName) {
|
||||
this.scriptName = scriptName;
|
||||
}
|
||||
|
||||
public CLIPACTIONRECORD(SWF swf, SWFInputStream sis, Tag tag) throws IOException {
|
||||
this.swf = swf;
|
||||
this.tag = tag;
|
||||
|
||||
@@ -37,6 +37,8 @@ public interface GraphSourceItem extends Serializable, Cloneable {
|
||||
|
||||
public long getOffset();
|
||||
|
||||
public long getLineOffset();
|
||||
|
||||
public boolean ignoredLoops();
|
||||
|
||||
public List<Integer> getBranches(GraphSource code);
|
||||
|
||||
BIN
libsrc/ffdec_lib/testdata/run_as2/run_as2.swf
vendored
Normal file
BIN
libsrc/ffdec_lib/testdata/run_as2/run_as2.swf
vendored
Normal file
Binary file not shown.
BIN
libsrc/ffdec_lib/testdata/run_as3/run.swf
vendored
BIN
libsrc/ffdec_lib/testdata/run_as3/run.swf
vendored
Binary file not shown.
@@ -14,17 +14,18 @@
|
||||
* 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.abc;
|
||||
package com.jpexs.decompiler.flash.gui;
|
||||
|
||||
import com.jpexs.debugger.flash.Variable;
|
||||
import com.jpexs.debugger.flash.messages.in.InBreakAtExt;
|
||||
import com.jpexs.debugger.flash.messages.in.InFrame;
|
||||
import com.jpexs.decompiler.flash.gui.AppStrings;
|
||||
import com.jpexs.decompiler.flash.gui.DebuggerHandler;
|
||||
import com.jpexs.decompiler.flash.gui.DebuggerHandler.VariableChangedListener;
|
||||
import com.jpexs.decompiler.flash.gui.DebuggerHandler.BreakListener;
|
||||
import com.jpexs.decompiler.flash.gui.HeaderLabel;
|
||||
import com.jpexs.decompiler.flash.gui.Main;
|
||||
import com.jpexs.decompiler.flash.gui.View;
|
||||
import com.jpexs.decompiler.flash.gui.abc.ABCPanel;
|
||||
import java.awt.BorderLayout;
|
||||
import java.awt.Color;
|
||||
import java.awt.FlowLayout;
|
||||
@@ -55,16 +56,25 @@ public class DebugPanel extends JPanel {
|
||||
private JTable callStackTable;
|
||||
private JTable stackTable;
|
||||
private JTabbedPane varTabs;
|
||||
private VariableChangedListener listener;
|
||||
private BreakListener listener;
|
||||
private JTextArea traceLogTextarea;
|
||||
private int logLength = 0;
|
||||
private List<SelectedTab> tabTypes = new ArrayList<>();
|
||||
private boolean loading = false;
|
||||
|
||||
public static enum SelectedTab {
|
||||
|
||||
LOG, STACK, SCOPECHAIN, LOCALS, REGISTERS, CALLSTACK
|
||||
}
|
||||
|
||||
public synchronized boolean isLoading() {
|
||||
return loading;
|
||||
}
|
||||
|
||||
public synchronized void setLoading(boolean loading) {
|
||||
this.loading = loading;
|
||||
}
|
||||
|
||||
private SelectedTab selectedTab = null;
|
||||
|
||||
public DebugPanel() {
|
||||
@@ -101,11 +111,30 @@ public class DebugPanel extends JPanel {
|
||||
}
|
||||
});
|
||||
|
||||
Main.getDebugHandler().addVariableChangedListener(listener = new DebuggerHandler.VariableChangedListener() {
|
||||
Main.getDebugHandler().addBreakListener(listener = new DebuggerHandler.BreakListener() {
|
||||
|
||||
@Override
|
||||
public void variablesChanged() {
|
||||
refresh();
|
||||
public void doContinue() {
|
||||
View.execInEventDispatch(new Runnable() {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
refresh();
|
||||
}
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void breakAt(String scriptName, int line) {
|
||||
View.execInEventDispatch(new Runnable() {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
refresh();
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
@@ -115,6 +144,9 @@ public class DebugPanel extends JPanel {
|
||||
@Override
|
||||
public void stateChanged(ChangeEvent e) {
|
||||
if (e.getSource() == varTabs) {
|
||||
if (isLoading()) {
|
||||
return;
|
||||
}
|
||||
synchronized (DebugPanel.this) {
|
||||
int si = varTabs.getSelectedIndex();
|
||||
if (si > -1 && si < tabTypes.size()) {
|
||||
@@ -135,10 +167,10 @@ public class DebugPanel extends JPanel {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
setLoading(true);
|
||||
synchronized (DebugPanel.this) {
|
||||
|
||||
SelectedTab oldSel = selectedTab;
|
||||
SelectedTab firstVisible = null;
|
||||
SelectedTab newSel = null;
|
||||
InFrame f = Main.getDebugHandler().getFrame();
|
||||
if (f != null) {
|
||||
debugRegistersTable.setModel(new ABCPanel.VariablesTableModel(f.registers));
|
||||
@@ -251,23 +283,24 @@ public class DebugPanel extends JPanel {
|
||||
setVisible(newVisible);
|
||||
}
|
||||
if (!tabTypes.isEmpty()) {
|
||||
if (oldSel != null && tabTypes.contains(oldSel)) {
|
||||
selectedTab = oldSel;
|
||||
} else {
|
||||
selectedTab = tabTypes.get(0);
|
||||
if (oldSel != null && !tabTypes.contains(oldSel)) {
|
||||
oldSel = null;
|
||||
}
|
||||
varTabs.setSelectedIndex(tabTypes.indexOf(selectedTab));
|
||||
} else {
|
||||
selectedTab = null;
|
||||
}
|
||||
if (oldSel != null) {
|
||||
selectedTab = oldSel;
|
||||
varTabs.setSelectedIndex(tabTypes.indexOf(selectedTab));
|
||||
}
|
||||
setLoading(false);
|
||||
}
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
public void dispose() {
|
||||
Main.getDebugHandler().removeVariableChangedListener(listener);
|
||||
Main.getDebugHandler().removeBreakListener(listener);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -21,6 +21,7 @@ import com.jpexs.debugger.flash.DebugMessageListener;
|
||||
import com.jpexs.debugger.flash.Debugger;
|
||||
import com.jpexs.debugger.flash.DebuggerCommands;
|
||||
import com.jpexs.debugger.flash.DebuggerConnection;
|
||||
import com.jpexs.debugger.flash.SWD;
|
||||
import com.jpexs.debugger.flash.Variable;
|
||||
import com.jpexs.debugger.flash.messages.in.InAskBreakpoints;
|
||||
import com.jpexs.debugger.flash.messages.in.InBreakAt;
|
||||
@@ -28,13 +29,19 @@ import com.jpexs.debugger.flash.messages.in.InBreakAtExt;
|
||||
import com.jpexs.debugger.flash.messages.in.InBreakReason;
|
||||
import com.jpexs.debugger.flash.messages.in.InContinue;
|
||||
import com.jpexs.debugger.flash.messages.in.InFrame;
|
||||
import com.jpexs.debugger.flash.messages.in.InGetSwd;
|
||||
import com.jpexs.debugger.flash.messages.in.InGetSwf;
|
||||
import com.jpexs.debugger.flash.messages.in.InNumScript;
|
||||
import com.jpexs.debugger.flash.messages.in.InProcessTag;
|
||||
import com.jpexs.debugger.flash.messages.in.InScript;
|
||||
import com.jpexs.debugger.flash.messages.in.InSetBreakpoint;
|
||||
import com.jpexs.debugger.flash.messages.in.InSwfInfo;
|
||||
import com.jpexs.debugger.flash.messages.in.InTrace;
|
||||
import com.jpexs.debugger.flash.messages.in.InVersion;
|
||||
import com.jpexs.debugger.flash.messages.out.OutGetBreakReason;
|
||||
import com.jpexs.debugger.flash.messages.out.OutGetSwd;
|
||||
import com.jpexs.debugger.flash.messages.out.OutGetSwf;
|
||||
import com.jpexs.debugger.flash.messages.out.OutProcessedTag;
|
||||
import com.jpexs.decompiler.flash.abc.ClassPath;
|
||||
import com.jpexs.decompiler.flash.abc.ScriptPack;
|
||||
import com.jpexs.decompiler.flash.configuration.Configuration;
|
||||
@@ -43,6 +50,7 @@ import com.jpexs.helpers.CancellableWorker;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
@@ -50,6 +58,8 @@ import java.util.TreeSet;
|
||||
import java.util.logging.ConsoleHandler;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/**
|
||||
*
|
||||
@@ -61,41 +71,178 @@ public class DebuggerHandler implements DebugConnectionListener {
|
||||
private DebuggerCommands commands = null;
|
||||
private List<InSwfInfo.SwfInfo> swfs = new ArrayList<>();
|
||||
private boolean paused = true;
|
||||
private Map<Integer, ClassPath> modulePaths = new HashMap<>();
|
||||
private Map<ClassPath, Integer> classToModule = new HashMap<>();
|
||||
private Map<Integer, String> modulePaths = new HashMap<>();
|
||||
private Map<String, Integer> classToModule = new HashMap<>();
|
||||
|
||||
private Map<String, Set<Integer>> toAddBPointMap = new HashMap<>();
|
||||
private Map<String, Set<Integer>> confirmedPointMap = new HashMap<>();
|
||||
private Map<String, Set<Integer>> invalidBreakPointMap = new HashMap<>();
|
||||
private Map<String, Set<Integer>> toRemoveBPointMap = new HashMap<>();
|
||||
|
||||
private int breakIp = -1;
|
||||
private String breakScriptName = null;
|
||||
|
||||
public int getBreakIp() {
|
||||
return breakIp;
|
||||
}
|
||||
|
||||
public String getBreakScriptName() {
|
||||
return breakScriptName;
|
||||
}
|
||||
|
||||
public synchronized void removeBreakPoint(String scriptName, int line) {
|
||||
if (isBreakpointInvalid(scriptName, line)) {
|
||||
return;
|
||||
}
|
||||
if (isBreakpointToAdd(scriptName, line)) {
|
||||
toAddBPointMap.get(scriptName).remove(line);
|
||||
if (toAddBPointMap.get(scriptName).isEmpty()) {
|
||||
toAddBPointMap.remove(scriptName);
|
||||
}
|
||||
} else if (isBreakpointConfirmed(scriptName, line)) {
|
||||
if (!toRemoveBPointMap.containsKey(scriptName)) {
|
||||
toRemoveBPointMap.put(scriptName, new TreeSet<>());
|
||||
}
|
||||
toRemoveBPointMap.get(scriptName).add(line);
|
||||
}
|
||||
try {
|
||||
sendBreakPoints(false);
|
||||
} catch (IOException ex) {
|
||||
//ignore
|
||||
}
|
||||
}
|
||||
|
||||
public synchronized Set<Integer> getBreakPoints(String scriptName) {
|
||||
Set<Integer> lines = new TreeSet<>();
|
||||
if (confirmedPointMap.containsKey(scriptName)) {
|
||||
lines.addAll(confirmedPointMap.get(scriptName));
|
||||
}
|
||||
if (toAddBPointMap.containsKey(scriptName)) {
|
||||
lines.addAll(toAddBPointMap.get(scriptName));
|
||||
}
|
||||
return lines;
|
||||
}
|
||||
|
||||
public synchronized void clearBreakPoints() {
|
||||
for (String scriptName : confirmedPointMap.keySet()) {
|
||||
if (!toAddBPointMap.containsKey(scriptName)) {
|
||||
toAddBPointMap.put(scriptName, new TreeSet<>());
|
||||
}
|
||||
toAddBPointMap.get(scriptName).addAll(confirmedPointMap.get(scriptName));
|
||||
}
|
||||
confirmedPointMap.clear();
|
||||
invalidBreakPointMap.clear();
|
||||
}
|
||||
|
||||
public synchronized Map<String, Set<Integer>> getAllBreakPoints(boolean validOnly) {
|
||||
Map<String, Set<Integer>> ret = new HashMap<>();
|
||||
for (String scriptName : confirmedPointMap.keySet()) {
|
||||
Set<Integer> lines = new TreeSet<>();
|
||||
lines.addAll(confirmedPointMap.get(scriptName));
|
||||
ret.put(scriptName, lines);
|
||||
}
|
||||
for (String scriptName : toAddBPointMap.keySet()) {
|
||||
if (!ret.containsKey(scriptName)) {
|
||||
ret.put(scriptName, new TreeSet<>());
|
||||
}
|
||||
ret.get(scriptName).addAll(toAddBPointMap.get(scriptName));
|
||||
}
|
||||
if (!validOnly) {
|
||||
for (String scriptName : invalidBreakPointMap.keySet()) {
|
||||
if (!ret.containsKey(scriptName)) {
|
||||
ret.put(scriptName, new TreeSet<>());
|
||||
}
|
||||
ret.get(scriptName).addAll(invalidBreakPointMap.get(scriptName));
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
public boolean addBreakPoint(String scriptName, int line) {
|
||||
synchronized (this) {
|
||||
Logger.getLogger(DebuggerHandler.class.getName()).log(Level.INFO, "adding bp " + scriptName + ":" + line);
|
||||
if (isBreakpointToRemove(scriptName, line)) {
|
||||
toRemoveBPointMap.get(scriptName).remove(line);
|
||||
if (toRemoveBPointMap.get(scriptName).isEmpty()) {
|
||||
toRemoveBPointMap.remove(scriptName);
|
||||
}
|
||||
}
|
||||
|
||||
if (isBreakpointConfirmed(scriptName, line)) {
|
||||
Logger.getLogger(DebuggerHandler.class.getName()).log(Level.INFO, "bp " + scriptName + ":" + line + " already confirmed");
|
||||
return true;
|
||||
}
|
||||
if (isBreakpointInvalid(scriptName, line)) {
|
||||
Logger.getLogger(DebuggerHandler.class.getName()).log(Level.INFO, "bp " + scriptName + ":" + line + " already invalid");
|
||||
return false;
|
||||
}
|
||||
if (!toAddBPointMap.containsKey(scriptName)) {
|
||||
toAddBPointMap.put(scriptName, new TreeSet<>());
|
||||
}
|
||||
toAddBPointMap.get(scriptName).add(line);
|
||||
Logger.getLogger(DebuggerHandler.class.getName()).log(Level.INFO, "bp " + scriptName + ":" + line + " added to todo");
|
||||
}
|
||||
try {
|
||||
sendBreakPoints(false);
|
||||
} catch (IOException ex) {
|
||||
//ignored
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public synchronized boolean isBreakpointConfirmed(String scriptName, int line) {
|
||||
return confirmedPointMap.containsKey(scriptName) && confirmedPointMap.get(scriptName).contains(line);
|
||||
}
|
||||
|
||||
public synchronized boolean isBreakpointToAdd(String scriptName, int line) {
|
||||
return toAddBPointMap.containsKey(scriptName) && toAddBPointMap.get(scriptName).contains(line);
|
||||
}
|
||||
|
||||
public synchronized boolean isBreakpointToRemove(String scriptName, int line) {
|
||||
return toRemoveBPointMap.containsKey(scriptName) && toRemoveBPointMap.get(scriptName).contains(line);
|
||||
}
|
||||
|
||||
public synchronized boolean isBreakpointInvalid(String scriptName, int line) {
|
||||
return invalidBreakPointMap.containsKey(scriptName) && invalidBreakPointMap.get(scriptName).contains(line);
|
||||
}
|
||||
|
||||
private synchronized void markBreakPointInvalid(String scriptName, int line) {
|
||||
if (!invalidBreakPointMap.containsKey(scriptName)) {
|
||||
invalidBreakPointMap.put(scriptName, new TreeSet<>());
|
||||
}
|
||||
invalidBreakPointMap.get(scriptName).add(line);
|
||||
}
|
||||
|
||||
private InFrame frame;
|
||||
|
||||
private InBreakAtExt breakInfo;
|
||||
private InBreakReason breakReason;
|
||||
|
||||
private final List<VariableChangedListener> varListeners = new ArrayList<>();
|
||||
private final List<BreakListener> breakListeners = new ArrayList<>();
|
||||
|
||||
private final List<TraceListener> traceListeners = new ArrayList<>();
|
||||
|
||||
private final List<ConnectionListener> clisteners = new ArrayList<>();
|
||||
|
||||
public void notSuspended() {
|
||||
frame = null;
|
||||
breakInfo = null;
|
||||
breakReason = null;
|
||||
for (VariableChangedListener l : varListeners) {
|
||||
l.variablesChanged();
|
||||
}
|
||||
}
|
||||
|
||||
public String moduleToString(int file) {
|
||||
if (!modulePaths.containsKey(file)) {
|
||||
return "unknown";
|
||||
}
|
||||
return modulePaths.get(file).toString();
|
||||
return modulePaths.get(file);
|
||||
}
|
||||
|
||||
public InBreakAtExt getBreakInfo() {
|
||||
public synchronized InBreakAtExt getBreakInfo() {
|
||||
if (!paused) {
|
||||
return null;
|
||||
}
|
||||
return breakInfo;
|
||||
}
|
||||
|
||||
public InBreakReason getBreakReason() {
|
||||
public synchronized InBreakReason getBreakReason() {
|
||||
if (!paused) {
|
||||
return null;
|
||||
}
|
||||
return breakReason;
|
||||
}
|
||||
|
||||
@@ -113,14 +260,16 @@ public class DebuggerHandler implements DebugConnectionListener {
|
||||
|
||||
}
|
||||
|
||||
public static interface VariableChangedListener {
|
||||
public static interface BreakListener {
|
||||
|
||||
public void variablesChanged();
|
||||
public void breakAt(String scriptName, int line);
|
||||
|
||||
public void doContinue();
|
||||
|
||||
}
|
||||
|
||||
public void addVariableChangedListener(VariableChangedListener l) {
|
||||
varListeners.add(l);
|
||||
public void addBreakListener(BreakListener l) {
|
||||
breakListeners.add(l);
|
||||
}
|
||||
|
||||
public void addTraceListener(TraceListener l) {
|
||||
@@ -131,8 +280,8 @@ public class DebuggerHandler implements DebugConnectionListener {
|
||||
traceListeners.remove(l);
|
||||
}
|
||||
|
||||
public void removeVariableChangedListener(VariableChangedListener l) {
|
||||
varListeners.remove(l);
|
||||
public void removeBreakListener(BreakListener l) {
|
||||
breakListeners.remove(l);
|
||||
}
|
||||
|
||||
public void addConnectionListener(ConnectionListener l) {
|
||||
@@ -143,19 +292,27 @@ public class DebuggerHandler implements DebugConnectionListener {
|
||||
clisteners.remove(l);
|
||||
}
|
||||
|
||||
public InFrame getFrame() {
|
||||
public synchronized InFrame getFrame() {
|
||||
if (!paused) {
|
||||
return null;
|
||||
}
|
||||
return frame;
|
||||
}
|
||||
|
||||
public int moduleIdOf(ScriptPack pack) {
|
||||
if (classToModule.containsKey(pack.getClassPath())) {
|
||||
return classToModule.get(pack.getClassPath());
|
||||
public synchronized int moduleIdOf(String pack) {
|
||||
if (classToModule.containsKey(pack)) {
|
||||
return classToModule.get(pack);
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
public synchronized boolean isPaused() {
|
||||
return paused;
|
||||
public boolean isPaused() {
|
||||
if (!isConnected()) {
|
||||
return false;
|
||||
}
|
||||
synchronized (this) {
|
||||
return paused;
|
||||
}
|
||||
}
|
||||
|
||||
public List<InSwfInfo.SwfInfo> getSwfs() {
|
||||
@@ -174,12 +331,12 @@ public class DebuggerHandler implements DebugConnectionListener {
|
||||
for (ConnectionListener l : clisteners) {
|
||||
l.disconnected();
|
||||
}
|
||||
for (VariableChangedListener l : varListeners) {
|
||||
l.variablesChanged();
|
||||
}
|
||||
/*for (BreakListener l : breakListeners) {
|
||||
l.breakAt();
|
||||
}*/
|
||||
}
|
||||
|
||||
public boolean isConnected() {
|
||||
public synchronized boolean isConnected() {
|
||||
return connected;
|
||||
}
|
||||
|
||||
@@ -191,7 +348,7 @@ public class DebuggerHandler implements DebugConnectionListener {
|
||||
}
|
||||
|
||||
private static void enlog(Class<?> cls) {
|
||||
Level level = Level.FINEST;
|
||||
Level level = Level.INFO;
|
||||
|
||||
Logger mylog = Logger.getLogger(cls.getName());
|
||||
mylog.setLevel(level);
|
||||
@@ -201,24 +358,95 @@ public class DebuggerHandler implements DebugConnectionListener {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void connected(DebuggerConnection con) {
|
||||
public void failedListen(IOException ex) {
|
||||
View.execInEventDispatchLater(new Runnable() {
|
||||
|
||||
synchronized (DebuggerHandler.this) {
|
||||
paused = true;
|
||||
@Override
|
||||
public void run() {
|
||||
disconnect();
|
||||
Main.stopRun();
|
||||
Main.stopWork();
|
||||
View.showMessageDialog(Main.getMainFrame().getPanel(), AppStrings.translate("error.debug.listen").replace("%port%", "" + Debugger.DEBUG_PORT));
|
||||
Main.getMainFrame().getPanel().updateMenu();
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void connected(DebuggerConnection con) {
|
||||
clearBreakPoints();
|
||||
|
||||
Main.startWork(AppStrings.translate("work.debugging"), null);
|
||||
|
||||
synchronized (this) {
|
||||
paused = false;
|
||||
}
|
||||
|
||||
Main.getMainFrame().getPanel().updateMenu();
|
||||
|
||||
//enlog(DebuggerConnection.class);
|
||||
//enlog(DebuggerCommands.class);
|
||||
enlog(DebuggerHandler.class);
|
||||
try {
|
||||
//rootLog.getHandlers()[0].setLevel(level);
|
||||
con.getMessage(InVersion.class);
|
||||
} catch (IOException ex) {
|
||||
Logger.getLogger(DebuggerHandler.class.getName()).log(Level.SEVERE, null, ex);
|
||||
}
|
||||
commands = new DebuggerCommands(con);
|
||||
|
||||
//Respon to InProcessTag with OutProcessedTag
|
||||
con.addMessageListener(new DebugMessageListener<InProcessTag>() {
|
||||
@Override
|
||||
public void message(InProcessTag message) {
|
||||
try {
|
||||
con.writeMessage(new OutProcessedTag(con));
|
||||
} catch (IOException ex) {
|
||||
//disconnect();
|
||||
//ignore
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
Map<Integer, String> moduleNames = new HashMap<>();
|
||||
|
||||
try {
|
||||
|
||||
int numScript = con.getMessage(InNumScript.class).num;
|
||||
for (int i = 0; i < numScript; i++) {
|
||||
InScript sc = con.getMessage(InScript.class);
|
||||
moduleNames.put(sc.module, sc.name);
|
||||
}
|
||||
|
||||
modulePaths = new HashMap<>();
|
||||
classToModule = new HashMap<>();
|
||||
//Pattern patMainFrame = Pattern.compile("^Actions for Scene ([0-9]+): Frame ([0-9]+) of Layer Name .*$");
|
||||
//Pattern patSymbol = Pattern.compile("^Actions for Symbol ([0-9]+): Frame ([0-9]+) of Layer Name .*$");
|
||||
//Pattern patAS2 = Pattern.compile("^([^:]+): .*\\.as$");
|
||||
Pattern patAS3 = Pattern.compile("^(.*);(.*);(.*)\\.as$");
|
||||
for (int file : moduleNames.keySet()) {
|
||||
String name = moduleNames.get(file);
|
||||
String[] parts = name.split(";");
|
||||
|
||||
Matcher m;
|
||||
/*if ((m = patMainFrame.matcher(name)).matches()) {
|
||||
name = "\\frame_" + m.group(2) + "\\DoAction";
|
||||
} else if ((m = patSymbol.matcher(name)).matches()) {
|
||||
name = "\\DefineSprite(" + m.group(1) + ")\\frame_" + m.group(2) + "\\DoAction";
|
||||
} else if ((m = patAS2.matcher(name)).matches()) {
|
||||
name = "\\_Packages\\" + m.group(1).replace(".", "\\");
|
||||
} else*/
|
||||
if ((m = patAS3.matcher(name)).matches()) {
|
||||
String clsName = m.group(3);
|
||||
String pkg = m.group(2).replace("\\", ".");
|
||||
name = DottedChain.parse(pkg).add(clsName).toString();
|
||||
}
|
||||
modulePaths.put(file, name);
|
||||
classToModule.put(name, file);
|
||||
}
|
||||
|
||||
//con.getMessage(InSetBreakpoint.class);
|
||||
commands = new DebuggerCommands(con);
|
||||
|
||||
commands.stopWarning();
|
||||
commands.setStopOnFault();
|
||||
commands.setEnumerateOverride();
|
||||
@@ -227,43 +455,56 @@ public class DebuggerHandler implements DebugConnectionListener {
|
||||
commands.setSwfLoadNotify();
|
||||
commands.setGetterTimeout(1500);
|
||||
commands.setSetterTimeout(5000);
|
||||
commands.squelch(true);
|
||||
swfs = commands.getSwfInfo(1);
|
||||
|
||||
Map<Integer, String> moduleNames = new HashMap<>();
|
||||
|
||||
modulePaths = new HashMap<>();
|
||||
classToModule = new HashMap<>();
|
||||
|
||||
int numScript = con.getMessage(InNumScript.class).num;
|
||||
for (int i = 0; i < numScript; i++) {
|
||||
InScript sc = con.getMessage(InScript.class);
|
||||
moduleNames.put(sc.module, sc.name);
|
||||
con.wideLines = commands.getOption("wide_line_player", "false").equals("true");
|
||||
if (con.wideLines) {
|
||||
commands.setOption("wide_line_debugger", "on");
|
||||
}
|
||||
commands.squelch(true);
|
||||
|
||||
for (int mname : moduleNames.keySet()) {
|
||||
String name = moduleNames.get(mname);
|
||||
String[] parts = name.split(";");
|
||||
swfs = commands.getSwfInfo(1);
|
||||
con.sendMessage(new OutGetSwf(con, 0), InGetSwf.class);
|
||||
InGetSwd iswd = con.sendMessage(new OutGetSwd(con, 0), InGetSwd.class);
|
||||
|
||||
if (parts.length == 3) {
|
||||
String clsName = parts[2].replace(".as", "");
|
||||
String pkg = parts[1].replace("/", "\\").replace("\\", ".");
|
||||
ClassPath cp = new ClassPath(DottedChain.parse(pkg), clsName);
|
||||
modulePaths.put(mname, cp);
|
||||
classToModule.put(cp, mname);
|
||||
boolean isAS3 = (Main.getMainFrame().getPanel().getCurrentSwf().isAS3());
|
||||
|
||||
InSetBreakpoint isb = con.getMessage(InSetBreakpoint.class);
|
||||
synchronized (this) {
|
||||
for (int i = 0; i < isb.files.size(); i++) {
|
||||
String sname = moduleNames.get(isb.files.get(i));
|
||||
if (!confirmedPointMap.containsKey(sname)) {
|
||||
confirmedPointMap.put(sname, new TreeSet<>());
|
||||
}
|
||||
if (toAddBPointMap.containsKey(sname)) {
|
||||
toAddBPointMap.get(sname).remove(isb.lines.get(i));
|
||||
if (toAddBPointMap.get(sname).isEmpty()) {
|
||||
toAddBPointMap.remove(sname);
|
||||
}
|
||||
}
|
||||
confirmedPointMap.get(sname).add(isb.lines.get(i));
|
||||
Logger.getLogger(DebuggerHandler.class.getName()).log(Level.INFO, "Breakpoint {0}:{1} submitted successfully", new Object[]{sname, isb.lines.get(i)});
|
||||
}
|
||||
}
|
||||
|
||||
con.getMessage(InSetBreakpoint.class);
|
||||
con.getMessage(InAskBreakpoints.class);
|
||||
con.addMessageListener(new DebugMessageListener<InContinue>() {
|
||||
synchronized (this) {
|
||||
connected = true;
|
||||
}
|
||||
con.addMessageListener(new DebugMessageListener<InAskBreakpoints>() {
|
||||
|
||||
@Override
|
||||
public void message(InAskBreakpoints message) {
|
||||
|
||||
}
|
||||
});
|
||||
con.addMessageListener(new DebugMessageListener<InContinue>() {
|
||||
@Override
|
||||
public void message(InContinue msg) {
|
||||
synchronized (DebuggerHandler.this) {
|
||||
paused = false;
|
||||
Logger.getLogger(DebuggerHandler.class.getName()).log(Level.FINE, "continued");
|
||||
}
|
||||
for (BreakListener bl : breakListeners) {
|
||||
bl.doContinue();
|
||||
}
|
||||
Main.getMainFrame().getPanel().updateMenu();
|
||||
}
|
||||
});
|
||||
con.addMessageListener(new DebugMessageListener<InBreakAt>() {
|
||||
@@ -272,89 +513,122 @@ public class DebuggerHandler implements DebugConnectionListener {
|
||||
public void message(InBreakAt message) {
|
||||
synchronized (DebuggerHandler.this) {
|
||||
paused = true;
|
||||
Logger.getLogger(DebuggerHandler.class.getName()).log(Level.FINE, "paused");
|
||||
}
|
||||
View.execInEventDispatchLater(new Runnable() {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
String newBreakScriptName = "unknown";
|
||||
if (modulePaths.containsKey(message.file)) {
|
||||
//Logger.getLogger(DebuggerCommands.class.getName()).log(Level.SEVERE, "Invalid file: " + message.file);
|
||||
newBreakScriptName = modulePaths.get(message.file);
|
||||
}
|
||||
|
||||
Main.getMainFrame().getPanel().updateMenu();
|
||||
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)) {
|
||||
try {
|
||||
breakInfo = con.getMessage(InBreakAtExt.class);
|
||||
breakReason = con.sendMessage(new OutGetBreakReason(con), InBreakReason.class);
|
||||
|
||||
final String[] reasonNames = new String[]{"unknown", "breakpoint", "watch", "fault", "stopRequest", "step", "halt", "scriptLoaded"};
|
||||
String reason = breakReason.reason < reasonNames.length ? reasonNames[breakReason.reason] : reasonNames[0];
|
||||
|
||||
Logger.getLogger(DebuggerHandler.class.getName()).log(Level.FINE, "break at {0}:{1}, reason: {2}", new Object[]{newBreakScriptName, message.line, reason});
|
||||
|
||||
sendBreakPoints(false);
|
||||
synchronized (DebuggerHandler.this) {
|
||||
breakScriptName = newBreakScriptName;
|
||||
breakIp = message.line;
|
||||
}
|
||||
|
||||
if (breakReason.reason == InBreakReason.REASON_SCRIPT_LOADED) {
|
||||
if (!Configuration.debugHalt.get()) {
|
||||
commands.sendContinue();
|
||||
return;
|
||||
}
|
||||
|
||||
ClassPath cls = modulePaths.get(message.file);
|
||||
Main.startWork(AppStrings.translate("work.breakat") + cls + ":" + message.line, null);
|
||||
|
||||
try {
|
||||
breakInfo = con.getMessage(InBreakAtExt.class);
|
||||
breakReason = con.sendMessage(new OutGetBreakReason(con), InBreakReason.class);
|
||||
frame = commands.getFrame(0);
|
||||
|
||||
for (VariableChangedListener l : varListeners) {
|
||||
l.variablesChanged();
|
||||
}
|
||||
|
||||
} catch (IOException ex) {
|
||||
//ignore
|
||||
}
|
||||
Main.breakAt(cls, message.line);
|
||||
Main.startWork(AppStrings.translate("work.halted"), null);
|
||||
} else {
|
||||
Main.startWork(AppStrings.translate("work.breakat") + newBreakScriptName + ":" + message.line + " " + AppStrings.translate("debug.break.reason." + reason), null);
|
||||
}
|
||||
frame = commands.getFrame(0);
|
||||
|
||||
for (BreakListener l : breakListeners) {
|
||||
l.breakAt(newBreakScriptName, message.line);
|
||||
}
|
||||
|
||||
} catch (IOException ex) {
|
||||
//ignore
|
||||
}
|
||||
);
|
||||
//dc.sendContinue();
|
||||
|
||||
}
|
||||
});
|
||||
//commands.sendContinue();
|
||||
List<ScriptPack> packs = Main.getMainFrame().getPanel().getCurrentSwf().getAS3Packs();
|
||||
for (ScriptPack sp : packs) {
|
||||
ClassPath cp = sp.getClassPath();
|
||||
if (classToModule.containsKey(cp)) {
|
||||
int file = classToModule.get(cp);
|
||||
Set<Integer> bpts = new TreeSet<>(Main.getPackBreakPoints(sp));
|
||||
for (int line : bpts) {
|
||||
if (!commands.addBreakPoint(file, line)) {
|
||||
Main.markBreakPointInvalid(sp, line);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Main.getMainFrame()
|
||||
.getPanel().refreshBreakPoints();
|
||||
connected = true;
|
||||
|
||||
for (ConnectionListener l : clisteners) {
|
||||
l.connected();
|
||||
}
|
||||
|
||||
if (Configuration.debugHalt.get()) {
|
||||
Main.startWork(AppStrings.translate("work.halted"), null);
|
||||
} else {
|
||||
con.addMessageListener(new DebugMessageListener<InTrace>() {
|
||||
|
||||
@Override
|
||||
public void message(InTrace tr) {
|
||||
for (TraceListener l : traceListeners) {
|
||||
l.trace(tr.text);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
if (!isAS3) {
|
||||
Logger.getLogger(DebuggerHandler.class.getName()).log(Level.FINER, "End of connect - sending continue");
|
||||
commands.sendContinue();
|
||||
}
|
||||
|
||||
new CancellableWorker() {
|
||||
|
||||
@Override
|
||||
protected Object doInBackground() throws Exception {
|
||||
try {
|
||||
while (isConnected()) {
|
||||
InTrace tr = con.getMessage(InTrace.class);
|
||||
for (TraceListener l : traceListeners) {
|
||||
l.trace(tr.text);
|
||||
}
|
||||
}
|
||||
} catch (IOException ex) {
|
||||
//ignore
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}.execute();
|
||||
|
||||
} catch (IOException ex) {
|
||||
connected = false;
|
||||
|
||||
synchronized (this) {
|
||||
connected = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void sendBreakPoints(boolean force) throws IOException {
|
||||
if (!force && !isPaused()) {
|
||||
Logger.getLogger(DebuggerHandler.class.getName()).log(Level.FINEST, "not sending bps, not paused");
|
||||
return;
|
||||
}
|
||||
synchronized (this) {
|
||||
for (String scriptName : toRemoveBPointMap.keySet()) {
|
||||
int file = moduleIdOf(scriptName);
|
||||
if (file > -1) {
|
||||
for (int line : toRemoveBPointMap.get(scriptName)) {
|
||||
if (isBreakpointConfirmed(scriptName, line)) {
|
||||
commands.removeBreakPoint(file, line);
|
||||
confirmedPointMap.get(scriptName).remove(line);
|
||||
if (confirmedPointMap.get(scriptName).isEmpty()) {
|
||||
confirmedPointMap.remove(scriptName);
|
||||
}
|
||||
}
|
||||
Logger.getLogger(DebuggerHandler.class.getName()).log(Level.INFO, "Breakpoint {0}:{1} removed", new Object[]{scriptName, line});
|
||||
}
|
||||
}
|
||||
}
|
||||
toRemoveBPointMap.clear();
|
||||
|
||||
for (String scriptName : toAddBPointMap.keySet()) {
|
||||
int file = moduleIdOf(scriptName);
|
||||
if (file > -1) {
|
||||
for (int line : toAddBPointMap.get(scriptName)) {
|
||||
if (commands.addBreakPoint(file, line)) {
|
||||
Logger.getLogger(DebuggerHandler.class.getName()).log(Level.INFO, "Breakpoint {0}:{1} submitted successfully", new Object[]{scriptName, line});
|
||||
if (!confirmedPointMap.containsKey(scriptName)) {
|
||||
confirmedPointMap.put(scriptName, new TreeSet<>());
|
||||
}
|
||||
confirmedPointMap.get(scriptName).add(line);
|
||||
} else {
|
||||
Logger.getLogger(DebuggerHandler.class.getName()).log(Level.INFO, "Breakpoint {0}:{1} unable to submit", new Object[]{scriptName, line});
|
||||
markBreakPointInvalid(scriptName, line);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
toAddBPointMap.clear();
|
||||
}
|
||||
Logger.getLogger(DebuggerHandler.class.getName()).log(Level.FINEST, "sending bps finished");
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,6 +21,7 @@ import com.jpexs.debugger.flash.DebugMessageListener;
|
||||
import com.jpexs.debugger.flash.Debugger;
|
||||
import com.jpexs.debugger.flash.DebuggerCommands;
|
||||
import com.jpexs.debugger.flash.DebuggerConnection;
|
||||
import com.jpexs.debugger.flash.SWD;
|
||||
import com.jpexs.debugger.flash.messages.in.InAskBreakpoints;
|
||||
import com.jpexs.debugger.flash.messages.in.InBreakAt;
|
||||
import com.jpexs.debugger.flash.messages.in.InNumScript;
|
||||
@@ -81,6 +82,7 @@ import java.io.FilenameFilter;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.OutputStream;
|
||||
import java.lang.reflect.Field;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.net.Proxy;
|
||||
@@ -159,117 +161,285 @@ public class Main {
|
||||
|
||||
private static DebuggerHandler debugHandler = null;
|
||||
|
||||
private static Map<ScriptPack, Set<Integer>> breakPointMap = new WeakHashMap<>();
|
||||
private static Map<ScriptPack, Set<Integer>> invalidBreakPointMap = new WeakHashMap<>();
|
||||
private static int ip = 0;
|
||||
private static ClassPath ipClass = null;
|
||||
//private static int ip = 0;
|
||||
//private static String ipClass = null;
|
||||
private static Process runProcess;
|
||||
private static boolean runProcessDebug;
|
||||
|
||||
public static void debuggerNotSuspended() {
|
||||
getDebugHandler().notSuspended();
|
||||
private static boolean inited = false;
|
||||
|
||||
private static File runTempFile;
|
||||
|
||||
public static void freeRun() {
|
||||
synchronized (Main.class) {
|
||||
if (runTempFile != null) {
|
||||
runTempFile.delete();
|
||||
runTempFile = null;
|
||||
}
|
||||
|
||||
runProcess = null;
|
||||
}
|
||||
mainFrame.getPanel().clearDebuggerColors();
|
||||
ip = 0;
|
||||
ipClass = null;
|
||||
}
|
||||
|
||||
public static void clearBreakPoints(ScriptPack pack) {
|
||||
if (breakPointMap.containsKey(pack)) {
|
||||
breakPointMap.remove(pack);
|
||||
if (runProcessDebug) {
|
||||
Main.getDebugHandler().disconnect();
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean isDebugging() {
|
||||
return mainFrame.getMenu().isDebugRunning();
|
||||
public static synchronized boolean isDebugPaused() {
|
||||
return runProcess != null && runProcessDebug && getDebugHandler().isPaused();
|
||||
}
|
||||
|
||||
public static int getIp(ScriptPack pack) {
|
||||
return ip;
|
||||
public static synchronized boolean isDebugRunning() {
|
||||
return runProcess != null && runProcessDebug;
|
||||
}
|
||||
|
||||
public static ClassPath getIpClass() {
|
||||
return ipClass;
|
||||
public static synchronized boolean isDebugConnected() {
|
||||
return getDebugHandler().isConnected();
|
||||
}
|
||||
|
||||
public static void breakAt(ClassPath clsName, int ip) {
|
||||
Main.ip = ip;
|
||||
Main.ipClass = clsName;
|
||||
mainFrame.getPanel().gotoClassLine(getMainFrame().getPanel().getCurrentSwf(), clsName.toString(), ip);
|
||||
//Main.getMainFrame().getPanel().debuggerBreakAt(Main.getMainFrame().getPanel().getCurrentSwf(), cls, message.line);
|
||||
public static synchronized boolean isRunning() {
|
||||
return runProcess != null && !runProcessDebug;
|
||||
}
|
||||
|
||||
public static boolean isBreakPointValid(ScriptPack pack, int line) {
|
||||
if (!invalidBreakPointMap.containsKey(pack)) {
|
||||
return true;
|
||||
public static void runPlayer(String title, final String exePath, String file, String flashVars) {
|
||||
if (flashVars != null && !flashVars.isEmpty()) {
|
||||
file += "?" + flashVars;
|
||||
}
|
||||
return !invalidBreakPointMap.get(pack).contains(line);
|
||||
|
||||
}
|
||||
|
||||
public static void markBreakPointInvalid(ScriptPack pack, int line) {
|
||||
if (!invalidBreakPointMap.containsKey(pack)) {
|
||||
invalidBreakPointMap.put(pack, new TreeSet<>());
|
||||
if (!new File(file).exists()) {
|
||||
return;
|
||||
}
|
||||
invalidBreakPointMap.get(pack).add(line);
|
||||
}
|
||||
|
||||
public static void addBreakPoint(ScriptPack pack, int line) {
|
||||
if (!breakPointMap.containsKey(pack)) {
|
||||
breakPointMap.put(pack, new TreeSet<>());
|
||||
}
|
||||
breakPointMap.get(pack).add(line);
|
||||
if (debugHandler.isConnected()) {
|
||||
int file = debugHandler.moduleIdOf(pack);
|
||||
if (file > -1) {
|
||||
final String ffile = file;
|
||||
|
||||
CancellableWorker runWorker = new CancellableWorker() {
|
||||
|
||||
@Override
|
||||
protected Object doInBackground() throws Exception {
|
||||
Process proc;
|
||||
try {
|
||||
if (!debugHandler.getCommands().addBreakPoint(file, line)) {
|
||||
markBreakPointInvalid(pack, line);
|
||||
proc = Runtime.getRuntime().exec("\"" + exePath + "\" \"file://" + ffile + "\"");
|
||||
} catch (IOException ex) {
|
||||
Logger.getLogger(MainFrameMenu.class.getName()).log(Level.SEVERE, null, ex);
|
||||
|
||||
return null;
|
||||
}
|
||||
boolean isDebug;
|
||||
|
||||
synchronized (Main.class) {
|
||||
runProcess = proc;
|
||||
isDebug = runProcessDebug;
|
||||
}
|
||||
if (isDebug) {
|
||||
mainFrame.getMenu().hilightPath("/debugging");
|
||||
}
|
||||
mainFrame.getMenu().updateComponents();
|
||||
try {
|
||||
if (proc != null) {
|
||||
proc.waitFor();
|
||||
}
|
||||
} catch (InterruptedException ex) {
|
||||
if (proc != null) {
|
||||
try {
|
||||
proc.destroy();
|
||||
} catch (Exception ex2) {
|
||||
//ignore
|
||||
}
|
||||
}
|
||||
} catch (IOException ex) {
|
||||
debugHandler.disconnect();
|
||||
//ignore
|
||||
}
|
||||
freeRun();
|
||||
mainFrame.getMenu().updateComponents();
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void done() {
|
||||
Main.stopWork();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void workerCancelled() {
|
||||
Main.stopWork();
|
||||
synchronized (Main.class) {
|
||||
if (runProcess != null) {
|
||||
try {
|
||||
runProcess.destroy();
|
||||
} catch (Exception ex) {
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
freeRun();
|
||||
mainFrame.getMenu().updateComponents();
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
mainFrame.getMenu().updateComponents();
|
||||
Main.startWork(title + "...", runWorker);
|
||||
runWorker.execute();
|
||||
}
|
||||
|
||||
public static void stopRun() {
|
||||
|
||||
synchronized (Main.class) {
|
||||
if (runProcess != null) {
|
||||
runProcess.destroy();
|
||||
}
|
||||
}
|
||||
freeRun();
|
||||
stopDebugger();
|
||||
mainFrame.getMenu().updateComponents();
|
||||
}
|
||||
|
||||
public static void run(SWF swf) {
|
||||
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);
|
||||
advancedSettings("paths");
|
||||
return;
|
||||
}
|
||||
if (swf == null) {
|
||||
return;
|
||||
}
|
||||
File tempFile;
|
||||
try {
|
||||
tempFile = File.createTempFile("ffdec_run_", ".swf");
|
||||
|
||||
try (OutputStream fos = new BufferedOutputStream(new FileOutputStream(tempFile))) {
|
||||
swf.saveTo(fos);
|
||||
}
|
||||
} catch (IOException ex) {
|
||||
return;
|
||||
|
||||
}
|
||||
if (tempFile != null) {
|
||||
synchronized (Main.class) {
|
||||
runTempFile = tempFile;
|
||||
runProcessDebug = false;
|
||||
}
|
||||
runPlayer(AppStrings.translate("work.running"), playerLocation, tempFile.getAbsolutePath(), flashVars);
|
||||
}
|
||||
}
|
||||
|
||||
public static void removeBreakPoint(ScriptPack pack, int line) {
|
||||
if (breakPointMap.containsKey(pack)) {
|
||||
Set<Integer> lines = breakPointMap.get(pack);
|
||||
if (lines != null) {
|
||||
lines.remove(line);
|
||||
}
|
||||
public static void runDebug(SWF swf) {
|
||||
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);
|
||||
Main.advancedSettings("paths");
|
||||
return;
|
||||
}
|
||||
if (debugHandler.isConnected()) {
|
||||
int file = debugHandler.moduleIdOf(pack);
|
||||
if (file > -1) {
|
||||
try {
|
||||
debugHandler.getCommands().removeBreakPoint(file, line);
|
||||
} catch (IOException ex) {
|
||||
debugHandler.disconnect();
|
||||
//ignore
|
||||
if (swf == null) {
|
||||
return;
|
||||
}
|
||||
File tempFile = null;
|
||||
|
||||
try {
|
||||
tempFile = File.createTempFile("ffdec_debug_", ".swf");
|
||||
} catch (Exception ex) {
|
||||
|
||||
}
|
||||
if (tempFile != null) {
|
||||
final File fTempFile = tempFile;
|
||||
CancellableWorker instrumentWorker = new CancellableWorker() {
|
||||
|
||||
@Override
|
||||
protected Object doInBackground() throws Exception {
|
||||
|
||||
try (OutputStream fos = new BufferedOutputStream(new FileOutputStream(fTempFile))) {
|
||||
swf.saveTo(fos);
|
||||
}
|
||||
//Inject Loader
|
||||
SWF instrSWF = null;
|
||||
try (FileInputStream fis = new FileInputStream(fTempFile)) {
|
||||
instrSWF = new SWF(fis, false, false);
|
||||
|
||||
} catch (InterruptedException ex) {
|
||||
Logger.getLogger(MainFrameMenu.class
|
||||
.getName()).log(Level.SEVERE, null, ex);
|
||||
}
|
||||
if (instrSWF != null) {
|
||||
if (instrSWF.isAS3()) {
|
||||
instrSWF.enableDebugging(true, new File("."));
|
||||
} else {
|
||||
instrSWF.enableDebugging(false, new File("."));
|
||||
File swdFile = new File(fTempFile.getAbsolutePath().replace(".swf", ".swd"));
|
||||
instrSWF.generateSwdFile(swdFile, getPackBreakPoints(true));
|
||||
}
|
||||
try (OutputStream fos = new BufferedOutputStream(new FileOutputStream(fTempFile))) {
|
||||
instrSWF.saveTo(fos);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void workerCancelled() {
|
||||
Main.stopWork();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void done() {
|
||||
synchronized (Main.class) {
|
||||
runTempFile = fTempFile;
|
||||
runProcessDebug = true;
|
||||
}
|
||||
Main.stopWork();
|
||||
Main.startDebugger();
|
||||
runPlayer(AppStrings.translate("work.debugging.wait"), playerLocation, fTempFile.getAbsolutePath(), flashVars);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
Main.startWork(AppStrings.translate("work.debugging.instrumenting"), instrumentWorker);
|
||||
instrumentWorker.execute();
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean toggleBreakPoint(ScriptPack pack, int line) {
|
||||
if (!breakPointMap.containsKey(pack)) {
|
||||
addBreakPoint(pack, line);
|
||||
return true;
|
||||
}
|
||||
if (breakPointMap.get(pack).contains(line)) {
|
||||
removeBreakPoint(pack, line);
|
||||
/* public static void debuggerNotSuspended() {
|
||||
|
||||
}*/
|
||||
public static boolean isDebugging() {
|
||||
return isDebugRunning();
|
||||
}
|
||||
|
||||
public synchronized static int getIp(Object pack) {
|
||||
return getDebugHandler().getBreakIp();
|
||||
}
|
||||
|
||||
public synchronized static String getIpClass() {
|
||||
return getDebugHandler().getBreakScriptName();
|
||||
}
|
||||
|
||||
public static synchronized boolean isBreakPointValid(String scriptName, int line) {
|
||||
return !getDebugHandler().isBreakpointInvalid(scriptName, line);
|
||||
}
|
||||
|
||||
public synchronized static void addBreakPoint(String scriptName, int line) {
|
||||
getDebugHandler().addBreakPoint(scriptName, line);
|
||||
}
|
||||
|
||||
public synchronized static void removeBreakPoint(String scriptName, int line) {
|
||||
getDebugHandler().removeBreakPoint(scriptName, line);
|
||||
}
|
||||
|
||||
public synchronized static boolean toggleBreakPoint(String scriptName, int line) {
|
||||
if (getDebugHandler().isBreakpointToAdd(scriptName, line) || getDebugHandler().isBreakpointConfirmed(scriptName, line)) {
|
||||
getDebugHandler().removeBreakPoint(scriptName, line);
|
||||
return false;
|
||||
} else {
|
||||
addBreakPoint(pack, line);
|
||||
getDebugHandler().addBreakPoint(scriptName, line);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
public static Set<Integer> getPackBreakPoints(ScriptPack pack) {
|
||||
if (!breakPointMap.containsKey(pack)) {
|
||||
return new HashSet<>();
|
||||
}
|
||||
return breakPointMap.get(pack);
|
||||
public synchronized static Map<String, Set<Integer>> getPackBreakPoints(boolean validOnly) {
|
||||
return getDebugHandler().getAllBreakPoints(validOnly);
|
||||
}
|
||||
|
||||
public synchronized static Set<Integer> getScriptBreakPoints(String pack) {
|
||||
return getDebugHandler().getBreakPoints(pack);
|
||||
}
|
||||
|
||||
public static DebuggerHandler getDebugHandler() {
|
||||
@@ -319,6 +489,14 @@ public class Main {
|
||||
}
|
||||
}
|
||||
|
||||
public synchronized static boolean isInited() {
|
||||
return inited;
|
||||
}
|
||||
|
||||
public synchronized static void setSessionLoaded(boolean v) {
|
||||
inited = v;
|
||||
}
|
||||
|
||||
public static boolean isWorking() {
|
||||
return working;
|
||||
}
|
||||
@@ -1151,26 +1329,51 @@ public class Main {
|
||||
*/
|
||||
flashDebugger = new Debugger();
|
||||
debugHandler = new DebuggerHandler();
|
||||
debugHandler.addBreakListener(new DebuggerHandler.BreakListener() {
|
||||
|
||||
@Override
|
||||
public void doContinue() {
|
||||
mainFrame.getPanel().clearDebuggerColors();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void breakAt(String scriptName, int line) {
|
||||
View.execInEventDispatch(new Runnable() {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
mainFrame.getPanel().gotoClassLine(getMainFrame().getPanel().getCurrentSwf(), scriptName, line);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
debugHandler.addConnectionListener(new DebuggerHandler.ConnectionListener() {
|
||||
|
||||
@Override
|
||||
public void connected() {
|
||||
Main.mainFrame.getMenu().updateComponents();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void disconnected() {
|
||||
ip = 0;
|
||||
ipClass = null;
|
||||
|
||||
}
|
||||
});
|
||||
flashDebugger.addConnectionListener(debugHandler);
|
||||
flashDebugger.start();
|
||||
} catch (IOException ex) {
|
||||
//ignore
|
||||
Logger.getLogger(Main.class.getName()).log(Level.SEVERE, "eeex", ex);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static void startDebugger() {
|
||||
flashDebugger.startDebugger();
|
||||
}
|
||||
|
||||
public static void stopDebugger() {
|
||||
flashDebugger.stopDebugger();
|
||||
}
|
||||
|
||||
public static void showModeFrame() {
|
||||
ensureMainFrame();
|
||||
mainFrame.setVisible(true);
|
||||
@@ -1371,6 +1574,7 @@ public class Main {
|
||||
* @throws IOException On error
|
||||
*/
|
||||
public static void main(String[] args) throws IOException {
|
||||
setSessionLoaded(false);
|
||||
clearTemp();
|
||||
|
||||
try {
|
||||
@@ -1400,6 +1604,7 @@ public class Main {
|
||||
}
|
||||
});
|
||||
} else {
|
||||
setSessionLoaded(true);
|
||||
String[] filesToOpen = CommandLineArgumentParser.parseArguments(args);
|
||||
if (filesToOpen != null && filesToOpen.length > 0) {
|
||||
View.execInEventDispatch(() -> {
|
||||
@@ -1447,9 +1652,16 @@ public class Main {
|
||||
if (sourceInfos.length > 0) {
|
||||
openFile(sourceInfos, () -> {
|
||||
mainFrame.getPanel().tagTree.setSelectionPathString(Configuration.lastSessionSelection.get());
|
||||
setSessionLoaded(true);
|
||||
});
|
||||
} else {
|
||||
setSessionLoaded(true);
|
||||
}
|
||||
} else {
|
||||
setSessionLoaded(true);
|
||||
}
|
||||
} else {
|
||||
setSessionLoaded(true);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
package com.jpexs.decompiler.flash.gui;
|
||||
|
||||
import com.jpexs.debugger.flash.DebuggerCommands;
|
||||
import com.jpexs.debugger.flash.messages.out.OutStepContinue;
|
||||
import com.jpexs.decompiler.flash.ApplicationInfo;
|
||||
import com.jpexs.decompiler.flash.SWF;
|
||||
import com.jpexs.decompiler.flash.SWFBundle;
|
||||
@@ -661,10 +662,11 @@ public abstract class MainFrameMenu implements MenuBuilder {
|
||||
|
||||
public void updateComponents(SWF swf) {
|
||||
this.swf = swf;
|
||||
boolean isRunning = isRunning();
|
||||
boolean isDebugRunning = isDebugRunning();
|
||||
boolean isRunning = Main.isRunning();
|
||||
boolean isDebugRunning = Main.isDebugRunning();
|
||||
boolean isDebugPaused = Main.isDebugPaused();
|
||||
|
||||
boolean isRunningOrDebugging = isRunning || isDebugRunning;
|
||||
boolean isDebugPaused = isDebugPaused();
|
||||
|
||||
boolean swfSelected = swf != null;
|
||||
boolean isWorking = Main.isWorking();
|
||||
@@ -725,7 +727,7 @@ public abstract class MainFrameMenu implements MenuBuilder {
|
||||
setMenuEnabled("/help/about", !isWorking);
|
||||
|
||||
setMenuEnabled("/file/start/run", swfSelected && !isRunningOrDebugging);
|
||||
setMenuEnabled("/file/start/debug", hasAbc && !isRunningOrDebugging);
|
||||
setMenuEnabled("/file/start/debug", !isRunningOrDebugging);
|
||||
|
||||
setMenuEnabled("/file/start/stop", isRunningOrDebugging);
|
||||
setMenuEnabled("/debugging/debug/stop", isRunningOrDebugging); //same as previous
|
||||
@@ -1098,231 +1100,22 @@ public abstract class MainFrameMenu implements MenuBuilder {
|
||||
KeyboardFocusManager manager = KeyboardFocusManager.getCurrentKeyboardFocusManager();
|
||||
manager.removeKeyEventDispatcher(keyEventDispatcher);
|
||||
|
||||
if (runProcess != null) {
|
||||
try {
|
||||
runProcess.destroy();
|
||||
} catch (Exception ex) {
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private Process runProcess;
|
||||
private boolean runProcessDebug;
|
||||
|
||||
private File runTempFile;
|
||||
|
||||
public synchronized boolean isDebugPaused() {
|
||||
return runProcess != null && runProcessDebug && Main.getDebugHandler().isPaused();
|
||||
}
|
||||
|
||||
public synchronized boolean isDebugRunning() {
|
||||
return runProcess != null && runProcessDebug;
|
||||
}
|
||||
|
||||
public synchronized boolean isRunning() {
|
||||
return runProcess != null && !runProcessDebug;
|
||||
}
|
||||
|
||||
private synchronized void freeRun() {
|
||||
if (runTempFile != null) {
|
||||
runTempFile.delete();
|
||||
runTempFile = null;
|
||||
}
|
||||
runProcess = null;
|
||||
mainFrame.getPanel().clearDebuggerColors();
|
||||
if (runProcessDebug) {
|
||||
Main.getDebugHandler().disconnect();
|
||||
}
|
||||
}
|
||||
|
||||
private void runPlayer(String title, final String exePath, String file, String flashVars) {
|
||||
if (flashVars != null && !flashVars.isEmpty()) {
|
||||
file += "?" + flashVars;
|
||||
}
|
||||
if (!new File(file).exists()) {
|
||||
return;
|
||||
}
|
||||
|
||||
final String ffile = file;
|
||||
|
||||
CancellableWorker runWorker = new CancellableWorker() {
|
||||
|
||||
@Override
|
||||
protected Object doInBackground() throws Exception {
|
||||
Process proc;
|
||||
try {
|
||||
proc = Runtime.getRuntime().exec("\"" + exePath + "\" \"file://" + ffile + "\"");
|
||||
} catch (IOException ex) {
|
||||
Logger.getLogger(MainFrameMenu.class.getName()).log(Level.SEVERE, null, ex);
|
||||
|
||||
return null;
|
||||
}
|
||||
synchronized (this) {
|
||||
runProcess = proc;
|
||||
}
|
||||
if (runProcessDebug) {
|
||||
hilightPath("/debugging");
|
||||
}
|
||||
updateComponents();
|
||||
try {
|
||||
if (proc != null) {
|
||||
proc.waitFor();
|
||||
}
|
||||
} catch (InterruptedException ex) {
|
||||
if (proc != null) {
|
||||
try {
|
||||
proc.destroy();
|
||||
} catch (Exception ex2) {
|
||||
//ignore
|
||||
}
|
||||
}
|
||||
}
|
||||
freeRun();
|
||||
updateComponents();
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void done() {
|
||||
Main.stopWork();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void workerCancelled() {
|
||||
Main.stopWork();
|
||||
synchronized (MainFrameMenu.this) {
|
||||
if (runProcess != null) {
|
||||
try {
|
||||
runProcess.destroy();
|
||||
} catch (Exception ex) {
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
freeRun();
|
||||
updateComponents();
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
updateComponents();
|
||||
Main.startWork(title + "...", runWorker);
|
||||
runWorker.execute();
|
||||
Main.stopRun();
|
||||
}
|
||||
|
||||
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);
|
||||
Main.advancedSettings("paths");
|
||||
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(AppStrings.translate("work.running"), playerLocation, tempFile.getAbsolutePath(), flashVars);
|
||||
}
|
||||
Main.run(swf);
|
||||
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);
|
||||
Main.advancedSettings("paths");
|
||||
return true;
|
||||
}
|
||||
if (swf == null) {
|
||||
return true;
|
||||
}
|
||||
File tempFile = null;
|
||||
|
||||
try {
|
||||
tempFile = File.createTempFile("ffdec_debug_", ".swf");
|
||||
} catch (Exception ex) {
|
||||
|
||||
}
|
||||
if (tempFile != null) {
|
||||
final File fTempFile = tempFile;
|
||||
CancellableWorker instrumentWorker = new CancellableWorker() {
|
||||
|
||||
@Override
|
||||
protected Object doInBackground() throws Exception {
|
||||
|
||||
try (OutputStream fos = new BufferedOutputStream(new FileOutputStream(fTempFile))) {
|
||||
swf.saveTo(fos);
|
||||
}
|
||||
//Inject Loader
|
||||
SWF instrSWF = null;
|
||||
try (FileInputStream fis = new FileInputStream(fTempFile)) {
|
||||
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(fTempFile))) {
|
||||
instrSWF.saveTo(fos);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void workerCancelled() {
|
||||
Main.stopWork();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void done() {
|
||||
synchronized (MainFrameMenu.this) {
|
||||
runTempFile = fTempFile;
|
||||
runProcessDebug = true;
|
||||
}
|
||||
Main.stopWork();
|
||||
runPlayer(AppStrings.translate("work.debugging"), playerLocation, fTempFile.getAbsolutePath(), flashVars);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
Main.startWork(AppStrings.translate("work.debugging.instrumenting"), instrumentWorker);
|
||||
instrumentWorker.execute();
|
||||
}
|
||||
Main.runDebug(swf);
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
public boolean stopActionPerformed(ActionEvent evt) {
|
||||
|
||||
synchronized (this) {
|
||||
if (runProcess != null) {
|
||||
runProcess.destroy();
|
||||
}
|
||||
}
|
||||
freeRun();
|
||||
|
||||
updateComponents();
|
||||
Main.stopRun();
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -1339,7 +1132,6 @@ public abstract class MainFrameMenu implements MenuBuilder {
|
||||
}
|
||||
|
||||
public boolean stepOverActionPerformed(ActionEvent evt) {
|
||||
Main.debuggerNotSuspended();
|
||||
|
||||
try {
|
||||
|
||||
@@ -1356,8 +1148,6 @@ public abstract class MainFrameMenu implements MenuBuilder {
|
||||
}
|
||||
|
||||
public boolean stepIntoActionPerformed(ActionEvent evt) {
|
||||
Main.debuggerNotSuspended();
|
||||
|
||||
try {
|
||||
DebuggerCommands cmd = Main.getDebugHandler().getCommands();
|
||||
mainFrame.getPanel().clearDebuggerColors();
|
||||
@@ -1373,8 +1163,6 @@ public abstract class MainFrameMenu implements MenuBuilder {
|
||||
}
|
||||
|
||||
public boolean stepOutActionPerformed(ActionEvent evt) {
|
||||
Main.debuggerNotSuspended();
|
||||
|
||||
try {
|
||||
DebuggerCommands cmd = Main.getDebugHandler().getCommands();
|
||||
mainFrame.getPanel().clearDebuggerColors();
|
||||
@@ -1389,10 +1177,9 @@ public abstract class MainFrameMenu implements MenuBuilder {
|
||||
}
|
||||
|
||||
public boolean continueActionPerformed(ActionEvent evt) {
|
||||
Main.debuggerNotSuspended();
|
||||
|
||||
try {
|
||||
DebuggerCommands cmd = Main.getDebugHandler().getCommands();
|
||||
mainFrame.getPanel().clearDebuggerColors();
|
||||
Main.startWork(AppStrings.translate("work.debugging") + "...", null);
|
||||
cmd.sendContinue();
|
||||
} catch (IOException ex) {
|
||||
|
||||
@@ -539,18 +539,22 @@ public class MainFrameRibbonMenu extends MainFrameMenu {
|
||||
throw new IllegalArgumentException("Menu not found: " + path);
|
||||
}
|
||||
Object o = menuItems.get(path);
|
||||
if (o instanceof JRibbonBand) {
|
||||
((JRibbonBand) o).setEnabled(enabled);
|
||||
} else if (o instanceof AbstractCommandButton) {
|
||||
((AbstractCommandButton) o).setEnabled(enabled);
|
||||
} else if (o instanceof RibbonApplicationMenuEntryPrimary) {
|
||||
((RibbonApplicationMenuEntryPrimary) o).setEnabled(enabled);
|
||||
} else if (o instanceof RibbonApplicationMenuEntryFooter) {
|
||||
((RibbonApplicationMenuEntryFooter) o).setEnabled(enabled);
|
||||
} else if (o instanceof JComponent) {
|
||||
((JComponent) o).setEnabled(enabled);
|
||||
} else {
|
||||
throw new IllegalArgumentException("Cannot set enabled to: " + path);
|
||||
try {
|
||||
if (o instanceof JRibbonBand) {
|
||||
((JRibbonBand) o).setEnabled(enabled);
|
||||
} else if (o instanceof AbstractCommandButton) {
|
||||
((AbstractCommandButton) o).setEnabled(enabled);
|
||||
} else if (o instanceof RibbonApplicationMenuEntryPrimary) {
|
||||
((RibbonApplicationMenuEntryPrimary) o).setEnabled(enabled);
|
||||
} else if (o instanceof RibbonApplicationMenuEntryFooter) {
|
||||
((RibbonApplicationMenuEntryFooter) o).setEnabled(enabled);
|
||||
} else if (o instanceof JComponent) {
|
||||
((JComponent) o).setEnabled(enabled);
|
||||
} else {
|
||||
throw new IllegalArgumentException("Cannot set enabled to: " + path);
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
//some substance issues, ignore
|
||||
}
|
||||
}
|
||||
|
||||
@@ -594,7 +598,11 @@ public class MainFrameRibbonMenu extends MainFrameMenu {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
ribbon.setVisible(rg, val);
|
||||
try {
|
||||
ribbon.setVisible(rg, val);
|
||||
} catch (Exception ex) {
|
||||
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
@@ -142,6 +142,7 @@ import com.jpexs.decompiler.flash.types.MATRIX;
|
||||
import com.jpexs.decompiler.flash.types.RECT;
|
||||
import com.jpexs.decompiler.flash.types.sound.SoundFormat;
|
||||
import com.jpexs.decompiler.flash.xfl.FLAVersion;
|
||||
import com.jpexs.decompiler.graph.DottedChain;
|
||||
import com.jpexs.helpers.CancellableWorker;
|
||||
import com.jpexs.helpers.Helper;
|
||||
import com.jpexs.helpers.Path;
|
||||
@@ -320,6 +321,8 @@ public final class MainPanel extends JPanel implements TreeSelectionListener, Se
|
||||
|
||||
private static final Logger logger = Logger.getLogger(MainPanel.class.getName());
|
||||
|
||||
private Map<String, ASMSource> asms = new HashMap<>();
|
||||
|
||||
public void setPercent(int percent) {
|
||||
progressBar.setValue(percent);
|
||||
progressBar.setVisible(true);
|
||||
@@ -816,6 +819,7 @@ public final class MainPanel extends JPanel implements TreeSelectionListener, Se
|
||||
mainFrame.setTitle(ApplicationInfo.applicationVerName + (Configuration.displayFileName.get() ? " - " + swf.getFileTitle() : ""));
|
||||
|
||||
List<ABCContainerTag> abcList = swf.getAbcList();
|
||||
asms = swf.getASMs(true);
|
||||
|
||||
boolean hasAbc = !abcList.isEmpty();
|
||||
|
||||
@@ -1533,9 +1537,11 @@ public final class MainPanel extends JPanel implements TreeSelectionListener, Se
|
||||
}
|
||||
|
||||
public void gotoClassLine(SWF swf, String cls, int line) {
|
||||
gotoClass(swf, cls);
|
||||
gotoScriptName(swf, cls);
|
||||
if (abcPanel != null) {
|
||||
abcPanel.decompiledTextArea.gotoLine(line);
|
||||
} else if (actionPanel != null) {
|
||||
actionPanel.decompiledEditor.gotoLine(line);
|
||||
}
|
||||
refreshBreakPoints();
|
||||
|
||||
@@ -1561,15 +1567,21 @@ public final class MainPanel extends JPanel implements TreeSelectionListener, Se
|
||||
|
||||
}*/
|
||||
|
||||
public void gotoClass(SWF swf, String cls) {
|
||||
public void gotoScriptName(SWF swf, String scriptName) {
|
||||
if (swf == null) {
|
||||
return;
|
||||
}
|
||||
List<ABCContainerTag> abcList = swf.getAbcList();
|
||||
if (!abcList.isEmpty()) {
|
||||
ABCPanel abcPanel = getABCPanel();
|
||||
abcPanel.setAbc(abcList.get(0).getABC());
|
||||
abcPanel.hilightScript(swf, cls);
|
||||
if (swf.isAS3()) {
|
||||
List<ABCContainerTag> abcList = swf.getAbcList();
|
||||
if (!abcList.isEmpty()) {
|
||||
ABCPanel abcPanel = getABCPanel();
|
||||
abcPanel.setAbc(abcList.get(0).getABC());
|
||||
abcPanel.hilightScript(swf, scriptName);
|
||||
}
|
||||
} else {
|
||||
if (actionPanel != null && asms.containsKey(scriptName)) {
|
||||
actionPanel.setSource(asms.get(scriptName), true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1583,8 +1595,13 @@ public final class MainPanel extends JPanel implements TreeSelectionListener, Se
|
||||
List<ABCContainerTag> abcList = swf.getAbcList();
|
||||
if (!abcList.isEmpty()) {
|
||||
ABCPanel abcPanel = getABCPanel();
|
||||
abcPanel.setAbc(abcList.get(0).getABC());
|
||||
abcPanel.hilightScript(swf, documentClass);
|
||||
for (ABCContainerTag c : abcList) {
|
||||
if (c.getABC().findClassByName(documentClass) > -1) {
|
||||
abcPanel.setAbc(c.getABC());
|
||||
abcPanel.hilightScript(swf, documentClass);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2823,6 +2840,9 @@ public final class MainPanel extends JPanel implements TreeSelectionListener, Se
|
||||
if (abcPanel != null) {
|
||||
abcPanel.decompiledTextArea.removeColorMarkerOnAllLines(DecompiledEditorPane.FG_IP_COLOR, DecompiledEditorPane.BG_IP_COLOR, DecompiledEditorPane.PRIORITY_IP);
|
||||
}
|
||||
if (actionPanel != null) {
|
||||
actionPanel.decompiledEditor.removeColorMarkerOnAllLines(DecompiledEditorPane.FG_IP_COLOR, DecompiledEditorPane.BG_IP_COLOR, DecompiledEditorPane.PRIORITY_IP);
|
||||
}
|
||||
}
|
||||
|
||||
private void stopFlashPlayer() {
|
||||
@@ -3050,7 +3070,7 @@ public final class MainPanel extends JPanel implements TreeSelectionListener, Se
|
||||
setSourceWorker.cancel(true);
|
||||
setSourceWorker = null;
|
||||
}
|
||||
if (!Main.isWorking() || Main.isDebugging()) {
|
||||
if (!Main.isInited() || !Main.isWorking() || Main.isDebugging()) {
|
||||
CancellableWorker worker = new CancellableWorker() {
|
||||
|
||||
@Override
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.gui.abc;
|
||||
|
||||
import com.jpexs.decompiler.flash.gui.DebugPanel;
|
||||
import com.jpexs.debugger.flash.Variable;
|
||||
import com.jpexs.debugger.flash.messages.in.InBreakAtExt;
|
||||
import com.jpexs.debugger.flash.messages.in.InBreakReason;
|
||||
|
||||
@@ -38,6 +38,7 @@ import com.jpexs.decompiler.flash.abc.types.traits.TraitSlotConst;
|
||||
import com.jpexs.decompiler.flash.gui.AppStrings;
|
||||
import com.jpexs.decompiler.flash.gui.Main;
|
||||
import com.jpexs.decompiler.flash.gui.View;
|
||||
import com.jpexs.decompiler.flash.gui.editor.DebuggableEditorPane;
|
||||
import com.jpexs.decompiler.flash.gui.editor.LineMarkedEditorPane;
|
||||
import com.jpexs.decompiler.flash.helpers.GraphTextWriter;
|
||||
import com.jpexs.decompiler.flash.helpers.hilight.HighlightData;
|
||||
@@ -59,7 +60,7 @@ import jsyntaxpane.Token;
|
||||
import jsyntaxpane.TokenType;
|
||||
import jsyntaxpane.components.BreakPointListener;
|
||||
|
||||
public class DecompiledEditorPane extends LineMarkedEditorPane implements CaretListener, BreakPointListener {
|
||||
public class DecompiledEditorPane extends DebuggableEditorPane implements CaretListener {
|
||||
|
||||
private List<Highlighting> highlights = new ArrayList<>();
|
||||
|
||||
@@ -91,34 +92,6 @@ public class DecompiledEditorPane extends LineMarkedEditorPane implements CaretL
|
||||
|
||||
private final List<Runnable> scriptListeners = new ArrayList<>();
|
||||
|
||||
public static final Color BG_BREAKPOINT_COLOR = new Color(0xfc, 0x9d, 0x9f);
|
||||
public static final Color FG_BREAKPOINT_COLOR = null;
|
||||
public static final int PRIORITY_BREAKPOINT = 20;
|
||||
|
||||
public static final Color BG_IP_COLOR = new Color(0xbd, 0xe6, 0xaa);
|
||||
public static final Color FG_IP_COLOR = null;
|
||||
public static final int PRIORITY_IP = 0;
|
||||
|
||||
public static final Color BG_INVALID_BREAKPOINT_COLOR = new Color(0xdc, 0xdc, 0xd8);
|
||||
public static final Color FG_INVALID_BREAKPOINT_COLOR = null;
|
||||
public static final int PRIORITY_INVALID_BREAKPOINT = 10;
|
||||
|
||||
@Override
|
||||
public void toggled(int line) {
|
||||
boolean on = Main.toggleBreakPoint(script, line);
|
||||
removeColorMarker(line, FG_INVALID_BREAKPOINT_COLOR, BG_INVALID_BREAKPOINT_COLOR, PRIORITY_INVALID_BREAKPOINT);
|
||||
if (on) {
|
||||
if (Main.isBreakPointValid(script, line)) {
|
||||
addColorMarker(line, FG_BREAKPOINT_COLOR, BG_BREAKPOINT_COLOR, PRIORITY_BREAKPOINT);
|
||||
} else {
|
||||
addColorMarker(line, FG_INVALID_BREAKPOINT_COLOR, BG_INVALID_BREAKPOINT_COLOR, PRIORITY_INVALID_BREAKPOINT);
|
||||
}
|
||||
} else {
|
||||
removeColorMarker(line, FG_BREAKPOINT_COLOR, BG_BREAKPOINT_COLOR, PRIORITY_BREAKPOINT);
|
||||
removeColorMarker(line, FG_INVALID_BREAKPOINT_COLOR, BG_INVALID_BREAKPOINT_COLOR, PRIORITY_INVALID_BREAKPOINT);
|
||||
}
|
||||
}
|
||||
|
||||
public void addScriptListener(Runnable l) {
|
||||
scriptListeners.add(l);
|
||||
}
|
||||
@@ -676,14 +649,16 @@ public class DecompiledEditorPane extends LineMarkedEditorPane implements CaretL
|
||||
if (!force && this.script == scriptLeaf) {
|
||||
return;
|
||||
}
|
||||
abcPanel.scriptNameLabel.setText(scriptLeaf.getClassPath().toString());
|
||||
String sn = scriptLeaf.getClassPath().toString();
|
||||
setScriptName(sn);
|
||||
abcPanel.scriptNameLabel.setText(sn);
|
||||
int scriptIndex = scriptLeaf.scriptIndex;
|
||||
ScriptInfo script = null;
|
||||
ScriptInfo nscript = null;
|
||||
ABC abc = scriptLeaf.abc;
|
||||
if (scriptIndex > -1) {
|
||||
script = abc.script_info.get(scriptIndex);
|
||||
nscript = abc.script_info.get(scriptIndex);
|
||||
}
|
||||
if (script == null) {
|
||||
if (nscript == null) {
|
||||
highlights = new ArrayList<>();
|
||||
specialHighlights = new ArrayList<>();
|
||||
traitHighlights = new ArrayList<>();
|
||||
@@ -738,36 +713,9 @@ public class DecompiledEditorPane extends LineMarkedEditorPane implements CaretL
|
||||
return script == null ? null : script.abc;
|
||||
}
|
||||
|
||||
public void refreshMarkers() {
|
||||
removeColorMarkerOnAllLines(FG_BREAKPOINT_COLOR, BG_BREAKPOINT_COLOR, PRIORITY_BREAKPOINT);
|
||||
removeColorMarkerOnAllLines(FG_INVALID_BREAKPOINT_COLOR, BG_INVALID_BREAKPOINT_COLOR, PRIORITY_INVALID_BREAKPOINT);
|
||||
removeColorMarkerOnAllLines(FG_IP_COLOR, BG_IP_COLOR, PRIORITY_IP);
|
||||
|
||||
if (script == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
Set<Integer> bkptLines = Main.getPackBreakPoints(script);
|
||||
|
||||
for (int line : bkptLines) {
|
||||
if (Main.isBreakPointValid(script, line)) {
|
||||
addColorMarker(line, FG_BREAKPOINT_COLOR, BG_BREAKPOINT_COLOR, PRIORITY_BREAKPOINT);
|
||||
} else {
|
||||
addColorMarker(line, FG_INVALID_BREAKPOINT_COLOR, BG_INVALID_BREAKPOINT_COLOR, PRIORITY_INVALID_BREAKPOINT);
|
||||
}
|
||||
}
|
||||
int ip = Main.getIp(script);
|
||||
ClassPath ipPath = Main.getIpClass();
|
||||
if (ip > 0 && ipPath != null && ipPath.equals(script.getClassPath())) {
|
||||
addColorMarker(ip, FG_IP_COLOR, BG_IP_COLOR, PRIORITY_IP);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setText(String t) {
|
||||
super.setText(t);
|
||||
setCaretPosition(0);
|
||||
refreshMarkers();
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,6 +18,7 @@ package com.jpexs.decompiler.flash.gui.action;
|
||||
|
||||
import com.jpexs.decompiler.flash.DisassemblyListener;
|
||||
import com.jpexs.decompiler.flash.SWF;
|
||||
import com.jpexs.decompiler.flash.abc.ClassPath;
|
||||
import com.jpexs.decompiler.flash.action.Action;
|
||||
import com.jpexs.decompiler.flash.action.ActionGraph;
|
||||
import com.jpexs.decompiler.flash.action.ActionList;
|
||||
@@ -34,6 +35,7 @@ import com.jpexs.decompiler.flash.action.swf4.ConstantIndex;
|
||||
import com.jpexs.decompiler.flash.configuration.Configuration;
|
||||
import com.jpexs.decompiler.flash.exporters.modes.ScriptExportMode;
|
||||
import com.jpexs.decompiler.flash.gui.AppStrings;
|
||||
import com.jpexs.decompiler.flash.gui.DebuggerHandler;
|
||||
import com.jpexs.decompiler.flash.gui.GraphDialog;
|
||||
import com.jpexs.decompiler.flash.gui.HeaderLabel;
|
||||
import com.jpexs.decompiler.flash.gui.Main;
|
||||
@@ -42,8 +44,19 @@ import com.jpexs.decompiler.flash.gui.SearchListener;
|
||||
import com.jpexs.decompiler.flash.gui.SearchPanel;
|
||||
import com.jpexs.decompiler.flash.gui.TagEditorPanel;
|
||||
import com.jpexs.decompiler.flash.gui.View;
|
||||
import com.jpexs.decompiler.flash.gui.DebugPanel;
|
||||
import static com.jpexs.decompiler.flash.gui.abc.DecompiledEditorPane.BG_BREAKPOINT_COLOR;
|
||||
import static com.jpexs.decompiler.flash.gui.abc.DecompiledEditorPane.BG_INVALID_BREAKPOINT_COLOR;
|
||||
import static com.jpexs.decompiler.flash.gui.abc.DecompiledEditorPane.BG_IP_COLOR;
|
||||
import static com.jpexs.decompiler.flash.gui.abc.DecompiledEditorPane.FG_BREAKPOINT_COLOR;
|
||||
import static com.jpexs.decompiler.flash.gui.abc.DecompiledEditorPane.FG_INVALID_BREAKPOINT_COLOR;
|
||||
import static com.jpexs.decompiler.flash.gui.abc.DecompiledEditorPane.FG_IP_COLOR;
|
||||
import static com.jpexs.decompiler.flash.gui.abc.DecompiledEditorPane.PRIORITY_BREAKPOINT;
|
||||
import static com.jpexs.decompiler.flash.gui.abc.DecompiledEditorPane.PRIORITY_INVALID_BREAKPOINT;
|
||||
import static com.jpexs.decompiler.flash.gui.abc.DecompiledEditorPane.PRIORITY_IP;
|
||||
import com.jpexs.decompiler.flash.gui.controls.JPersistentSplitPane;
|
||||
import com.jpexs.decompiler.flash.gui.controls.NoneSelectedButtonGroup;
|
||||
import com.jpexs.decompiler.flash.gui.editor.DebuggableEditorPane;
|
||||
import com.jpexs.decompiler.flash.gui.editor.LineMarkedEditorPane;
|
||||
import com.jpexs.decompiler.flash.gui.tagtree.TagTreeModel;
|
||||
import com.jpexs.decompiler.flash.helpers.HighlightedText;
|
||||
@@ -66,6 +79,7 @@ import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.CancellationException;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
@@ -96,7 +110,7 @@ public class ActionPanel extends JPanel implements SearchListener<ActionSearchRe
|
||||
|
||||
public LineMarkedEditorPane editor;
|
||||
|
||||
public LineMarkedEditorPane decompiledEditor;
|
||||
public DebuggableEditorPane decompiledEditor;
|
||||
|
||||
public JPersistentSplitPane splitPane;
|
||||
|
||||
@@ -170,6 +184,26 @@ public class ActionPanel extends JPanel implements SearchListener<ActionSearchRe
|
||||
srcConstants = null;
|
||||
}
|
||||
|
||||
/*public void refreshMarkers() {
|
||||
decompiledEditor.removeColorMarkerOnAllLines(FG_BREAKPOINT_COLOR, BG_BREAKPOINT_COLOR, PRIORITY_BREAKPOINT);
|
||||
decompiledEditor.removeColorMarkerOnAllLines(FG_INVALID_BREAKPOINT_COLOR, BG_INVALID_BREAKPOINT_COLOR, PRIORITY_INVALID_BREAKPOINT);
|
||||
decompiledEditor.removeColorMarkerOnAllLines(FG_IP_COLOR, BG_IP_COLOR, PRIORITY_IP);
|
||||
|
||||
Set<Integer> bkptLines = Main.getScriptBreakPoints(sc);
|
||||
|
||||
for (int line : bkptLines) {
|
||||
if (Main.isBreakPointValid(lastASM, line)) {
|
||||
decompiledEditor.addColorMarker(line, FG_BREAKPOINT_COLOR, BG_BREAKPOINT_COLOR, PRIORITY_BREAKPOINT);
|
||||
} else {
|
||||
decompiledEditor.addColorMarker(line, FG_INVALID_BREAKPOINT_COLOR, BG_INVALID_BREAKPOINT_COLOR, PRIORITY_INVALID_BREAKPOINT);
|
||||
}
|
||||
}
|
||||
int ip = Main.getIp(lastASM);
|
||||
String ipPath = Main.getIpClass();
|
||||
if (ip > 0 && ipPath != null && lastASM.getSwf().getASMs(false).get(ipPath) == lastASM) {
|
||||
decompiledEditor.addColorMarker(ip, FG_IP_COLOR, BG_IP_COLOR, PRIORITY_IP);
|
||||
}
|
||||
}*/
|
||||
public String getStringUnderCursor() {
|
||||
int pos = decompiledEditor.getCaretPosition();
|
||||
|
||||
@@ -206,7 +240,7 @@ public class ActionPanel extends JPanel implements SearchListener<ActionSearchRe
|
||||
selIns = ins;
|
||||
break;
|
||||
}
|
||||
if (ins.getOffset() > h.getProperties().offset) {
|
||||
if (ins.getOffset() > h.getProperties().offset && lastIns != null) {
|
||||
inspos = (int) (h.getProperties().offset - lastIns.getAddress());
|
||||
selIns = lastIns;
|
||||
break;
|
||||
@@ -274,9 +308,10 @@ public class ActionPanel extends JPanel implements SearchListener<ActionSearchRe
|
||||
return null;
|
||||
}
|
||||
|
||||
private void setDecompiledText(final String text) {
|
||||
private void setDecompiledText(final String scriptName, final String text) {
|
||||
View.execInEventDispatch(() -> {
|
||||
ignoreCarret = true;
|
||||
decompiledEditor.setScriptName(scriptName);
|
||||
decompiledEditor.setText(text);
|
||||
ignoreCarret = false;
|
||||
});
|
||||
@@ -415,12 +450,13 @@ public class ActionPanel extends JPanel implements SearchListener<ActionSearchRe
|
||||
|
||||
@Override
|
||||
protected Void doInBackground() throws Exception {
|
||||
|
||||
setEditorText("; " + AppStrings.translate("work.disassembling") + "...", "text/flasm");
|
||||
if (Configuration.decompile.get()) {
|
||||
setDecompiledText("// " + AppStrings.translate("work.waitingfordissasembly") + "...");
|
||||
setDecompiledText("-", "// " + AppStrings.translate("work.waitingfordissasembly") + "...");
|
||||
} else {
|
||||
lastDecompiled = Helper.getDecompilationSkippedComment();
|
||||
setDecompiledText(lastDecompiled);
|
||||
setDecompiledText(asm.getScriptName(), lastDecompiled);
|
||||
}
|
||||
DisassemblyListener listener = getDisassemblyListener();
|
||||
asm.addDisassemblyListener(listener);
|
||||
@@ -433,7 +469,7 @@ public class ActionPanel extends JPanel implements SearchListener<ActionSearchRe
|
||||
srcConstants = null;
|
||||
setHex(getExportMode());
|
||||
if (Configuration.decompile.get()) {
|
||||
setDecompiledText("// " + AppStrings.translate("work.decompiling") + "...");
|
||||
setDecompiledText("-", "// " + AppStrings.translate("work.decompiling") + "...");
|
||||
if (!useCache) {
|
||||
SWF.uncache(asm);
|
||||
}
|
||||
@@ -442,10 +478,11 @@ public class ActionPanel extends JPanel implements SearchListener<ActionSearchRe
|
||||
decompiledHilights = sc.hilights;
|
||||
lastDecompiled = sc.text;
|
||||
lastASM = asm;
|
||||
setDecompiledText(lastDecompiled);
|
||||
setDecompiledText(lastASM.getScriptName(), lastDecompiled);
|
||||
}
|
||||
setEditMode(false);
|
||||
setDecompiledEditMode(false);
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -453,21 +490,25 @@ public class ActionPanel extends JPanel implements SearchListener<ActionSearchRe
|
||||
protected void done() {
|
||||
View.execInEventDispatch(() -> {
|
||||
setSourceWorker = null;
|
||||
Main.stopWork();
|
||||
if (!Main.isDebugging()) {
|
||||
Main.stopWork();
|
||||
}
|
||||
|
||||
try {
|
||||
get();
|
||||
} catch (CancellationException ex) {
|
||||
setEditorText("; " + AppStrings.translate("work.canceled"), "text/flasm");
|
||||
} catch (Exception ex) {
|
||||
setDecompiledText("// " + AppStrings.translate("decompilationError") + ": " + ex);
|
||||
setDecompiledText("-", "// " + AppStrings.translate("decompilationError") + ": " + ex);
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
worker.execute();
|
||||
setSourceWorker = worker;
|
||||
Main.startWork(AppStrings.translate("work.decompiling") + "...", worker);
|
||||
if (!Main.isDebugging()) {
|
||||
Main.startWork(AppStrings.translate("work.decompiling") + "...", worker);
|
||||
}
|
||||
}
|
||||
|
||||
public void hilightOffset(long offset) {
|
||||
@@ -477,7 +518,7 @@ public class ActionPanel extends JPanel implements SearchListener<ActionSearchRe
|
||||
this.mainPanel = mainPanel;
|
||||
editor = new LineMarkedEditorPane();
|
||||
editor.setEditable(false);
|
||||
decompiledEditor = new LineMarkedEditorPane();
|
||||
decompiledEditor = new DebuggableEditorPane();
|
||||
decompiledEditor.setEditable(false);
|
||||
|
||||
searchPanel = new SearchPanel<>(new FlowLayout(), this);
|
||||
@@ -570,15 +611,37 @@ public class ActionPanel extends JPanel implements SearchListener<ActionSearchRe
|
||||
saveDecompiledButton.setVisible(false);
|
||||
cancelDecompiledButton.setVisible(false);
|
||||
|
||||
JPanel decPanel = new JPanel(new BorderLayout());
|
||||
decPanel.add(new JScrollPane(decompiledEditor), BorderLayout.CENTER);
|
||||
//decPanel.add(searchPanel, BorderLayout.NORTH);
|
||||
JPanel panA = new JPanel(new BorderLayout());
|
||||
|
||||
JPanel panA = new JPanel();
|
||||
panA.setLayout(new BorderLayout());
|
||||
panA.add(decPanel, BorderLayout.CENTER);
|
||||
panA.add(decLabel, BorderLayout.NORTH);
|
||||
|
||||
DebugPanel debugPanel = new DebugPanel();
|
||||
|
||||
panA.add(new JPersistentSplitPane(JSplitPane.VERTICAL_SPLIT, new JScrollPane(decompiledEditor), debugPanel, Configuration.guiActionVarsSplitPaneDividerLocationPercent), BorderLayout.CENTER);
|
||||
panA.add(decButtonsPan, BorderLayout.SOUTH);
|
||||
|
||||
//decPanel.add(searchPanel, BorderLayout.NORTH);
|
||||
Main.getDebugHandler().addConnectionListener(new DebuggerHandler.ConnectionListener() {
|
||||
|
||||
@Override
|
||||
public void connected() {
|
||||
decButtonsPan.setVisible(false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void disconnected() {
|
||||
decButtonsPan.setVisible(true);
|
||||
}
|
||||
});
|
||||
|
||||
//new JSplitPane(JSplitPane.VERTICAL_SPLIT, decompiledEditor, debugPanel)
|
||||
//decPanel.add(decButtonsPan, BorderLayout.SOUTH);
|
||||
//JPanel panBot = new JPanel(new BorderLayout());
|
||||
//panBot.add(decButtonsPan, BorderLayout.NORTH);
|
||||
//panBot.add(debugPanel, BorderLayout.CENTER);
|
||||
//panA.add(decButtonsPan, BorderLayout.SOUTH);
|
||||
debugPanel.setVisible(false);
|
||||
|
||||
decLabel.setHorizontalAlignment(SwingConstants.CENTER);
|
||||
//decLabel.setBorder(new BevelBorder(BevelBorder.RAISED));
|
||||
|
||||
@@ -678,63 +741,66 @@ public class ActionPanel extends JPanel implements SearchListener<ActionSearchRe
|
||||
}
|
||||
|
||||
public void setEditMode(boolean val) {
|
||||
if (val) {
|
||||
if (hexOnlyButton.isSelected()) {
|
||||
setHex(ScriptExportMode.HEX);
|
||||
} else if (constantsViewButton.isSelected()) {
|
||||
setHex(ScriptExportMode.CONSTANTS);
|
||||
} else {
|
||||
setHex(ScriptExportMode.PCODE);
|
||||
View.execInEventDispatch(() -> {
|
||||
if (val) {
|
||||
if (hexOnlyButton.isSelected()) {
|
||||
setHex(ScriptExportMode.HEX);
|
||||
} else if (constantsViewButton.isSelected()) {
|
||||
setHex(ScriptExportMode.CONSTANTS);
|
||||
} else {
|
||||
setHex(ScriptExportMode.PCODE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
editor.setEditable(val);
|
||||
saveButton.setVisible(val);
|
||||
saveButton.setEnabled(false);
|
||||
editButton.setVisible(!val);
|
||||
cancelButton.setVisible(val);
|
||||
editor.setEditable(val);
|
||||
saveButton.setVisible(val);
|
||||
saveButton.setEnabled(false);
|
||||
editButton.setVisible(!val);
|
||||
cancelButton.setVisible(val);
|
||||
|
||||
editor.getCaret().setVisible(true);
|
||||
asmLabel.setIcon(val ? View.getIcon("editing16") : null); // this line is not working
|
||||
topButtonsPan.setVisible(!val);
|
||||
editMode = val;
|
||||
editor.requestFocusInWindow();
|
||||
editor.getCaret().setVisible(true);
|
||||
asmLabel.setIcon(val ? View.getIcon("editing16") : null); // this line is not working
|
||||
topButtonsPan.setVisible(!val);
|
||||
editMode = val;
|
||||
editor.requestFocusInWindow();
|
||||
});
|
||||
}
|
||||
|
||||
public void setDecompiledEditMode(boolean val) {
|
||||
if (lastASM == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
int lastLine = decompiledEditor.getLine();
|
||||
int prefLines = lastASM.getPrefixLineCount();
|
||||
if (val) {
|
||||
String newText = lastASM.removePrefixAndSuffix(lastDecompiled);
|
||||
setDecompiledText(newText);
|
||||
if (lastLine > -1) {
|
||||
if (lastLine - prefLines >= 0) {
|
||||
decompiledEditor.gotoLine(lastLine - prefLines + 1);
|
||||
View.execInEventDispatch(() -> {
|
||||
int lastLine = decompiledEditor.getLine();
|
||||
int prefLines = lastASM.getPrefixLineCount();
|
||||
if (val) {
|
||||
String newText = lastASM.removePrefixAndSuffix(lastDecompiled);
|
||||
setDecompiledText(lastASM.getScriptName(), newText);
|
||||
if (lastLine > -1) {
|
||||
if (lastLine - prefLines >= 0) {
|
||||
decompiledEditor.gotoLine(lastLine - prefLines + 1);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
String newText = lastDecompiled;
|
||||
setDecompiledText(lastASM.getScriptName(), newText);
|
||||
if (lastLine > -1) {
|
||||
decompiledEditor.gotoLine(lastLine + prefLines + 1);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
String newText = lastDecompiled;
|
||||
setDecompiledText(newText);
|
||||
if (lastLine > -1) {
|
||||
decompiledEditor.gotoLine(lastLine + prefLines + 1);
|
||||
}
|
||||
}
|
||||
|
||||
decompiledEditor.setEditable(val);
|
||||
saveDecompiledButton.setVisible(val);
|
||||
saveDecompiledButton.setEnabled(false);
|
||||
editDecompiledButton.setVisible(!val);
|
||||
experimentalLabel.setVisible(!val);
|
||||
cancelDecompiledButton.setVisible(val);
|
||||
decompiledEditor.setEditable(val);
|
||||
saveDecompiledButton.setVisible(val);
|
||||
saveDecompiledButton.setEnabled(false);
|
||||
editDecompiledButton.setVisible(!val);
|
||||
experimentalLabel.setVisible(!val);
|
||||
cancelDecompiledButton.setVisible(val);
|
||||
|
||||
decompiledEditor.getCaret().setVisible(true);
|
||||
decLabel.setIcon(val ? View.getIcon("editing16") : null);
|
||||
editDecompiledMode = val;
|
||||
decompiledEditor.requestFocusInWindow();
|
||||
decompiledEditor.getCaret().setVisible(true);
|
||||
decLabel.setIcon(val ? View.getIcon("editing16") : null);
|
||||
editDecompiledMode = val;
|
||||
decompiledEditor.requestFocusInWindow();
|
||||
});
|
||||
}
|
||||
|
||||
private void graphButtonActionPerformed(ActionEvent evt) {
|
||||
|
||||
@@ -0,0 +1,102 @@
|
||||
/*
|
||||
* Copyright (C) 2015 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.editor;
|
||||
|
||||
import com.jpexs.decompiler.flash.gui.Main;
|
||||
import java.awt.Color;
|
||||
import java.util.Set;
|
||||
import jsyntaxpane.components.BreakPointListener;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public class DebuggableEditorPane extends LineMarkedEditorPane implements BreakPointListener {
|
||||
|
||||
public static final Color BG_BREAKPOINT_COLOR = new Color(0xfc, 0x9d, 0x9f);
|
||||
public static final Color FG_BREAKPOINT_COLOR = null;
|
||||
public static final int PRIORITY_BREAKPOINT = 20;
|
||||
|
||||
public static final Color BG_IP_COLOR = new Color(0xbd, 0xe6, 0xaa);
|
||||
public static final Color FG_IP_COLOR = null;
|
||||
public static final int PRIORITY_IP = 0;
|
||||
|
||||
public static final Color BG_INVALID_BREAKPOINT_COLOR = new Color(0xdc, 0xdc, 0xd8);
|
||||
public static final Color FG_INVALID_BREAKPOINT_COLOR = null;
|
||||
public static final int PRIORITY_INVALID_BREAKPOINT = 10;
|
||||
|
||||
protected String scriptName = null;
|
||||
|
||||
public synchronized void setScriptName(String scriptName) {
|
||||
this.scriptName = scriptName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void toggled(int line) {
|
||||
if (scriptName == null) {
|
||||
return;
|
||||
}
|
||||
boolean on = Main.toggleBreakPoint(scriptName, line);
|
||||
removeColorMarker(line, FG_INVALID_BREAKPOINT_COLOR, BG_INVALID_BREAKPOINT_COLOR, PRIORITY_INVALID_BREAKPOINT);
|
||||
if (on) {
|
||||
if (Main.isBreakPointValid(scriptName, line)) {
|
||||
addColorMarker(line, FG_BREAKPOINT_COLOR, BG_BREAKPOINT_COLOR, PRIORITY_BREAKPOINT);
|
||||
} else {
|
||||
addColorMarker(line, FG_INVALID_BREAKPOINT_COLOR, BG_INVALID_BREAKPOINT_COLOR, PRIORITY_INVALID_BREAKPOINT);
|
||||
}
|
||||
} else {
|
||||
removeColorMarker(line, FG_BREAKPOINT_COLOR, BG_BREAKPOINT_COLOR, PRIORITY_BREAKPOINT);
|
||||
removeColorMarker(line, FG_INVALID_BREAKPOINT_COLOR, BG_INVALID_BREAKPOINT_COLOR, PRIORITY_INVALID_BREAKPOINT);
|
||||
}
|
||||
}
|
||||
|
||||
public synchronized void refreshMarkers() {
|
||||
removeColorMarkerOnAllLines(FG_BREAKPOINT_COLOR, BG_BREAKPOINT_COLOR, PRIORITY_BREAKPOINT);
|
||||
removeColorMarkerOnAllLines(FG_INVALID_BREAKPOINT_COLOR, BG_INVALID_BREAKPOINT_COLOR, PRIORITY_INVALID_BREAKPOINT);
|
||||
removeColorMarkerOnAllLines(FG_IP_COLOR, BG_IP_COLOR, PRIORITY_IP);
|
||||
|
||||
if (scriptName == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
Set<Integer> bkptLines = Main.getScriptBreakPoints(scriptName);
|
||||
|
||||
for (int line : bkptLines) {
|
||||
if (Main.isBreakPointValid(scriptName, line)) {
|
||||
addColorMarker(line, FG_BREAKPOINT_COLOR, BG_BREAKPOINT_COLOR, PRIORITY_BREAKPOINT);
|
||||
} else {
|
||||
addColorMarker(line, FG_INVALID_BREAKPOINT_COLOR, BG_INVALID_BREAKPOINT_COLOR, PRIORITY_INVALID_BREAKPOINT);
|
||||
}
|
||||
}
|
||||
int ip = Main.getIp(scriptName);
|
||||
String ipPath = Main.getIpClass();
|
||||
if (ip > 0 && ipPath != null && ipPath.equals(scriptName)) {
|
||||
addColorMarker(ip, FG_IP_COLOR, BG_IP_COLOR, PRIORITY_IP);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setText(String t) {
|
||||
super.setText(t);
|
||||
refreshMarkers();
|
||||
}
|
||||
|
||||
public String getScriptName() {
|
||||
return scriptName;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -678,4 +678,17 @@ work.breakat = Breat at\u0020
|
||||
work.halted = Debugging started, execution halted. Add breakpoints and click Continue (F5) to resume running.
|
||||
|
||||
debuglog.header = Log
|
||||
debuglog.button.clear = Clear
|
||||
debuglog.button.clear = Clear
|
||||
|
||||
work.debugging.wait = Waiting for Flash debug projector to connect
|
||||
|
||||
error.debug.listen = Cannot listen on port %port%. There might be other flash debugger running.
|
||||
|
||||
debug.break.reason.unknown = (Unknown)
|
||||
debug.break.reason.breakpoint = (Breakpoint)
|
||||
debug.break.reason.watch = (Watch)
|
||||
debug.break.reason.fault = (Fault)
|
||||
debug.break.reason.stopRequest = (Stop request)
|
||||
debug.break.reason.step = (Step)
|
||||
debug.break.reason.halt = (Halt)
|
||||
debug.break.reason.scriptLoaded = (Script loaded)
|
||||
@@ -84,6 +84,7 @@ import java.util.Random;
|
||||
import static org.testng.Assert.assertEquals;
|
||||
import static org.testng.Assert.assertTrue;
|
||||
import static org.testng.Assert.fail;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
/**
|
||||
*
|
||||
|
||||
Reference in New Issue
Block a user