diff --git a/CHANGELOG.md b/CHANGELOG.md index 5ae62a40c..d9f7c7867 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,8 @@ All notable changes to this project will be documented in this file. ## [Unreleased] +### Added +- [#2221] AS3 P-code - add new function button (creates methodinfo, methodbody) ## [21.0.0] - 2024-08-05 ### Added @@ -3463,6 +3465,7 @@ Major version of SWF to XML export changed to 2. [alpha 9]: https://github.com/jindrapetrik/jpexs-decompiler/compare/alpha8...alpha9 [alpha 8]: https://github.com/jindrapetrik/jpexs-decompiler/compare/alpha7...alpha8 [alpha 7]: https://github.com/jindrapetrik/jpexs-decompiler/releases/tag/alpha7 +[#2221]: https://www.free-decompiler.com/flash/issues/2221 [#2176]: https://www.free-decompiler.com/flash/issues/2176 [#2179]: https://www.free-decompiler.com/flash/issues/2179 [#2185]: https://www.free-decompiler.com/flash/issues/2185 diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/configuration/Configuration.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/configuration/Configuration.java index 15315ddc1..be925bda5 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/configuration/Configuration.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/configuration/Configuration.java @@ -1008,6 +1008,11 @@ public final class Configuration { @ConfigurationDefaultBoolean(true) @ConfigurationCategory("script") public static ConfigurationItem warningAbcClean = null; + + @ConfigurationDefaultBoolean(true) + @ConfigurationCategory("script") + public static ConfigurationItem warningAddFunction = null; + private enum OSId { WINDOWS, OSX, UNIX diff --git a/src/com/jpexs/decompiler/flash/gui/abc/ABCPanel.java b/src/com/jpexs/decompiler/flash/gui/abc/ABCPanel.java index e95908ed7..1deabfe74 100644 --- a/src/com/jpexs/decompiler/flash/gui/abc/ABCPanel.java +++ b/src/com/jpexs/decompiler/flash/gui/abc/ABCPanel.java @@ -51,7 +51,6 @@ import com.jpexs.decompiler.flash.configuration.SwfSpecificCustomConfiguration; import com.jpexs.decompiler.flash.ecma.EcmaScript; import com.jpexs.decompiler.flash.gui.AppDialog; import com.jpexs.decompiler.flash.gui.AppStrings; -import com.jpexs.decompiler.flash.gui.BreakpointListDialog; import com.jpexs.decompiler.flash.gui.DebugPanel; import com.jpexs.decompiler.flash.gui.DebuggerHandler; import com.jpexs.decompiler.flash.gui.FasterScrollPane; @@ -114,7 +113,6 @@ import java.util.Map; import java.util.Objects; import java.util.logging.Level; import java.util.logging.Logger; -import java.util.regex.Pattern; import javax.swing.AbstractAction; import javax.swing.BorderFactory; import javax.swing.BoxLayout; diff --git a/src/com/jpexs/decompiler/flash/gui/abc/MethodCodePanel.java b/src/com/jpexs/decompiler/flash/gui/abc/MethodCodePanel.java index aa2db5958..4c6bd3432 100644 --- a/src/com/jpexs/decompiler/flash/gui/abc/MethodCodePanel.java +++ b/src/com/jpexs/decompiler/flash/gui/abc/MethodCodePanel.java @@ -17,6 +17,12 @@ package com.jpexs.decompiler.flash.gui.abc; import com.jpexs.decompiler.flash.abc.ABC; +import com.jpexs.decompiler.flash.abc.avm2.instructions.AVM2Instruction; +import com.jpexs.decompiler.flash.abc.avm2.instructions.AVM2Instructions; +import com.jpexs.decompiler.flash.abc.avm2.instructions.InstructionDefinition; +import com.jpexs.decompiler.flash.abc.types.MethodBody; +import com.jpexs.decompiler.flash.abc.types.MethodInfo; +import com.jpexs.decompiler.flash.abc.types.ValueKind; import com.jpexs.decompiler.flash.abc.types.traits.Trait; import com.jpexs.decompiler.flash.configuration.Configuration; import com.jpexs.decompiler.flash.exporters.modes.ScriptExportMode; @@ -25,16 +31,24 @@ import com.jpexs.decompiler.flash.gui.DocsPanel; import com.jpexs.decompiler.flash.gui.FasterScrollPane; import com.jpexs.decompiler.flash.gui.Main; import com.jpexs.decompiler.flash.gui.View; +import com.jpexs.decompiler.flash.gui.ViewMessages; import com.jpexs.decompiler.flash.gui.controls.JPersistentSplitPane; import com.jpexs.decompiler.flash.gui.controls.NoneSelectedButtonGroup; import com.jpexs.decompiler.flash.helpers.hilight.HighlightSpecialType; +import com.jpexs.decompiler.flash.tags.Tag; import java.awt.BorderLayout; import java.awt.Dimension; +import java.awt.FlowLayout; import java.awt.Insets; +import java.awt.Toolkit; +import java.awt.datatransfer.Clipboard; +import java.awt.datatransfer.StringSelection; import java.awt.event.ActionEvent; +import java.util.List; import javax.swing.Box; import javax.swing.BoxLayout; import javax.swing.JButton; +import javax.swing.JOptionPane; import javax.swing.JPanel; import javax.swing.JSplitPane; import javax.swing.JToggleButton; @@ -49,12 +63,14 @@ public class MethodCodePanel extends JPanel { private final FasterScrollPane sourceScrollPane; - public JPanel buttonsPanel; + public JPanel detailButtonsPanel; private final JToggleButton hexButton; private final JToggleButton hexOnlyButton; + private final JButton addFunctionButton; + private final DocsPanel docsPanel; public ABC getABC() { @@ -140,8 +156,8 @@ public class MethodCodePanel extends JPanel { sourceTextArea.changeContentType("text/flasm3"); sourceTextArea.setFont(Configuration.getSourceFont()); - buttonsPanel = new JPanel(); - buttonsPanel.setLayout(new BoxLayout(buttonsPanel, BoxLayout.X_AXIS)); + detailButtonsPanel = new JPanel(); + detailButtonsPanel.setLayout(new BoxLayout(detailButtonsPanel, BoxLayout.X_AXIS)); JButton graphButton = new JButton(View.getIcon("graph16")); graphButton.addActionListener(this::graphButtonActionPerformed); @@ -158,16 +174,30 @@ public class MethodCodePanel extends JPanel { hexOnlyButton.setToolTipText(AppStrings.translate("button.viewhex")); hexOnlyButton.setMargin(new Insets(3, 3, 3, 3)); + addFunctionButton = new JButton(View.getIcon("addfunction16")); + addFunctionButton.addActionListener(this::addFunctionButtonActionPerformed); + addFunctionButton.setToolTipText(AppStrings.translate("button.addfunction")); + addFunctionButton.setMargin(new Insets(3, 3, 3, 3)); + NoneSelectedButtonGroup exportModeButtonGroup = new NoneSelectedButtonGroup(); exportModeButtonGroup.add(hexButton); exportModeButtonGroup.add(hexOnlyButton); - buttonsPanel.add(graphButton); - buttonsPanel.add(Box.createRigidArea(new Dimension(10, 0))); - buttonsPanel.add(hexButton); - buttonsPanel.add(hexOnlyButton); - buttonsPanel.add(new JPanel()); + detailButtonsPanel.add(graphButton); + detailButtonsPanel.add(Box.createRigidArea(new Dimension(10, 0))); + detailButtonsPanel.add(hexButton); + detailButtonsPanel.add(hexOnlyButton); + JPanel buttonsPanel = new JPanel(); + buttonsPanel.setLayout(new BoxLayout(buttonsPanel, BoxLayout.X_AXIS)); + JPanel editVisibleButtonsPanel = new JPanel(); + editVisibleButtonsPanel.setLayout(new BoxLayout(editVisibleButtonsPanel, BoxLayout.X_AXIS)); + editVisibleButtonsPanel.add(addFunctionButton); + + buttonsPanel.add(detailButtonsPanel); + buttonsPanel.add(Box.createHorizontalStrut(5)); + buttonsPanel.add(editVisibleButtonsPanel); + buttonsPanel.add(Box.createHorizontalGlue()); add(buttonsPanel, BorderLayout.NORTH); } @@ -196,6 +226,27 @@ public class MethodCodePanel extends JPanel { sourceTextArea.setHex(getExportMode(), false); } + private void addFunctionButtonActionPerformed(ActionEvent evt) { + if (ViewMessages.showConfirmDialog(this, AppStrings.translate("message.confirm.addfunction"), AppStrings.translate("message.warning"), JOptionPane.OK_CANCEL_OPTION, JOptionPane.WARNING_MESSAGE, Configuration.warningAddFunction, JOptionPane.OK_OPTION) != JOptionPane.OK_OPTION) { + return; + } + MethodInfo methodInfoObj = new MethodInfo(new int[0], 0, 0, 0, null, null); + ABC abc = getABC(); + int methodInfo = abc.addMethodInfo(methodInfoObj); + MethodBody body = new MethodBody(); + List code = body.getCode().code; + code.add(new AVM2Instruction(0, AVM2Instructions.ReturnVoid, new int[0])); + body.method_info = methodInfo; + abc.addMethodBody(body); + ((Tag) abc.parentTag).setModified(true); + if (ViewMessages.showConfirmDialog(this, AppStrings.translate("addfunction.result").replace("%method_info_index%", "" + methodInfo), AppStrings.translate("addfunction.result.title"), JOptionPane.OK_CANCEL_OPTION) != JOptionPane.OK_OPTION) { + return; + } + StringSelection stringSelection = new StringSelection("" + methodInfo); + Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard(); + clipboard.setContents(stringSelection, null); + } + public ASMSourceEditorPane getSourceTextArea() { return sourceTextArea; } @@ -216,6 +267,6 @@ public class MethodCodePanel extends JPanel { sourceTextArea.setEditable(val); sourceTextArea.getCaret().setVisible(true); - buttonsPanel.setVisible(!val); + detailButtonsPanel.setVisible(!val); } } diff --git a/src/com/jpexs/decompiler/flash/gui/graphics/addfunction16.png b/src/com/jpexs/decompiler/flash/gui/graphics/addfunction16.png new file mode 100644 index 000000000..9c799402f Binary files /dev/null and b/src/com/jpexs/decompiler/flash/gui/graphics/addfunction16.png differ diff --git a/src/com/jpexs/decompiler/flash/gui/locales/AdvancedSettingsDialog.properties b/src/com/jpexs/decompiler/flash/gui/locales/AdvancedSettingsDialog.properties index be9a796f5..fc3e2e735 100644 --- a/src/com/jpexs/decompiler/flash/gui/locales/AdvancedSettingsDialog.properties +++ b/src/com/jpexs/decompiler/flash/gui/locales/AdvancedSettingsDialog.properties @@ -773,3 +773,5 @@ config.description.lastExportTransparentBackground = Last setting of ignoring ba config.name.warningAbcClean = Warn on Abc clean action config.description.warningAbcClean = Show warning before doing Abc clean action +config.name.warningAddFunction = Warn on adding new function in AS3 P-code +config.description.warningAddFunction = Show warning before creating new function in AS3 P-code. It also shows some info how the action works. diff --git a/src/com/jpexs/decompiler/flash/gui/locales/AdvancedSettingsDialog_cs.properties b/src/com/jpexs/decompiler/flash/gui/locales/AdvancedSettingsDialog_cs.properties index 512208dd3..2c8b91b4f 100644 --- a/src/com/jpexs/decompiler/flash/gui/locales/AdvancedSettingsDialog_cs.properties +++ b/src/com/jpexs/decompiler/flash/gui/locales/AdvancedSettingsDialog_cs.properties @@ -761,4 +761,7 @@ config.name.lastExportTransparentBackground = Posledn\u00ed nastaven\u00ed ignor config.description.lastExportTransparentBackground = Posledn\u00ed nastaven\u00ed ignorov\u00e1n\u00ed barvy pozad\u00ed v exportu sn\u00edmk\u016f pro pou\u017eit\u00ed pr\u016fhledn\u00e9ho pozad\u00ed config.name.warningAbcClean= Varovat p\u0159i Abc \u010di\u0161t\u011bn\u00ed -config.description.warningAbcClean = Zobrazovat varov\u00e1n\u00ed p\u0159ed proveden\u00edm Abc \u010di\u0161t\u011bn\u00ed \ No newline at end of file +config.description.warningAbcClean = Zobrazovat varov\u00e1n\u00ed p\u0159ed proveden\u00edm Abc \u010di\u0161t\u011bn\u00ed + +config.name.warningAddFunction = Varovat p\u0159i p\u0159id\u00e1v\u00e1n\u00ed nov\u00e9 funkce v AS3 P-k\u00f3du +config.description.warningAddFunction = Zobrazovat varov\u00e1n\u00ed p\u0159ed p\u0159id\u00e1n\u00edm nov\u00e9 funkce v AS3 P-k\u00f3du. Tak\u00e9 to zobrazuje n\u011bjak\u00e9 informace o tom, jak tato akce funguje. diff --git a/src/com/jpexs/decompiler/flash/gui/locales/MainFrame.properties b/src/com/jpexs/decompiler/flash/gui/locales/MainFrame.properties index 3ada9f712..bfcf9e577 100644 --- a/src/com/jpexs/decompiler/flash/gui/locales/MainFrame.properties +++ b/src/com/jpexs/decompiler/flash/gui/locales/MainFrame.properties @@ -1302,4 +1302,15 @@ filter.exe.projectorWin = Windows projector file (*.exe) filter.exe.projectorMac = Mac Os projector file (*.dmg) filter.exe.projectorLinux = Linux projector file -callStack.header.swf = SWF \ No newline at end of file +callStack.header.swf = SWF + +#after 21.0.0 +button.addfunction = Add new function + +message.confirm.addfunction = This action creates a new MethodInfo object with \ + assigned MethodBody and returns method info index\r\n\ + which you can use as operand for newfunction instruction.\r\n\ + For editation of body and parameters of such function, you must locate it then in ActionScript view. + +addfunction.result = New method info id generated: %method_info_index%. Press OK to copy it to clipboard. +addfunction.result.title = New method info \ No newline at end of file diff --git a/src/com/jpexs/decompiler/flash/gui/locales/MainFrame_cs.properties b/src/com/jpexs/decompiler/flash/gui/locales/MainFrame_cs.properties index 2644d0cb2..d6d2ee9fa 100644 --- a/src/com/jpexs/decompiler/flash/gui/locales/MainFrame_cs.properties +++ b/src/com/jpexs/decompiler/flash/gui/locales/MainFrame_cs.properties @@ -1271,4 +1271,15 @@ contextmenu.exportFla = Exportovat do FLA export.project.select.directory = Vyberte um\u00edst\u011bn\u00ed nov\u00e9ho adres\u00e1\u0159e projektu -callStack.header.swf = SWF \ No newline at end of file +callStack.header.swf = SWF + +#after 21.0.0 +button.addfunction = P\u0159idat novou funkci + +message.confirm.addfunction = Tato akce vytvo\u0159\u00ed nov\u00fd objekt MethodInfo s \ + p\u0159i\u0159azen\u00fdm MethodBody a vr\u00e1t\u00ed index infa metody\r\n\ + kter\u00fd m\u016f\u017eete pou\u017e\u00edt jako operand pro instrukci newfunction.\r\n\ + Pro editaci t\u011bla a parametr\u016f takov\u00e9 funkce ji mus\u00edte pot\u00e9 vyhledat v ActionScript pohledu. + +addfunction.result = Nov\u00e9 id method infa: %method_info_index%. Stiskn\u011bte OK pro zkop\u00edrov\u00e1n\u00ed do schr\u00e1nky. +addfunction.result.title = Nov\u00e9 method info \ No newline at end of file