mirror of
https://git.huckle.dev/Huckles-Minecraft-Archive/jpexs-decompiler.git
synced 2026-09-25 14:00:45 +00:00
Issue #350 (Allow to open multiple SWF files into the same ffdec instance)
This commit is contained in:
@@ -56,6 +56,7 @@ import com.jpexs.decompiler.flash.flv.FLVOutputStream;
|
||||
import com.jpexs.decompiler.flash.flv.FLVTAG;
|
||||
import com.jpexs.decompiler.flash.flv.VIDEODATA;
|
||||
import com.jpexs.decompiler.flash.gui.SWFSourceInfo;
|
||||
import com.jpexs.decompiler.flash.gui.abc.ClassesListTreeModel;
|
||||
import com.jpexs.decompiler.flash.helpers.collections.MyEntry;
|
||||
import com.jpexs.decompiler.flash.tags.ABCContainerTag;
|
||||
import com.jpexs.decompiler.flash.tags.DefineBinaryDataTag;
|
||||
@@ -212,6 +213,7 @@ public final class SWF {
|
||||
public HashMap<Integer, CharacterTag> characters;
|
||||
public List<ABCContainerTag> abcList;
|
||||
public JPEGTablesTag jtt;
|
||||
public ClassesListTreeModel classTreeModel;
|
||||
|
||||
/**
|
||||
* Gets all tags with specified id
|
||||
|
||||
@@ -40,6 +40,7 @@ import java.awt.event.MouseEvent;
|
||||
import java.io.*;
|
||||
import java.net.Socket;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Calendar;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
@@ -191,13 +192,35 @@ public class Main {
|
||||
|
||||
public static SWF parseSWF(SWFSourceInfo sourceInfo) throws Exception {
|
||||
SWF locswf;
|
||||
InputStream fis = sourceInfo.getInputStream();
|
||||
locswf = new SWF(fis, new ProgressListener() {
|
||||
|
||||
InputStream inputStream = sourceInfo.getInputStream();
|
||||
if (inputStream == null) {
|
||||
inputStream = new FileInputStream(sourceInfo.getFile());
|
||||
} else if (inputStream instanceof SeekableInputStream) {
|
||||
try {
|
||||
((SeekableInputStream) inputStream).seek(0);
|
||||
} catch (IOException ex) {
|
||||
Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
|
||||
}
|
||||
} else if (inputStream instanceof BufferedInputStream) {
|
||||
try {
|
||||
((BufferedInputStream) inputStream).reset();
|
||||
} catch (IOException ex) {
|
||||
Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
|
||||
}
|
||||
}
|
||||
|
||||
locswf = new SWF(inputStream, new ProgressListener() {
|
||||
@Override
|
||||
public void progress(int p) {
|
||||
startWork(AppStrings.translate("work.reading.swf"), p);
|
||||
}
|
||||
}, Configuration.parallelSpeedUp.get());
|
||||
|
||||
if (inputStream instanceof FileInputStream) {
|
||||
inputStream.close();
|
||||
}
|
||||
|
||||
locswf.sourceInfo = sourceInfo;
|
||||
locswf.file = sourceInfo.getFile();
|
||||
locswf.fileTitle = sourceInfo.getFileTitle();
|
||||
@@ -242,51 +265,52 @@ public class Main {
|
||||
|
||||
private static class OpenFileWorker extends SwingWorker {
|
||||
|
||||
private SWFSourceInfo sourceInfo;
|
||||
private SWFSourceInfo[] sourceInfos;
|
||||
|
||||
public OpenFileWorker(SWFSourceInfo sourceInfo) {
|
||||
this.sourceInfo = sourceInfo;
|
||||
this.sourceInfos = new SWFSourceInfo[] { sourceInfo };
|
||||
}
|
||||
|
||||
public OpenFileWorker(SWFSourceInfo[] sourceInfos) {
|
||||
this.sourceInfos = sourceInfos;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Object doInBackground() throws Exception {
|
||||
SWF swf = null;
|
||||
try {
|
||||
Main.startWork(AppStrings.translate("work.reading.swf") + "...");
|
||||
InputStream inputStream = sourceInfo.getInputStream();
|
||||
swf = parseSWF(sourceInfo);
|
||||
if (inputStream instanceof FileInputStream) {
|
||||
inputStream.close();
|
||||
for (SWFSourceInfo sourceInfo : sourceInfos) {
|
||||
SWF swf = null;
|
||||
try {
|
||||
Main.startWork(AppStrings.translate("work.reading.swf") + "...");
|
||||
swf = parseSWF(sourceInfo);
|
||||
} catch (OutOfMemoryError ex) {
|
||||
Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
|
||||
View.showMessageDialog(null, "Cannot load SWF file. Out of memory.");
|
||||
} catch (Exception ex) {
|
||||
Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
|
||||
View.showMessageDialog(null, "Cannot load SWF file.");
|
||||
}
|
||||
|
||||
final SWF swf1 = swf;
|
||||
try {
|
||||
Main.startWork(AppStrings.translate("work.creatingwindow") + "...");
|
||||
View.execInEventDispatch(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (mainFrame == null) {
|
||||
mainFrame = new MainFrame();
|
||||
}
|
||||
mainFrame.load(swf1);
|
||||
if (errorState) {
|
||||
mainFrame.setErrorState();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
} catch (Exception ex) {
|
||||
Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
|
||||
}
|
||||
} catch (OutOfMemoryError ex) {
|
||||
Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
|
||||
View.showMessageDialog(null, "Cannot load SWF file. Out of memory.");
|
||||
loadingDialog.setVisible(false);
|
||||
} catch (Exception ex) {
|
||||
Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
|
||||
View.showMessageDialog(null, "Cannot load SWF file.");
|
||||
loadingDialog.setVisible(false);
|
||||
}
|
||||
|
||||
final SWF swf1 = swf;
|
||||
try {
|
||||
Main.startWork(AppStrings.translate("work.creatingwindow") + "...");
|
||||
View.execInEventDispatch(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (mainFrame == null) {
|
||||
mainFrame = new MainFrame();
|
||||
}
|
||||
mainFrame.load(swf1);
|
||||
if (errorState) {
|
||||
mainFrame.setErrorState();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
} catch (Exception ex) {
|
||||
Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
|
||||
}
|
||||
loadingDialog.setVisible(false);
|
||||
View.execInEventDispatch(new Runnable() {
|
||||
@Override
|
||||
@@ -304,6 +328,7 @@ public class Main {
|
||||
|
||||
public static boolean reloadSWFs() {
|
||||
CancellableWorker.cancelBackgroundThreads();
|
||||
mainFrame.closeAll();
|
||||
if (Main.sourceInfos.isEmpty()) {
|
||||
Cache.clearAll();
|
||||
System.gc();
|
||||
@@ -312,27 +337,9 @@ public class Main {
|
||||
} else {
|
||||
SWFSourceInfo[] sourceInfosCopy = new SWFSourceInfo[sourceInfos.size()];
|
||||
sourceInfos.toArray(sourceInfosCopy);
|
||||
for (SWFSourceInfo sourceInfo : sourceInfosCopy) {
|
||||
InputStream inputStream = sourceInfo.getInputStream();
|
||||
if (inputStream instanceof FileInputStream) {
|
||||
openFile(sourceInfo.getFile(), null);
|
||||
} else if (inputStream instanceof SeekableInputStream) {
|
||||
try {
|
||||
((SeekableInputStream) inputStream).seek(0);
|
||||
} catch (IOException ex) {
|
||||
Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
|
||||
}
|
||||
return openFile(inputStream, sourceInfo.getFileTitle()) == OpenFileResult.OK;
|
||||
} else if (inputStream instanceof BufferedInputStream) {
|
||||
try {
|
||||
((BufferedInputStream) inputStream).reset();
|
||||
} catch (IOException ex) {
|
||||
Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
|
||||
}
|
||||
return openFile(inputStream, sourceInfo.getFileTitle()) == OpenFileResult.OK;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
sourceInfos.clear();
|
||||
openFile(sourceInfosCopy);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -363,14 +370,15 @@ public class Main {
|
||||
public static OpenFileResult openFile(String swfFile, String fileTitle) {
|
||||
try {
|
||||
File file = new File(swfFile);
|
||||
if (!file.exists()) {
|
||||
View.showMessageDialog(null, "File not found", "Error", JOptionPane.ERROR_MESSAGE);
|
||||
return OpenFileResult.NOT_FOUND;
|
||||
}
|
||||
swfFile = file.getCanonicalPath();
|
||||
Configuration.addRecentFile(swfFile);
|
||||
SWFSourceInfo sourceInfo = new SWFSourceInfo(new FileInputStream(swfFile), swfFile, fileTitle);
|
||||
SWFSourceInfo sourceInfo = new SWFSourceInfo(null, swfFile, fileTitle);
|
||||
OpenFileResult openResult = openFile(sourceInfo);
|
||||
return openResult;
|
||||
} catch (FileNotFoundException ex) {
|
||||
View.showMessageDialog(null, "File not found", "Error", JOptionPane.ERROR_MESSAGE);
|
||||
return OpenFileResult.NOT_FOUND;
|
||||
} catch (IOException ex) {
|
||||
View.showMessageDialog(null, "Cannot open file", "Error", JOptionPane.ERROR_MESSAGE);
|
||||
return OpenFileResult.ERROR;
|
||||
@@ -378,6 +386,10 @@ public class Main {
|
||||
}
|
||||
|
||||
public static OpenFileResult openFile(SWFSourceInfo sourceInfo) {
|
||||
return openFile(new SWFSourceInfo[] { sourceInfo });
|
||||
}
|
||||
|
||||
public static OpenFileResult openFile(SWFSourceInfo[] newSourceInfos) {
|
||||
if (mainFrame != null && !Configuration.openMultiple.get()) {
|
||||
sourceInfos.clear();
|
||||
mainFrame.closeAll();
|
||||
@@ -396,9 +408,9 @@ public class Main {
|
||||
});
|
||||
|
||||
Main.loadingDialog.setVisible(true);
|
||||
OpenFileWorker wrk = new OpenFileWorker(sourceInfo);
|
||||
OpenFileWorker wrk = new OpenFileWorker(newSourceInfos);
|
||||
wrk.execute();
|
||||
sourceInfos.add(sourceInfo);
|
||||
sourceInfos.addAll(Arrays.asList(newSourceInfos));
|
||||
return OpenFileResult.OK;
|
||||
}
|
||||
|
||||
|
||||
@@ -1009,6 +1009,7 @@ public final class MainFrame extends AppRibbonFrame implements ActionListener, T
|
||||
actionPanel.clearSource();
|
||||
}
|
||||
updateUi();
|
||||
updateTagTree();
|
||||
}
|
||||
|
||||
public void close(SWF swf) {
|
||||
@@ -1019,6 +1020,12 @@ public final class MainFrame extends AppRibbonFrame implements ActionListener, T
|
||||
actionPanel.clearSource();
|
||||
oldValue = null;
|
||||
updateUi();
|
||||
updateTagTree();
|
||||
}
|
||||
|
||||
private void updateTagTree() {
|
||||
tagTree.setModel(new TagTreeModel(this, swfs, null));
|
||||
expandSwfRoots();
|
||||
}
|
||||
|
||||
public void enableDrop(boolean value) {
|
||||
@@ -1048,7 +1055,7 @@ public final class MainFrame extends AppRibbonFrame implements ActionListener, T
|
||||
boolean updateNeeded = false;
|
||||
for (TagNode n : nodes) {
|
||||
if (n.tag instanceof ClassesListTreeModel) {
|
||||
n.tag = new ClassesListTreeModel(abcPanel.classTree.treeList, n.getSwf(), filterField.getText());
|
||||
((ClassesListTreeModel) n.tag).setFilter(filterField.getText());
|
||||
updateNeeded = true;
|
||||
}
|
||||
}
|
||||
@@ -1473,19 +1480,21 @@ public final class MainFrame extends AppRibbonFrame implements ActionListener, T
|
||||
|
||||
public List<TagNode> getASTagNode(JTree tree) {
|
||||
List<TagNode> result = new ArrayList<>();
|
||||
TreeModel tm = tree.getModel();
|
||||
TagTreeModel tm = (TagTreeModel) tree.getModel();
|
||||
if (tm == null) {
|
||||
return result;
|
||||
}
|
||||
Object root = tm.getRoot();
|
||||
for (int i = 0; i < tm.getChildCount(root); i++) {
|
||||
Object node = tm.getChild(root, i);
|
||||
if (node instanceof TagNode) {
|
||||
Object tag = ((TagNode) tm.getChild(root, i)).tag;
|
||||
if (tag != null) {
|
||||
if ("scripts".equals(((TagNode) node).mark)) {
|
||||
TreeNode root = tm.getRoot();
|
||||
for (int j = 0; j < tm.getChildCount(root); j++) {
|
||||
SWFRoot swfRoot = (SWFRoot) tm.getChild(root, j);
|
||||
for (int i = 0; i < tm.getChildCount(swfRoot); i++) {
|
||||
TreeNode node = tm.getChild(swfRoot, i);
|
||||
if (node instanceof TagNode) {
|
||||
TagNode tagNode = (TagNode) node;
|
||||
TreeElementItem tag = tagNode.tag;
|
||||
if (tag != null && "scripts".equals(tagNode.mark)) {
|
||||
result.add((TagNode) node);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -49,7 +49,7 @@ public class TagTreeModel implements TreeModel {
|
||||
for (SWF swf : swfs) {
|
||||
List<ContainerItem> objs = new ArrayList<>();
|
||||
objs.addAll(swf.tags);
|
||||
List<TagNode> list = createTagList(objs, null, abcPanel, swf);
|
||||
List<TagNode> list = createTagList(objs, null, swf);
|
||||
|
||||
SWFRoot swfRoot = new SWFRoot(swf, new File(swf.file).getName(), list);
|
||||
this.swfs.add(swfRoot);
|
||||
@@ -75,7 +75,7 @@ public class TagTreeModel implements TreeModel {
|
||||
return ret;
|
||||
}
|
||||
|
||||
private List<TagNode> createTagList(List<ContainerItem> list, Object parent, ABCPanel abcPanel, SWF swf) {
|
||||
private List<TagNode> createTagList(List<ContainerItem> list, Object parent, SWF swf) {
|
||||
List<TagNode> ret = new ArrayList<>();
|
||||
List<TagNode> frames = getTagNodesWithType(list, TagType.FRAME, parent, true);
|
||||
List<TagNode> shapes = getTagNodesWithType(list, TagType.SHAPE, parent, true);
|
||||
@@ -88,7 +88,6 @@ public class TagTreeModel implements TreeModel {
|
||||
List<TagNode> movies = getTagNodesWithType(list, TagType.MOVIE, parent, true);
|
||||
List<TagNode> sounds = getTagNodesWithType(list, TagType.SOUND, parent, true);
|
||||
List<TagNode> binaryData = getTagNodesWithType(list, TagType.BINARY_DATA, parent, true);
|
||||
List<TagNode> actionScript = new ArrayList<>();
|
||||
|
||||
for (int i = 0; i < sounds.size(); i++) {
|
||||
if (sounds.get(i).tag instanceof SoundStreamHeadTypeTag) {
|
||||
@@ -118,13 +117,13 @@ public class TagTreeModel implements TreeModel {
|
||||
TagNode tti = new TagNode(t, t.getSwf());
|
||||
if (((Container) t).getItemCount() > 0) {
|
||||
List<ContainerItem> subItems = ((Container) t).getSubItems();
|
||||
tti.subItems = createTagList(subItems, t, abcPanel, t.getSwf());
|
||||
tti.subItems = createTagList(subItems, t, swf);
|
||||
}
|
||||
//ret.add(tti);
|
||||
}
|
||||
}
|
||||
|
||||
actionScript = SWF.createASTagList(list, null);
|
||||
List<TagNode> actionScript = SWF.createASTagList(list, null);
|
||||
TagNode textsNode = new TagNode(new StringNode(translate("node.texts")), swf);
|
||||
textsNode.subItems.addAll(texts);
|
||||
|
||||
@@ -198,11 +197,13 @@ public class TagTreeModel implements TreeModel {
|
||||
ret.add(framesNode);
|
||||
}
|
||||
|
||||
if (abcPanel != null) {
|
||||
boolean hasAbc = swf.abcList != null && !swf.abcList.isEmpty();
|
||||
|
||||
if (hasAbc) {
|
||||
actionScriptNode.subItems.clear();
|
||||
actionScriptNode.tag = abcPanel.classTree.getModel();
|
||||
actionScriptNode.tag = swf.classTreeModel;
|
||||
}
|
||||
if ((!actionScriptNode.subItems.isEmpty()) || (abcPanel != null)) {
|
||||
if ((!actionScriptNode.subItems.isEmpty()) || hasAbc) {
|
||||
ret.add(actionScriptNode);
|
||||
}
|
||||
|
||||
@@ -248,7 +249,7 @@ public class TagTreeModel implements TreeModel {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getRoot() {
|
||||
public TreeNode getRoot() {
|
||||
return root;
|
||||
}
|
||||
|
||||
|
||||
@@ -16,14 +16,21 @@
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.gui;
|
||||
|
||||
import com.jpexs.decompiler.flash.SWF;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public class TagTreeRoot {
|
||||
public class TagTreeRoot implements TreeNode {
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "root";
|
||||
}
|
||||
|
||||
@Override
|
||||
public SWF getSwf() {
|
||||
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
|
||||
}
|
||||
}
|
||||
|
||||
@@ -38,7 +38,6 @@ import javax.swing.tree.TreeSelectionModel;
|
||||
|
||||
public final class ClassesListTree extends JTree implements TreeSelectionListener {
|
||||
|
||||
private List<ABCContainerTag> abcList;
|
||||
public List<MyEntry<ClassPath, ScriptPack>> treeList;
|
||||
private ABCPanel abcPanel;
|
||||
private SWF swf;
|
||||
@@ -55,7 +54,6 @@ public final class ClassesListTree extends JTree implements TreeSelectionListene
|
||||
this.abcPanel = abcPanel;
|
||||
addTreeSelectionListener(this);
|
||||
DefaultTreeCellRenderer treeRenderer = new DefaultTreeCellRenderer();
|
||||
ClassLoader cldr = this.getClass().getClassLoader();
|
||||
treeRenderer.setLeafIcon(View.getIcon("as16"));
|
||||
setCellRenderer(treeRenderer);
|
||||
}
|
||||
@@ -96,21 +94,21 @@ public final class ClassesListTree extends JTree implements TreeSelectionListene
|
||||
}
|
||||
|
||||
public void clearDoABCTags() {
|
||||
this.abcList = null;
|
||||
this.treeList = null;
|
||||
this.swf = null;
|
||||
setModel(null);
|
||||
}
|
||||
|
||||
public void setDoABCTags(List<ABCContainerTag> list, SWF swf) {
|
||||
this.abcList = list;
|
||||
this.treeList = swf.getAS3Packs();
|
||||
this.swf = swf;
|
||||
setModel(new ClassesListTreeModel(this.treeList, swf));
|
||||
ClassesListTreeModel model = new ClassesListTreeModel(this.treeList, swf);
|
||||
this.swf.classTreeModel = model;
|
||||
setModel(model);
|
||||
}
|
||||
|
||||
public void applyFilter(String filter) {
|
||||
setModel(new ClassesListTreeModel(this.treeList, swf, filter));
|
||||
getModel().setFilter(filter);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -142,10 +140,10 @@ public final class ClassesListTree extends JTree implements TreeSelectionListene
|
||||
break;
|
||||
}
|
||||
}
|
||||
abcPanel.navigator.setABC(abcList, scriptLeaf.abc);
|
||||
abcPanel.navigator.setABC(swf.abcList, scriptLeaf.abc);
|
||||
abcPanel.navigator.setClassIndex(classIndex, scriptLeaf.scriptIndex);
|
||||
abcPanel.setAbc(scriptLeaf.abc);
|
||||
abcPanel.decompiledTextArea.setScript(scriptLeaf, abcList);
|
||||
abcPanel.decompiledTextArea.setScript(scriptLeaf, swf.abcList);
|
||||
abcPanel.decompiledTextArea.setClassIndex(classIndex);
|
||||
abcPanel.decompiledTextArea.setNoTrait();
|
||||
abcPanel.detailPanel.methodTraitPanel.methodCodePanel.clear();
|
||||
|
||||
@@ -79,6 +79,7 @@ class ClassIndexVisitor implements TreeVisitor {
|
||||
|
||||
public class ClassesListTreeModel implements TreeModel, TreeElementItem {
|
||||
|
||||
private SWF swf;
|
||||
private Tree classTree;
|
||||
private List<MyEntry<ClassPath, ScriptPack>> list;
|
||||
|
||||
@@ -89,8 +90,14 @@ public class ClassesListTreeModel implements TreeModel, TreeElementItem {
|
||||
public ClassesListTreeModel(List<MyEntry<ClassPath, ScriptPack>> list, SWF swf) {
|
||||
this(list, swf, null);
|
||||
}
|
||||
|
||||
|
||||
public ClassesListTreeModel(List<MyEntry<ClassPath, ScriptPack>> list, SWF swf, String filter) {
|
||||
this.swf = swf;
|
||||
this.list = list;
|
||||
setFilter(filter);
|
||||
}
|
||||
|
||||
public final void setFilter(String filter) {
|
||||
classTree = new Tree(swf);
|
||||
for (MyEntry<ClassPath, ScriptPack> item : list) {
|
||||
if (filter != null) {
|
||||
@@ -104,8 +111,6 @@ public class ClassesListTreeModel implements TreeModel, TreeElementItem {
|
||||
//String packageName = path.contains(".") ? path.substring(0, path.lastIndexOf(".")) : "";
|
||||
classTree.add(item.key.className, item.key.packageStr, item.value);
|
||||
}
|
||||
this.list = list;
|
||||
|
||||
}
|
||||
|
||||
public Object getItemByPath(String fullPath) {
|
||||
|
||||
Reference in New Issue
Block a user