Optimize ABC action renamed to Clean ABC

Clean ABC is available through context menu on ABC, ABCContainers, SWFs
This commit is contained in:
Jindra Petřík
2024-07-29 11:14:35 +02:00
parent 0e6c092e6a
commit ddac29e342
12 changed files with 74 additions and 50 deletions

View File

@@ -22,7 +22,8 @@ All notable changes to this project will be documented in this file.
- ABC Explorer - items with zero usages are semi-transparent
- ABC Explorer - copy path to clipboard
- ABC Explorer - Go to path via `Ctrl + G`
- Optimize ABC action (remove unused items) - available through ABC Explorer
- Clean ABC action (remove unused items)
available through context menu on ABC, ABCContainers, SWFs and in the ABC Explorer
### Fixed
- Debugger - getting children of top level variables

View File

@@ -39,23 +39,19 @@ import com.jpexs.decompiler.flash.abc.types.traits.TraitSlotConst;
import com.jpexs.decompiler.flash.abc.types.traits.Traits;
import com.jpexs.decompiler.flash.tags.Tag;
import com.jpexs.helpers.NulStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;
/**
*
* @author JPEXS
*/
public class ABCOptimizer {
public class ABCCleaner {
public void optimize(ABC abc) {
public void clean(ABC abc) {
ABCSimpleUsageDetector usageDetector = new ABCSimpleUsageDetector(abc);
usageDetector.detect();
Map<ABCSimpleUsageDetector.ItemKind, List<List<String>>> usages = usageDetector.getUsages();
@@ -78,21 +74,7 @@ public class ABCOptimizer {
pos++;
}
}
}
/*
for (ABCSimpleUsageDetector.ItemKind kind : replaceMap.keySet()) {
System.err.println("---------");
System.err.println("" + kind + " map:");
for (int key : replaceMap.get(kind).keySet()) {
System.err.println(" " + key + " => " + replaceMap.get(kind).get(key));
}
System.err.println(" " + kind + " not referenced:");
for (int key : notReferencedIndices.get(kind)) {
System.err.println(" " + key);
}
}
System.err.println("==================="); */
}
for (int i = 0; i < abc.script_info.size(); i++) {
ScriptInfo m = abc.script_info.get(i);

View File

@@ -1007,7 +1007,7 @@ public final class Configuration {
@ConfigurationDefaultBoolean(true)
@ConfigurationCategory("script")
public static ConfigurationItem<Boolean> warningAbcOptimize = null;
public static ConfigurationItem<Boolean> warningAbcClean = null;
private enum OSId {
WINDOWS, OSX, UNIX

View File

@@ -38,7 +38,7 @@ import com.jpexs.decompiler.flash.abc.types.traits.TraitFunction;
import com.jpexs.decompiler.flash.abc.types.traits.TraitMethodGetterSetter;
import com.jpexs.decompiler.flash.abc.types.traits.TraitSlotConst;
import com.jpexs.decompiler.flash.abc.types.traits.Traits;
import com.jpexs.decompiler.flash.abc.usages.simple.ABCOptimizer;
import com.jpexs.decompiler.flash.abc.usages.simple.ABCCleaner;
import com.jpexs.decompiler.flash.abc.usages.simple.ABCSimpleUsageDetector;
import com.jpexs.decompiler.flash.configuration.Configuration;
import com.jpexs.decompiler.flash.ecma.EcmaScript;
@@ -135,7 +135,7 @@ public class ABCExplorerDialog extends AppDialog {
private ABCSimpleUsageDetector usageDetector = null;
private JButton optimizeButton = new JButton(View.getIcon("optimize16"));
private JButton cleanButton = new JButton(View.getIcon("clean16"));
private JTable usagesTable = new JTable(new DefaultTableModel()) {
@Override
@@ -209,11 +209,11 @@ public class ABCExplorerDialog extends AppDialog {
tagInfoLabel = new JLabel();
topLeftPanel.add(tagInfoLabel);
optimizeButton.setToolTipText(translate("button.optimize"));
optimizeButton.addActionListener(this::optimizeActionPerformed);
cleanButton.setToolTipText(translate("button.clean"));
cleanButton.addActionListener(this::cleanActionPerformed);
JPanel topRightPanel = new JPanel(new FlowLayout());
topRightPanel.add(optimizeButton);
topRightPanel.add(cleanButton);
JPanel topPanel = new JPanel(new BorderLayout());
topPanel.add(topLeftPanel, BorderLayout.WEST);
@@ -445,8 +445,8 @@ public class ABCExplorerDialog extends AppDialog {
newUsageDetector.detect();
usageDetector = newUsageDetector;
int zeroUsages = newUsageDetector.getZeroUsagesCount();
optimizeButton.setText("(" + zeroUsages + ")");
optimizeButton.setEnabled(zeroUsages > 0);
cleanButton.setText("(" + zeroUsages + ")");
cleanButton.setEnabled(zeroUsages > 0);
}
private JTree getCurrentTree() {
@@ -2652,16 +2652,16 @@ public class ABCExplorerDialog extends AppDialog {
}
}
private void optimizeActionPerformed(ActionEvent e) {
private void cleanActionPerformed(ActionEvent e) {
ABC abc = getSelectedAbc();
if (abc != null) {
if (ViewMessages.showConfirmDialog(this, translate("warning.optimize"), AppStrings.translate("message.warning"), JOptionPane.OK_CANCEL_OPTION, Configuration.warningAbcOptimize, JOptionPane.OK_OPTION) != JOptionPane.OK_OPTION) {
if (ViewMessages.showConfirmDialog(this, AppStrings.translate("warning.cleanAbc"), AppStrings.translate("message.warning"), JOptionPane.OK_CANCEL_OPTION, Configuration.warningAbcClean, JOptionPane.OK_OPTION) != JOptionPane.OK_OPTION) {
return;
}
int mainIndex = mainTabbedPane.getSelectedIndex();
int cpIndex = cpTabbedPane.getSelectedIndex();
ABCOptimizer optimizer = new ABCOptimizer();
optimizer.optimize(abc);
ABCCleaner cleaner = new ABCCleaner();
cleaner.clean(abc);
if (cpIndex > -1) {
cpTabbedPane.setSelectedIndex(cpIndex);
}

View File

Before

Width:  |  Height:  |  Size: 1.6 KiB

After

Width:  |  Height:  |  Size: 1.6 KiB

View File

@@ -770,6 +770,6 @@ config.description.previewResampleSound = Resample to 44kHz in sound previews
config.name.lastExportTransparentBackground = Last setting of ignoring background color in frame export
config.description.lastExportTransparentBackground = Last setting of ignoring background color for frame export to make background transparency
config.name.warningAbcOptimize = Warn on Abc optimize action
config.description.warningAbcOptimize = Show warning before doing Abc optimize action
config.name.warningAbcClean = Warn on Abc clean action
config.description.warningAbcClean = Show warning before doing Abc clean action

View File

@@ -760,5 +760,5 @@ config.description.previewResampleSound = P\u0159evzorkovat na 44kHz v n\u00e1hl
config.name.lastExportTransparentBackground = Posledn\u00ed nastaven\u00ed ignorov\u00e1n\u00ed barvy pozad\u00ed v exportu sn\u00edmk\u016f
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.warningAbcOptimize = Varovat p\u0159i Abc optimizaci
config.description.warningAbcOptimize = Zobrazovat varov\u00e1n\u00ed p\u0159ed proveden\u00edm Abc optimizace
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

View File

@@ -1261,4 +1261,10 @@ contextmenu.collectDepthAsSprites = Collect tags at same depth as sprites
preview.resample = Resample sound to 44kHz
contextmenu.setClassToCharacterMapping = Set class to character mapping
contextmenu.setClassToCharacterMapping = Set class to character mapping
contextmenu.cleanAbc = Clean ABC - remove unused items
warning.cleanAbc = This action will remove items from ABC which have zero usages - they are not referenced form any script.\r\n\
Some kinds of obfuscated SWFs could be damaged this way.\r\n\
Use it at your own risk. Do you want to continue?

View File

@@ -1236,4 +1236,10 @@ contextmenu.collectDepthAsSprites = Posb\u00edrat tagy ve stejn\u00e9 hloubce do
preview.resample = Resample sound to 44kHz
contextmenu.setClassToCharacterMapping = Nastavit mapov\u00e1n\u00ed t\u0159\u00eddy na charakter
contextmenu.setClassToCharacterMapping = Nastavit mapov\u00e1n\u00ed t\u0159\u00eddy na charakter
contextmenu.cleanAbc = Vy\u010distit ABC - odebrat nepou\u017e\u00edvan\u00e9 polo\u017eky
warning.cleanAbc = Tato akce odstran\u00ed z ABC polo\u017eky, kter\u00e9 maj\u00ed nula pou\u017eit\u00ed - nen\u00ed na n\u011b odkazov\u00e1no z \u017e\u00e1dn\u00e9ho skriptu.\r\n\
N\u011bkter\u00e9 druhy obfuskovan\u00fdch SWF to m\u016f\u017ee po\u0161kodit.\r\n\
Pou\u017e\u00edvejte ji na vlastn\u00ed riziko. Chcete pokra\u010dovat?

View File

@@ -39,8 +39,4 @@ hilight.usage = Hilight selected path
goto.path = Go to path
goto.path.label = Enter path to navigate to
button.optimize = Optimize - remove unused items
warning.optimize = This action will remove items from ABC which have zero usages - they are not referenced form any script.\r\n\
Some kinds of obfuscated SWFs could be damaged this way.\r\n\
Use it at your own risk. Do you want to continue?
button.clean = Clean - remove unused items

View File

@@ -40,8 +40,4 @@ hilight.usage = Zv\u00fdraznit vybranou cestu
goto.path = P\u0159ej\u00edt na cestu
goto.path.label = Zadejte cestu kam p\u0159ej\u00edt
button.optimize = Optimalizovat - odebrat nepou\u017e\u00edvan\u00e9 polo\u017eky
warning.optimize = Tato akce odstran\u00ed z ABC polo\u017eky, kter\u00e9 maj\u00ed nula pou\u017eit\u00ed - nen\u00ed na n\u011b odkazov\u00e1no z \u017e\u00e1dn\u00e9ho skriptu.\r\n\
N\u011bkter\u00e9 druhy obfuskovan\u00fdch SWF to m\u016f\u017ee po\u0161kodit.\r\n\
Pou\u017e\u00edvejte ji na vlastn\u00ed riziko. Chcete pokra\u010dovat?
button.clean = Vy\u010distit - odebrat nepou\u017e\u00edvan\u00e9 polo\u017eky

View File

@@ -27,6 +27,7 @@ import com.jpexs.decompiler.flash.abc.ScriptPack;
import com.jpexs.decompiler.flash.abc.avm2.parser.AVM2ParseException;
import com.jpexs.decompiler.flash.abc.avm2.parser.script.AbcIndexing;
import com.jpexs.decompiler.flash.abc.avm2.parser.script.ActionScript3Parser;
import com.jpexs.decompiler.flash.abc.usages.simple.ABCCleaner;
import com.jpexs.decompiler.flash.action.Action;
import com.jpexs.decompiler.flash.action.parser.ActionParseException;
import com.jpexs.decompiler.flash.action.parser.script.ActionScript2Parser;
@@ -314,6 +315,8 @@ public class TagTreeContextMenu extends JPopupMenu {
private JMenuItem unpinOthersMenuItem;
private JMenuItem abcExplorerMenuItem;
private JMenuItem cleanAbcMenuItem;
private JMenuItem replaceWithGifMenuItem;
@@ -453,6 +456,11 @@ public class TagTreeContextMenu extends JPopupMenu {
abcExplorerMenuItem.addActionListener(this::abcExplorerActionPerformed);
abcExplorerMenuItem.setIcon(View.getIcon("abcexplorer16"));
add(abcExplorerMenuItem);
cleanAbcMenuItem = new JMenuItem(mainPanel.translate("contextmenu.cleanAbc"));
cleanAbcMenuItem.addActionListener(this::cleanAbcActionPerformed);
cleanAbcMenuItem.setIcon(View.getIcon("clean16"));
add(cleanAbcMenuItem);
rawEditMenuItem = new JMenuItem(mainPanel.translate("contextmenu.rawEdit"));
rawEditMenuItem.addActionListener(this::rawEditActionPerformed);
@@ -1134,6 +1142,7 @@ public class TagTreeContextMenu extends JPopupMenu {
replaceWithTagMenuItem.setVisible(false);
replaceRefsWithTagMenuItem.setVisible(false);
abcExplorerMenuItem.setVisible(false);
cleanAbcMenuItem.setVisible(false);
rawEditMenuItem.setVisible(false);
jumpToCharacterMenuItem.setVisible(false);
exportJavaSourceMenuItem.setVisible(allSelectedIsSwf);
@@ -1382,10 +1391,12 @@ public class TagTreeContextMenu extends JPopupMenu {
if (firstItem instanceof ABCContainerTag) {
abcExplorerMenuItem.setVisible(true);
cleanAbcMenuItem.setVisible(true);
}
if (firstItem instanceof ABC) {
abcExplorerMenuItem.setVisible(true);
cleanAbcMenuItem.setVisible(true);
}
if (firstItem instanceof ClassesListTreeModel) {
@@ -1396,6 +1407,7 @@ public class TagTreeContextMenu extends JPopupMenu {
SWF swf = (SWF) firstItem;
if (swf.isAS3()) {
abcExplorerMenuItem.setVisible(true);
cleanAbcMenuItem.setVisible(true);
}
}
@@ -2480,6 +2492,31 @@ public class TagTreeContextMenu extends JPopupMenu {
}
}
private void cleanAbcActionPerformed(ActionEvent evt) {
TreeItem item = getCurrentItem();
if (item == null) {
return;
}
if (ViewMessages.showConfirmDialog(this, AppStrings.translate("warning.cleanAbc"), AppStrings.translate("message.warning"), JOptionPane.OK_CANCEL_OPTION, Configuration.warningAbcClean, JOptionPane.OK_OPTION) != JOptionPane.OK_OPTION) {
return;
}
ABCCleaner cleaner = new ABCCleaner();
if (item instanceof ABCContainerTag) {
ABCContainerTag cnt = (ABCContainerTag) item;
cleaner.clean(cnt.getABC());
}
if (item instanceof ABC) {
cleaner.clean((ABC) item);
}
if (item instanceof SWF) {
SWF swf = (SWF) item;
for (ABCContainerTag cnt : swf.getAbcList()) {
cleaner.clean(cnt.getABC());
}
}
Main.getMainFrame().getPanel().refreshTree();
}
private void rawEditActionPerformed(ActionEvent evt) {
TreeItem itemr = getCurrentItem();
if (itemr == null) {