Added #1181 Remembering choice of loading assets via importassets tag

This commit is contained in:
Jindra Petřík
2022-12-10 14:50:14 +01:00
parent bc801128f3
commit 68a4ec52a9
6 changed files with 138 additions and 63 deletions

View File

@@ -16,6 +16,7 @@ All notable changes to this project will be documented in this file.
- Option to mute frame sounds
- Experimental option to fix conflation artifacts in antialising (slow)
- Option to disable autoplay of sounds (DefineSound)
- [#1181] Remembering choice of loading assets via importassets tag
### Fixed
- [#1897] Close menu button without selecting specific item
@@ -2724,6 +2725,7 @@ All notable changes to this project will be documented in this file.
[#1676]: https://www.free-decompiler.com/flash/issues/1676
[#1697]: https://www.free-decompiler.com/flash/issues/1697
[#1893]: https://www.free-decompiler.com/flash/issues/1893
[#1181]: https://www.free-decompiler.com/flash/issues/1181
[#1897]: https://www.free-decompiler.com/flash/issues/1897
[#1006]: https://www.free-decompiler.com/flash/issues/1006
[#1888]: https://www.free-decompiler.com/flash/issues/1888

View File

@@ -9,4 +9,5 @@ public class CustomConfigurationKeys {
public static final String KEY_LAST_SELECTED_PATH_TAGLIST = "lastSelectedPath.taglist";
public static final String KEY_CHARSET = "charset";
public static final String KEY_LIBRARY = "library";
public static final String KEY_LOADED_IMPORT_ASSETS = "loadedImportAssets";
}

View File

@@ -134,6 +134,7 @@ import java.util.logging.Level;
import java.util.logging.LogManager;
import java.util.logging.Logger;
import java.util.logging.SimpleFormatter;
import java.util.regex.Pattern;
import javax.swing.JFileChooser;
import javax.swing.JOptionPane;
import javax.swing.SwingUtilities;
@@ -150,6 +151,8 @@ import org.pushingpixels.substance.api.SubstanceLookAndFeel;
*/
public class Main {
public static final String IMPORT_ASSETS_SEPARATOR = "{*sep*}";
protected static ProxyFrame proxyFrame;
private static List<OpenableSourceInfo> sourceInfos = new ArrayList<>();
@@ -212,8 +215,6 @@ public class Main {
public static CancellableWorker deobfuscatePCodeWorker = null;
public static CancellableWorker swfPrepareWorker = null;
public static boolean isSwfAir(Openable openable) {
SwfSpecificCustomConfiguration conf = Configuration.getSwfSpecificCustomConfiguration(openable.getShortPathTitle());
if (conf != null) {
@@ -999,6 +1000,24 @@ public class Main {
String fileKey = shortName == null ? "" : new File(shortName).getName();
SwfSpecificCustomConfiguration conf = Configuration.getSwfSpecificCustomConfiguration(fileKey);
String charset = conf == null ? Charset.defaultCharset().name() : conf.getCustomData(CustomConfigurationKeys.KEY_CHARSET, Charset.defaultCharset().name());
List<String> loadedUrls = new ArrayList<>();
List<String> loadedStatus = new ArrayList<>();
Map<String, String> configuredImportAssets = new HashMap<>();
if (conf != null) {
String impAssetsStr = conf.getCustomData(CustomConfigurationKeys.KEY_LOADED_IMPORT_ASSETS, "");
if (impAssetsStr != null && !impAssetsStr.isEmpty()) {
String[] parts = (impAssetsStr + IMPORT_ASSETS_SEPARATOR).split(Pattern.quote(IMPORT_ASSETS_SEPARATOR));
for (String s : parts) {
if (!s.isEmpty()) {
String urlPlusStatus[] = (s + "|").split(Pattern.quote("|"));
String url = urlPlusStatus[0];
String status = urlPlusStatus[1];
configuredImportAssets.put(url, status);
}
}
}
}
SWF swf = new SWF(is, file, fileTitle, new ProgressListener() {
@Override
@@ -1008,50 +1027,75 @@ public class Main {
}, Configuration.parallelSpeedUp.get(), false, true, new UrlResolver() {
@Override
public SWF resolveUrl(final String url) {
loadedUrls.add(url);
File selFile = null;
int opt = -1;
if (!(yestoall || notoall)) {
opt = ViewMessages.showOptionDialog(getDefaultMessagesComponent(), AppStrings.translate("message.imported.swf").replace("%url%", url), AppStrings.translate("message.warning"), JOptionPane.YES_NO_OPTION, JOptionPane.WARNING_MESSAGE, null, yesno, AppStrings.translate("button.yes"));
if (opt == 2) {
yestoall = true;
if (configuredImportAssets.containsKey(url)) {
String statusStr = configuredImportAssets.get(url);
if (statusStr.equals("NO")) {
loadedStatus.add("NO");
return null;
}
if (opt == 3) {
notoall = true;
if (statusStr.startsWith("CUSTOM:")) {
selFile = new File(statusStr.substring("CUSTOM:".length()));
}
} else {
if (!(yestoall || notoall)) {
opt = ViewMessages.showOptionDialog(getDefaultMessagesComponent(), AppStrings.translate("message.imported.swf").replace("%url%", url), AppStrings.translate("message.warning"), JOptionPane.YES_NO_OPTION, JOptionPane.WARNING_MESSAGE, null, yesno, AppStrings.translate("button.yes"));
if (opt == 2) {
yestoall = true;
}
if (opt == 3) {
notoall = true;
}
}
if (yestoall) {
opt = 0; // yes
} else if (notoall) {
opt = 1; // no
}
if (opt == 1) //no
{
loadedStatus.add("NO");
return null;
}
}
if (yestoall) {
opt = 0; // yes
} else if (notoall) {
opt = 1; // no
}
if (opt == 1) //no
{
return null;
}
if (url.startsWith("http://") || url.startsWith("https://")) {
if (selFile == null && (url.startsWith("http://") || url.startsWith("https://"))) {
try {
URL u = new URL(url);
return open(u.openStream(), null, url); //?
SWF ret = open(u.openStream(), null, url); //?
loadedStatus.add("YES");
return ret;
} catch (Exception ex) {
//ignore
}
} else {
File swf = new File(new File(file).getParentFile(), url);
File swf = selFile != null ? selFile : new File(new File(file).getParentFile(), url);
if (swf.exists()) {
try {
return open(new FileInputStream(swf), swf.getAbsolutePath(), swf.getName());
SWF ret = open(new FileInputStream(swf), swf.getAbsolutePath(), swf.getName());
if (selFile != null) {
loadedStatus.add("CUSTOM:" + selFile.getAbsolutePath());
} else {
loadedStatus.add("YES");
}
return ret;
} catch (Exception ex) {
//ignore
}
}
// try .gfx if .swf failed
if (url.endsWith(".swf")) {
if (selFile == null && url.endsWith(".swf")) {
File gfx = new File(new File(file).getParentFile(), url.substring(0, url.length() - 4) + ".gfx");
if (gfx.exists()) {
try {
return open(new FileInputStream(gfx), gfx.getAbsolutePath(), gfx.getName());
SWF ret = open(new FileInputStream(gfx), gfx.getAbsolutePath(), gfx.getName());
loadedStatus.add("YES");
return ret;
} catch (Exception ex) {
//ignore
}
@@ -1120,11 +1164,13 @@ public class Main {
File selFile = Helper.fixDialogFile(fc.getSelectedFile());
try {
ret.setVal(open(new FileInputStream(selFile), selFile.getAbsolutePath(), selFile.getName()));
loadedStatus.add("CUSTOM:" + selFile.getAbsolutePath());
break;
} catch (Exception ex) {
} catch (Exception ex) {
//ignore;
}
} else {
loadedStatus.add("NO");
break;
}
}
@@ -1133,6 +1179,21 @@ public class Main {
return ret.getVal();
}
}, charset);
if (!loadedUrls.isEmpty()) {
SwfSpecificCustomConfiguration cc2 = Configuration.getOrCreateSwfSpecificCustomConfiguration(swf.getShortPathTitle());
StringBuilder sb = new StringBuilder();
for (int i = 0; i < loadedUrls.size(); i++) {
if (i > 0) {
sb.append(IMPORT_ASSETS_SEPARATOR);
}
sb.append(loadedUrls.get(i));
sb.append("|");
sb.append(loadedStatus.get(i));
}
cc2.setCustomData(CustomConfigurationKeys.KEY_LOADED_IMPORT_ASSETS, sb.toString());
}
return swf;
}
@@ -1165,7 +1226,7 @@ public class Main {
}
result.sourceInfo = sourceInfo;
boolean hasVideoStreams = false;
for (Openable openable : result) {
@@ -1181,13 +1242,13 @@ public class Main {
int height = (int) ((swf.displayRect.Ymax - swf.displayRect.Ymin) / SWF.unitDivisor);
logger.log(Level.INFO, "Width: {0}", width);
logger.log(Level.INFO, "Height: {0}", height);
for (Tag t: swf.getTags()) {
for (Tag t : swf.getTags()) {
if (t instanceof DefineVideoStreamTag) {
hasVideoStreams = true;
}
}
swf.addEventListener(new EventListener() {
@Override
public void handleExportingEvent(String type, int index, int count, Object data) {
@@ -1233,14 +1294,14 @@ public class Main {
});
}
}
if (hasVideoStreams && !DefineVideoStreamTag.displayAvailable()) {
View.execInEventDispatchLater(new Runnable() {
@Override
public void run() {
ViewMessages.showMessageDialog(getDefaultMessagesComponent(), AppStrings.translate("message.video.installvlc").replace("%file%", sourceInfo.getFileTitleOrName()), AppStrings.translate("message.warning"), JOptionPane.WARNING_MESSAGE, Configuration.warningVideoVlc);
ViewMessages.showMessageDialog(getDefaultMessagesComponent(), AppStrings.translate("message.video.installvlc").replace("%file%", sourceInfo.getFileTitleOrName()), AppStrings.translate("message.warning"), JOptionPane.WARNING_MESSAGE, Configuration.warningVideoVlc);
}
});
}
@@ -1558,7 +1619,7 @@ public class Main {
}
if (mainFrame != null) {
mainFrame.setVisible(false);
mainFrame.getPanel().closeAll(false);
mainFrame.getPanel().closeAll(false, false);
mainFrame.dispose();
mainFrame = null;
}
@@ -1630,7 +1691,7 @@ public class Main {
if (newFileDialog.showDialog() == AppDialog.OK_OPTION) {
if (mainFrame != null && !Configuration.openMultipleFiles.get()) {
sourceInfos.clear();
mainFrame.getPanel().closeAll(false);
mainFrame.getPanel().closeAll(false, false);
mainFrame.setVisible(false);
Helper.freeMem();
}
@@ -1684,7 +1745,7 @@ public class Main {
if (mainFrame != null && !Configuration.openMultipleFiles.get()) {
sourceInfos.clear();
mainFrame.getPanel().closeAll(false);
mainFrame.getPanel().closeAll(false, false);
mainFrame.setVisible(false);
Helper.freeMem();
reloadIndices = null;
@@ -1736,6 +1797,13 @@ public class Main {
public static void reloadFile(OpenableList swf) {
View.checkAccess();
for (Openable o : swf.items) {
SwfSpecificCustomConfiguration cc = Configuration.getSwfSpecificCustomConfiguration(o.getShortPathTitle());
if (cc != null) {
cc.setCustomData(CustomConfigurationKeys.KEY_LOADED_IMPORT_ASSETS, "");
}
}
openFile(swf.sourceInfo, null, sourceInfos.indexOf(swf.sourceInfo));
}
@@ -1751,10 +1819,10 @@ public class Main {
}
}
public static boolean closeAll() {
public static boolean closeAll(boolean onExit) {
View.checkAccess();
boolean closeResult = mainFrame.getPanel().closeAll(true);
boolean closeResult = mainFrame.getPanel().closeAll(true, onExit);
if (closeResult) {
sourceInfos.clear();
System.gc();
@@ -2090,8 +2158,6 @@ public class Main {
return null;
}
private static void initGui() {
if (GraphicsEnvironment.isHeadless()) {
System.err.println("Error: Your system does not support Graphic User Interface");
@@ -2100,7 +2166,7 @@ public class Main {
System.setProperty("sun.java2d.d3d", "false");
System.setProperty("sun.java2d.noddraw", "true");
if (System.getProperty("sun.java2d.uiScale") == null) { //it was not set by commandline, etc.
System.setProperty("sun.java2d.uiScale", "" + Configuration.uiScale.get());
}

View File

@@ -308,7 +308,7 @@ public abstract class MainFrameMenu implements MenuBuilder {
}
if (openable != null) {
boolean result = Main.closeAll();
boolean result = Main.closeAll(false);
if (result) {
openable = null;
Timer timer = new Timer();

View File

@@ -157,7 +157,7 @@ public final class MainFrameRibbon extends AppRibbonFrame {
}
boolean closeResult = panel.closeAll(true);
boolean closeResult = panel.closeAll(true, true);
if (closeResult) {
Main.exit();
}

View File

@@ -322,7 +322,7 @@ public final class MainPanel extends JPanel implements TreeSelectionListener, Se
private final JPanel displayPanel;
public FolderPreviewPanel folderPreviewPanel;
public FolderListPanel folderListPanel;
private boolean isWelcomeScreen = true;
@@ -330,9 +330,8 @@ public final class MainPanel extends JPanel implements TreeSelectionListener, Se
private static final String CARDPREVIEWPANEL = "Preview card";
private static final String CARDFOLDERPREVIEWPANEL = "Folder preview card";
private static final String CARDFOLDERLISTPANEL = "Folder list card";
private static final String CARDFOLDERLISTPANEL = "Folder list card";
private static final String CARDEMPTYPANEL = "Empty card";
@@ -672,8 +671,8 @@ public final class MainPanel extends JPanel implements TreeSelectionListener, Se
public boolean isClipboardCut() {
return clipboardCut;
}
}
public boolean checkEdited() {
if (abcPanel != null && abcPanel.isEditing()) {
abcPanel.tryAutoSave();
@@ -698,8 +697,6 @@ public final class MainPanel extends JPanel implements TreeSelectionListener, Se
private class MyTreeSelectionModel extends DefaultTreeSelectionModel {
@Override
public void addSelectionPath(TreePath path) {
if (checkEdited()) {
@@ -885,7 +882,6 @@ public final class MainPanel extends JPanel implements TreeSelectionListener, Se
return folderListCard;
}
private JPanel createDumpPreviewCard() {
JPanel dumpViewCard = new JPanel(new BorderLayout());
dumpViewPanel = new DumpViewPanel(dumpTree);
@@ -1416,7 +1412,7 @@ public final class MainPanel extends JPanel implements TreeSelectionListener, Se
return false;
}
public boolean closeAll(boolean showCloseConfirmation) {
public boolean closeAll(boolean showCloseConfirmation, boolean onExit) {
View.checkAccess();
if (showCloseConfirmation && isModified()) {
@@ -1456,6 +1452,12 @@ public final class MainPanel extends JPanel implements TreeSelectionListener, Se
for (SWF swf : swfsToClose) {
swf.clearTagSwfs();
if (!onExit) {
SwfSpecificCustomConfiguration cc = Configuration.getSwfSpecificCustomConfiguration(swf.getShortPathTitle());
if (cc != null) {
cc.setCustomData(CustomConfigurationKeys.KEY_LOADED_IMPORT_ASSETS, "");
}
}
}
refreshTree();
@@ -1510,6 +1512,10 @@ public final class MainPanel extends JPanel implements TreeSelectionListener, Se
for (SWF swf : swfsToClose) {
Main.searchResultsStorage.destroySwf(swf);
pinsPanel.removeOpenable(swf);
SwfSpecificCustomConfiguration cc = Configuration.getSwfSpecificCustomConfiguration(swf.getShortPathTitle());
if (cc != null) {
cc.setCustomData(CustomConfigurationKeys.KEY_LOADED_IMPORT_ASSETS, "");
}
}
openables.remove(openableList);
@@ -1924,7 +1930,7 @@ public final class MainPanel extends JPanel implements TreeSelectionListener, Se
ScriptExportSettings scriptExportSettings = new ScriptExportSettings(export.getValue(ScriptExportMode.class), singleScriptFile, false);
String singleFileName = Path.combine(scriptsFolder, openable.getShortFileName() + scriptExportSettings.getFileExtension());
try (FileTextWriter writer = scriptExportSettings.singleFile ? new FileTextWriter(Configuration.getCodeFormatting(), new FileOutputStream(singleFileName)) : null) {
try ( FileTextWriter writer = scriptExportSettings.singleFile ? new FileTextWriter(Configuration.getCodeFormatting(), new FileOutputStream(singleFileName)) : null) {
scriptExportSettings.singleFileWriter = writer;
if (swf.isAS3()) {
ret.addAll(new AS3ScriptExporter().exportActionScript3(swf, handler, scriptsFolder, as3scripts, scriptExportSettings, parallel, evl));
@@ -2031,7 +2037,7 @@ public final class MainPanel extends JPanel implements TreeSelectionListener, Se
ScriptExportSettings scriptExportSettings = new ScriptExportSettings(export.getValue(ScriptExportMode.class), singleScriptFile, false);
String singleFileName = Path.combine(scriptsFolder, swf.getShortFileName() + scriptExportSettings.getFileExtension());
try (FileTextWriter writer = scriptExportSettings.singleFile ? new FileTextWriter(Configuration.getCodeFormatting(), new FileOutputStream(singleFileName)) : null) {
try ( FileTextWriter writer = scriptExportSettings.singleFile ? new FileTextWriter(Configuration.getCodeFormatting(), new FileOutputStream(singleFileName)) : null) {
scriptExportSettings.singleFileWriter = writer;
swf.exportActionScript(handler, scriptsFolder, scriptExportSettings, parallel, evl);
}
@@ -2148,7 +2154,7 @@ public final class MainPanel extends JPanel implements TreeSelectionListener, Se
ScriptExportSettings scriptExportSettings = new ScriptExportSettings(exportMode, singleScriptFile, false);
String singleFileName = Path.combine(scriptsFolder, swf.getShortFileName() + scriptExportSettings.getFileExtension());
try (FileTextWriter writer = scriptExportSettings.singleFile ? new FileTextWriter(Configuration.getCodeFormatting(), new FileOutputStream(singleFileName)) : null) {
try ( FileTextWriter writer = scriptExportSettings.singleFile ? new FileTextWriter(Configuration.getCodeFormatting(), new FileOutputStream(singleFileName)) : null) {
scriptExportSettings.singleFileWriter = writer;
swf.exportActionScript(handler, scriptsFolder, scriptExportSettings, parallel, evl);
}
@@ -3552,7 +3558,7 @@ public final class MainPanel extends JPanel implements TreeSelectionListener, Se
if (selectedFile != null) {
File selfile = Helper.fixDialogFile(selectedFile);
try {
try (FileInputStream fis = new FileInputStream(selfile)) {
try ( FileInputStream fis = new FileInputStream(selfile)) {
new SwfXmlImporter().importSwf(swf, fis);
}
swf.clearAllCache();
@@ -4625,9 +4631,9 @@ public final class MainPanel extends JPanel implements TreeSelectionListener, Se
return;
}
boolean internalViewer = !isAdobeFlashPlayerEnabled();
boolean isVideoButNotDrawable = (treeItem instanceof DefineVideoStreamTag) && (!DefineVideoStreamTag.displayAvailable());
boolean isVideoButNotDrawable = (treeItem instanceof DefineVideoStreamTag) && (!DefineVideoStreamTag.displayAvailable());
if (treeItem instanceof SWF) {
SWF swf = (SWF) treeItem;
if (internalViewer) {
@@ -4674,7 +4680,7 @@ public final class MainPanel extends JPanel implements TreeSelectionListener, Se
if (treeItem instanceof ShapeTag) {
previewPanel.setImageReplaceButtonVisible(false, false, !((Tag) treeItem).isReadOnly(), false);
}
previewPanel.showImagePanel(timelined, tag.getSwf(), -1, true, Configuration.autoPlayPreviews.get(), !Configuration.animateSubsprites.get(), treeItem instanceof ShapeTag, !Configuration.playFrameSounds.get(), (treeItem instanceof DefineSpriteTag)||(treeItem instanceof ButtonTag));
previewPanel.showImagePanel(timelined, tag.getSwf(), -1, true, Configuration.autoPlayPreviews.get(), !Configuration.animateSubsprites.get(), treeItem instanceof ShapeTag, !Configuration.playFrameSounds.get(), (treeItem instanceof DefineSpriteTag) || (treeItem instanceof ButtonTag));
} else if (treeItem instanceof Frame && internalViewer) {
Frame fn = (Frame) treeItem;
SWF swf = (SWF) fn.getOpenable();
@@ -5042,7 +5048,7 @@ public final class MainPanel extends JPanel implements TreeSelectionListener, Se
case TagTreeModel.FOLDER_MOVIES:
for (Tag tag : timelined.getTags()) {
if (tag instanceof DefineVideoStreamTag) {
folderPreviewItems.add(tag);
folderPreviewItems.add(tag);
}
if (tag instanceof DefineSpriteTag) {
addFolderPreviewItems(folderPreviewItems, folderName, (DefineSpriteTag) tag);
@@ -5110,9 +5116,9 @@ public final class MainPanel extends JPanel implements TreeSelectionListener, Se
folderPreviewPanel.setItems(folderPreviewItems);
showCard(CARDFOLDERPREVIEWPANEL);
}
private void showFolderList(TreePath path) {
List<TreeItem> items = new ArrayList<>(getCurrentTree().getFullModel().getAllChildren((TreeItem)path.getLastPathComponent()));
List<TreeItem> items = new ArrayList<>(getCurrentTree().getFullModel().getAllChildren((TreeItem) path.getLastPathComponent()));
folderListPanel.setItems(path, items);
showCard(CARDFOLDERLISTPANEL);
}