diff --git a/CHANGELOG.md b/CHANGELOG.md index edefe8919..ba2ed8e10 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -31,6 +31,10 @@ All notable changes to this project will be documented in this file. - Recalculating dependencies in the loop (now only on change) - Dependencies handling - Raw editing of DefineFontInfo/DefineFont2-3, KERNINGRECORD - proper switching wide codes +- Storing SWF configuration for files inside bundles and/or binarydata + +### Changed +- Full path inside bundle is displayed as SWF name instead simple name ## [16.2.0] - 2022-11-08 ### Added diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/SWF.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/SWF.java index 69acae32c..c4ef8c58e 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/SWF.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/SWF.java @@ -183,6 +183,7 @@ import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; +import java.nio.charset.Charset; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; @@ -1279,11 +1280,11 @@ public final class SWF implements SWFContainerItem, Timelined { } public SWF(InputStream is, String file, String fileTitle, ProgressListener listener, boolean parallelRead, boolean checkOnly, boolean lazy) throws IOException, InterruptedException { - this(is, file, fileTitle, listener, parallelRead, checkOnly, lazy, null, Utf8Helper.charsetName); + this(is, file, fileTitle, listener, parallelRead, checkOnly, lazy, null, Charset.defaultCharset().name()); } public SWF(InputStream is, String file, String fileTitle, ProgressListener listener, boolean parallelRead, boolean checkOnly, boolean lazy, UrlResolver resolver) throws IOException, InterruptedException { - this(is, file, fileTitle, listener, parallelRead, checkOnly, lazy, resolver, Utf8Helper.charsetName); + this(is, file, fileTitle, listener, parallelRead, checkOnly, lazy, resolver, Charset.defaultCharset().name()); } /** @@ -1489,12 +1490,15 @@ public final class SWF implements SWFContainerItem, Timelined { return file; } + public String getTitleOrShortFileName() { + if (fileTitle != null) { + return fileTitle; + } + return new File(file).getName(); + } + public String getShortFileName() { - String title = getFileTitle(); - if (title == null) { - return ""; - } - return new File(title).getName(); + return new File(getTitleOrShortFileName()).getName(); } /** @@ -1507,10 +1511,10 @@ public final class SWF implements SWFContainerItem, Timelined { } if (swfList != null) { if (swfList.isBundle()) { - return swfList.name + "/" + getShortFileName(); + return swfList.name + "/" + getTitleOrShortFileName(); } } - return getShortFileName(); + return getTitleOrShortFileName(); } /** @@ -3379,7 +3383,7 @@ public final class SWF implements SWFContainerItem, Timelined { @Override public String toString() { - return getShortFileName(); + return getTitleOrShortFileName(); } public void deobfuscate(DeobfuscationLevel level) throws InterruptedException { diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/SWFInputStream.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/SWFInputStream.java index ac60ae25a..f5e31118d 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/SWFInputStream.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/SWFInputStream.java @@ -1557,7 +1557,7 @@ public class SWFInputStream implements AutoCloseable { } } catch (IOException ex) { if (logErrors) { - logger.log(Level.SEVERE, "Error during tag reading. SWF: " + swf.getShortFileName() + " ID: " + tag.getId() + " name: " + tag.getName() + " pos: " + data.getPos(), ex); + logger.log(Level.SEVERE, "Error during tag reading. SWF: " + swf.getTitleOrShortFileName() + " ID: " + tag.getId() + " name: " + tag.getName() + " pos: " + data.getPos(), ex); } ret = new TagStub(swf, tag.getId(), "Error", data, null); } diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/DefineBinaryDataTag.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/DefineBinaryDataTag.java index 49253b3c3..cd9cf884b 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/DefineBinaryDataTag.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/DefineBinaryDataTag.java @@ -20,6 +20,7 @@ import com.jpexs.decompiler.flash.SWF; import com.jpexs.decompiler.flash.SWFInputStream; import com.jpexs.decompiler.flash.SWFOutputStream; import com.jpexs.decompiler.flash.configuration.Configuration; +import com.jpexs.decompiler.flash.configuration.SwfSpecificCustomConfiguration; import com.jpexs.decompiler.flash.tags.base.CharacterTag; import com.jpexs.decompiler.flash.types.BasicType; import com.jpexs.decompiler.flash.types.annotations.Internal; @@ -31,6 +32,7 @@ import com.jpexs.helpers.utf8.Utf8Helper; import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.InputStream; +import java.nio.charset.Charset; /** * @@ -78,9 +80,13 @@ public class DefineBinaryDataTag extends CharacterTag { binaryData = sis.readByteRangeEx(sis.available(), "binaryData"); if (Configuration.autoLoadEmbeddedSwfs.get()) { + String path = getSwf().getShortPathTitle()+"/DefineBinaryData (" + getCharacterId() + ")"; + SwfSpecificCustomConfiguration conf = Configuration.getSwfSpecificCustomConfiguration(path); + String charset = conf == null ? Charset.defaultCharset().name() : conf.getCustomData(SwfSpecificCustomConfiguration.KEY_CHARSET, Charset.defaultCharset().name()); + try { InputStream is = new ByteArrayInputStream(binaryData.getArray(), binaryData.getPos(), binaryData.getLength()); - SWF bswf = new SWF(is, null, "(SWF Data)", Configuration.parallelSpeedUp.get()); + SWF bswf = new SWF(is, null, "(SWF Data)", Configuration.parallelSpeedUp.get(), charset); innerSwf = bswf; bswf.binaryData = this; } catch (IOException | InterruptedException ex) { diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/base/FontTag.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/base/FontTag.java index e552cf0f1..663e91d5f 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/base/FontTag.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/base/FontTag.java @@ -233,7 +233,7 @@ public abstract class FontTag extends DrawableTag implements AloneTag { int fontId = getFontId(); String selectedFont = swf.sourceFontNamesMap.get(fontId); if (selectedFont == null) { - SwfSpecificConfiguration swfConf = Configuration.getSwfSpecificConfiguration(swf.getShortFileName()); + SwfSpecificConfiguration swfConf = Configuration.getSwfSpecificConfiguration(swf.getShortPathTitle()); String key = fontId + "_" + getFontNameIntag(); if (swfConf != null) { selectedFont = swfConf.fontPairingMap.get(key); @@ -494,6 +494,9 @@ public abstract class FontTag extends DrawableTag implements AloneTag { } public DefineFontNameTag getFontNameTag() { + if (swf == null) { + return null; + } for (Tag t : swf.getTags()) { if (t instanceof DefineFontNameTag) { DefineFontNameTag dfn = (DefineFontNameTag) t; diff --git a/libsrc/ffdec_lib/test/com/jpexs/decompiler/flash/DirectEditingTest.java b/libsrc/ffdec_lib/test/com/jpexs/decompiler/flash/DirectEditingTest.java index 955969454..3459aea8e 100644 --- a/libsrc/ffdec_lib/test/com/jpexs/decompiler/flash/DirectEditingTest.java +++ b/libsrc/ffdec_lib/test/com/jpexs/decompiler/flash/DirectEditingTest.java @@ -125,14 +125,14 @@ public class DirectEditingTest extends FileTestBase { try { asm.setActions(par.actionsFromString(as2, Utf8Helper.charsetName)); } catch (ActionParseException | CompilationException ex) { - fail("Unable to parse: " + asm.getSwf().getShortFileName() + "/" + asm.toString(), ex); + fail("Unable to parse: " + asm.getSwf().getTitleOrShortFileName()+ "/" + asm.toString(), ex); } writer = new HighlightedTextWriter(new CodeFormatting(), false); asm.getActionScriptSource(writer, null); String as3 = writer.toString(); //as3 = asm.removePrefixAndSuffix(as3); if (!as3.equals(as2)) { - fail("ActionScript is different: " + asm.getSwf().getShortFileName() + "/" + asm.toString()); + fail("ActionScript is different: " + asm.getSwf().getTitleOrShortFileName()+ "/" + asm.toString()); } asm.setModified(); } catch (InterruptedException | IOException | OutOfMemoryError | TranslateException | StackOverflowError ex) { diff --git a/src/com/jpexs/decompiler/flash/gui/FontPanel.java b/src/com/jpexs/decompiler/flash/gui/FontPanel.java index 6785768f9..eff76035c 100644 --- a/src/com/jpexs/decompiler/flash/gui/FontPanel.java +++ b/src/com/jpexs/decompiler/flash/gui/FontPanel.java @@ -654,7 +654,7 @@ public class FontPanel extends JPanel { SWF swf = f.getSwf(); String selectedName = ((FontFace) fontFaceSelection.getSelectedItem()).font.getFontName(Locale.ENGLISH); swf.sourceFontNamesMap.put(f.getFontId(), selectedName); - Configuration.addFontPair(swf.getShortFileName(), f.getFontId(), f.getFontNameIntag(), selectedName); + Configuration.addFontPair(swf.getShortPathTitle(), f.getFontId(), f.getFontNameIntag(), selectedName); } } diff --git a/src/com/jpexs/decompiler/flash/gui/Main.java b/src/com/jpexs/decompiler/flash/gui/Main.java index c619768ca..ce442ed75 100644 --- a/src/com/jpexs/decompiler/flash/gui/Main.java +++ b/src/com/jpexs/decompiler/flash/gui/Main.java @@ -862,6 +862,7 @@ public class Main { } result.bundle = bundle; result.name = new File(sourceInfo.getFileTitleOrName()).getName(); + final String fname = result.name; for (Entry streamEntry : bundle.getAll().entrySet()) { InputStream stream = streamEntry.getValue(); stream.reset(); @@ -869,7 +870,7 @@ public class Main { @Override public SWF doInBackground() throws Exception { final CancellableWorker worker = this; - String fileKey = new File(streamEntry.getKey()).getName(); + String fileKey = fname + "/" + streamEntry.getKey(); SwfSpecificCustomConfiguration conf = Configuration.getSwfSpecificCustomConfiguration(fileKey); String charset = conf == null ? Charset.defaultCharset().name() : conf.getCustomData(SwfSpecificCustomConfiguration.KEY_CHARSET, Charset.defaultCharset().name()); @@ -1347,13 +1348,13 @@ public class Main { } if (mainFrame != null && fswf != null) { - SwfSpecificConfiguration swfConf = Configuration.getSwfSpecificConfiguration(fswf.getShortFileName()); + SwfSpecificConfiguration swfConf = Configuration.getSwfSpecificConfiguration(fswf.getShortPathTitle()); String resourcesPathStr = null; String tagListPathStr = null; if (swfConf != null) { resourcesPathStr = swfConf.lastSelectedPath; } - SwfSpecificCustomConfiguration swfCustomConf = Configuration.getSwfSpecificCustomConfiguration(fswf.getShortFileName()); + SwfSpecificCustomConfiguration swfCustomConf = Configuration.getSwfSpecificCustomConfiguration(fswf.getShortPathTitle()); if (swfCustomConf != null) { resourcesPathStr = swfCustomConf.getCustomData(SwfSpecificCustomConfiguration.KEY_LAST_SELECTED_PATH_RESOURCES, resourcesPathStr); tagListPathStr = swfCustomConf.getCustomData(SwfSpecificCustomConfiguration.KEY_LAST_SELECTED_PATH_TAGLIST, null); diff --git a/src/com/jpexs/decompiler/flash/gui/MainPanel.java b/src/com/jpexs/decompiler/flash/gui/MainPanel.java index d0de6cb57..74ed0f2fa 100644 --- a/src/com/jpexs/decompiler/flash/gui/MainPanel.java +++ b/src/com/jpexs/decompiler/flash/gui/MainPanel.java @@ -225,6 +225,7 @@ import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.lang.ref.WeakReference; +import java.nio.charset.Charset; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; @@ -1674,7 +1675,7 @@ public final class MainPanel extends JPanel implements TreeSelectionListener, Se String selFile2; if (usedSwfs.size() > 1) { - selFile2 = selFile + File.separator + Helper.getNextId(swf.getShortFileName(), usedSwfsIds); + selFile2 = selFile + File.separator + Helper.getNextId(swf.getTitleOrShortFileName(), usedSwfsIds); } else { selFile2 = selFile; } @@ -4187,14 +4188,17 @@ public final class MainPanel extends JPanel implements TreeSelectionListener, Se protected Void doInBackground() throws Exception { try { for (DefineBinaryDataTag binaryDataTag : binaryDataTags) { + String path = binaryDataTag.getSwf().getShortPathTitle()+"/DefineBinaryData (" + binaryDataTag.getCharacterId() + ")"; try { + SwfSpecificCustomConfiguration conf = Configuration.getSwfSpecificCustomConfiguration(path); + String charset = conf == null ? Charset.defaultCharset().name() : conf.getCustomData(SwfSpecificCustomConfiguration.KEY_CHARSET, Charset.defaultCharset().name()); InputStream is = new ByteArrayInputStream(binaryDataTag.binaryData.getRangeData()); SWF bswf = new SWF(is, null, "(SWF Data)", new ProgressListener() { @Override public void progress(int p) { Main.loadingDialog.setPercent(p); } - }, Configuration.parallelSpeedUp.get()); + }, Configuration.parallelSpeedUp.get(), charset); binaryDataTag.innerSwf = bswf; bswf.binaryData = binaryDataTag; } catch (IOException ex) { @@ -4424,7 +4428,7 @@ public final class MainPanel extends JPanel implements TreeSelectionListener, Se } if (swf != null) { - SwfSpecificCustomConfiguration swfCustomConf = Configuration.getOrCreateSwfSpecificCustomConfiguration(swf.getShortFileName()); + SwfSpecificCustomConfiguration swfCustomConf = Configuration.getOrCreateSwfSpecificCustomConfiguration(swf.getShortPathTitle()); //swfConf.lastSelectedPath = tagTree.getSelectionPathString(); swfCustomConf.setCustomData(SwfSpecificCustomConfiguration.KEY_LAST_SELECTED_PATH_RESOURCES, tagTree.getSelectionPathString()); swfCustomConf.setCustomData(SwfSpecificCustomConfiguration.KEY_LAST_SELECTED_PATH_TAGLIST, tagListTree.getSelectionPathString()); diff --git a/src/com/jpexs/decompiler/flash/gui/tagtree/TagTreeContextMenu.java b/src/com/jpexs/decompiler/flash/gui/tagtree/TagTreeContextMenu.java index b365cf84c..5efd306ae 100644 --- a/src/com/jpexs/decompiler/flash/gui/tagtree/TagTreeContextMenu.java +++ b/src/com/jpexs/decompiler/flash/gui/tagtree/TagTreeContextMenu.java @@ -3040,7 +3040,7 @@ public class TagTreeContextMenu extends JPopupMenu { return; } - SwfSpecificCustomConfiguration conf = Configuration.getOrCreateSwfSpecificCustomConfiguration(item.getShortFileName()); + SwfSpecificCustomConfiguration conf = Configuration.getOrCreateSwfSpecificCustomConfiguration(item.getShortPathTitle()); conf.setCustomData(SwfSpecificCustomConfiguration.KEY_CHARSET, newCharset); while (item.binaryData != null) { item = item.binaryData.getSwf();