mirror of
https://git.huckle.dev/Huckles-Minecraft-Archive/jpexs-decompiler.git
synced 2026-06-30 16:11:43 +00:00
Added AS3 Debugging - export/import ByteArray variable data
Fixed Debugging - properly getting variable value through getter
This commit is contained in:
@@ -6,6 +6,7 @@ All notable changes to this project will be documented in this file.
|
||||
- Configurable tab size (formatting must be set to use tabs) - default matches indent size of 3
|
||||
- [#2100] Copy/paste frames (same SWF only)
|
||||
- Updated portugese-brasil translation
|
||||
- AS3 Debugging - export/import ByteArray variable data
|
||||
|
||||
### Fixed
|
||||
- [#2021], [#2000] Caret position in editors when using tabs and / or unicode
|
||||
@@ -17,6 +18,7 @@ All notable changes to this project will be documented in this file.
|
||||
- [#2122] `-header` command did not support negative integers for displayrect
|
||||
- AS3 direct editation - namespaces were initialized in class initializers
|
||||
- Debugging - do not invoke getter when there is none - avoid freezing
|
||||
- Debugging - properly getting variable value through getter
|
||||
|
||||
|
||||
## [20.0.0] - 2023-11-05
|
||||
|
||||
Binary file not shown.
@@ -20,8 +20,11 @@ import com.jpexs.debugger.flash.Variable;
|
||||
import com.jpexs.debugger.flash.messages.in.InBreakAtExt;
|
||||
import com.jpexs.debugger.flash.messages.in.InConstantPool;
|
||||
import com.jpexs.debugger.flash.messages.in.InFrame;
|
||||
import com.jpexs.decompiler.flash.configuration.Configuration;
|
||||
import com.jpexs.decompiler.flash.gui.DebuggerHandler.BreakListener;
|
||||
import static com.jpexs.decompiler.flash.gui.Main.getDefaultMessagesComponent;
|
||||
import com.jpexs.decompiler.flash.gui.abc.ABCPanel;
|
||||
import com.jpexs.helpers.Helper;
|
||||
import de.hameister.treetable.MyTreeTable;
|
||||
import de.hameister.treetable.MyTreeTableModel;
|
||||
import java.awt.BorderLayout;
|
||||
@@ -31,9 +34,16 @@ import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
import java.awt.event.MouseAdapter;
|
||||
import java.awt.event.MouseEvent;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
import javax.swing.JButton;
|
||||
import javax.swing.JFileChooser;
|
||||
import javax.swing.JLabel;
|
||||
import javax.swing.JMenu;
|
||||
import javax.swing.JMenuItem;
|
||||
@@ -161,23 +171,60 @@ public class DebugPanel extends JPanel {
|
||||
ABCPanel.VariableNode vn;
|
||||
if (node instanceof ABCPanel.VariableNode) {
|
||||
vn = ((ABCPanel.VariableNode) node);
|
||||
v = vn.var;
|
||||
v = vn.varInsideGetter != null ? vn.varInsideGetter : vn.var;
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
|
||||
JPopupMenu pm = new JPopupMenu();
|
||||
//TODO!!
|
||||
/*if (v.typeName != null && v.typeName.startsWith("flash.utils::ByteArray")) {
|
||||
JMenu exportMenu = new JMenu("Export %name%".replace("%name%", v.name));
|
||||
JMenuItem exportByteArray = new JMenuItem("Export bytearray");
|
||||
exportByteArray.addActionListener((ActionEvent e1) -> {
|
||||
Main.dumpBytes(v);
|
||||
boolean isByteArray = false;
|
||||
for (Variable t : vn.traits) {
|
||||
if ("flash.utils::ByteArray".equals(t.name)) {
|
||||
isByteArray = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (isByteArray) {
|
||||
JMenu exportMenu = new JMenu(AppStrings.translate("debug.export").replace("%name%", v.name));
|
||||
JMenuItem exportByteArrayMenuItem = new JMenuItem(AppStrings.translate("debug.export.bytearray"));
|
||||
exportByteArrayMenuItem.addActionListener((ActionEvent e1) -> {
|
||||
JFileChooser fc = new JFileChooser();
|
||||
fc.setCurrentDirectory(new File(Configuration.lastExportDir.get()));
|
||||
if (fc.showSaveDialog(Main.getDefaultMessagesComponent()) == JFileChooser.APPROVE_OPTION) {
|
||||
File file = Helper.fixDialogFile(fc.getSelectedFile());
|
||||
try (FileOutputStream fos = new FileOutputStream(file)) {
|
||||
Main.debugExportByteArray(v, fos);
|
||||
Configuration.lastExportDir.set(file.getParentFile().getAbsolutePath());
|
||||
} catch (IOException ex) {
|
||||
Logger.getLogger(DebugPanel.class.getName()).log(Level.SEVERE, null, ex);
|
||||
ViewMessages.showMessageDialog(getDefaultMessagesComponent(), AppStrings.translate("error.file.save") + ": " + ex.getLocalizedMessage(), AppStrings.translate("error"), JOptionPane.ERROR_MESSAGE);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
exportMenu.add(exportByteArray);
|
||||
exportMenu.add(exportByteArrayMenuItem);
|
||||
pm.add(exportMenu);
|
||||
}*/
|
||||
|
||||
JMenu importMenu = new JMenu(AppStrings.translate("debug.import").replace("%name%", v.name));
|
||||
JMenuItem importByteArrayMenuItem = new JMenuItem(AppStrings.translate("debug.import.bytearray"));
|
||||
importByteArrayMenuItem.addActionListener((ActionEvent e1) -> {
|
||||
JFileChooser fc = new JFileChooser();
|
||||
fc.setCurrentDirectory(new File(Configuration.lastOpenDir.get()));
|
||||
if (fc.showOpenDialog(Main.getDefaultMessagesComponent()) == JFileChooser.APPROVE_OPTION) {
|
||||
File file = Helper.fixDialogFile(fc.getSelectedFile());
|
||||
Configuration.lastOpenDir.set(file.getParentFile().getAbsolutePath());
|
||||
try (FileInputStream fis = new FileInputStream(file)) {
|
||||
Main.debugImportByteArray(v, fis);
|
||||
} catch (IOException ex) {
|
||||
Logger.getLogger(DebugPanel.class.getName()).log(Level.SEVERE, null, ex);
|
||||
ViewMessages.showMessageDialog(getDefaultMessagesComponent(), AppStrings.translate("error.file.save") + ": " + ex.getLocalizedMessage(), AppStrings.translate("error"), JOptionPane.ERROR_MESSAGE);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
importMenu.add(importByteArrayMenuItem);
|
||||
pm.add(importMenu);
|
||||
}
|
||||
long watchParentId = vn.parentObjectId;
|
||||
|
||||
JMenu addWatchMenu = new JMenu(AppStrings.translate("debug.watch.add").replace("%name%", v.name));
|
||||
|
||||
@@ -291,25 +291,50 @@ public class Main {
|
||||
return runProcess != null && !runProcessDebug;
|
||||
}
|
||||
|
||||
/*
|
||||
* FIXME!
|
||||
*/
|
||||
public static synchronized void dumpBytes(Variable v) {
|
||||
InCallFunction icf;
|
||||
|
||||
public static synchronized void debugExportByteArray(Variable v, OutputStream os) throws IOException {
|
||||
try {
|
||||
long objectId = 0L;
|
||||
if ((v.vType == VariableType.OBJECT || v.vType == VariableType.MOVIECLIP)) {
|
||||
objectId = (Long) v.value;
|
||||
}
|
||||
Object oldPos = getDebugHandler().getVariable(objectId, "position", true, true).parent.value;
|
||||
Object oldPos = getDebugHandler().getVariable(objectId, "position", false, true).parent.value;
|
||||
getDebugHandler().setVariable(objectId, "position", VariableType.NUMBER, 0);
|
||||
icf = getDebugHandler().callFunction(false, "readUTF", v, new ArrayList<>());
|
||||
System.out.println("Result=" + icf.variables.get(0).value);
|
||||
int length = (int)(double)(Double)getDebugHandler().getVariable(objectId, "length", false, true).parent.value;
|
||||
|
||||
for (int i = 0; i < length; i++) {
|
||||
int b = (int)(double)(Double)getDebugHandler().callFunction(false, "readByte", v, new ArrayList<>()).variables.get(0).value;
|
||||
os.write(b);
|
||||
}
|
||||
getDebugHandler().setVariable(objectId, "position", VariableType.NUMBER, oldPos);
|
||||
} catch (DebuggerHandler.ActionScriptException ex) {
|
||||
Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
|
||||
}
|
||||
}
|
||||
|
||||
public static synchronized void debugImportByteArray(Variable v, InputStream is) throws IOException {
|
||||
try {
|
||||
long objectId = 0L;
|
||||
if ((v.vType == VariableType.OBJECT || v.vType == VariableType.MOVIECLIP)) {
|
||||
objectId = (Long) v.value;
|
||||
}
|
||||
Double oldPos = (Double) getDebugHandler().getVariable(objectId, "position", false, true).parent.value;
|
||||
getDebugHandler().setVariable(objectId, "length", VariableType.NUMBER, 0);
|
||||
getDebugHandler().setVariable(objectId, "position", VariableType.NUMBER, 0);
|
||||
|
||||
int length = 0;
|
||||
int b;
|
||||
while ((b = is.read()) > -1) {
|
||||
getDebugHandler().callFunction(false, "writeByte", v, Arrays.asList((Double)(double) b));
|
||||
length++;
|
||||
}
|
||||
if (oldPos > length) {
|
||||
oldPos = (Double) (double) length;
|
||||
}
|
||||
getDebugHandler().setVariable(objectId, "position", VariableType.NUMBER, oldPos);
|
||||
} catch (DebuggerHandler.ActionScriptException ex) {
|
||||
Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static synchronized boolean addWatch(Variable v, long v_id, boolean watchRead, boolean watchWrite) {
|
||||
|
||||
@@ -289,6 +289,8 @@ public class ABCPanel extends JPanel implements ItemListener, SearchListener<Scr
|
||||
public long traitId;
|
||||
|
||||
private List<VariableNode> childs;
|
||||
|
||||
public List<Variable> traits = new ArrayList<>();
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
@@ -347,17 +349,18 @@ public class ABCPanel extends JPanel implements ItemListener, SearchListener<Scr
|
||||
|
||||
private void reloadChildren() {
|
||||
childs = new ArrayList<>();
|
||||
traits = new ArrayList<>();
|
||||
|
||||
if ("".equals(var.name)) {
|
||||
return;
|
||||
}
|
||||
InGetVariable igv;
|
||||
|
||||
Long objectId = varToObjectId(varInsideGetter);
|
||||
Long objectId = varToObjectId(var);
|
||||
|
||||
boolean useGetter = (var.flags & VariableFlags.HAS_GETTER) > 0;
|
||||
|
||||
if (parentObjectId == 0 && objectId != 0) {
|
||||
boolean useGetter = (var.flags & VariableFlags.IS_CONST) == 0;
|
||||
|
||||
if (objectId != 0) {
|
||||
igv = Main.getDebugHandler().getVariable(objectId, "", true, useGetter);
|
||||
} else {
|
||||
igv = Main.getDebugHandler().getVariable(parentObjectId, var.name, true, useGetter);
|
||||
@@ -371,10 +374,11 @@ public class ABCPanel extends JPanel implements ItemListener, SearchListener<Scr
|
||||
Variable curTrait = null;
|
||||
for (int i = 0; i < igv.childs.size(); i++) {
|
||||
if (!isTraits(igv.childs.get(i))) {
|
||||
Long parentObjectId = varToObjectId(var);
|
||||
Long parentObjectId = varToObjectId(varInsideGetter);
|
||||
childs.add(new VariableNode(path, level + 1, igv.childs.get(i), parentObjectId, curTrait));
|
||||
} else {
|
||||
curTrait = igv.childs.get(i);
|
||||
traits.add(curTrait);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -427,11 +431,13 @@ public class ABCPanel extends JPanel implements ItemListener, SearchListener<Scr
|
||||
}
|
||||
|
||||
public static Long varToObjectId(Variable var) {
|
||||
if (var != null && (var.vType == VariableType.OBJECT)) {
|
||||
return (Long) var.value;
|
||||
} else {
|
||||
if (var == null) {
|
||||
return 0L;
|
||||
}
|
||||
if (var.vType == VariableType.OBJECT) {
|
||||
return (Long) var.value;
|
||||
}
|
||||
return 0L;
|
||||
}
|
||||
|
||||
public static class VariablesTableModel implements MyTreeTableModel {
|
||||
|
||||
@@ -1229,4 +1229,9 @@ contextmenu.moveFrame = Move frame to
|
||||
contextmenu.clipboard.frame = Frame clipboard
|
||||
|
||||
clipboard.hint.frame = Number of items in the frame clipboard
|
||||
clipboard.clear.frame = Clear the frame clipboard
|
||||
clipboard.clear.frame = Clear the frame clipboard
|
||||
|
||||
debug.export = Export %name%
|
||||
debug.export.bytearray = Export byte array data...
|
||||
debug.import = Import to %name%
|
||||
debug.import.bytearray = Import byte array data...
|
||||
@@ -1206,4 +1206,9 @@ contextmenu.moveFrame = P\u0159esunout sn\u00edmek do
|
||||
contextmenu.clipboard.frame = Sn\u00edmkov\u00e1 schr\u00e1nka
|
||||
|
||||
clipboard.hint.frame = Po\u010det polo\u017eek ve sn\u00edmkov\u00e9 schr\u00e1nce
|
||||
clipboard.clear.frame = Vy\u010distit sn\u00edmkovou schr\u00e1nku
|
||||
clipboard.clear.frame = Vy\u010distit sn\u00edmkovou schr\u00e1nku
|
||||
|
||||
debug.export = Exportovat %name%
|
||||
debug.export.bytearray = Exportovat byte array data...
|
||||
debug.import = Importovat do %name%
|
||||
debug.import.bytearray = Importovat byte array data...
|
||||
Reference in New Issue
Block a user