mirror of
https://git.huckle.dev/Huckles-Minecraft-Archive/jpexs-decompiler.git
synced 2026-08-02 15:51:16 +00:00
Added: Debugger - Remove watch
Added: Debugger - List of watches Added: Debugger - Show flag of watch type (read/write) Fixed: Debugger - Threading issues with multiple SWFs Fixed: Debugger - Reading variables on 64bit flash players (like in browsers) Enhanced debug game test SWFs
This commit is contained in:
@@ -4,10 +4,14 @@ All notable changes to this project will be documented in this file.
|
||||
## [Unreleased]
|
||||
### Added
|
||||
- Debugger - Debugged SWF file name in the session title
|
||||
- Debugger - Remove watch
|
||||
- Debugger - List of watches
|
||||
- Debugger - Show flag of watch type (read/write)
|
||||
|
||||
### Fixed
|
||||
- [#2639] Export to FLA - missing sound streams
|
||||
- Debugger - Threading issues with multiple SWFs
|
||||
- Debugger - Reading variables on 64bit flash players (like in browsers)
|
||||
|
||||
## [25.1.1] - 2026-02-19
|
||||
### Fixed
|
||||
|
||||
Binary file not shown.
Binary file not shown.
BIN
libsrc/ffdec_lib/testdata/debug_game/as2_scoring.swd
vendored
Normal file
BIN
libsrc/ffdec_lib/testdata/debug_game/as2_scoring.swd
vendored
Normal file
Binary file not shown.
BIN
libsrc/ffdec_lib/testdata/debug_game/as2_scoring.swf
vendored
BIN
libsrc/ffdec_lib/testdata/debug_game/as2_scoring.swf
vendored
Binary file not shown.
@@ -6,6 +6,8 @@
|
||||
<Include href="Button1.xml" itemIcon="0" loadImmediate="false" itemID="699362e3-000001d5" lastModified="1771267090"/>
|
||||
<Include href="Button2.xml" itemIcon="0" loadImmediate="false" itemID="6993636a-000001dc" lastModified="1771267096"/>
|
||||
<Include href="Button3.xml" itemIcon="0" loadImmediate="false" itemID="699367b4-000001e5" lastModified="1771268063"/>
|
||||
<Include href="ButtonDown.xml" itemIcon="0" loadImmediate="false" itemID="6999ec93-000001e6" lastModified="1771695532"/>
|
||||
<Include href="ButtonUp.xml" itemIcon="0" loadImmediate="false" itemID="6999ec8b-000001e1" lastModified="1771695510"/>
|
||||
</symbols>
|
||||
<timelines>
|
||||
<DOMTimeline name="Scene 1">
|
||||
@@ -43,6 +45,7 @@ stop();]]></script>
|
||||
var score = parseInt(_root.inpScore.text);
|
||||
score = score + 5;
|
||||
_root.inpScore.text = score;
|
||||
trace("plus 5");
|
||||
}]]></script>
|
||||
</Actionscript>
|
||||
</DOMSymbolInstance>
|
||||
@@ -58,6 +61,7 @@ stop();]]></script>
|
||||
var score = parseInt(_root.inpScore.text);
|
||||
score = score * 2;
|
||||
_root.inpScore.text = score;
|
||||
trace("multiply 2");
|
||||
}]]></script>
|
||||
</Actionscript>
|
||||
</DOMSymbolInstance>
|
||||
@@ -100,7 +104,7 @@ stop();]]></script>
|
||||
</DOMTextRun>
|
||||
</textRuns>
|
||||
</DOMDynamicText>
|
||||
<DOMSymbolInstance libraryItemName="Button3" symbolType="button">
|
||||
<DOMSymbolInstance libraryItemName="Button3" selected="true" symbolType="button">
|
||||
<matrix>
|
||||
<Matrix tx="216.95" ty="294.5"/>
|
||||
</matrix>
|
||||
@@ -110,6 +114,48 @@ stop();]]></script>
|
||||
<Actionscript>
|
||||
<script><![CDATA[on(press) {
|
||||
_root.inpScore.text = 0;
|
||||
trace("reset");
|
||||
}]]></script>
|
||||
</Actionscript>
|
||||
</DOMSymbolInstance>
|
||||
<DOMStaticText fontRenderingMode="standard" width="51" height="22.15" isSelectable="false">
|
||||
<matrix>
|
||||
<Matrix tx="474.2" ty="12"/>
|
||||
</matrix>
|
||||
<textRuns>
|
||||
<DOMTextRun>
|
||||
<characters>Speed</characters>
|
||||
<textAttrs>
|
||||
<DOMTextAttrs aliasText="false" size="20" bitmapSize="400" face="TimesNewRomanPSMT"/>
|
||||
</textAttrs>
|
||||
</DOMTextRun>
|
||||
</textRuns>
|
||||
</DOMStaticText>
|
||||
<DOMSymbolInstance libraryItemName="ButtonUp" name="btnSpeedUp" symbolType="button">
|
||||
<matrix>
|
||||
<Matrix tx="450" ty="11.3"/>
|
||||
</matrix>
|
||||
<transformationPoint>
|
||||
<Point x="6.6" y="5.6"/>
|
||||
</transformationPoint>
|
||||
<Actionscript>
|
||||
<script><![CDATA[on(press) {
|
||||
_root.delay = Math.round(_root.delay / 1.1);
|
||||
trace("speed up");
|
||||
}]]></script>
|
||||
</Actionscript>
|
||||
</DOMSymbolInstance>
|
||||
<DOMSymbolInstance libraryItemName="ButtonDown" name="btnSpeedDown" symbolType="button">
|
||||
<matrix>
|
||||
<Matrix tx="450" ty="26"/>
|
||||
</matrix>
|
||||
<transformationPoint>
|
||||
<Point x="6.6" y="5.6"/>
|
||||
</transformationPoint>
|
||||
<Actionscript>
|
||||
<script><![CDATA[on(press) {
|
||||
_root.delay = Math.round(_root.delay * 1.1);
|
||||
trace("speed down");
|
||||
}]]></script>
|
||||
</Actionscript>
|
||||
</DOMSymbolInstance>
|
||||
@@ -122,6 +168,10 @@ stop();]]></script>
|
||||
</timelines>
|
||||
<PrinterSettings/>
|
||||
<publishHistory>
|
||||
<PublishItem publishSize="9272" publishTime="1771699758"/>
|
||||
<PublishItem publishSize="9288" publishTime="1771695673" publishDebug="true"/>
|
||||
<PublishItem publishSize="9287" publishTime="1771695604" publishDebug="true"/>
|
||||
<PublishItem publishSize="9303" publishTime="1771695543" publishDebug="true"/>
|
||||
<PublishItem publishSize="8792" publishTime="1771271352"/>
|
||||
<PublishItem publishSize="8784" publishTime="1771269741"/>
|
||||
<PublishItem publishSize="8774" publishTime="1771269515"/>
|
||||
@@ -138,6 +188,5 @@ stop();]]></script>
|
||||
<PublishItem publishSize="7223" publishTime="1771267567" publishDebug="true"/>
|
||||
<PublishItem publishSize="7203" publishTime="1771267511" publishDebug="true"/>
|
||||
<PublishItem publishSize="7172" publishTime="1771267431" publishDebug="true"/>
|
||||
<PublishItem publishSize="7170" publishTime="1771267362" publishDebug="true"/>
|
||||
</publishHistory>
|
||||
</DOMDocument>
|
||||
90
libsrc/ffdec_lib/testdata/debug_game/as2_scoring/LIBRARY/ButtonDown.xml
vendored
Normal file
90
libsrc/ffdec_lib/testdata/debug_game/as2_scoring/LIBRARY/ButtonDown.xml
vendored
Normal file
@@ -0,0 +1,90 @@
|
||||
<DOMSymbolItem xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://ns.adobe.com/xfl/2008/" name="ButtonDown" itemID="6999ec93-000001e6" symbolType="button" lastModified="1771695532">
|
||||
<timeline>
|
||||
<DOMTimeline name="ButtonDown" currentFrame="2">
|
||||
<layers>
|
||||
<DOMLayer name="Layer 1" color="#4FFF4F" current="true" isSelected="true">
|
||||
<frames>
|
||||
<DOMFrame index="0" keyMode="9728">
|
||||
<elements>
|
||||
<DOMShape>
|
||||
<fills>
|
||||
<FillStyle index="1">
|
||||
<SolidColor color="#0099FF"/>
|
||||
</FillStyle>
|
||||
</fills>
|
||||
<strokes>
|
||||
<StrokeStyle index="1">
|
||||
<SolidStroke scaleMode="normal">
|
||||
<fill>
|
||||
<SolidColor/>
|
||||
</fill>
|
||||
</SolidStroke>
|
||||
</StrokeStyle>
|
||||
</strokes>
|
||||
<edges>
|
||||
<Edge fillStyle0="1" strokeStyle="1" edges="!135 225S5|265 0!265 0|0 0!0 0|135 225"/>
|
||||
<Edge cubics="!265 0(;265,0 0,0 0,0q265 0 0 0);"/>
|
||||
<Edge cubics="!0 0(;0,0 135,225 135,225q0 0 135 225);"/>
|
||||
<Edge cubics="!135 225(;135,225 265,0 265,0q135 225 265 0);"/>
|
||||
</edges>
|
||||
</DOMShape>
|
||||
</elements>
|
||||
</DOMFrame>
|
||||
<DOMFrame index="1" keyMode="9728">
|
||||
<elements>
|
||||
<DOMShape>
|
||||
<fills>
|
||||
<FillStyle index="1">
|
||||
<SolidColor color="#00FFFF"/>
|
||||
</FillStyle>
|
||||
</fills>
|
||||
<strokes>
|
||||
<StrokeStyle index="1">
|
||||
<SolidStroke scaleMode="normal">
|
||||
<fill>
|
||||
<SolidColor/>
|
||||
</fill>
|
||||
</SolidStroke>
|
||||
</StrokeStyle>
|
||||
</strokes>
|
||||
<edges>
|
||||
<Edge fillStyle0="1" strokeStyle="1" edges="!265 0|0 0!0 0|135 225!135 225|265 0"/>
|
||||
<Edge cubics="!265 0(;265,0 0,0 0,0q265 0 0 0);"/>
|
||||
<Edge cubics="!0 0(;0,0 135,225 135,225q0 0 135 225);"/>
|
||||
<Edge cubics="!135 225(;135,225 265,0 265,0q135 225 265 0);"/>
|
||||
</edges>
|
||||
</DOMShape>
|
||||
</elements>
|
||||
</DOMFrame>
|
||||
<DOMFrame index="2" keyMode="9728">
|
||||
<elements>
|
||||
<DOMShape>
|
||||
<fills>
|
||||
<FillStyle index="1">
|
||||
<SolidColor color="#0000FF"/>
|
||||
</FillStyle>
|
||||
</fills>
|
||||
<strokes>
|
||||
<StrokeStyle index="1">
|
||||
<SolidStroke scaleMode="normal">
|
||||
<fill>
|
||||
<SolidColor/>
|
||||
</fill>
|
||||
</SolidStroke>
|
||||
</StrokeStyle>
|
||||
</strokes>
|
||||
<edges>
|
||||
<Edge fillStyle0="1" strokeStyle="1" edges="!265 0|0 0!0 0|135 225!135 225|265 0"/>
|
||||
<Edge cubics="!265 0(;265,0 0,0 0,0q265 0 0 0);"/>
|
||||
<Edge cubics="!0 0(;0,0 135,225 135,225q0 0 135 225);"/>
|
||||
<Edge cubics="!135 225(;135,225 265,0 265,0q135 225 265 0);"/>
|
||||
</edges>
|
||||
</DOMShape>
|
||||
</elements>
|
||||
</DOMFrame>
|
||||
</frames>
|
||||
</DOMLayer>
|
||||
</layers>
|
||||
</DOMTimeline>
|
||||
</timeline>
|
||||
</DOMSymbolItem>
|
||||
90
libsrc/ffdec_lib/testdata/debug_game/as2_scoring/LIBRARY/ButtonUp.xml
vendored
Normal file
90
libsrc/ffdec_lib/testdata/debug_game/as2_scoring/LIBRARY/ButtonUp.xml
vendored
Normal file
@@ -0,0 +1,90 @@
|
||||
<DOMSymbolItem xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://ns.adobe.com/xfl/2008/" name="ButtonUp" itemID="6999ec8b-000001e1" symbolType="button" lastModified="1771695510">
|
||||
<timeline>
|
||||
<DOMTimeline name="ButtonUp" currentFrame="2">
|
||||
<layers>
|
||||
<DOMLayer name="Layer 1" color="#4FFF4F" current="true" isSelected="true">
|
||||
<frames>
|
||||
<DOMFrame index="0" keyMode="9728">
|
||||
<elements>
|
||||
<DOMShape>
|
||||
<fills>
|
||||
<FillStyle index="1">
|
||||
<SolidColor color="#0099FF"/>
|
||||
</FillStyle>
|
||||
</fills>
|
||||
<strokes>
|
||||
<StrokeStyle index="1">
|
||||
<SolidStroke scaleMode="normal">
|
||||
<fill>
|
||||
<SolidColor/>
|
||||
</fill>
|
||||
</SolidStroke>
|
||||
</StrokeStyle>
|
||||
</strokes>
|
||||
<edges>
|
||||
<Edge fillStyle0="1" strokeStyle="1" edges="!130 0S5|0 225!0 225|265 225!265 225|130 0"/>
|
||||
<Edge cubics="!0 225(;0,225 265,225 265,225q0 225 265 225);"/>
|
||||
<Edge cubics="!265 225(;265,225 130,0 130,0q265 225 130 0);"/>
|
||||
<Edge cubics="!130 0(;130,0 0,225 0,225q130 0 0 225);"/>
|
||||
</edges>
|
||||
</DOMShape>
|
||||
</elements>
|
||||
</DOMFrame>
|
||||
<DOMFrame index="1" keyMode="9728">
|
||||
<elements>
|
||||
<DOMShape>
|
||||
<fills>
|
||||
<FillStyle index="1">
|
||||
<SolidColor color="#00FFFF"/>
|
||||
</FillStyle>
|
||||
</fills>
|
||||
<strokes>
|
||||
<StrokeStyle index="1">
|
||||
<SolidStroke scaleMode="normal">
|
||||
<fill>
|
||||
<SolidColor/>
|
||||
</fill>
|
||||
</SolidStroke>
|
||||
</StrokeStyle>
|
||||
</strokes>
|
||||
<edges>
|
||||
<Edge fillStyle0="1" strokeStyle="1" edges="!0 225|265 225!265 225|130 0!130 0|0 225"/>
|
||||
<Edge cubics="!0 225(;0,225 265,225 265,225q0 225 265 225);"/>
|
||||
<Edge cubics="!265 225(;265,225 130,0 130,0q265 225 130 0);"/>
|
||||
<Edge cubics="!130 0(;130,0 0,225 0,225q130 0 0 225);"/>
|
||||
</edges>
|
||||
</DOMShape>
|
||||
</elements>
|
||||
</DOMFrame>
|
||||
<DOMFrame index="2" keyMode="9728">
|
||||
<elements>
|
||||
<DOMShape>
|
||||
<fills>
|
||||
<FillStyle index="1">
|
||||
<SolidColor color="#0000FF"/>
|
||||
</FillStyle>
|
||||
</fills>
|
||||
<strokes>
|
||||
<StrokeStyle index="1">
|
||||
<SolidStroke scaleMode="normal">
|
||||
<fill>
|
||||
<SolidColor/>
|
||||
</fill>
|
||||
</SolidStroke>
|
||||
</StrokeStyle>
|
||||
</strokes>
|
||||
<edges>
|
||||
<Edge fillStyle0="1" strokeStyle="1" edges="!265 225|130 0!130 0|0 225!0 225|265 225"/>
|
||||
<Edge cubics="!0 225(;0,225 265,225 265,225q0 225 265 225);"/>
|
||||
<Edge cubics="!265 225(;265,225 130,0 130,0q265 225 130 0);"/>
|
||||
<Edge cubics="!130 0(;130,0 0,225 0,225q130 0 0 225);"/>
|
||||
</edges>
|
||||
</DOMShape>
|
||||
</elements>
|
||||
</DOMFrame>
|
||||
</frames>
|
||||
</DOMLayer>
|
||||
</layers>
|
||||
</DOMTimeline>
|
||||
</timeline>
|
||||
</DOMSymbolItem>
|
||||
@@ -5,8 +5,8 @@
|
||||
xmlns:xmp="http://ns.adobe.com/xap/1.0/">
|
||||
<xmp:CreatorTool>Adobe Flash Professional CS6 - build 481</xmp:CreatorTool>
|
||||
<xmp:CreateDate>2026-02-16T10:31:42-08:00</xmp:CreateDate>
|
||||
<xmp:MetadataDate>2026-02-16T11:18:35-08:00</xmp:MetadataDate>
|
||||
<xmp:ModifyDate>2026-02-16T11:18:35-08:00</xmp:ModifyDate>
|
||||
<xmp:MetadataDate>2026-02-21T09:35:10-08:00</xmp:MetadataDate>
|
||||
<xmp:ModifyDate>2026-02-21T09:35:10-08:00</xmp:ModifyDate>
|
||||
</rdf:Description>
|
||||
<rdf:Description rdf:about=""
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/">
|
||||
@@ -17,7 +17,7 @@
|
||||
xmlns:stEvt="http://ns.adobe.com/xap/1.0/sType/ResourceEvent#">
|
||||
<xmpMM:DerivedFrom rdf:parseType="Resource"/>
|
||||
<xmpMM:DocumentID>xmp.did:7FE581FA660BF11197008EF33C376745</xmpMM:DocumentID>
|
||||
<xmpMM:InstanceID>xmp.iid:9BDF39F36B0BF11197008EF33C376745</xmpMM:InstanceID>
|
||||
<xmpMM:InstanceID>xmp.iid:377DE8AB4B0FF111A0D3B09FD2F43FD4</xmpMM:InstanceID>
|
||||
<xmpMM:OriginalDocumentID>xmp.did:7FE581FA660BF11197008EF33C376745</xmpMM:OriginalDocumentID>
|
||||
<xmpMM:History>
|
||||
<rdf:Seq>
|
||||
@@ -39,6 +39,12 @@
|
||||
<stEvt:when>2026-02-16T10:31:42-08:00</stEvt:when>
|
||||
<stEvt:softwareAgent>Adobe Flash Professional CS6 - build 481</stEvt:softwareAgent>
|
||||
</rdf:li>
|
||||
<rdf:li rdf:parseType="Resource">
|
||||
<stEvt:action>created</stEvt:action>
|
||||
<stEvt:instanceID>xmp.iid:377DE8AB4B0FF111A0D3B09FD2F43FD4</stEvt:instanceID>
|
||||
<stEvt:when>2026-02-16T10:31:42-08:00</stEvt:when>
|
||||
<stEvt:softwareAgent>Adobe Flash Professional CS6 - build 481</stEvt:softwareAgent>
|
||||
</rdf:li>
|
||||
</rdf:Seq>
|
||||
</xmpMM:History>
|
||||
</rdf:Description>
|
||||
|
||||
Binary file not shown.
BIN
libsrc/ffdec_lib/testdata/debug_game/as3_scoring.swf
vendored
BIN
libsrc/ffdec_lib/testdata/debug_game/as3_scoring.swf
vendored
Binary file not shown.
@@ -6,6 +6,8 @@
|
||||
<Include href="Button1.xml" itemIcon="0" loadImmediate="false" itemID="699362e3-000001d5" lastModified="1771267090"/>
|
||||
<Include href="Button2.xml" itemIcon="0" loadImmediate="false" itemID="6993636a-000001dc" lastModified="1771267096"/>
|
||||
<Include href="Button3.xml" itemIcon="0" loadImmediate="false" itemID="699367b4-000001e5" lastModified="1771268063"/>
|
||||
<Include href="ButtonDown.xml" itemIcon="0" loadImmediate="false" itemID="6999ec93-000001e6" lastModified="1771695532"/>
|
||||
<Include href="ButtonUp.xml" itemIcon="0" loadImmediate="false" itemID="6999ec8b-000001e1" lastModified="1771695510"/>
|
||||
</symbols>
|
||||
<timelines>
|
||||
<DOMTimeline name="Scene 1">
|
||||
@@ -42,7 +44,8 @@ setTimeout(decreaseScore, delay);
|
||||
function onPlus5(e:MouseEvent):void {
|
||||
var score:int = getScore();
|
||||
score = score + 5;
|
||||
setScore(score);
|
||||
setScore(score);
|
||||
trace("plus 5");
|
||||
}
|
||||
|
||||
butPlus5.addEventListener(MouseEvent.CLICK, onPlus5);
|
||||
@@ -51,15 +54,32 @@ function onMultiply2(e:MouseEvent):void {
|
||||
var score:int = getScore();
|
||||
score = score * 2;
|
||||
setScore(score);
|
||||
trace("multiply 2");
|
||||
}
|
||||
|
||||
butMultiply2.addEventListener(MouseEvent.CLICK, onMultiply2);
|
||||
|
||||
function onReset(e:MouseEvent):void {
|
||||
setScore(0);
|
||||
trace("reset");
|
||||
}
|
||||
|
||||
butReset.addEventListener(MouseEvent.CLICK, onReset);]]></script>
|
||||
butReset.addEventListener(MouseEvent.CLICK, onReset);
|
||||
|
||||
function onSpeedUp(e:MouseEvent): void {
|
||||
delay = Math.round(delay / 1.1);
|
||||
trace("speed up");
|
||||
}
|
||||
|
||||
btnSpeedUp.addEventListener(MouseEvent.CLICK, onSpeedUp);
|
||||
|
||||
function onSpeedDown(e:MouseEvent): void {
|
||||
delay = Math.round(delay * 1.1);
|
||||
trace("speed down");
|
||||
}
|
||||
|
||||
btnSpeedDown.addEventListener(MouseEvent.CLICK, onSpeedDown);
|
||||
]]></script>
|
||||
</Actionscript>
|
||||
<elements>
|
||||
<DOMSymbolInstance libraryItemName="Button1" name="butPlus5" symbolType="button">
|
||||
@@ -125,6 +145,35 @@ butReset.addEventListener(MouseEvent.CLICK, onReset);]]></script>
|
||||
<Point/>
|
||||
</transformationPoint>
|
||||
</DOMSymbolInstance>
|
||||
<DOMStaticText fontRenderingMode="standard" width="51" height="22.15" isSelectable="false">
|
||||
<matrix>
|
||||
<Matrix tx="474.2" ty="12"/>
|
||||
</matrix>
|
||||
<textRuns>
|
||||
<DOMTextRun>
|
||||
<characters>Speed</characters>
|
||||
<textAttrs>
|
||||
<DOMTextAttrs aliasText="false" size="20" bitmapSize="400" face="TimesNewRomanPSMT"/>
|
||||
</textAttrs>
|
||||
</DOMTextRun>
|
||||
</textRuns>
|
||||
</DOMStaticText>
|
||||
<DOMSymbolInstance libraryItemName="ButtonUp" name="btnSpeedUp" symbolType="button">
|
||||
<matrix>
|
||||
<Matrix tx="450" ty="11.3"/>
|
||||
</matrix>
|
||||
<transformationPoint>
|
||||
<Point x="6.6" y="5.6"/>
|
||||
</transformationPoint>
|
||||
</DOMSymbolInstance>
|
||||
<DOMSymbolInstance libraryItemName="ButtonDown" name="btnSpeedDown" symbolType="button">
|
||||
<matrix>
|
||||
<Matrix tx="450" ty="26"/>
|
||||
</matrix>
|
||||
<transformationPoint>
|
||||
<Point x="6.6" y="5.6"/>
|
||||
</transformationPoint>
|
||||
</DOMSymbolInstance>
|
||||
</elements>
|
||||
</DOMFrame>
|
||||
</frames>
|
||||
@@ -134,6 +183,8 @@ butReset.addEventListener(MouseEvent.CLICK, onReset);]]></script>
|
||||
</timelines>
|
||||
<PrinterSettings/>
|
||||
<publishHistory>
|
||||
<PublishItem publishSize="9791" publishTime="1771699753"/>
|
||||
<PublishItem publishSize="10087" publishTime="1771695966" publishDebug="true"/>
|
||||
<PublishItem publishSize="9267" publishTime="1771270767"/>
|
||||
<PublishItem publishSize="9269" publishTime="1771270237"/>
|
||||
<PublishItem publishSize="9215" publishTime="1771270105"/>
|
||||
@@ -152,7 +203,5 @@ butReset.addEventListener(MouseEvent.CLICK, onReset);]]></script>
|
||||
<PublishItem publishSize="7221" publishTime="1771267633" publishDebug="true"/>
|
||||
<PublishItem publishSize="7221" publishTime="1771267610" publishDebug="true"/>
|
||||
<PublishItem publishSize="7223" publishTime="1771267567" publishDebug="true"/>
|
||||
<PublishItem publishSize="7203" publishTime="1771267511" publishDebug="true"/>
|
||||
<PublishItem publishSize="7172" publishTime="1771267431" publishDebug="true"/>
|
||||
</publishHistory>
|
||||
</DOMDocument>
|
||||
90
libsrc/ffdec_lib/testdata/debug_game/as3_scoring/LIBRARY/ButtonDown.xml
vendored
Normal file
90
libsrc/ffdec_lib/testdata/debug_game/as3_scoring/LIBRARY/ButtonDown.xml
vendored
Normal file
@@ -0,0 +1,90 @@
|
||||
<DOMSymbolItem xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://ns.adobe.com/xfl/2008/" name="ButtonDown" itemID="6999ec93-000001e6" symbolType="button" lastModified="1771695532">
|
||||
<timeline>
|
||||
<DOMTimeline name="ButtonDown" currentFrame="2">
|
||||
<layers>
|
||||
<DOMLayer name="Layer 1" color="#4FFF4F" current="true" isSelected="true">
|
||||
<frames>
|
||||
<DOMFrame index="0" keyMode="9728">
|
||||
<elements>
|
||||
<DOMShape>
|
||||
<fills>
|
||||
<FillStyle index="1">
|
||||
<SolidColor color="#0099FF"/>
|
||||
</FillStyle>
|
||||
</fills>
|
||||
<strokes>
|
||||
<StrokeStyle index="1">
|
||||
<SolidStroke scaleMode="normal">
|
||||
<fill>
|
||||
<SolidColor/>
|
||||
</fill>
|
||||
</SolidStroke>
|
||||
</StrokeStyle>
|
||||
</strokes>
|
||||
<edges>
|
||||
<Edge fillStyle0="1" strokeStyle="1" edges="!135 225S5|265 0!265 0|0 0!0 0|135 225"/>
|
||||
<Edge cubics="!265 0(;265,0 0,0 0,0q265 0 0 0);"/>
|
||||
<Edge cubics="!0 0(;0,0 135,225 135,225q0 0 135 225);"/>
|
||||
<Edge cubics="!135 225(;135,225 265,0 265,0q135 225 265 0);"/>
|
||||
</edges>
|
||||
</DOMShape>
|
||||
</elements>
|
||||
</DOMFrame>
|
||||
<DOMFrame index="1" keyMode="9728">
|
||||
<elements>
|
||||
<DOMShape>
|
||||
<fills>
|
||||
<FillStyle index="1">
|
||||
<SolidColor color="#00FFFF"/>
|
||||
</FillStyle>
|
||||
</fills>
|
||||
<strokes>
|
||||
<StrokeStyle index="1">
|
||||
<SolidStroke scaleMode="normal">
|
||||
<fill>
|
||||
<SolidColor/>
|
||||
</fill>
|
||||
</SolidStroke>
|
||||
</StrokeStyle>
|
||||
</strokes>
|
||||
<edges>
|
||||
<Edge fillStyle0="1" strokeStyle="1" edges="!265 0|0 0!0 0|135 225!135 225|265 0"/>
|
||||
<Edge cubics="!265 0(;265,0 0,0 0,0q265 0 0 0);"/>
|
||||
<Edge cubics="!0 0(;0,0 135,225 135,225q0 0 135 225);"/>
|
||||
<Edge cubics="!135 225(;135,225 265,0 265,0q135 225 265 0);"/>
|
||||
</edges>
|
||||
</DOMShape>
|
||||
</elements>
|
||||
</DOMFrame>
|
||||
<DOMFrame index="2" keyMode="9728">
|
||||
<elements>
|
||||
<DOMShape>
|
||||
<fills>
|
||||
<FillStyle index="1">
|
||||
<SolidColor color="#0000FF"/>
|
||||
</FillStyle>
|
||||
</fills>
|
||||
<strokes>
|
||||
<StrokeStyle index="1">
|
||||
<SolidStroke scaleMode="normal">
|
||||
<fill>
|
||||
<SolidColor/>
|
||||
</fill>
|
||||
</SolidStroke>
|
||||
</StrokeStyle>
|
||||
</strokes>
|
||||
<edges>
|
||||
<Edge fillStyle0="1" strokeStyle="1" edges="!265 0|0 0!0 0|135 225!135 225|265 0"/>
|
||||
<Edge cubics="!265 0(;265,0 0,0 0,0q265 0 0 0);"/>
|
||||
<Edge cubics="!0 0(;0,0 135,225 135,225q0 0 135 225);"/>
|
||||
<Edge cubics="!135 225(;135,225 265,0 265,0q135 225 265 0);"/>
|
||||
</edges>
|
||||
</DOMShape>
|
||||
</elements>
|
||||
</DOMFrame>
|
||||
</frames>
|
||||
</DOMLayer>
|
||||
</layers>
|
||||
</DOMTimeline>
|
||||
</timeline>
|
||||
</DOMSymbolItem>
|
||||
90
libsrc/ffdec_lib/testdata/debug_game/as3_scoring/LIBRARY/ButtonUp.xml
vendored
Normal file
90
libsrc/ffdec_lib/testdata/debug_game/as3_scoring/LIBRARY/ButtonUp.xml
vendored
Normal file
@@ -0,0 +1,90 @@
|
||||
<DOMSymbolItem xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://ns.adobe.com/xfl/2008/" name="ButtonUp" itemID="6999ec8b-000001e1" symbolType="button" lastModified="1771695510">
|
||||
<timeline>
|
||||
<DOMTimeline name="ButtonUp" currentFrame="2">
|
||||
<layers>
|
||||
<DOMLayer name="Layer 1" color="#4FFF4F" current="true" isSelected="true">
|
||||
<frames>
|
||||
<DOMFrame index="0" keyMode="9728">
|
||||
<elements>
|
||||
<DOMShape>
|
||||
<fills>
|
||||
<FillStyle index="1">
|
||||
<SolidColor color="#0099FF"/>
|
||||
</FillStyle>
|
||||
</fills>
|
||||
<strokes>
|
||||
<StrokeStyle index="1">
|
||||
<SolidStroke scaleMode="normal">
|
||||
<fill>
|
||||
<SolidColor/>
|
||||
</fill>
|
||||
</SolidStroke>
|
||||
</StrokeStyle>
|
||||
</strokes>
|
||||
<edges>
|
||||
<Edge fillStyle0="1" strokeStyle="1" edges="!130 0S5|0 225!0 225|265 225!265 225|130 0"/>
|
||||
<Edge cubics="!0 225(;0,225 265,225 265,225q0 225 265 225);"/>
|
||||
<Edge cubics="!265 225(;265,225 130,0 130,0q265 225 130 0);"/>
|
||||
<Edge cubics="!130 0(;130,0 0,225 0,225q130 0 0 225);"/>
|
||||
</edges>
|
||||
</DOMShape>
|
||||
</elements>
|
||||
</DOMFrame>
|
||||
<DOMFrame index="1" keyMode="9728">
|
||||
<elements>
|
||||
<DOMShape>
|
||||
<fills>
|
||||
<FillStyle index="1">
|
||||
<SolidColor color="#00FFFF"/>
|
||||
</FillStyle>
|
||||
</fills>
|
||||
<strokes>
|
||||
<StrokeStyle index="1">
|
||||
<SolidStroke scaleMode="normal">
|
||||
<fill>
|
||||
<SolidColor/>
|
||||
</fill>
|
||||
</SolidStroke>
|
||||
</StrokeStyle>
|
||||
</strokes>
|
||||
<edges>
|
||||
<Edge fillStyle0="1" strokeStyle="1" edges="!0 225|265 225!265 225|130 0!130 0|0 225"/>
|
||||
<Edge cubics="!0 225(;0,225 265,225 265,225q0 225 265 225);"/>
|
||||
<Edge cubics="!265 225(;265,225 130,0 130,0q265 225 130 0);"/>
|
||||
<Edge cubics="!130 0(;130,0 0,225 0,225q130 0 0 225);"/>
|
||||
</edges>
|
||||
</DOMShape>
|
||||
</elements>
|
||||
</DOMFrame>
|
||||
<DOMFrame index="2" keyMode="9728">
|
||||
<elements>
|
||||
<DOMShape>
|
||||
<fills>
|
||||
<FillStyle index="1">
|
||||
<SolidColor color="#0000FF"/>
|
||||
</FillStyle>
|
||||
</fills>
|
||||
<strokes>
|
||||
<StrokeStyle index="1">
|
||||
<SolidStroke scaleMode="normal">
|
||||
<fill>
|
||||
<SolidColor/>
|
||||
</fill>
|
||||
</SolidStroke>
|
||||
</StrokeStyle>
|
||||
</strokes>
|
||||
<edges>
|
||||
<Edge fillStyle0="1" strokeStyle="1" edges="!265 225|130 0!130 0|0 225!0 225|265 225"/>
|
||||
<Edge cubics="!0 225(;0,225 265,225 265,225q0 225 265 225);"/>
|
||||
<Edge cubics="!265 225(;265,225 130,0 130,0q265 225 130 0);"/>
|
||||
<Edge cubics="!130 0(;130,0 0,225 0,225q130 0 0 225);"/>
|
||||
</edges>
|
||||
</DOMShape>
|
||||
</elements>
|
||||
</DOMFrame>
|
||||
</frames>
|
||||
</DOMLayer>
|
||||
</layers>
|
||||
</DOMTimeline>
|
||||
</timeline>
|
||||
</DOMSymbolItem>
|
||||
@@ -5,8 +5,8 @@
|
||||
xmlns:xmp="http://ns.adobe.com/xap/1.0/">
|
||||
<xmp:CreatorTool>Adobe Flash Professional CS6 - build 481</xmp:CreatorTool>
|
||||
<xmp:CreateDate>2026-02-16T10:31:42-08:00</xmp:CreateDate>
|
||||
<xmp:MetadataDate>2026-02-16T11:18:44-08:00</xmp:MetadataDate>
|
||||
<xmp:ModifyDate>2026-02-16T11:18:44-08:00</xmp:ModifyDate>
|
||||
<xmp:MetadataDate>2026-02-21T09:45:46-08:00</xmp:MetadataDate>
|
||||
<xmp:ModifyDate>2026-02-21T09:45:46-08:00</xmp:ModifyDate>
|
||||
</rdf:Description>
|
||||
<rdf:Description rdf:about=""
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/">
|
||||
@@ -22,7 +22,7 @@
|
||||
<stRef:originalDocumentID>xmp.did:7FE581FA660BF11197008EF33C376745</stRef:originalDocumentID>
|
||||
</xmpMM:DerivedFrom>
|
||||
<xmpMM:DocumentID>xmp.did:EDF1CDD4690BF11197008EF33C376745</xmpMM:DocumentID>
|
||||
<xmpMM:InstanceID>xmp.iid:9DDF39F36B0BF11197008EF33C376745</xmpMM:InstanceID>
|
||||
<xmpMM:InstanceID>xmp.iid:3B7DE8AB4B0FF111A0D3B09FD2F43FD4</xmpMM:InstanceID>
|
||||
<xmpMM:OriginalDocumentID>xmp.did:7FE581FA660BF11197008EF33C376745</xmpMM:OriginalDocumentID>
|
||||
<xmpMM:History>
|
||||
<rdf:Seq>
|
||||
@@ -45,6 +45,12 @@
|
||||
<stEvt:when>2026-02-16T10:31:42-08:00</stEvt:when>
|
||||
<stEvt:softwareAgent>Adobe Flash Professional CS6 - build 481</stEvt:softwareAgent>
|
||||
</rdf:li>
|
||||
<rdf:li rdf:parseType="Resource">
|
||||
<stEvt:action>created</stEvt:action>
|
||||
<stEvt:instanceID>xmp.iid:3B7DE8AB4B0FF111A0D3B09FD2F43FD4</stEvt:instanceID>
|
||||
<stEvt:when>2026-02-16T10:31:42-08:00</stEvt:when>
|
||||
<stEvt:softwareAgent>Adobe Flash Professional CS6 - build 481</stEvt:softwareAgent>
|
||||
</rdf:li>
|
||||
</rdf:Seq>
|
||||
</xmpMM:History>
|
||||
</rdf:Description>
|
||||
|
||||
Binary file not shown.
@@ -16,6 +16,8 @@
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.gui;
|
||||
|
||||
import com.jpexs.debugger.flash.Debugger;
|
||||
import com.jpexs.debugger.flash.DebuggerCommands;
|
||||
import com.jpexs.debugger.flash.Variable;
|
||||
import com.jpexs.debugger.flash.messages.in.InConstantPool;
|
||||
import com.jpexs.debugger.flash.messages.in.InFrame;
|
||||
@@ -70,7 +72,9 @@ public class DebugPanel extends JPanel {
|
||||
|
||||
private MyTreeTable debugRegistersTable;
|
||||
|
||||
private MyTreeTable debugLocalsTable; //JTable debugLocalsTable;
|
||||
private MyTreeTable debugLocalsTable;
|
||||
|
||||
private MyTreeTable debugWatchesTable;
|
||||
|
||||
private MyTreeTable debugScopeTable;
|
||||
|
||||
@@ -91,14 +95,14 @@ public class DebugPanel extends JPanel {
|
||||
private boolean loading = false;
|
||||
|
||||
public ABCPanel.VariablesTableModel localsTable;
|
||||
|
||||
|
||||
private WeakReference<DebuggerSession> currentSessionRef = null;
|
||||
|
||||
private boolean as3;
|
||||
|
||||
|
||||
public static enum SelectedTab {
|
||||
|
||||
LOG, STACK, SCOPECHAIN, LOCALS, REGISTERS, CALLSTACK, CONSTANTPOOL
|
||||
LOG, STACK, SCOPECHAIN, LOCALS, WATCHES, REGISTERS, CALLSTACK, CONSTANTPOOL
|
||||
}
|
||||
|
||||
public synchronized boolean isLoading() {
|
||||
@@ -107,6 +111,7 @@ public class DebugPanel extends JPanel {
|
||||
|
||||
public synchronized void setLoading(boolean loading) {
|
||||
this.loading = loading;
|
||||
//varTabs.setVisible(!loading);
|
||||
}
|
||||
|
||||
private SelectedTab selectedTab = null;
|
||||
@@ -157,15 +162,16 @@ public class DebugPanel extends JPanel {
|
||||
//ignore
|
||||
}
|
||||
if (wasEmpty) {
|
||||
refresh(session);
|
||||
refresh();
|
||||
}
|
||||
}
|
||||
|
||||
public DebugPanel(boolean as3) {
|
||||
super(new BorderLayout());
|
||||
this.as3 = as3;
|
||||
debugRegistersTable = new MyTreeTable(new ABCPanel.VariablesTableModel(as3, debugRegistersTable, new ArrayList<>()), false);
|
||||
debugLocalsTable = new MyTreeTable(new ABCPanel.VariablesTableModel(as3, debugLocalsTable, new ArrayList<>()), false);
|
||||
debugRegistersTable = new MyTreeTable(new ABCPanel.VariablesTableModel(null, as3, debugRegistersTable, new ArrayList<>(), new ArrayList<>()), false);
|
||||
debugLocalsTable = new MyTreeTable(new ABCPanel.VariablesTableModel(null, as3, debugLocalsTable, new ArrayList<>(), new ArrayList<>()), false);
|
||||
debugWatchesTable = new MyTreeTable(new ABCPanel.VariablesTableModel(null, as3, debugWatchesTable, new ArrayList<>(), new ArrayList<>()), false);
|
||||
|
||||
MouseAdapter watchHandler = new MouseAdapter() {
|
||||
|
||||
@@ -184,7 +190,7 @@ public class DebugPanel extends JPanel {
|
||||
}
|
||||
|
||||
private void dopop(MouseEvent e) {
|
||||
|
||||
|
||||
if (currentSessionRef == null) {
|
||||
return;
|
||||
}
|
||||
@@ -192,11 +198,13 @@ public class DebugPanel extends JPanel {
|
||||
if (session == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (debugLocalsTable.getSelectedRow() == -1) {
|
||||
|
||||
MyTreeTable src = (MyTreeTable) e.getSource();
|
||||
|
||||
if (src.getSelectedRow() == -1) {
|
||||
return;
|
||||
}
|
||||
Object node = debugLocalsTable.getTree().getPathForRow(debugLocalsTable.getSelectedRow()).getLastPathComponent();
|
||||
Object node = src.getTree().getPathForRow(src.getSelectedRow()).getLastPathComponent();
|
||||
Variable v;
|
||||
ABCPanel.VariableNode vn;
|
||||
if (node instanceof ABCPanel.VariableNode) {
|
||||
@@ -261,7 +269,7 @@ public class DebugPanel extends JPanel {
|
||||
if (igv == null) {
|
||||
return;
|
||||
}
|
||||
Variable debugConnectionClass = igv.parent;
|
||||
Variable debugConnectionClass = igv.parent;
|
||||
String dataStr = (String) session.callMethod(debugConnectionClass, "readCommaSeparatedFromByteArray", Arrays.asList(v)).variables.get(0).value;
|
||||
String[] parts = dataStr.split(",");
|
||||
byte[] data = new byte[parts.length];
|
||||
@@ -356,35 +364,63 @@ public class DebugPanel extends JPanel {
|
||||
watchReadMenuItem.addActionListener((ActionEvent e1) -> {
|
||||
if (!Main.addWatch(session, v, watchParentId, true, false)) {
|
||||
ViewMessages.showMessageDialog(DebugPanel.this, AppStrings.translate("error.debug.watch.add"), AppStrings.translate("error"), JOptionPane.ERROR_MESSAGE);
|
||||
return;
|
||||
}
|
||||
refresh();
|
||||
});
|
||||
JMenuItem watchWriteMenuItem = new JMenuItem(AppStrings.translate("debug.watch.add.write"));
|
||||
watchWriteMenuItem.addActionListener((ActionEvent e1) -> {
|
||||
if (!Main.addWatch(session, v, watchParentId, false, true)) {
|
||||
ViewMessages.showMessageDialog(DebugPanel.this, AppStrings.translate("error.debug.watch.add"), AppStrings.translate("error"), JOptionPane.ERROR_MESSAGE);
|
||||
return;
|
||||
}
|
||||
refresh();
|
||||
});
|
||||
JMenuItem watchReadWriteMenuItem = new JMenuItem(AppStrings.translate("debug.watch.add.readwrite"));
|
||||
watchReadWriteMenuItem.addActionListener((ActionEvent e1) -> {
|
||||
if (!Main.addWatch(session, v, watchParentId, true, true)) {
|
||||
ViewMessages.showMessageDialog(DebugPanel.this, AppStrings.translate("error.debug.watch.add"), AppStrings.translate("error"), JOptionPane.ERROR_MESSAGE);
|
||||
return;
|
||||
}
|
||||
refresh();
|
||||
});
|
||||
|
||||
addWatchMenu.add(watchReadMenuItem);
|
||||
addWatchMenu.add(watchWriteMenuItem);
|
||||
addWatchMenu.add(watchReadWriteMenuItem);
|
||||
pm.add(addWatchMenu);
|
||||
|
||||
JMenuItem removeWatcheMenuItem = new JMenuItem(AppStrings.translate("debug.watch.remove"));
|
||||
removeWatcheMenuItem.addActionListener((ActionEvent e1) -> {
|
||||
if (!Main.removeWatch(session, v, watchParentId)) {
|
||||
ViewMessages.showMessageDialog(DebugPanel.this, AppStrings.translate("error.debug.watch.remove"), AppStrings.translate("error"), JOptionPane.ERROR_MESSAGE);
|
||||
return;
|
||||
}
|
||||
refresh();
|
||||
});
|
||||
if (session.getWatch(v.name, watchParentId) != null) {
|
||||
pm.add(removeWatcheMenuItem);
|
||||
}
|
||||
pm.show(e.getComponent(), e.getX(), e.getY());
|
||||
}
|
||||
};
|
||||
|
||||
debugLocalsTable.addMouseListener(watchHandler);
|
||||
debugWatchesTable.addMouseListener(watchHandler);
|
||||
|
||||
//debugScopeTable.addMouseListener(watchHandler);
|
||||
debugScopeTable = new MyTreeTable(new ABCPanel.VariablesTableModel(as3, debugScopeTable, new ArrayList<>()), false);
|
||||
debugScopeTable = new MyTreeTable(new ABCPanel.VariablesTableModel(null, as3, debugScopeTable, new ArrayList<>(), new ArrayList<>()), false);
|
||||
|
||||
constantPoolTable = new JTable();
|
||||
constantPoolTable = new JTable(new DefaultTableModel(new Object[2][0], new Object[]{
|
||||
AppStrings.translate("constantpool.header.id"),
|
||||
AppStrings.translate("constantpool.header.value")
|
||||
}) {
|
||||
@Override
|
||||
public boolean isCellEditable(int row, int column) {
|
||||
return false;
|
||||
}
|
||||
|
||||
});
|
||||
traceLogTextarea = new JTextArea();
|
||||
traceLogTextarea.setEditable(false);
|
||||
traceLogTextarea.setOpaque(false);
|
||||
@@ -408,7 +444,7 @@ public class DebugPanel extends JPanel {
|
||||
public void errorException(DebuggerSession session, String message, Variable thrownVar) {
|
||||
logAdd(session, "unhandled exception: " + message);
|
||||
selectedTab = tabTypes.get(tabTypes.size() - 1);
|
||||
refresh(session);
|
||||
refresh();
|
||||
}
|
||||
});
|
||||
|
||||
@@ -420,19 +456,26 @@ public class DebugPanel extends JPanel {
|
||||
|
||||
@Override
|
||||
public void disconnected(DebuggerSession session) {
|
||||
refresh(session);
|
||||
refresh();
|
||||
}
|
||||
});
|
||||
|
||||
Main.getDebugHandler().addSelectionListener(new DebuggerHandler.SessionSelectionListener() {
|
||||
@Override
|
||||
public void sessionSelected(DebuggerSession newSession, int oldSessionId) {
|
||||
refresh();
|
||||
}
|
||||
});
|
||||
|
||||
Main.getDebugHandler().addFrameChangeListener(frameChangeListener = new DebuggerHandler.FrameChangeListener() {
|
||||
@Override
|
||||
public void frameChanged(DebuggerSession session) {
|
||||
View.execInEventDispatchLater(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
refresh(session);
|
||||
}
|
||||
});
|
||||
/*DebuggerSession currentSession = Main.getCurrentDebugSession();
|
||||
if (session != currentSession) {
|
||||
return;
|
||||
} */
|
||||
|
||||
refresh();
|
||||
}
|
||||
});
|
||||
|
||||
@@ -440,22 +483,18 @@ public class DebugPanel extends JPanel {
|
||||
|
||||
@Override
|
||||
public void doContinue(DebuggerSession session) {
|
||||
View.execInEventDispatch(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
refresh(Main.getCurrentDebugSession());
|
||||
}
|
||||
});
|
||||
refresh();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void breakAt(DebuggerSession session, String scriptName, int line, int classIndex, int traitIndex, int methodIndex) {
|
||||
View.execInEventDispatch(new Runnable() {
|
||||
/*View.execInEventDispatch(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
refresh(Main.getCurrentDebugSession());
|
||||
}
|
||||
});
|
||||
});*/
|
||||
//reacts to frameChanged instead
|
||||
}
|
||||
});
|
||||
|
||||
@@ -479,7 +518,7 @@ public class DebugPanel extends JPanel {
|
||||
});
|
||||
|
||||
add(new HeaderLabel(AppStrings.translate("debugpanel.header")), BorderLayout.NORTH);
|
||||
add(varTabs, BorderLayout.CENTER);
|
||||
add(varTabs, BorderLayout.CENTER);
|
||||
}
|
||||
|
||||
/* private void getVariableList() {
|
||||
@@ -509,190 +548,269 @@ public class DebugPanel extends JPanel {
|
||||
}
|
||||
return v.getMembers(this);
|
||||
}*/
|
||||
public void refresh(DebuggerSession session) {
|
||||
|
||||
if (session != null && !session.isPaused()) {
|
||||
return;
|
||||
private final Object refreshLock = new Object();
|
||||
|
||||
public void refresh() {
|
||||
DebuggerSession session = Main.getCurrentDebugSession();
|
||||
|
||||
if (session != null) {
|
||||
SWF swf = session.getCurrentSwf();
|
||||
if (swf != null) {
|
||||
if (swf.isAS3() != as3) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
currentSessionRef = session == null ? null : new WeakReference<>(session);
|
||||
View.execInEventDispatch(new Runnable() {
|
||||
Runnable r = new Runnable() {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
if (session != null && !session.isPaused()) {
|
||||
return;
|
||||
}
|
||||
setLoading(true);
|
||||
synchronized (DebugPanel.this) {
|
||||
synchronized (refreshLock) {
|
||||
try {
|
||||
setLoading(true);
|
||||
|
||||
SelectedTab oldSel = selectedTab;
|
||||
localsTable = null;
|
||||
InFrame f = session == null ? null : session.getFrame();
|
||||
if (f != null) {
|
||||
|
||||
|
||||
List<Variable> locals = new ArrayList<>();
|
||||
|
||||
|
||||
Map<String, Long> placedObjects = session.getPlacedObjects();
|
||||
for (String poName : placedObjects.keySet()) {
|
||||
String realName = poName;
|
||||
if ("/".equals(realName)) {
|
||||
realName = "_root";
|
||||
} else if (realName.startsWith("/")) {
|
||||
continue;
|
||||
}
|
||||
InGetVariable igv = session.getVariable(0, realName, false, false);
|
||||
if (igv != null) {
|
||||
Variable placedVar = igv.parent;
|
||||
if (placedVar != null) {
|
||||
locals.add(placedVar);
|
||||
int sessionId = -1;
|
||||
|
||||
if (session != null) {
|
||||
sessionId = session.getId();
|
||||
ABCPanel.VariableNode.stopLoading(sessionId); //stop any previous loading
|
||||
}
|
||||
|
||||
Logger.getLogger(DebugPanel.class.getName()).log(Level.FINE, "session{0}: Refreshing debug panel", new Object[]{sessionId});
|
||||
|
||||
localsTable = null;
|
||||
InFrame f = session == null ? null : session.getFrame();
|
||||
|
||||
ABCPanel.VariablesTableModel registersTableModel = new ABCPanel.VariablesTableModel(session, as3, debugRegistersTable, new ArrayList<>(), new ArrayList<>());
|
||||
ABCPanel.VariablesTableModel localsTableModel = new ABCPanel.VariablesTableModel(session, as3, debugLocalsTable, new ArrayList<>(), new ArrayList<>());
|
||||
ABCPanel.VariablesTableModel scopeTableModel = new ABCPanel.VariablesTableModel(session, as3, debugScopeTable, new ArrayList<>(), new ArrayList<>());
|
||||
ABCPanel.VariablesTableModel watchesTableModel = new ABCPanel.VariablesTableModel(session, as3, debugWatchesTable, new ArrayList<>(), new ArrayList<>());
|
||||
ABCPanel.VariablesTableModel fRegistersTableModel;
|
||||
ABCPanel.VariablesTableModel fLocalsTableModel;
|
||||
ABCPanel.VariablesTableModel fScopeTableModel;
|
||||
ABCPanel.VariablesTableModel fWatchesTableModel;
|
||||
Object[][] fCpoolData;
|
||||
|
||||
if (f != null) {
|
||||
|
||||
Logger.getLogger(DebugPanel.class.getName()).log(Level.FINE, "session{0}: Debug panel - has frame", new Object[]{sessionId});
|
||||
|
||||
List<Variable> locals = new ArrayList<>();
|
||||
|
||||
Map<String, Long> placedObjects = session.getPlacedObjects();
|
||||
for (String poName : placedObjects.keySet()) {
|
||||
String realName = poName;
|
||||
if ("/".equals(realName)) {
|
||||
realName = "_root";
|
||||
} else if (realName.startsWith("/")) {
|
||||
continue;
|
||||
}
|
||||
Logger.getLogger(DebugPanel.class.getName()).log(Level.FINE, "session{0}: Getting placedObject {1}", new Object[]{sessionId, realName});
|
||||
InGetVariable igv = session.getVariable(0, realName, false, false);
|
||||
if (igv != null) {
|
||||
Variable placedVar = igv.parent;
|
||||
if (placedVar != null) {
|
||||
locals.add(placedVar);
|
||||
}
|
||||
} else {
|
||||
Logger.getLogger(DebugPanel.class.getName()).log(Level.FINE, "session{0}: Cannot get placedObject {1}", new Object[]{sessionId, realName});
|
||||
}
|
||||
}
|
||||
|
||||
locals.addAll(f.arguments);
|
||||
locals.addAll(f.variables);
|
||||
|
||||
localsTable = new ABCPanel.VariablesTableModel(session, as3, debugLocalsTable, locals, null);
|
||||
|
||||
List<Variable> watchedVars = new ArrayList<>();
|
||||
List<Long> watchedParentIds = new ArrayList<>();
|
||||
for (DebuggerCommands.Watch w : session.getWatches().values()) {
|
||||
InGetVariable igv = session.getVariable(w.varId, w.varName, false, false);
|
||||
if (igv != null) {
|
||||
Variable wVar = igv.parent;
|
||||
if (wVar != null) {
|
||||
watchedVars.add(wVar);
|
||||
watchedParentIds.add(w.varId);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TreeModelListener refreshListener = new TreeModelListener() {
|
||||
@Override
|
||||
public void treeNodesChanged(TreeModelEvent e) {
|
||||
synchronized (DebugPanel.this) {
|
||||
if (loading) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
session.refreshFrame();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void treeNodesInserted(TreeModelEvent e) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void treeNodesRemoved(TreeModelEvent e) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void treeStructureChanged(TreeModelEvent e) {
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
registersTableModel = new ABCPanel.VariablesTableModel(session, as3, debugRegistersTable, f.registers, null);
|
||||
localsTableModel = localsTable;
|
||||
scopeTableModel = new ABCPanel.VariablesTableModel(session, as3, debugScopeTable, f.scopeChain, null);
|
||||
watchesTableModel = new ABCPanel.VariablesTableModel(session, as3, debugWatchesTable, watchedVars, watchedParentIds);
|
||||
|
||||
localsTableModel.addTreeModelListener(refreshListener);
|
||||
scopeTableModel.addTreeModelListener(refreshListener);
|
||||
watchesTableModel.addTreeModelListener(refreshListener);
|
||||
}
|
||||
|
||||
safeSetTreeModel(debugRegistersTable, new ABCPanel.VariablesTableModel(as3, debugRegistersTable, f.registers));
|
||||
|
||||
locals.addAll(f.arguments);
|
||||
locals.addAll(f.variables);
|
||||
|
||||
localsTable = new ABCPanel.VariablesTableModel(as3, debugLocalsTable, locals);
|
||||
safeSetTreeModel(debugLocalsTable, localsTable);
|
||||
safeSetTreeModel(debugScopeTable, new ABCPanel.VariablesTableModel(as3, debugScopeTable, f.scopeChain));
|
||||
|
||||
/*TableModelListener refreshListener = new TableModelListener() {
|
||||
@Override
|
||||
public void tableChanged(TableModelEvent e) {
|
||||
Main.getDebugHandler().refreshFrame();
|
||||
refresh();
|
||||
}
|
||||
};*/
|
||||
TreeModelListener refreshListener = new TreeModelListener() {
|
||||
@Override
|
||||
public void treeNodesChanged(TreeModelEvent e) {
|
||||
session.refreshFrame();
|
||||
refresh(session);
|
||||
InConstantPool cpool = session == null ? null : session.getConstantPool();
|
||||
Object[][] cpoolData = new Object[0][2];
|
||||
if (cpool != null) {
|
||||
cpoolData = new Object[cpool.vars.size()][2];
|
||||
for (int i = 0; i < cpool.vars.size(); i++) {
|
||||
cpoolData[i][0] = cpool.ids.get(i);
|
||||
cpoolData[i][1] = cpool.vars.get(i).value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void treeNodesInserted(TreeModelEvent e) {
|
||||
session.refreshFrame();
|
||||
refresh(session);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void treeNodesRemoved(TreeModelEvent e) {
|
||||
session.refreshFrame();
|
||||
refresh(session);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void treeStructureChanged(TreeModelEvent e) {
|
||||
session.refreshFrame();
|
||||
refresh(session);
|
||||
}
|
||||
};
|
||||
debugLocalsTable.getTreeTableModel().addTreeModelListener(refreshListener);
|
||||
debugScopeTable.getTreeTableModel().addTreeModelListener(refreshListener);
|
||||
} else {
|
||||
debugRegistersTable.setTreeModel(new ABCPanel.VariablesTableModel(as3, debugRegistersTable, new ArrayList<>()));
|
||||
debugLocalsTable.setTreeModel(new ABCPanel.VariablesTableModel(as3, debugLocalsTable, new ArrayList<>()));
|
||||
debugScopeTable.setTreeModel(new ABCPanel.VariablesTableModel(as3, debugScopeTable, new ArrayList<>()));
|
||||
}
|
||||
InConstantPool cpool = session == null ? null : session.getConstantPool();
|
||||
if (cpool != null) {
|
||||
Object[][] data2 = new Object[cpool.vars.size()][2];
|
||||
for (int i = 0; i < cpool.vars.size(); i++) {
|
||||
data2[i][0] = cpool.ids.get(i);
|
||||
data2[i][1] = cpool.vars.get(i).value;
|
||||
}
|
||||
constantPoolTable.setModel(new DefaultTableModel(data2, new Object[]{
|
||||
AppStrings.translate("constantpool.header.id"),
|
||||
AppStrings.translate("constantpool.header.value")
|
||||
}) {
|
||||
|
||||
fRegistersTableModel = registersTableModel;
|
||||
fLocalsTableModel = localsTableModel;
|
||||
fScopeTableModel = scopeTableModel;
|
||||
fWatchesTableModel = watchesTableModel;
|
||||
fCpoolData = cpoolData;
|
||||
|
||||
View.execInEventDispatch(new Runnable() {
|
||||
@Override
|
||||
public boolean isCellEditable(int row, int column) {
|
||||
return false;
|
||||
}
|
||||
public void run() {
|
||||
try {
|
||||
if (f != null) {
|
||||
safeSetTreeModel(debugRegistersTable, fRegistersTableModel);
|
||||
safeSetTreeModel(debugLocalsTable, fLocalsTableModel);
|
||||
safeSetTreeModel(debugScopeTable, fScopeTableModel);
|
||||
safeSetTreeModel(debugWatchesTable, fWatchesTableModel);
|
||||
} else {
|
||||
debugRegistersTable.setTreeModel(fRegistersTableModel);
|
||||
debugLocalsTable.setTreeModel(fLocalsTableModel);
|
||||
debugScopeTable.setTreeModel(fScopeTableModel);
|
||||
debugWatchesTable.setTreeModel(fWatchesTableModel);
|
||||
}
|
||||
|
||||
});
|
||||
} else {
|
||||
constantPoolTable.setModel(new DefaultTableModel());
|
||||
}
|
||||
constantPoolTable.setModel(new DefaultTableModel(fCpoolData, new Object[]{
|
||||
AppStrings.translate("constantpool.header.id"),
|
||||
AppStrings.translate("constantpool.header.value")
|
||||
}) {
|
||||
@Override
|
||||
public boolean isCellEditable(int row, int column) {
|
||||
return false;
|
||||
}
|
||||
|
||||
varTabs.removeAll();
|
||||
tabTypes.clear();
|
||||
JPanel pa;
|
||||
if (debugRegistersTable.getRowCount() > 0) {
|
||||
tabTypes.add(SelectedTab.REGISTERS);
|
||||
pa = new JPanel(new BorderLayout());
|
||||
pa.add(new FasterScrollPane(debugRegistersTable), BorderLayout.CENTER);
|
||||
varTabs.addTab(AppStrings.translate("variables.header.registers"), pa);
|
||||
}
|
||||
if (debugLocalsTable.getRowCount() > 0) {
|
||||
tabTypes.add(SelectedTab.LOCALS);
|
||||
});
|
||||
|
||||
pa = new JPanel(new BorderLayout());
|
||||
pa.add(new FasterScrollPane(debugLocalsTable), BorderLayout.CENTER);
|
||||
varTabs.addTab(AppStrings.translate("variables.header.locals"), pa);
|
||||
}
|
||||
varTabs.removeAll();
|
||||
tabTypes.clear();
|
||||
JPanel pa;
|
||||
if (debugRegistersTable.getRowCount() > 0) {
|
||||
tabTypes.add(SelectedTab.REGISTERS);
|
||||
pa = new JPanel(new BorderLayout());
|
||||
pa.add(new FasterScrollPane(debugRegistersTable), BorderLayout.CENTER);
|
||||
varTabs.addTab(AppStrings.translate("variables.header.registers"), pa);
|
||||
}
|
||||
if (debugLocalsTable.getRowCount() > 0) {
|
||||
tabTypes.add(SelectedTab.LOCALS);
|
||||
|
||||
if (debugScopeTable.getRowCount() > 0) {
|
||||
tabTypes.add(SelectedTab.SCOPECHAIN);
|
||||
pa = new JPanel(new BorderLayout());
|
||||
pa.add(new FasterScrollPane(debugLocalsTable), BorderLayout.CENTER);
|
||||
varTabs.addTab(AppStrings.translate("variables.header.locals"), pa);
|
||||
}
|
||||
|
||||
pa = new JPanel(new BorderLayout());
|
||||
pa.add(new FasterScrollPane(debugScopeTable), BorderLayout.CENTER);
|
||||
varTabs.addTab(AppStrings.translate("variables.header.scopeChain"), pa);
|
||||
}
|
||||
if (debugWatchesTable.getRowCount() > 0) {
|
||||
tabTypes.add(SelectedTab.WATCHES);
|
||||
|
||||
if (constantPoolTable.getRowCount() > 0) {
|
||||
tabTypes.add(SelectedTab.CONSTANTPOOL);
|
||||
pa = new JPanel(new BorderLayout());
|
||||
pa.add(new FasterScrollPane(debugWatchesTable), BorderLayout.CENTER);
|
||||
varTabs.addTab(AppStrings.translate("variables.header.watches"), pa);
|
||||
}
|
||||
|
||||
pa = new JPanel(new BorderLayout());
|
||||
pa.add(new FasterScrollPane(constantPoolTable), BorderLayout.CENTER);
|
||||
varTabs.addTab(AppStrings.translate("constantpool.header"), pa);
|
||||
}
|
||||
if (debugScopeTable.getRowCount() > 0) {
|
||||
tabTypes.add(SelectedTab.SCOPECHAIN);
|
||||
|
||||
if (logLength > 0) {
|
||||
tabTypes.add(SelectedTab.LOG);
|
||||
pa = new JPanel(new BorderLayout());
|
||||
pa.add(new FasterScrollPane(debugScopeTable), BorderLayout.CENTER);
|
||||
varTabs.addTab(AppStrings.translate("variables.header.scopeChain"), pa);
|
||||
}
|
||||
|
||||
pa = new JPanel(new BorderLayout());
|
||||
pa.add(new FasterScrollPane(traceLogTextarea), BorderLayout.CENTER);
|
||||
JButton clearButton = new JButton(AppStrings.translate("debuglog.button.clear"));
|
||||
clearButton.addActionListener(new ActionListener() {
|
||||
if (constantPoolTable.getRowCount() > 0) {
|
||||
tabTypes.add(SelectedTab.CONSTANTPOOL);
|
||||
|
||||
pa = new JPanel(new BorderLayout());
|
||||
pa.add(new FasterScrollPane(constantPoolTable), BorderLayout.CENTER);
|
||||
varTabs.addTab(AppStrings.translate("constantpool.header"), pa);
|
||||
}
|
||||
|
||||
if (logLength > 0) {
|
||||
tabTypes.add(SelectedTab.LOG);
|
||||
|
||||
pa = new JPanel(new BorderLayout());
|
||||
pa.add(new FasterScrollPane(traceLogTextarea), BorderLayout.CENTER);
|
||||
JButton clearButton = new JButton(AppStrings.translate("debuglog.button.clear"));
|
||||
clearButton.addActionListener(new ActionListener() {
|
||||
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
traceLogTextarea.setText("");
|
||||
logLength = 0;
|
||||
refresh();
|
||||
}
|
||||
});
|
||||
JPanel butPanel = new JPanel(new FlowLayout());
|
||||
butPanel.add(clearButton);
|
||||
pa.add(butPanel, BorderLayout.SOUTH);
|
||||
varTabs.addTab(AppStrings.translate("debuglog.header"), pa);
|
||||
}
|
||||
boolean newVisible = !tabTypes.isEmpty();
|
||||
if (newVisible != isVisible()) {
|
||||
setVisible(newVisible);
|
||||
}
|
||||
|
||||
SelectedTab oldSel = selectedTab;
|
||||
|
||||
if (!tabTypes.isEmpty()) {
|
||||
if (oldSel != null && !tabTypes.contains(oldSel)) {
|
||||
oldSel = null;
|
||||
}
|
||||
}
|
||||
if (oldSel != null) {
|
||||
selectedTab = oldSel;
|
||||
varTabs.setSelectedIndex(tabTypes.indexOf(selectedTab));
|
||||
}
|
||||
} catch (Throwable t) {
|
||||
int sessionId = session == null ? -1 : session.getId();
|
||||
Logger.getLogger(DebugPanel.class.getName()).log(Level.FINE, "session" + sessionId + ": Error refeshing debug panel in UI thread", t);
|
||||
}
|
||||
|
||||
setLoading(false);
|
||||
Logger.getLogger(DebugPanel.class.getName()).log(Level.FINE, "session{0}: Refreshed debug panel", new Object[]{session == null ? -1 : session.getId()});
|
||||
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
traceLogTextarea.setText("");
|
||||
logLength = 0;
|
||||
refresh(session);
|
||||
}
|
||||
});
|
||||
JPanel butPanel = new JPanel(new FlowLayout());
|
||||
butPanel.add(clearButton);
|
||||
pa.add(butPanel, BorderLayout.SOUTH);
|
||||
varTabs.addTab(AppStrings.translate("debuglog.header"), pa);
|
||||
} catch (Throwable t) {
|
||||
int sessionId = session == null ? -1 : session.getId();
|
||||
Logger.getLogger(DebugPanel.class.getName()).log(Level.FINE, "session" + sessionId + ": Error refeshing debug panel", t);
|
||||
}
|
||||
boolean newVisible = !tabTypes.isEmpty();
|
||||
if (newVisible != isVisible()) {
|
||||
setVisible(newVisible);
|
||||
}
|
||||
if (!tabTypes.isEmpty()) {
|
||||
if (oldSel != null && !tabTypes.contains(oldSel)) {
|
||||
oldSel = null;
|
||||
}
|
||||
}
|
||||
if (oldSel != null) {
|
||||
selectedTab = oldSel;
|
||||
varTabs.setSelectedIndex(tabTypes.indexOf(selectedTab));
|
||||
}
|
||||
setLoading(false);
|
||||
}
|
||||
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
DebuggerHandler.getPool().submit(r);
|
||||
}
|
||||
|
||||
public void dispose() {
|
||||
|
||||
@@ -45,6 +45,7 @@ import javax.swing.SwingUtilities;
|
||||
import javax.swing.table.DefaultTableCellRenderer;
|
||||
import javax.swing.table.DefaultTableModel;
|
||||
import javax.swing.table.TableCellRenderer;
|
||||
import javax.swing.table.TableModel;
|
||||
|
||||
/**
|
||||
* @author JPEXS
|
||||
@@ -67,8 +68,23 @@ public class DebugStackPanel extends JPanel {
|
||||
private int[] traitIndices = new int[0];
|
||||
private WeakReference<DebuggerSession> currentSessionRef = null;
|
||||
|
||||
private DefaultTableModel getStackTableModel(Object[][] data) {
|
||||
return new DefaultTableModel(data, new Object[]{
|
||||
AppStrings.translate("callStack.header.swf"),
|
||||
AppStrings.translate("callStack.header.file"),
|
||||
AppStrings.translate("callStack.header.line"),
|
||||
AppStrings.translate("stack.header.item")
|
||||
}) {
|
||||
@Override
|
||||
public boolean isCellEditable(int row, int column) {
|
||||
return false;
|
||||
}
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
public DebugStackPanel() {
|
||||
stackTable = new JTable();
|
||||
stackTable = new JTable(getStackTableModel(new Object[0][4]));
|
||||
Main.getDebugHandler().addFrameChangeListener(new DebuggerHandler.FrameChangeListener() {
|
||||
@Override
|
||||
public void frameChanged(DebuggerSession session) {
|
||||
@@ -160,8 +176,10 @@ public class DebugStackPanel extends JPanel {
|
||||
sessionComboBox.addActionListener(new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
if (sessionComboBoxCreating) {
|
||||
return;
|
||||
synchronized (DebugStackPanel.this) {
|
||||
if (sessionComboBoxCreating) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
SessionItem selection = (SessionItem) sessionComboBox.getSelectedItem();
|
||||
if (selection != null) {
|
||||
@@ -174,12 +192,13 @@ public class DebugStackPanel extends JPanel {
|
||||
lastSessionComboBoxIndex = sessionComboBox.getSelectedIndex();
|
||||
|
||||
Main.getDebugHandler().setSelectedSessionId(session.getId());
|
||||
//session.refreshFrame();
|
||||
View.execInEventDispatch(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
refresh(session);
|
||||
}
|
||||
});
|
||||
});
|
||||
View.execInEventDispatchLater(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
@@ -210,7 +229,7 @@ public class DebugStackPanel extends JPanel {
|
||||
SessionItem item = (SessionItem) value;
|
||||
if (item != null) {
|
||||
DebuggerSession session = Main.getDebugHandler().getSessionById(item.id);
|
||||
if (!session.isPaused()) {
|
||||
if (session == null || !session.isPaused()) {
|
||||
c.setForeground(Color.GRAY);
|
||||
c.setBackground(list.getBackground());
|
||||
} else {
|
||||
@@ -279,8 +298,8 @@ public class DebugStackPanel extends JPanel {
|
||||
}
|
||||
}
|
||||
|
||||
public void clear() {
|
||||
stackTable.setModel(new DefaultTableModel());
|
||||
public void clear() {
|
||||
stackTable.setModel(getStackTableModel(new Object[0][4]));
|
||||
if (Main.getDebugHandler().getActiveSessions().isEmpty()) {
|
||||
active = false;
|
||||
}
|
||||
@@ -304,7 +323,10 @@ public class DebugStackPanel extends JPanel {
|
||||
model.addElement(new SessionItem(id));
|
||||
j++;
|
||||
}
|
||||
sessionComboBoxCreating = true;
|
||||
synchronized (this) {
|
||||
sessionComboBoxCreating = true;
|
||||
}
|
||||
|
||||
if (itemIndex > -1) {
|
||||
final int fItemIndex = itemIndex;
|
||||
View.execInEventDispatchLater(new Runnable() {
|
||||
@@ -315,7 +337,9 @@ public class DebugStackPanel extends JPanel {
|
||||
sessionComboBox.setSelectedIndex(fItemIndex);
|
||||
}
|
||||
lastSessionComboBoxIndex = fItemIndex;
|
||||
sessionComboBoxCreating = false;
|
||||
synchronized (DebugStackPanel.this) {
|
||||
sessionComboBoxCreating = false;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -378,19 +402,7 @@ public class DebugStackPanel extends JPanel {
|
||||
newTraitIndices[i] = newTraitIndex == null ? -1 : newTraitIndex;
|
||||
}
|
||||
|
||||
DefaultTableModel tm = new DefaultTableModel(data, new Object[]{
|
||||
AppStrings.translate("callStack.header.swf"),
|
||||
AppStrings.translate("callStack.header.file"),
|
||||
AppStrings.translate("callStack.header.line"),
|
||||
AppStrings.translate("stack.header.item")
|
||||
}) {
|
||||
@Override
|
||||
public boolean isCellEditable(int row, int column) {
|
||||
return false;
|
||||
}
|
||||
|
||||
};
|
||||
stackTable.setModel(tm);
|
||||
stackTable.setModel(getStackTableModel(data));
|
||||
this.swfHashes = newSwfHashes;
|
||||
this.classIndices = newClassIndices;
|
||||
this.methodIndices = newMethodIndices;
|
||||
@@ -410,11 +422,12 @@ public class DebugStackPanel extends JPanel {
|
||||
}
|
||||
|
||||
};
|
||||
if (stackTable.getColumnModel().getColumnCount() >= 3) {
|
||||
stackTable.setDefaultRenderer(String.class, renderer);
|
||||
/*if (stackTable.getColumnModel().getColumnCount() >= 3) {
|
||||
stackTable.getColumnModel().getColumn(0).setCellRenderer(renderer);
|
||||
stackTable.getColumnModel().getColumn(1).setCellRenderer(renderer);
|
||||
stackTable.getColumnModel().getColumn(2).setCellRenderer(renderer);
|
||||
}
|
||||
}*/
|
||||
repaint();
|
||||
}
|
||||
});
|
||||
|
||||
@@ -31,6 +31,10 @@ import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.TreeSet;
|
||||
import java.util.WeakHashMap;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.ThreadFactory;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
/**
|
||||
* @author JPEXS
|
||||
@@ -46,6 +50,8 @@ public class DebuggerHandler implements DebugConnectionListener {
|
||||
private boolean terminating = false;
|
||||
|
||||
private Map<SWF, Map<String, Set<Integer>>> allBreakPoints = new WeakHashMap<>();
|
||||
|
||||
private static ExecutorService pool = null;
|
||||
|
||||
public static class ActionScriptException extends Exception {
|
||||
|
||||
@@ -263,6 +269,11 @@ public class DebuggerHandler implements DebugConnectionListener {
|
||||
synchronized (this) {
|
||||
terminating = false;
|
||||
}
|
||||
|
||||
if (pool != null) {
|
||||
pool.shutdownNow();
|
||||
pool = null;
|
||||
}
|
||||
}
|
||||
|
||||
public synchronized Map<String, Set<Integer>> getAllSessionsBreakPoints(SWF swf) {
|
||||
@@ -423,4 +434,20 @@ public class DebuggerHandler implements DebugConnectionListener {
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public static synchronized ExecutorService getPool() {
|
||||
if (pool == null) {
|
||||
AtomicInteger counter = new AtomicInteger(1);
|
||||
|
||||
ThreadFactory namedThreadFactory = runnable -> {
|
||||
Thread t = new Thread(runnable);
|
||||
t.setName("debugger-handler-thread-" + counter.getAndIncrement());
|
||||
return t;
|
||||
};
|
||||
pool = Executors.newCachedThreadPool(namedThreadFactory);
|
||||
}
|
||||
return pool;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
package com.jpexs.decompiler.flash.gui;
|
||||
|
||||
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.Variable;
|
||||
@@ -34,6 +35,7 @@ import com.jpexs.debugger.flash.messages.in.InFrame;
|
||||
import com.jpexs.debugger.flash.messages.in.InGetSwf;
|
||||
import com.jpexs.debugger.flash.messages.in.InGetVariable;
|
||||
import com.jpexs.debugger.flash.messages.in.InNumScript;
|
||||
import com.jpexs.debugger.flash.messages.in.InOption;
|
||||
import com.jpexs.debugger.flash.messages.in.InPlaceObject;
|
||||
import com.jpexs.debugger.flash.messages.in.InProcessTag;
|
||||
import com.jpexs.debugger.flash.messages.in.InScript;
|
||||
@@ -47,6 +49,7 @@ import com.jpexs.debugger.flash.messages.out.OutGetSwf;
|
||||
import com.jpexs.debugger.flash.messages.out.OutPlay;
|
||||
import com.jpexs.debugger.flash.messages.out.OutProcessedTag;
|
||||
import com.jpexs.debugger.flash.messages.out.OutRewind;
|
||||
import com.jpexs.debugger.flash.messages.out.OutSetOption;
|
||||
import com.jpexs.debugger.flash.messages.out.OutSwfInfo;
|
||||
import com.jpexs.decompiler.flash.SWF;
|
||||
import com.jpexs.decompiler.flash.configuration.Configuration;
|
||||
@@ -56,6 +59,7 @@ import java.io.IOException;
|
||||
import java.security.MessageDigest;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
@@ -136,14 +140,17 @@ public class DebuggerSession {
|
||||
private InSetBreakpoint inSetBreakpoint;
|
||||
|
||||
private int id;
|
||||
|
||||
|
||||
private String title = "";
|
||||
|
||||
|
||||
private static final int DEFAULT_TIMEOUT = 1000;
|
||||
|
||||
private List<Thread> getSwfThreadList = Collections.synchronizedList(new ArrayList<>());
|
||||
|
||||
private Map<String, DebuggerCommands.Watch> watches = new LinkedHashMap<>();
|
||||
|
||||
public DebuggerSession(DebuggerHandler handler, DebuggerConnection con, Map<SWF, Map<String, Set<Integer>>> breakpoints) {
|
||||
id = con.getId();
|
||||
id = con.getId();
|
||||
|
||||
toAddBPointMap = breakpoints;
|
||||
this.handler = handler;
|
||||
@@ -157,10 +164,8 @@ public class DebuggerSession {
|
||||
@Override
|
||||
public void run() {
|
||||
Main.getMainFrame().getPanel().updateMenu();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
|
||||
//enlog(DebuggerConnection.class);
|
||||
//enlog(DebuggerCommands.class);
|
||||
@@ -291,6 +296,10 @@ public class DebuggerSession {
|
||||
commands.setGetterTimeout(1500);
|
||||
commands.setSetterTimeout(5000);
|
||||
|
||||
if (commands.playerConcurrency()) {
|
||||
commands.debuggerSetConcurrency();
|
||||
}
|
||||
|
||||
commands.squelch(true);
|
||||
|
||||
con.addMessageListener(new DebugMessageListener<InExit>() {
|
||||
@@ -340,16 +349,16 @@ public class DebuggerSession {
|
||||
if (inGetSwf == null) {
|
||||
Logger.getLogger(DebuggerSession.class.getName()).log(Level.FINE, "session{0}: Cannot read SWF", id);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
String sha256 = Helper.byteArrayToHex(MessageDigest.getInstance("SHA-256").digest(inGetSwf.swfData));
|
||||
Logger.getLogger(DebuggerSession.class.getName()).log(Level.FINE, "session{0}: Received SWF hash = {1}", new Object[]{id, sha256});
|
||||
|
||||
|
||||
String originalHash = Main.getHashFromMetadataFromSwfBytes(inGetSwf.swfData);
|
||||
if (originalHash != null) {
|
||||
Logger.getLogger(DebuggerSession.class.getName()).log(Level.FINE, "session{0}: Received SWF original hash = {1}", new Object[]{id, originalHash});
|
||||
sha256 = originalHash;
|
||||
}
|
||||
|
||||
|
||||
SWF debuggedSwf = Main.findOpenedSwfByHash(sha256);
|
||||
if (debuggedSwf == null) {
|
||||
con.disconnect();
|
||||
@@ -379,9 +388,9 @@ public class DebuggerSession {
|
||||
}
|
||||
|
||||
try {
|
||||
|
||||
|
||||
Set<String> hashes = new LinkedHashSet<>();
|
||||
|
||||
|
||||
for (int file : modulePaths.keySet()) {
|
||||
String path = modulePaths.get(file);
|
||||
if (!path.contains(":")) {
|
||||
@@ -391,22 +400,22 @@ public class DebuggerSession {
|
||||
String hash = path.substring(0, path.indexOf(":"));
|
||||
hashes.add(hash);
|
||||
}
|
||||
for (String hash : hashes) {
|
||||
for (String hash : hashes) {
|
||||
if (Main.findOpenedSwfByHash(hash) == null) {
|
||||
//This is probably SWF file instrumented by another software
|
||||
throw new IOException("SWF with hash " + hash + " not found");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (!debuggedSwfs.isEmpty() && modulesEmptyBefore) {
|
||||
if (title.isEmpty()) {
|
||||
title = debuggedSwfs.values().iterator().next().toString();
|
||||
}
|
||||
if (con.isAS3) {
|
||||
//Widelines - only AS3, it hangs in AS1/2 and SWD does not support UI32 lines
|
||||
con.wideLines = commands.getOption("wide_line_player", "false").equals("true");
|
||||
//Widelines - only AS3, it hangs in AS1/2 and SWD does not support UI32 lines
|
||||
con.wideLines = commands.playerIsWideLine();
|
||||
if (con.wideLines) {
|
||||
commands.setOption("wide_line_debugger", "on");
|
||||
commands.debuggerSetWideLine();;
|
||||
}
|
||||
} else {
|
||||
Logger.getLogger(DebuggerSession.class.getName()).log(Level.FINER, "session{0}: End of connect - sending continue", id);
|
||||
@@ -461,7 +470,19 @@ public class DebuggerSession {
|
||||
con.addMessageListener(new DebugMessageListener<InPlaceObject>() {
|
||||
@Override
|
||||
public void message(InPlaceObject t) {
|
||||
placedObjects.put(t.path, t.objId);
|
||||
//Sometimes the player sends _global variable with 4 byte PTR instead of 8 byte
|
||||
byte[] globalVar = new byte[]{(byte) 0xfe, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0x5f, (byte) 0x67, (byte) 0x6c, (byte) 0x6f, (byte) 0x62, (byte) 0x61, (byte) 0x6c, (byte) 0x00};
|
||||
String placeName = t.path;
|
||||
long placeId = t.objId;
|
||||
if (Arrays.equals(t.data, globalVar)) {
|
||||
Logger.getLogger(DebuggerSession.class.getName()).log(Level.FINER, "session{0}: Received mangled placeobject _global", new Object[]{id});
|
||||
placeName = "_global";
|
||||
placeId = -2;
|
||||
} else {
|
||||
Logger.getLogger(DebuggerSession.class.getName()).log(Level.FINER, "session{0}: Received placeobject {1}", new Object[]{id, t.path});
|
||||
}
|
||||
Logger.getLogger(DebuggerSession.class.getName()).log(Level.FINEST, "session{0}: Placeobject hex data: {1}", new Object[]{id, Helper.byteArrayToHex(t.data)});
|
||||
placedObjects.put(placeName, placeId);
|
||||
con.dropMessage(t);
|
||||
}
|
||||
});
|
||||
@@ -474,10 +495,10 @@ public class DebuggerSession {
|
||||
synchronized (DebuggerSession.this) {
|
||||
paused = false;
|
||||
Logger.getLogger(DebuggerSession.class.getName()).log(Level.FINE, "session{0}: continued", id);
|
||||
}
|
||||
}
|
||||
for (DebuggerHandler.BreakListener bl : handler.getBreakListeners()) {
|
||||
bl.doContinue(DebuggerSession.this);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
@@ -491,14 +512,13 @@ public class DebuggerSession {
|
||||
@Override
|
||||
public void run() {
|
||||
Logger.getLogger(DebuggerSession.class.getName()).log(Level.FINE, "session{0}: In break at start", id);
|
||||
|
||||
|
||||
synchronized (DebuggerSession.this) {
|
||||
if (!connected) {
|
||||
Logger.getLogger(DebuggerSession.class.getName()).log(Level.FINE, "session{0}: Received break while not connected", id);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
paused = true;
|
||||
Logger.getLogger(DebuggerSession.class.getName()).log(Level.FINE, "session{0}: paused", id);
|
||||
}
|
||||
@@ -543,7 +563,7 @@ public class DebuggerSession {
|
||||
sendBreakPoints();
|
||||
} catch (IOException ex) {
|
||||
//ignore
|
||||
Logger.getLogger(DebuggerSession.class.getName()).log(Level.FINE, "session{0}: send breakpoints exception: {1}", new Object[] {id, ex.getMessage()});
|
||||
Logger.getLogger(DebuggerSession.class.getName()).log(Level.FINE, "session{0}: send breakpoints exception: {1}", new Object[]{id, ex.getMessage()});
|
||||
}
|
||||
|
||||
synchronized (DebuggerSession.this) {
|
||||
@@ -574,14 +594,15 @@ public class DebuggerSession {
|
||||
} else {
|
||||
Main.startWork(AppStrings.translate("debug.session").replace("%id%", "" + id) + " - " + AppStrings.translate("work.breakat") + userBreakScriptName + ":" + message.line + " " + AppStrings.translate("debug.break.reason." + reason), null, true);
|
||||
}
|
||||
depth = 0;
|
||||
refreshFrame();
|
||||
|
||||
|
||||
//If there is single one left paused, switch to it
|
||||
if (Main.getDebugHandler().getNumberOfPausedSessions() == 1) {
|
||||
Main.getDebugHandler().setSelectedSessionId(getId());
|
||||
}
|
||||
|
||||
|
||||
depth = 0;
|
||||
refreshFrame();
|
||||
|
||||
for (DebuggerHandler.BreakListener l : handler.getBreakListeners()) {
|
||||
l.breakAt(DebuggerSession.this, newBreakScriptName, message.line,
|
||||
moduleToClassIndex.containsKey(message.file) ? moduleToClassIndex.get(message.file) : -1,
|
||||
@@ -631,7 +652,7 @@ public class DebuggerSession {
|
||||
} catch (IOException ex) {
|
||||
Logger.getLogger(DebuggerSession.class.getName()).log(Level.SEVERE, null, ex);
|
||||
}
|
||||
}*/
|
||||
}*/
|
||||
|
||||
con.addMessageListener(new DebugMessageListener<InTrace>() {
|
||||
@Override
|
||||
@@ -657,8 +678,6 @@ public class DebuggerSession {
|
||||
public int getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public boolean containsSwf(SWF swf) {
|
||||
return debuggedSwfs.containsValue(swf);
|
||||
@@ -705,9 +724,9 @@ public class DebuggerSession {
|
||||
return stackLines;
|
||||
}
|
||||
|
||||
public InGetVariable getVariable(long parentId, String varName, boolean children, boolean useGetter) {
|
||||
public synchronized InGetVariable getVariable(long parentId, String varName, boolean children, boolean useGetter) {
|
||||
try {
|
||||
return commands.getVariableWithTimeout(parentId, varName, useGetter, children, 100);
|
||||
return commands.getVariableWithTimeout(parentId, varName, useGetter, children, DEFAULT_TIMEOUT);
|
||||
} catch (IOException ex) {
|
||||
return null;
|
||||
}
|
||||
@@ -740,7 +759,7 @@ public class DebuggerSession {
|
||||
}
|
||||
|
||||
public void removeBreakPoint(SWF swf, String scriptName, int line) {
|
||||
synchronized (this) {
|
||||
synchronized (this) {
|
||||
if (isBreakpointInvalid(swf, scriptName, line)) {
|
||||
invalidBreakPointMap.get(swf).get(scriptName).remove(line);
|
||||
if (invalidBreakPointMap.get(swf).get(scriptName).isEmpty()) {
|
||||
@@ -772,10 +791,19 @@ public class DebuggerSession {
|
||||
|
||||
private int watchTag = 1;
|
||||
|
||||
public synchronized com.jpexs.debugger.flash.DebuggerCommands.Watch addWatch(Variable v, long v_id, boolean watchRead, boolean watchWrite) {
|
||||
public synchronized DebuggerCommands.Watch addWatch(String varName, long varId, boolean watchRead, boolean watchWrite) {
|
||||
if (getWatch(varName, varId) != null) {
|
||||
if (!removeWatch(varName, varId)) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
int tag = watchTag++;
|
||||
try {
|
||||
return commands.addWatch(v_id, v.name, (watchRead ? OutAddWatch2.FLAG_READ : 0) | (watchWrite ? OutAddWatch2.FLAG_WRITE : 0), tag);
|
||||
com.jpexs.debugger.flash.DebuggerCommands.Watch w = commands.addWatch(varId, varName, (watchRead ? OutAddWatch2.FLAG_READ : 0) | (watchWrite ? OutAddWatch2.FLAG_WRITE : 0), tag);
|
||||
if (w != null) {
|
||||
watches.put("" + w.varId + ":" + w.varName, w);
|
||||
}
|
||||
return w;
|
||||
} catch (IOException ex) {
|
||||
return null;
|
||||
}
|
||||
@@ -953,8 +981,11 @@ public class DebuggerSession {
|
||||
}
|
||||
|
||||
public void setDepth(int depth) {
|
||||
boolean depthChanged = depth != this.depth;
|
||||
this.depth = depth;
|
||||
refreshFrame();
|
||||
if (depthChanged) {
|
||||
refreshFrame();
|
||||
}
|
||||
}
|
||||
|
||||
public String moduleToString(int file) {
|
||||
@@ -991,20 +1022,42 @@ public class DebuggerSession {
|
||||
}
|
||||
|
||||
public void refreshFrame() {
|
||||
synchronized (this) {
|
||||
synchronized (DebuggerSession.this) {
|
||||
if (!paused) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
frame = commands.getFrameWithTimeout(depth, 100);
|
||||
pool = commands.getConstantPoolWithTimeout(0, 100);
|
||||
} catch (IOException ex) {
|
||||
//ignore
|
||||
}
|
||||
|
||||
DebuggerHandler.getPool().submit(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
synchronized (DebuggerSession.this) {
|
||||
if (!paused) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
try {
|
||||
frame = commands.getFrameWithTimeout(depth, DEFAULT_TIMEOUT);
|
||||
pool = commands.getConstantPoolWithTimeout(0, DEFAULT_TIMEOUT);
|
||||
} catch (IOException ex) {
|
||||
//ignore
|
||||
}
|
||||
|
||||
Logger.getLogger(DebugPanel.class.getName()).log(Level.FINE, "session{0}: Frame loaded", new Object[]{getId()});
|
||||
|
||||
if (frame == null) {
|
||||
Logger.getLogger(DebugPanel.class.getName()).log(Level.FINE, "session{0}: Frame is null!", new Object[]{getId()});
|
||||
}
|
||||
|
||||
if (pool == null) {
|
||||
Logger.getLogger(DebugPanel.class.getName()).log(Level.FINE, "session{0}: CPool is null!", new Object[]{getId()});
|
||||
}
|
||||
|
||||
for (DebuggerHandler.FrameChangeListener l : handler.getFrameChangeListeners()) {
|
||||
l.frameChanged(DebuggerSession.this);
|
||||
}
|
||||
}
|
||||
}
|
||||
for (DebuggerHandler.FrameChangeListener l : handler.getFrameChangeListeners()) {
|
||||
l.frameChanged(DebuggerSession.this);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public synchronized InFrame getFrame() {
|
||||
@@ -1066,17 +1119,17 @@ public class DebuggerSession {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//If there is single one left paused, switch to it
|
||||
if (Main.getDebugHandler().getNumberOfPausedSessions() == 1) {
|
||||
for (DebuggerSession session : Main.getDebugHandler().getActiveSessions().values()) {
|
||||
for (DebuggerSession session : Main.getDebugHandler().getActiveSessions().values()) {
|
||||
if (session.isPaused()) {
|
||||
Main.getDebugHandler().setSelectedSessionId(session.getId());
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
for (DebuggerHandler.ConnectionListener l : handler.getConnectionListeners()) {
|
||||
l.disconnected(DebuggerSession.this);
|
||||
}
|
||||
@@ -1282,5 +1335,45 @@ public class DebuggerSession {
|
||||
|
||||
public String getTitle() {
|
||||
return title;
|
||||
}
|
||||
}
|
||||
|
||||
public Map<String, DebuggerCommands.Watch> getWatches() {
|
||||
return new LinkedHashMap<>(watches);
|
||||
}
|
||||
|
||||
public DebuggerCommands.Watch getWatch(String varName, long varId) {
|
||||
return watches.get("" + varId + ":" + varName);
|
||||
}
|
||||
|
||||
public boolean removeWatch(String varName, long variId) {
|
||||
String key = "" + variId + ":" + varName;
|
||||
if (!watches.containsKey(key)) {
|
||||
return false;
|
||||
}
|
||||
try {
|
||||
if (commands.removeWatch(variId, varName)) {
|
||||
watches.remove(key);
|
||||
return true;
|
||||
}
|
||||
} catch (IOException ex) {
|
||||
//false
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public SWF getCurrentSwf() {
|
||||
InBreakAtExt info = getBreakInfo();
|
||||
if (info == null) {
|
||||
return null;
|
||||
}
|
||||
//Object[][] data = new Object[info.files.size()][4];
|
||||
String moduleName = moduleToString(info.file);
|
||||
if (moduleName.contains(":")) {
|
||||
String swfHash = moduleName.substring(0, moduleName.indexOf(":"));
|
||||
return Main.findOpenedSwfByHash(swfHash);
|
||||
} else {
|
||||
List<SWF> debuggedSwfs = new ArrayList<>(getDebuggedSwfs().values());
|
||||
return debuggedSwfs.get(debuggedSwfs.size() - 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -441,9 +441,13 @@ public class Main {
|
||||
}
|
||||
|
||||
public static synchronized boolean addWatch(DebuggerSession session, Variable v, long v_id, boolean watchRead, boolean watchWrite) {
|
||||
DebuggerCommands.Watch w = session.addWatch(v, v_id, watchRead, watchWrite);
|
||||
DebuggerCommands.Watch w = session.addWatch(v.name, v_id, watchRead, watchWrite);
|
||||
return w != null;
|
||||
}
|
||||
|
||||
public static synchronized boolean removeWatch(DebuggerSession session, Variable v, long v_id) {
|
||||
return session.removeWatch(v.name, v_id);
|
||||
}
|
||||
|
||||
public static void runPlayer(String title, final String exePath, String file, String flashVars) {
|
||||
if (!new File(file).exists()) {
|
||||
@@ -1137,7 +1141,7 @@ public class Main {
|
||||
}
|
||||
|
||||
public static void updateSession() {
|
||||
DebuggerSession session = getCurrentDebugSession();
|
||||
/*DebuggerSession session = getCurrentDebugSession();
|
||||
for (DebuggerHandler.FrameChangeListener l : getDebugHandler().getFrameChangeListeners()) {
|
||||
l.frameChanged(session);
|
||||
}
|
||||
@@ -1145,6 +1149,7 @@ public class Main {
|
||||
if (getDebugHandler().getNumberOfPausedSessions() > 0) {
|
||||
mainFrame.getPanel().showDebugStackFrame();
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
public static void ensureMainFrame() {
|
||||
@@ -3197,7 +3202,7 @@ public class Main {
|
||||
|
||||
@Override
|
||||
public void disconnected(DebuggerSession session) {
|
||||
Main.updateSession();
|
||||
//Main.updateSession();
|
||||
if (Main.mainFrame != null) {
|
||||
Main.mainFrame.getMenu().updateComponents();
|
||||
}
|
||||
|
||||
@@ -1636,7 +1636,7 @@ public final class MainPanel extends JPanel implements TreeSelectionListener, Se
|
||||
|
||||
private void updateUi(final Openable openable) {
|
||||
View.checkAccess();
|
||||
Main.updateSession();
|
||||
//Main.updateSession();
|
||||
SWF swf = null;
|
||||
if (openable instanceof SWF) {
|
||||
swf = (SWF) openable;
|
||||
@@ -5785,7 +5785,7 @@ public final class MainPanel extends JPanel implements TreeSelectionListener, Se
|
||||
return;
|
||||
}
|
||||
|
||||
Main.updateSession();
|
||||
//Main.updateSession();
|
||||
|
||||
if (!(treeItem instanceof OpenableList)) {
|
||||
Openable openable = treeItem.getOpenable();
|
||||
|
||||
@@ -16,10 +16,13 @@
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.gui.abc;
|
||||
|
||||
import com.jpexs.debugger.flash.DebuggerCommands;
|
||||
import com.jpexs.debugger.flash.DebuggerMessage;
|
||||
import com.jpexs.debugger.flash.Variable;
|
||||
import com.jpexs.debugger.flash.VariableFlags;
|
||||
import com.jpexs.debugger.flash.VariableType;
|
||||
import com.jpexs.debugger.flash.messages.in.InGetVariable;
|
||||
import com.jpexs.debugger.flash.messages.out.OutAddWatch2;
|
||||
import com.jpexs.decompiler.flash.SWF;
|
||||
import com.jpexs.decompiler.flash.abc.ABC;
|
||||
import com.jpexs.decompiler.flash.abc.ClassPath;
|
||||
@@ -266,7 +269,7 @@ public class ABCPanel extends JPanel implements ItemListener, SearchListener<Scr
|
||||
return;
|
||||
}
|
||||
|
||||
this.abc = abc;
|
||||
this.abc = abc;
|
||||
if (Main.isSwfAir(abc.getOpenable())) {
|
||||
libraryComboBox.setSelectedIndex(SWF.LIBRARY_AIR);
|
||||
} else {
|
||||
@@ -301,10 +304,11 @@ public class ABCPanel extends JPanel implements ItemListener, SearchListener<Scr
|
||||
|
||||
public static class VariableNode {
|
||||
|
||||
private static Thread variableLoaderThread;
|
||||
private static List<Runnable> loaderList = Collections.synchronizedList(new ArrayList<>());
|
||||
private static final Object loaderLock = new Object();
|
||||
|
||||
private static Map<Integer, Thread> sessionIdToVariableLoaderThread = new HashMap<>();
|
||||
private static Map<Integer, List<Runnable>> sessionIdToLoaderList = new HashMap<>();
|
||||
private static Map<Integer, List<VariableNode>> sessionIdToLoadedVariableNode = new HashMap<>();
|
||||
private static Map<Integer, Object> sessionIdToLoaderLock = new HashMap<>();
|
||||
|
||||
public List<VariableNode> path = new ArrayList<>();
|
||||
|
||||
public Variable var;
|
||||
@@ -322,8 +326,25 @@ public class ABCPanel extends JPanel implements ItemListener, SearchListener<Scr
|
||||
private List<VariableNode> childs;
|
||||
|
||||
public List<Variable> traits = new ArrayList<>();
|
||||
private DebuggerSession session;
|
||||
private MyTreeTable treeTable;
|
||||
private boolean as3;
|
||||
|
||||
|
||||
public static void stopLoading(int sessionId) {
|
||||
if (!sessionIdToLoadedVariableNode.containsKey(sessionId)) {
|
||||
return;
|
||||
}
|
||||
sessionIdToLoaderList.get(sessionId).clear();
|
||||
for (VariableNode node : sessionIdToLoadedVariableNode.get(sessionId)) {
|
||||
synchronized (node) {
|
||||
node.childs = new ArrayList<>();
|
||||
node.loading = false;
|
||||
node.loaded = true;
|
||||
}
|
||||
}
|
||||
sessionIdToLoadedVariableNode.get(sessionId).clear();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int hash = 3;
|
||||
@@ -361,6 +382,8 @@ public class ABCPanel extends JPanel implements ItemListener, SearchListener<Scr
|
||||
|
||||
public boolean loaded = false;
|
||||
|
||||
private boolean loading = false;
|
||||
|
||||
private static boolean isTraits(Variable v) {
|
||||
return (v.vType == VariableType.UNKNOWN && "traits".equals(v.typeName));
|
||||
}
|
||||
@@ -393,19 +416,24 @@ public class ABCPanel extends JPanel implements ItemListener, SearchListener<Scr
|
||||
boolean useGetter = (var.flags & VariableFlags.IS_CONST) == 0;
|
||||
|
||||
//boolean isAS3 = (Main.getMainFrame().getPanel().getCurrentSwf().isAS3());
|
||||
DebuggerSession currentSession = Main.getCurrentDebugSession();
|
||||
|
||||
if (Main.getCurrentDebugSession() == null) {
|
||||
if (currentSession == null || !currentSession.isPaused()) {
|
||||
return;
|
||||
}
|
||||
if (currentSession != session) {
|
||||
return;
|
||||
}
|
||||
if (parentObjectId == 0 && objectId != 0L && as3) {
|
||||
igv = Main.getCurrentDebugSession().getVariable(objectId, "", true, useGetter);
|
||||
igv = currentSession.getVariable(objectId, "", true, useGetter);
|
||||
} else {
|
||||
igv = Main.getCurrentDebugSession().getVariable(parentObjectId, var.name, true, useGetter);
|
||||
igv = currentSession.getVariable(parentObjectId, var.name, true, useGetter);
|
||||
}
|
||||
if (igv == null) { //timeout
|
||||
return;
|
||||
}
|
||||
|
||||
//Logger.getLogger(VariableNode.class.getName()).log(Level.FINE, "session{0}: Get var data: {1}", new Object[]{currentSession.getId(), Helper.byteArrayToHex(igv.data)});
|
||||
//current var is getter function - set it to value really got
|
||||
if ((var.flags & VariableFlags.HAS_GETTER) > 0) {
|
||||
varInsideGetter = igv.parent;
|
||||
@@ -416,10 +444,10 @@ public class ABCPanel extends JPanel implements ItemListener, SearchListener<Scr
|
||||
if (!Configuration.showVarsWithDontEnumerateFlag.get() && (igv.childs.get(i).flags & VariableFlags.DONT_ENUMERATE) > 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
if (!isTraits(igv.childs.get(i))) {
|
||||
Long parentObjectId = varToObjectId(varInsideGetter);
|
||||
childs.add(new VariableNode(as3, path, level + 1, igv.childs.get(i), parentObjectId, curTrait));
|
||||
childs.add(new VariableNode(currentSession, treeTable, as3, path, level + 1, igv.childs.get(i), parentObjectId, curTrait));
|
||||
} else {
|
||||
curTrait = igv.childs.get(i);
|
||||
traits.add(curTrait);
|
||||
@@ -427,62 +455,130 @@ public class ABCPanel extends JPanel implements ItemListener, SearchListener<Scr
|
||||
}
|
||||
}
|
||||
|
||||
private void ensureLoaded() {
|
||||
if (!loaded) {
|
||||
|
||||
/*synchronized (VariableNode.class) {
|
||||
if (variableLoaderThread == null) {
|
||||
Runnable r = new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
while(true) {
|
||||
if (loaderList.isEmpty()) {
|
||||
synchronized (loaderLock) {
|
||||
try {
|
||||
loaderLock.wait(500);
|
||||
} catch (InterruptedException ex) {
|
||||
|
||||
}
|
||||
}
|
||||
} else {
|
||||
Runnable toRun = loaderList.remove(0);
|
||||
toRun.run();
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
variableLoaderThread = new Thread(r, "Variable loader");
|
||||
variableLoaderThread.setDaemon(true);
|
||||
variableLoaderThread.start();
|
||||
}
|
||||
private void ensureLoaded() {
|
||||
synchronized (VariableNode.this) {
|
||||
if (loaded || loading) {
|
||||
return;
|
||||
}
|
||||
|
||||
loaderList.add(new Runnable() {
|
||||
loading = true;
|
||||
}
|
||||
int sessionId = session.getId();
|
||||
if (!sessionIdToVariableLoaderThread.containsKey(sessionId)) {
|
||||
Runnable r = new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
reloadChildren();
|
||||
loaded = true;
|
||||
}
|
||||
});
|
||||
synchronized (loaderLock) {
|
||||
loaderLock.notify();
|
||||
}*/
|
||||
reloadChildren();
|
||||
loaded = true;
|
||||
while (true) {
|
||||
if (sessionIdToLoaderList.get(sessionId).isEmpty()) {
|
||||
Object lock = sessionIdToLoaderLock.get(session.getId());
|
||||
synchronized (lock) {
|
||||
try {
|
||||
lock.wait(500);
|
||||
} catch (InterruptedException ex) {
|
||||
//ignored
|
||||
}
|
||||
}
|
||||
} else {
|
||||
Runnable toRun = sessionIdToLoaderList.get(sessionId).remove(0);
|
||||
toRun.run();
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
sessionIdToLoaderList.put(sessionId, new ArrayList<>());
|
||||
sessionIdToLoaderLock.put(sessionId, new Object());
|
||||
Thread t = new Thread(r, "Variable loader for session " + sessionId);
|
||||
sessionIdToVariableLoaderThread.put(sessionId, t);
|
||||
t.setDaemon(true);
|
||||
t.start();
|
||||
try {
|
||||
Thread.sleep(100);
|
||||
} catch (InterruptedException ex) {
|
||||
//ignore
|
||||
}
|
||||
}
|
||||
|
||||
sessionIdToLoaderList.get(sessionId).add(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
synchronized (VariableNode.this) {
|
||||
if (!loading) {
|
||||
Logger.getLogger(VariableNode.class.getName()).log(Level.FINE, "session{0}: Already loaded {1}, skipping", new Object[]{session.getId(), var.name});
|
||||
return;
|
||||
}
|
||||
}
|
||||
Logger.getLogger(VariableNode.class.getName()).log(Level.FINE, "session{0}: Loading children of {1}", new Object[]{session.getId(), var.name});
|
||||
|
||||
reloadChildren();
|
||||
|
||||
synchronized (VariableNode.this) {
|
||||
if (!loading) {
|
||||
Logger.getLogger(VariableNode.class.getName()).log(Level.FINE, "session{0}: Already loaded {1}, not firing", new Object[]{session.getId(), var.name});
|
||||
return;
|
||||
}
|
||||
loaded = true;
|
||||
loading = false;
|
||||
Logger.getLogger(VariableNode.class.getName()).log(Level.FINE, "session{0}: Children of {1} loaded", new Object[]{session.getId(), var.name});
|
||||
}
|
||||
|
||||
DebuggerSession currentSession = Main.getCurrentDebugSession();
|
||||
if (currentSession == null || currentSession.getId() != sessionId) {
|
||||
return;
|
||||
}
|
||||
|
||||
VariablesTableModel variableModel = (VariablesTableModel) treeTable.getTreeTableModel();
|
||||
Object[] changedPath = new Object[path.size()];
|
||||
for (int i = 0; i < path.size(); i++) {
|
||||
changedPath[i] = path.get(i);
|
||||
}
|
||||
View.execInEventDispatch(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
Logger.getLogger(VariableNode.class.getName()).log(Level.FINE, "session{0}: Firing change of {1} - {2} childs", new Object[]{session.getId(), var.name, childs.size()});
|
||||
int[] childIds = new int[childs.size()];
|
||||
Object[] childObjs = new Object[childs.size()];
|
||||
|
||||
for (int i = 0; i < childIds.length; i++) {
|
||||
childIds[i] = i;
|
||||
childObjs[i] = childs.get(i);
|
||||
}
|
||||
|
||||
//variableModel.fireTreeStructureChanged(treeTable.getTree(), changedPath, new int[0], null);
|
||||
variableModel.fireTreeNodesInserted(treeTable.getTree(), changedPath, childIds, childObjs);
|
||||
treeTable.repaint();
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
if (!sessionIdToLoadedVariableNode.containsKey(sessionId)) {
|
||||
sessionIdToLoadedVariableNode.put(sessionId, new ArrayList<>());
|
||||
}
|
||||
sessionIdToLoadedVariableNode.get(sessionId).add(this);
|
||||
Object lock = sessionIdToLoaderLock.get(sessionId);
|
||||
Logger.getLogger(VariableNode.class.getName()).log(Level.FINE, "session{0}: Scheduling loading children of {1}", new Object[]{session.getId(), var.name});
|
||||
synchronized (lock) {
|
||||
lock.notify();
|
||||
}
|
||||
/*reloadChildren();
|
||||
loaded = true;*/
|
||||
}
|
||||
|
||||
public VariableNode getChildAt(int index) {
|
||||
ensureLoaded();
|
||||
if (!loaded) {
|
||||
return null;
|
||||
}
|
||||
return childs.get(index);
|
||||
}
|
||||
|
||||
public int getChildCount() {
|
||||
ensureLoaded();
|
||||
if (!loaded) {
|
||||
return 0;
|
||||
}
|
||||
return childs.size();
|
||||
}
|
||||
|
||||
public VariableNode(boolean as3, List<VariableNode> parentPath, int level, Variable var, Long parentObjectId, Variable trait) {
|
||||
public VariableNode(DebuggerSession session, MyTreeTable treeTable, boolean as3, List<VariableNode> parentPath, int level, Variable var, Long parentObjectId, Variable trait) {
|
||||
this.var = var;
|
||||
this.varInsideGetter = var;
|
||||
this.parentObjectId = parentObjectId;
|
||||
@@ -491,10 +587,12 @@ public class ABCPanel extends JPanel implements ItemListener, SearchListener<Scr
|
||||
this.path.addAll(parentPath);
|
||||
this.path.add(this);
|
||||
loaded = false;
|
||||
this.session = session;
|
||||
this.treeTable = treeTable;
|
||||
this.as3 = as3;
|
||||
}
|
||||
|
||||
public VariableNode(boolean as3, List<VariableNode> parentPath, int level, Variable var, Long parentObjectId, Variable trait, List<VariableNode> subvars) {
|
||||
public VariableNode(DebuggerSession session, MyTreeTable treeTable, boolean as3, List<VariableNode> parentPath, int level, Variable var, Long parentObjectId, Variable trait, List<VariableNode> subvars) {
|
||||
this.var = var;
|
||||
this.varInsideGetter = var;
|
||||
this.parentObjectId = parentObjectId;
|
||||
@@ -510,6 +608,8 @@ public class ABCPanel extends JPanel implements ItemListener, SearchListener<Scr
|
||||
vn.path.add(vn);
|
||||
}
|
||||
loaded = true;
|
||||
this.session = session;
|
||||
this.treeTable = treeTable;
|
||||
this.as3 = as3;
|
||||
}
|
||||
}
|
||||
@@ -545,17 +645,18 @@ public class ABCPanel extends JPanel implements ItemListener, SearchListener<Scr
|
||||
|
||||
private static final int STRUCTURE_CHANGED = 3;
|
||||
|
||||
private final MyTreeTable ttable;
|
||||
private final MyTreeTable treeTable;
|
||||
|
||||
public VariablesTableModel(boolean as3, MyTreeTable ttable, List<Variable> vars) {
|
||||
this.ttable = ttable;
|
||||
public VariablesTableModel(DebuggerSession session, boolean as3, MyTreeTable treeTable, List<Variable> vars, List<Long> parentIds) {
|
||||
this.treeTable = treeTable;
|
||||
|
||||
List<VariableNode> childs = new ArrayList<>();
|
||||
|
||||
for (int i = 0; i < vars.size(); i++) {
|
||||
childs.add(new VariableNode(as3, new ArrayList<>(), 1, vars.get(i), 0L, null));
|
||||
childs.add(new VariableNode(session, treeTable, as3, new ArrayList<>(), 1, vars.get(i), parentIds == null ? 0L : parentIds.get(i), null));
|
||||
}
|
||||
root = new VariableNode(as3, new ArrayList<>(), 0, null, 0L, null, childs);
|
||||
root = new VariableNode(session, treeTable, as3, new ArrayList<>(), 0, null, 0L, null, childs);
|
||||
root.loaded = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -767,7 +868,26 @@ public class ABCPanel extends JPanel implements ItemListener, SearchListener<Scr
|
||||
case COLUMN_SCOPE:
|
||||
return flagsToScopeString(var.flags);
|
||||
case COLUMN_FLAGS:
|
||||
return flagsToString(var.flags);
|
||||
String flags = flagsToString(var.flags);
|
||||
DebuggerSession session = Main.getCurrentDebugSession();
|
||||
DebuggerCommands.Watch w = session == null ? null : session.getWatch(((VariableNode) node).var.name, ((VariableNode) node).parentObjectId);
|
||||
if (w != null) {
|
||||
if ((w.flags & OutAddWatch2.FLAG_READ) > 0) {
|
||||
if (!flags.isEmpty()) {
|
||||
flags += ", ";
|
||||
}
|
||||
|
||||
flags += "watch:read";
|
||||
}
|
||||
if ((w.flags & OutAddWatch2.FLAG_WRITE) > 0) {
|
||||
if (!flags.isEmpty()) {
|
||||
flags += ", ";
|
||||
}
|
||||
|
||||
flags += "watch:write";
|
||||
}
|
||||
}
|
||||
return flags;
|
||||
case COLUMN_TYPE:
|
||||
String typeStr = val.getTypeAsStr();
|
||||
if ("Object".equals(typeStr)) {
|
||||
@@ -782,7 +902,7 @@ public class ABCPanel extends JPanel implements ItemListener, SearchListener<Scr
|
||||
case VariableType.OBJECT:
|
||||
case VariableType.MOVIECLIP:
|
||||
case VariableType.FUNCTION:
|
||||
return var.getTypeAsStr() + "(" + val.value + ")";
|
||||
return var.getTypeAsStr() + "(0x" + Long.toUnsignedString((Long) val.value, 16) + ")";
|
||||
case VariableType.STRING:
|
||||
return "\"" + Helper.escapeActionScriptString("" + val.value) + "\"";
|
||||
default:
|
||||
@@ -868,7 +988,7 @@ public class ABCPanel extends JPanel implements ItemListener, SearchListener<Scr
|
||||
|
||||
@Override
|
||||
public void valueForPathChanged(TreePath path, Object newValue) {
|
||||
fireTreeNodesChanged(ttable, path.getParentPath().getPath(), new int[0], new Object[]{path.getLastPathComponent()});
|
||||
fireTreeNodesChanged(treeTable, path.getParentPath().getPath(), new int[0], new Object[]{path.getLastPathComponent()});
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -1068,8 +1188,8 @@ public class ABCPanel extends JPanel implements ItemListener, SearchListener<Scr
|
||||
}
|
||||
|
||||
String scriptNamePrintable = DottedChain.parseWithSuffix(scriptName.toString()).toPrintableString(new LinkedHashSet<>(), ci.abc.getSwf(), true);
|
||||
|
||||
if (swfRef.getVal() == abc.getSwf()) {
|
||||
|
||||
if (swfRef.getVal() == abc.getSwf()) {
|
||||
hilightScript(getOpenable(), scriptNamePrintable);
|
||||
return;
|
||||
}
|
||||
@@ -1131,12 +1251,12 @@ public class ABCPanel extends JPanel implements ItemListener, SearchListener<Scr
|
||||
|
||||
private Path typeToPath(GraphTargetItem type) {
|
||||
if (type instanceof TypeItem) {
|
||||
TypeItem ti = (TypeItem) type;
|
||||
TypeItem ti = (TypeItem) type;
|
||||
return new Path(ti.fullTypeName.getStringParts());
|
||||
}
|
||||
return new Path(Helper.splitString(".", type.toString())); //Arrays.asList(type.toString().split("\\.")));
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Path getTraitSubType(Path className, String traitName, int level) {
|
||||
Reference<Boolean> foundStatic = new Reference<>(null);
|
||||
@@ -1212,7 +1332,7 @@ public class ABCPanel extends JPanel implements ItemListener, SearchListener<Scr
|
||||
Path callType = null;
|
||||
if (ti != null) {
|
||||
type = typeToPath(ti.returnType);
|
||||
callType = typeToPath(ti.callReturnType);
|
||||
callType = typeToPath(ti.callReturnType);
|
||||
}
|
||||
if (ti.trait instanceof TraitSlotConst) {
|
||||
callType = null;
|
||||
@@ -1230,7 +1350,7 @@ public class ABCPanel extends JPanel implements ItemListener, SearchListener<Scr
|
||||
}
|
||||
if (tmgs.kindType == Trait.TRAIT_GETTER) {
|
||||
type = callType;
|
||||
callType = null;
|
||||
callType = null;
|
||||
}
|
||||
}
|
||||
ret.add(new com.jpexs.decompiler.flash.simpleparser.Variable(true, new Path(def.getPropertyName()), 0, isStaticList.get(i), type, callType));
|
||||
@@ -1318,7 +1438,7 @@ public class ABCPanel extends JPanel implements ItemListener, SearchListener<Scr
|
||||
JCheckBoxMenuItem deobfuscateIdentifiersMenuItem = new JCheckBoxMenuItem(AppStrings.translate("deobfuscate_options.deobfuscateIdentifiers"));
|
||||
deobfuscateIdentifiersMenuItem.setSelected(Configuration.autoDeobfuscateIdentifiers.get());
|
||||
deobfuscateIdentifiersMenuItem.addActionListener(ABCPanel.this::autoDeobfuscateIdentifiersMenuItemActionPerformed);
|
||||
|
||||
|
||||
JCheckBoxMenuItem simplifyExpressionsMenuItem = new JCheckBoxMenuItem(AppStrings.translate("deobfuscate_options.simplify_expressions"));
|
||||
simplifyExpressionsMenuItem.setSelected(Configuration.simplifyExpressions.get());
|
||||
simplifyExpressionsMenuItem.addActionListener(ABCPanel.this::simplifyExpressionsMenuItemActionPerformed);
|
||||
@@ -1326,14 +1446,12 @@ public class ABCPanel extends JPanel implements ItemListener, SearchListener<Scr
|
||||
removeObfuscatedDeclarationsMenuItem.setSelected(Configuration.deobfuscateAs12RemoveInvalidNamesAssignments.get());
|
||||
removeObfuscatedDeclarationsMenuItem.addActionListener(this::removeObfuscatedDeclarationsMenuItemActionPerformed);
|
||||
*/
|
||||
|
||||
|
||||
|
||||
JCheckBoxMenuItem disableDecompilationMenuItem = new JCheckBoxMenuItem(AppStrings.translate("menu.settings.disabledecompilation"));
|
||||
disableDecompilationMenuItem.setSelected(!Configuration.decompile.get());
|
||||
disableDecompilationMenuItem.addActionListener(ABCPanel.this::disableDecompilationMenuItemActionPerformed);
|
||||
|
||||
|
||||
popupMenu.add(deobfuscateIdentifiersMenuItem);
|
||||
|
||||
popupMenu.add(deobfuscateIdentifiersMenuItem);
|
||||
popupMenu.add(simplifyExpressionsMenuItem);
|
||||
//popupMenu.add(removeObfuscatedDeclarationsMenuItem);
|
||||
popupMenu.add(disableDecompilationMenuItem);
|
||||
@@ -1549,6 +1667,8 @@ public class ABCPanel extends JPanel implements ItemListener, SearchListener<Scr
|
||||
splitPane = null;
|
||||
add(panB, BorderLayout.CENTER);
|
||||
}
|
||||
|
||||
debugPanel.refresh();
|
||||
}
|
||||
|
||||
private void decompiledTextAreaTextChanged() {
|
||||
@@ -1811,12 +1931,12 @@ public class ABCPanel extends JPanel implements ItemListener, SearchListener<Scr
|
||||
String swfHash = nameIncludingSwfHash.substring(nameIncludingSwfHash.indexOf(":"));
|
||||
String name = nameIncludingSwfHash.substring(nameIncludingSwfHash.indexOf(":") + 1);
|
||||
Openable openable = Main.findOpenedSwfByHash(swfHash);
|
||||
|
||||
|
||||
if (openable != null) {
|
||||
hilightScript(openable, name);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Hilights specific script.
|
||||
*
|
||||
@@ -2188,13 +2308,13 @@ public class ABCPanel extends JPanel implements ItemListener, SearchListener<Scr
|
||||
Configuration.simplifyExpressions.set(menuItem.isSelected());
|
||||
mainPanel.autoDeobfuscateChanged();
|
||||
}
|
||||
|
||||
|
||||
private void autoDeobfuscateIdentifiersMenuItemActionPerformed(ActionEvent evt) {
|
||||
JCheckBoxMenuItem menuItem = (JCheckBoxMenuItem) evt.getSource();
|
||||
Configuration.autoDeobfuscateIdentifiers.set(menuItem.isSelected());
|
||||
mainPanel.autoDeobfuscateChanged();
|
||||
}
|
||||
|
||||
|
||||
private void disableDecompilationMenuItemActionPerformed(ActionEvent evt) {
|
||||
JCheckBoxMenuItem menuItem = (JCheckBoxMenuItem) evt.getSource();
|
||||
Configuration.decompile.set(!menuItem.isSelected());
|
||||
|
||||
@@ -1158,7 +1158,7 @@ public class ActionPanel extends JPanel implements SearchListener<ScriptSearchRe
|
||||
|
||||
editor.addTextChangedListener(this::editorTextChanged);
|
||||
decompiledEditor.addTextChangedListener(this::decompiledEditorTextChanged);
|
||||
debugPanel.refresh(Main.getCurrentDebugSession());
|
||||
debugPanel.refresh();
|
||||
decompiledEditor.refreshMarkers();
|
||||
editor.refreshMarkers();
|
||||
}
|
||||
|
||||
@@ -598,7 +598,7 @@ button.edit.script.disassembled = Edit P-code
|
||||
debug.watch.add = Add watch to %name%
|
||||
debug.watch.add.read = Read
|
||||
debug.watch.add.write = Write
|
||||
debug.watch.add.readwrite = Read+Write-
|
||||
debug.watch.add.readwrite = Read + Write
|
||||
error.debug.watch.add = Cannot add watch to this variable.
|
||||
variables.column.scope = Scope
|
||||
variables.column.flags = Flags
|
||||
@@ -1127,4 +1127,9 @@ message.info.debugListen = The listening action allows you to run SWF files via
|
||||
You can prepare SWF with context menu action "Prepare file for debugging".\n\
|
||||
Unprepared files will be ignored by the debugger!\n\n\
|
||||
Tip: If you want just Debug SWF in the standalone content debugger,\n\
|
||||
use "Debug" action instead, because that will prepare SWF automatically.\n\n
|
||||
use "Debug" action instead, because that will prepare SWF automatically.\n\n
|
||||
|
||||
#after 25.1.1
|
||||
debug.watch.remove = Remove watch
|
||||
error.debug.watch.remove = Cannot remove watch from this variable.
|
||||
variables.header.watches = Watches
|
||||
@@ -598,7 +598,7 @@ button.edit.script.disassembled = Edita codi-P
|
||||
debug.watch.add = Afegeix guaita a %name%
|
||||
debug.watch.add.read = Lectura
|
||||
debug.watch.add.write = Escriptura
|
||||
debug.watch.add.readwrite = Lectura+Escriptura-
|
||||
debug.watch.add.readwrite = Lectura + Escriptura
|
||||
error.debug.watch.add = No es pot afegir un guaita a aquesta variable.
|
||||
variables.column.scope = Abast
|
||||
variables.column.flags = Banderes
|
||||
|
||||
@@ -598,7 +598,7 @@ button.edit.script.disassembled = Upravit P-k\u00f3d
|
||||
debug.watch.add = P\u0159idat sledov\u00e1n\u00ed pro %name%
|
||||
debug.watch.add.read = \u010cten\u00ed
|
||||
debug.watch.add.write = Z\u00e1pis
|
||||
debug.watch.add.readwrite = \u010cten\u00ed+Z\u00e1pis-
|
||||
debug.watch.add.readwrite = \u010cten\u00ed + Z\u00e1pis
|
||||
error.debug.watch.add = Nelze p\u0159idat sledov\u00e1n\u00ed na tuto prom\u011bnnou.
|
||||
variables.column.scope = Rozsah
|
||||
variables.column.flags = P\u0159\u00edznaky
|
||||
@@ -1127,4 +1127,9 @@ message.info.debugListen = Akce naslouch\u00e1n\u00ed v\u00e1m umo\u017en\u00ed
|
||||
menu s n\u00e1zvem "P\u0159ipravit soubor pro lad\u011bn\u00ed".\n\
|
||||
Nep\u0159ipraven\u00e9 soubory budou v debuggeru ignorov\u00e1ny!\n\n\
|
||||
Tip: Pokud chcete pouze ladit SWF v standalone content debuggeru,\n\
|
||||
pou\u017eijte m\u00edsto toho akci "Ladit", proto\u017ee ta p\u0159ipravuje SWF automaticky.\n\n
|
||||
pou\u017eijte m\u00edsto toho akci "Ladit", proto\u017ee ta p\u0159ipravuje SWF automaticky.\n\n
|
||||
|
||||
#after 25.1.1
|
||||
debug.watch.remove = Odstranit sledov\u00e1n\u00ed
|
||||
error.debug.watch.remove = Nelze odstranit sledov\u00e1n\u00ed z t\u00e9to prom\u011bnn\u00e9.
|
||||
variables.header.watches = Sledov\u00e1n\u00ed
|
||||
@@ -989,3 +989,8 @@ message.info.debugListen = Die Listening-Aktion erm\u00f6glicht es Ihnen, SWF-Da
|
||||
Nicht vorbereitete Dateien werden vom Debugger ignoriert!\n\n\
|
||||
Tipp: Wenn Sie SWF nur im eigenst\u00e4ndigen Content-Debugger debuggen m\u00f6chten,\n\
|
||||
verwenden Sie stattdessen die Aktion "Debuggen", da diese SWF automatisch vorbereitet.\n\n
|
||||
|
||||
#after 25.1.1
|
||||
debug.watch.remove = \u00dcberwachung entfernen
|
||||
error.debug.watch.remove = \u00dcberwachung kann von dieser Variablen nicht entfernt werden.
|
||||
variables.header.watches = \u00dcberwachungen
|
||||
@@ -598,7 +598,7 @@ button.edit.script.disassembled = P-code \u3092\u7de8\u96c6
|
||||
debug.watch.add = %name% \u306b\u30a6\u30a9\u30c3\u30c1\u3092\u8ffd\u52a0
|
||||
debug.watch.add.read = \u8aad\u307f\u53d6\u308a
|
||||
debug.watch.add.write = \u66f8\u304d\u8fbc\u307f
|
||||
debug.watch.add.readwrite = \u8aad\u307f\u53d6\u308a+\u66f8\u304d\u8fbc\u307f-
|
||||
debug.watch.add.readwrite = \u8aad\u307f\u53d6\u308a + \u66f8\u304d\u8fbc\u307f
|
||||
error.debug.watch.add = \u3053\u306e\u5909\u6570\u306b\u30a6\u30a9\u30c3\u30c1\u3092\u8ffd\u52a0\u3067\u304d\u307e\u305b\u3093\u3002
|
||||
variables.column.scope = \u30b9\u30b3\u30fc\u30d7
|
||||
variables.column.flags = \u30d5\u30e9\u30b0
|
||||
|
||||
@@ -598,7 +598,7 @@ button.edit.script.disassembled = P-code bewerken
|
||||
debug.watch.add = Voeg bekijken toe aan %name%
|
||||
debug.watch.add.read = Lezen
|
||||
debug.watch.add.write = Schrijven
|
||||
debug.watch.add.readwrite = Lezen+Schrijven+
|
||||
debug.watch.add.readwrite = Lezen + Schrijven
|
||||
error.debug.watch.add = Kan bekijken niet toevoegen aan deze variabele
|
||||
variables.column.scope = Scope
|
||||
variables.column.flags = Vlaggen
|
||||
|
||||
@@ -598,7 +598,7 @@ button.edit.script.disassembled = Editar P-code
|
||||
debug.watch.add = Adicionar rel\u00f3gio a %name%
|
||||
debug.watch.add.read = Ler
|
||||
debug.watch.add.write = Escrever
|
||||
debug.watch.add.readwrite = Ler+Escrever-
|
||||
debug.watch.add.readwrite = Ler + Escrever
|
||||
error.debug.watch.add = N\u00e3o foi poss\u00edvel adicionar rel\u00f3gio a esta vari\u00e1vel.
|
||||
variables.column.scope = Escopo
|
||||
variables.column.flags = Flags
|
||||
|
||||
@@ -598,7 +598,7 @@ button.edit.script.disassembled = Upravi\u0165 P-code
|
||||
debug.watch.add = Prida\u0165 sledovanie pre %name%
|
||||
debug.watch.add.read = \u010c\u00edtanie
|
||||
debug.watch.add.write = Z\u00e1pis
|
||||
debug.watch.add.readwrite = \u010c\u00edtanie+Z\u00e1pis-
|
||||
debug.watch.add.readwrite = \u010c\u00edtanie + Z\u00e1pis
|
||||
error.debug.watch.add = Nie je mo\u017en\u00e9 prida\u0165 sledovanie pre t\u00fato premenn\u00fa.
|
||||
variables.column.scope = Rozsah
|
||||
variables.column.flags = Pr\u00edznaky
|
||||
@@ -1128,3 +1128,8 @@ message.info.debugListen = Akcia po\u010d\u00favania v\u00e1m umo\u017e\u0148uje
|
||||
Nepripraven\u00e9 s\u00fabory bud\u00fa debuggerom ignorovan\u00e9!\n\n\
|
||||
Tip: Ak chcete len ladi\u0165 SWF v samostatnom content debuggeri,\n\
|
||||
pou\u017eite namiesto toho akciu "Ladi\u0165", preto\u017ee t\u00e1 pripravi SWF automaticky.\n\n
|
||||
|
||||
#after 25.1.1
|
||||
debug.watch.remove = Odstr\u00e1ni\u0165 sledovanie
|
||||
error.debug.watch.remove = Nie je mo\u017en\u00e9 odstr\u00e1ni\u0165 sledovanie z tejto premennej.
|
||||
variables.header.watches = Sledovania
|
||||
@@ -598,7 +598,7 @@ button.edit.script.disassembled = Uredi P-kodo
|
||||
debug.watch.add = Dodaj nadzor v %name%
|
||||
debug.watch.add.read = Preberi
|
||||
debug.watch.add.write = Pi\u0161i
|
||||
debug.watch.add.readwrite = Branje + pisanje-
|
||||
debug.watch.add.readwrite = Branje + pisanje
|
||||
error.debug.watch.add = Tej spremenljivki ni mogo\u010de dodati nadzora.
|
||||
variables.column.scope = Obseg
|
||||
variables.column.flags = Zastavice
|
||||
|
||||
@@ -596,7 +596,7 @@ button.edit.script.disassembled = Redigera P-Kod
|
||||
debug.watch.add = L\u00e4gg till watch till %name%
|
||||
debug.watch.add.read = L\u00e4s
|
||||
debug.watch.add.write = Skriv
|
||||
debug.watch.add.readwrite = L\u00e4s+Skriv-
|
||||
debug.watch.add.readwrite = L\u00e4s + Skriv
|
||||
error.debug.watch.add = Kan inte l\u00e4gga till watch till denna variabel.
|
||||
variables.column.scope = Scope
|
||||
variables.column.flags = Flags
|
||||
|
||||
@@ -598,7 +598,7 @@ button.edit.script.disassembled = P kodu d\u00fczenle
|
||||
debug.watch.add = \u0130zlemeyi %name% i\u00e7in ekle
|
||||
debug.watch.add.read = Oku
|
||||
debug.watch.add.write = Yaz
|
||||
debug.watch.add.readwrite = Oku+yaz-
|
||||
debug.watch.add.readwrite = Oku + yaz
|
||||
error.debug.watch.add = Bu de\u011fi\u015fkene izleme eklenemez.
|
||||
variables.column.scope = Kapsam
|
||||
variables.column.flags = Bayraklar
|
||||
|
||||
@@ -598,7 +598,7 @@ button.edit.script.disassembled = \u7f16\u8f91 P-code
|
||||
debug.watch.add = \u5c06\u76d1\u89c6\u6dfb\u52a0\u5230%name%
|
||||
debug.watch.add.read = \u8bfb\u53d6
|
||||
debug.watch.add.write = \u5199\u5165
|
||||
debug.watch.add.readwrite = \u8bfb+\u5199-
|
||||
debug.watch.add.readwrite = \u8bfb+\u5199
|
||||
error.debug.watch.add = \u65e0\u6cd5\u5c06\u76d1\u89c6\u6dfb\u52a0\u5230\u6b64\u53d8\u91cf\u3002
|
||||
variables.column.scope = \u8303\u56f4
|
||||
variables.column.flags = \u6807\u8bb0
|
||||
|
||||
Reference in New Issue
Block a user