diff --git a/trunk/src/com/jpexs/decompiler/flash/SWF.java b/trunk/src/com/jpexs/decompiler/flash/SWF.java index 7e9f3cede..01f5d048e 100644 --- a/trunk/src/com/jpexs/decompiler/flash/SWF.java +++ b/trunk/src/com/jpexs/decompiler/flash/SWF.java @@ -18,7 +18,7 @@ package com.jpexs.decompiler.flash; import SevenZip.Compression.LZMA.Encoder; import com.jpexs.decompiler.flash.abc.ABC; -import com.jpexs.decompiler.flash.abc.gui.TreeLeafScript; +import com.jpexs.decompiler.flash.abc.ScriptPack; import com.jpexs.decompiler.flash.abc.types.traits.Trait; import com.jpexs.decompiler.flash.action.Action; import com.jpexs.decompiler.flash.action.ActionGraphSource; @@ -415,16 +415,15 @@ public class SWF { } for (int i = 0; i < abcTags.size(); i++) { ABC abc = abcTags.get(i).getABC(); - TreeLeafScript scr = abc.findScriptTraitByPath(className); + ScriptPack scr = abc.findScriptTraitByPath(className); if (scr != null) { String cnt = ""; if (abc.script_info.length > 1) { cnt = "script " + (i + 1) + "/" + abc.script_info.length + " "; } - Trait t = abc.script_info[scr.scriptIndex].traits.traits[scr.traitIndex]; - String exStr = "Exporting " + "tag " + (i + 1) + "/" + abcTags.size() + " " + cnt + t.getPath(abc) + " ..."; + String exStr = "Exporting " + "tag " + (i + 1) + "/" + abcTags.size() + " " + cnt + scr.getPath() + " ..."; informListeners("export", exStr); - t.export(outdir, abc, abcTags, isPcode, scr.scriptIndex, -1, false); + scr.export(outdir, abcTags, isPcode); return true; } } diff --git a/trunk/src/com/jpexs/decompiler/flash/abc/ABC.java b/trunk/src/com/jpexs/decompiler/flash/abc/ABC.java index 89a38a561..9cf9f67bf 100644 --- a/trunk/src/com/jpexs/decompiler/flash/abc/ABC.java +++ b/trunk/src/com/jpexs/decompiler/flash/abc/ABC.java @@ -21,7 +21,6 @@ import com.jpexs.decompiler.flash.abc.avm2.AVM2Code; import com.jpexs.decompiler.flash.abc.avm2.ConstantPool; import com.jpexs.decompiler.flash.abc.avm2.UnknownInstructionCode; import com.jpexs.decompiler.flash.abc.avm2.instructions.AVM2Instruction; -import com.jpexs.decompiler.flash.abc.gui.TreeLeafScript; import com.jpexs.decompiler.flash.abc.types.*; import com.jpexs.decompiler.flash.abc.types.traits.Trait; import com.jpexs.decompiler.flash.abc.types.traits.TraitMethodGetterSetter; @@ -571,10 +570,11 @@ public class ABC { if (script_info.length > 1) { cnt = "script " + (i + 1) + "/" + script_info.length + " "; } - for (Trait t : script_info[i].traits.traits) { - String exStr = "Exporting " + abcStr + cnt + t.getPath(this) + " ..."; + HashMap packs = script_info[i].getPacks(this, i); + for (String path : packs.keySet()) { + String exStr = "Exporting " + abcStr + cnt + path + " ..."; informListeners("export", exStr); - t.export(directory, this, abcList, pcode, i, -1, false); + packs.get(path).export(directory, abcList, pcode); } } } @@ -888,12 +888,14 @@ public class ABC { return -1; } - public TreeLeafScript findScriptTraitByPath(String name) { + public ScriptPack findScriptTraitByPath(String name) { for (int c = 0; c < script_info.length; c++) { for (int t = 0; t < script_info[c].traits.traits.length; t++) { Trait tr = script_info[c].traits.traits[t]; if (tr.getPath(this).equals(name)) { - return new TreeLeafScript(this, c, t); + List indices = new ArrayList(); + indices.add(t); + return new ScriptPack(this, c, indices); } } } diff --git a/trunk/src/com/jpexs/decompiler/flash/abc/ScriptPack.java b/trunk/src/com/jpexs/decompiler/flash/abc/ScriptPack.java new file mode 100644 index 000000000..e412af511 --- /dev/null +++ b/trunk/src/com/jpexs/decompiler/flash/abc/ScriptPack.java @@ -0,0 +1,80 @@ +/* + * Copyright (C) 2012-2013 JPEXS + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package com.jpexs.decompiler.flash.abc; + +import com.jpexs.decompiler.flash.abc.ABC; +import com.jpexs.decompiler.flash.abc.types.Multiname; +import com.jpexs.decompiler.flash.abc.types.Namespace; +import com.jpexs.decompiler.flash.tags.ABCContainerTag; +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; + +/** + * + * @author JPEXS + */ +public class ScriptPack { + + public ABC abc; + public int scriptIndex; + public List traitIndices; + + public ScriptPack(ABC abc, int scriptIndex, List traitIndices) { + this.abc = abc; + this.scriptIndex = scriptIndex; + this.traitIndices = traitIndices; + } + + public String getPath() { + String packageName = ""; + String scriptName = ""; + for (int t : traitIndices) { + Multiname name = abc.script_info[scriptIndex].traits.traits[t].getName(abc); + Namespace ns = name.getNamespace(abc.constants); + if ((ns.kind == Namespace.KIND_PACKAGE) || (ns.kind == Namespace.KIND_PACKAGE_INTERNAL)) { + packageName = ns.getName(abc.constants); + scriptName = name.getName(abc.constants, new ArrayList()); + } + } + return packageName + "." + scriptName; + } + + public void export(String directory, List abcList, boolean pcode) throws IOException { + String path = getPath(); + String scriptName = path.substring(path.lastIndexOf(".") + 1); + String packageName = path.substring(0, path.lastIndexOf(".")); + File outDir = new File(directory + File.separatorChar + packageName.replace('.', File.separatorChar)); + if (!outDir.exists()) { + outDir.mkdirs(); + } + String fileName = outDir.toString() + File.separator + scriptName + ".as"; + FileOutputStream fos = new FileOutputStream(fileName); + for (int t : traitIndices) { + Multiname name = abc.script_info[scriptIndex].traits.traits[t].getName(abc); + Namespace ns = name.getNamespace(abc.constants); + if ((ns.kind == Namespace.KIND_PACKAGE) || (ns.kind == Namespace.KIND_PACKAGE_INTERNAL)) { + fos.write(abc.script_info[scriptIndex].traits.traits[t].convertPackaged("", abcList, abc, false, pcode, scriptIndex, -1, false, new ArrayList()).getBytes()); + } else { + fos.write(abc.script_info[scriptIndex].traits.traits[t].convert("", abcList, abc, false, pcode, scriptIndex, -1, false, new ArrayList()).getBytes()); + } + } + fos.close(); + } +} diff --git a/trunk/src/com/jpexs/decompiler/flash/abc/gui/ClassesListTree.java b/trunk/src/com/jpexs/decompiler/flash/abc/gui/ClassesListTree.java index b9759e922..e1d9bd87e 100644 --- a/trunk/src/com/jpexs/decompiler/flash/abc/gui/ClassesListTree.java +++ b/trunk/src/com/jpexs/decompiler/flash/abc/gui/ClassesListTree.java @@ -16,6 +16,7 @@ */ package com.jpexs.decompiler.flash.abc.gui; +import com.jpexs.decompiler.flash.abc.ScriptPack; import com.jpexs.decompiler.flash.Main; import com.jpexs.decompiler.flash.abc.ABC; import com.jpexs.decompiler.flash.abc.types.Multiname; @@ -38,7 +39,7 @@ import javax.swing.tree.TreeSelectionModel; public class ClassesListTree extends JTree implements TreeSelectionListener { private List abcList; - public HashMap treeList; + public HashMap treeList; private ABCPanel abcPanel; public void selectClass(int classIndex) { @@ -61,9 +62,9 @@ public class ClassesListTree extends JTree implements TreeSelectionListener { setCellRenderer(treeRenderer); } - public List getSelectedScripts() { + public List getSelectedScripts() { TreeSelectionModel tsm = getSelectionModel(); - final List selectedScripts = new ArrayList(); + final List selectedScripts = new ArrayList(); TreePath tps[] = tsm.getSelectionPaths(); if (tps == null) { return selectedScripts; @@ -72,8 +73,8 @@ public class ClassesListTree extends JTree implements TreeSelectionListener { TreeElement te = (TreeElement) tp.getLastPathComponent(); if (te.isLeaf()) { Object item = te.getItem(); - if (item instanceof TreeLeafScript) { - selectedScripts.add((TreeLeafScript) item); + if (item instanceof ScriptPack) { + selectedScripts.add((ScriptPack) item); } } else { TreeVisitor tvi = new TreeVisitor() { @@ -84,8 +85,8 @@ public class ClassesListTree extends JTree implements TreeSelectionListener { @Override public void onLeaf(TreeElement leaf) { Object item = leaf.getItem(); - if (item instanceof TreeLeafScript) { - selectedScripts.add((TreeLeafScript) item); + if (item instanceof ScriptPack) { + selectedScripts.add((ScriptPack) item); } } }; @@ -96,23 +97,16 @@ public class ClassesListTree extends JTree implements TreeSelectionListener { return selectedScripts; } - public HashMap getTreeList(List list) { - HashMap ret = new HashMap(); + public HashMap getTreeList(List list) { + HashMap ret = new HashMap(); for (ABCContainerTag tag : list) { ABC abc = tag.getABC(); for (int i = 0; i < abc.script_info.length; i++) { ScriptInfo script = abc.script_info[i]; - for (int j = 0; j < script.traits.traits.length; j++) { - Trait t = script.traits.traits[j]; - Multiname name = t.getName(abc); - Namespace ns = name.getNamespace(abc.constants); - String packageName = ns.getName(abc.constants); - String objectName = name.getName(abc.constants, new ArrayList()); - String path = packageName + "." + objectName; - ret.put(path, new TreeLeafScript(abc, i, j)); - } - - + HashMap packs=script.getPacks(abc, i); + for(String path:packs.keySet()){ + ret.put(path, packs.get(path)); + } } } return ret; @@ -138,8 +132,8 @@ public class ClassesListTree extends JTree implements TreeSelectionListener { return; } Object item = tp.getItem(); - if (item instanceof TreeLeafScript) { - final TreeLeafScript scriptLeaf = (TreeLeafScript) item; + if (item instanceof ScriptPack) { + final ScriptPack scriptLeaf = (ScriptPack) item; if (!Main.isWorking()) { Main.startWork("Decompiling..."); diff --git a/trunk/src/com/jpexs/decompiler/flash/abc/gui/ClassesListTreeModel.java b/trunk/src/com/jpexs/decompiler/flash/abc/gui/ClassesListTreeModel.java index 118e1a29b..69f9e7227 100644 --- a/trunk/src/com/jpexs/decompiler/flash/abc/gui/ClassesListTreeModel.java +++ b/trunk/src/com/jpexs/decompiler/flash/abc/gui/ClassesListTreeModel.java @@ -16,6 +16,7 @@ */ package com.jpexs.decompiler.flash.abc.gui; +import com.jpexs.decompiler.flash.abc.ScriptPack; import com.jpexs.decompiler.flash.abc.types.traits.Trait; import com.jpexs.decompiler.flash.abc.types.traits.TraitClass; import java.util.HashMap; @@ -38,7 +39,7 @@ class ClassIndexVisitor implements TreeVisitor { if (o == null) { return; } - TreeLeafScript sc = (TreeLeafScript) o; + ScriptPack sc = (ScriptPack) o; for (Trait t : sc.abc.script_info[sc.scriptIndex].traits.traits) { if (t instanceof TraitClass) { if (((TraitClass) t).class_info == classIndex) { @@ -55,7 +56,7 @@ class ClassIndexVisitor implements TreeVisitor { if (o == null) { return; } - TreeLeafScript sc = (TreeLeafScript) o; + ScriptPack sc = (ScriptPack) o; for (Trait t : sc.abc.script_info[sc.scriptIndex].traits.traits) { if (t instanceof TraitClass) { if (((TraitClass) t).class_info == classIndex) { @@ -75,11 +76,11 @@ public class ClassesListTreeModel implements TreeModel { private Tree classTree = new Tree(); - public ClassesListTreeModel(HashMap list) { + public ClassesListTreeModel(HashMap list) { this(list, null); } - public ClassesListTreeModel(HashMap list, String filter) { + public ClassesListTreeModel(HashMap list, String filter) { for (String path : list.keySet()) { if (filter != null) { if (!filter.equals("")) { diff --git a/trunk/src/com/jpexs/decompiler/flash/abc/gui/DecompiledEditorPane.java b/trunk/src/com/jpexs/decompiler/flash/abc/gui/DecompiledEditorPane.java index 2daed5b42..d82851e54 100644 --- a/trunk/src/com/jpexs/decompiler/flash/abc/gui/DecompiledEditorPane.java +++ b/trunk/src/com/jpexs/decompiler/flash/abc/gui/DecompiledEditorPane.java @@ -16,6 +16,7 @@ */ package com.jpexs.decompiler.flash.abc.gui; +import com.jpexs.decompiler.flash.abc.ScriptPack; import com.jpexs.decompiler.flash.abc.ABC; import com.jpexs.decompiler.flash.abc.types.ScriptInfo; import com.jpexs.decompiler.flash.abc.types.traits.Trait; @@ -38,7 +39,7 @@ public class DecompiledEditorPane extends LineMarkedEditorPane implements CaretL private List classHighlights = new ArrayList(); private Highlighting currentMethodHighlight; private ABC abc; - private TreeLeafScript script; + private ScriptPack script; public int lastTraitIndex = 0; private boolean ignoreCarret = false; private boolean reset = false; @@ -46,7 +47,7 @@ public class DecompiledEditorPane extends LineMarkedEditorPane implements CaretL private int classIndex = -1; private boolean isStatic = false; - public TreeLeafScript getScriptLeaf() { + public ScriptPack getScriptLeaf() { return script; } @@ -227,7 +228,7 @@ public class DecompiledEditorPane extends LineMarkedEditorPane implements CaretL this.classHighlights = classHighlights; } } - private HashMap bufferedClasses = new HashMap(); + private HashMap bufferedClasses = new HashMap(); public void gotoLastTrait() { gotoTrait(lastTraitIndex); @@ -285,9 +286,8 @@ public class DecompiledEditorPane extends LineMarkedEditorPane implements CaretL bufferedClasses.clear(); } - public void setScript(TreeLeafScript scriptLeaf, List abcList) { + public void setScript(ScriptPack scriptLeaf, List abcList) { int scriptIndex = scriptLeaf.scriptIndex; - int scriptTraitIndex = scriptLeaf.traitIndex; ScriptInfo script = null; ABC abc = scriptLeaf.abc; if (scriptIndex > -1) { @@ -302,9 +302,13 @@ public class DecompiledEditorPane extends LineMarkedEditorPane implements CaretL } setText("//Please wait..."); - String hilightedCode; + StringBuilder hilightedCodeBuf = new StringBuilder(); + String hilightedCode = ""; if (!bufferedClasses.containsKey(scriptLeaf)) { - hilightedCode = script.traits.traits[scriptTraitIndex].convertPackaged("", abcList, abc, false, false, scriptIndex, -1, true, new ArrayList()); + for (int scriptTraitIndex : scriptLeaf.traitIndices) { + hilightedCodeBuf.append(script.traits.traits[scriptTraitIndex].convertPackaged("", abcList, abc, false, false, scriptIndex, -1, true, new ArrayList())); + } + hilightedCode = hilightedCodeBuf.toString(); highlights = Highlighting.getInstrHighlights(hilightedCode); traitHighlights = Highlighting.getTraitHighlights(hilightedCode); methodHighlights = Highlighting.getMethodHighlights(hilightedCode); diff --git a/trunk/src/com/jpexs/decompiler/flash/abc/gui/TreeLeafScript.java b/trunk/src/com/jpexs/decompiler/flash/abc/gui/TreeLeafScript.java deleted file mode 100644 index 4b62d0fb2..000000000 --- a/trunk/src/com/jpexs/decompiler/flash/abc/gui/TreeLeafScript.java +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright (C) 2012-2013 JPEXS - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package com.jpexs.decompiler.flash.abc.gui; - -import com.jpexs.decompiler.flash.abc.ABC; - -/** - * - * @author JPEXS - */ -public class TreeLeafScript { - - public ABC abc; - public int scriptIndex; - public int traitIndex = 0; - - public TreeLeafScript(ABC abc, int scriptIndex, int traitIndex) { - this.abc = abc; - this.scriptIndex = scriptIndex; - this.traitIndex = traitIndex; - } -} diff --git a/trunk/src/com/jpexs/decompiler/flash/abc/types/ScriptInfo.java b/trunk/src/com/jpexs/decompiler/flash/abc/types/ScriptInfo.java index 297379c6c..e0ddf1871 100644 --- a/trunk/src/com/jpexs/decompiler/flash/abc/types/ScriptInfo.java +++ b/trunk/src/com/jpexs/decompiler/flash/abc/types/ScriptInfo.java @@ -17,11 +17,13 @@ package com.jpexs.decompiler.flash.abc.types; import com.jpexs.decompiler.flash.abc.ABC; +import com.jpexs.decompiler.flash.abc.ScriptPack; import com.jpexs.decompiler.flash.abc.types.traits.Trait; import com.jpexs.decompiler.flash.abc.types.traits.Traits; import com.jpexs.decompiler.flash.tags.ABCContainerTag; import java.io.IOException; import java.util.ArrayList; +import java.util.HashMap; import java.util.List; public class ScriptInfo { @@ -29,6 +31,41 @@ public class ScriptInfo { public int init_index; //MethodInfo public Traits traits; + public HashMap getPacks(ABC abc, int scriptIndex) { + HashMap ret = new HashMap(); + + List otherTraits = new ArrayList(); + for (int j = 0; j < traits.traits.length; j++) { + Trait t = traits.traits[j]; + Multiname name = t.getName(abc); + Namespace ns = name.getNamespace(abc.constants); + if (!((ns.kind == Namespace.KIND_PACKAGE_INTERNAL) + || (ns.kind == Namespace.KIND_PACKAGE))) { + otherTraits.add(j); + } + } + for (int j = 0; j < traits.traits.length; j++) { + Trait t = traits.traits[j]; + Multiname name = t.getName(abc); + Namespace ns = name.getNamespace(abc.constants); + if ((ns.kind == Namespace.KIND_PACKAGE_INTERNAL) + || (ns.kind == Namespace.KIND_PACKAGE)) { + String packageName = ns.getName(abc.constants); + String objectName = name.getName(abc.constants, new ArrayList()); + String path = packageName + "." + objectName; + List traitIndices = new ArrayList(); + + traitIndices.add(j); + if (!otherTraits.isEmpty()) { + traitIndices.addAll(otherTraits); + } + otherTraits = new ArrayList(); + ret.put(path, new ScriptPack(abc, scriptIndex, traitIndices)); + } + } + return ret; + } + public int removeTraps(int scriptIndex, ABC abc) { return traits.removeTraps(scriptIndex, -1, true, abc); } @@ -47,10 +84,9 @@ public class ScriptInfo { } public void export(ABC abc, List abcList, String directory, boolean pcode, int scriptIndex) throws IOException { - for (Trait t : traits.traits) { - t.export(directory, abc, abcList, pcode, scriptIndex, -1, false); + HashMap packs = getPacks(abc, scriptIndex); + for (ScriptPack pack : packs.values()) { + pack.export(directory, abcList, pcode); } - - } } diff --git a/trunk/src/com/jpexs/decompiler/flash/gui/MainFrame.java b/trunk/src/com/jpexs/decompiler/flash/gui/MainFrame.java index 78753a67a..6b8a5d367 100644 --- a/trunk/src/com/jpexs/decompiler/flash/gui/MainFrame.java +++ b/trunk/src/com/jpexs/decompiler/flash/gui/MainFrame.java @@ -25,7 +25,7 @@ import com.jpexs.decompiler.flash.abc.gui.ClassesListTreeModel; import com.jpexs.decompiler.flash.abc.gui.DeobfuscationDialog; import com.jpexs.decompiler.flash.abc.gui.LineMarkedEditorPane; import com.jpexs.decompiler.flash.abc.gui.TreeElement; -import com.jpexs.decompiler.flash.abc.gui.TreeLeafScript; +import com.jpexs.decompiler.flash.abc.ScriptPack; import com.jpexs.decompiler.flash.abc.types.traits.Trait; import com.jpexs.decompiler.flash.abc.types.traits.TraitClass; import com.jpexs.decompiler.flash.action.gui.ActionPanel; @@ -881,7 +881,7 @@ public class MainFrame extends JFrame implements ActionListener, TreeSelectionLi } if (t instanceof TreeElement) { TreeElement te = (TreeElement) t; - if (te.getItem() instanceof TreeLeafScript) { + if (te.getItem() instanceof ScriptPack) { return "as"; } else { return "package"; @@ -1302,7 +1302,7 @@ public class MainFrame extends JFrame implements ActionListener, TreeSelectionLi if (onlySel) { List sel = getAllSelected(tagTree); - List tlsList = new ArrayList(); + List tlsList = new ArrayList(); JPEGTablesTag jtt = null; for (Tag t : swf.tags) { if (t instanceof JPEGTablesTag) { @@ -1344,7 +1344,7 @@ public class MainFrame extends JFrame implements ActionListener, TreeSelectionLi } if (d instanceof TreeElement) { if (((TreeElement) d).isLeaf()) { - tlsList.add((TreeLeafScript) ((TreeElement) d).getItem()); + tlsList.add((ScriptPack) ((TreeElement) d).getItem()); } } } @@ -1356,13 +1356,9 @@ public class MainFrame extends JFrame implements ActionListener, TreeSelectionLi swf.exportBinaryData(selFile + File.separator + "binaryData", binaryData); if (abcPanel != null) { for (int i = 0; i < tlsList.size(); i++) { - TreeLeafScript tls = tlsList.get(i); - - - for (Trait t : tls.abc.script_info[tls.scriptIndex].traits.traits) { - Main.startWork("Exporting " + (i + 1) + "/" + tlsList.size() + " " + t.getPath(tls.abc) + " ..."); - t.export(selFile, tls.abc, abcList, isPcode, tls.scriptIndex, -1, false); - } + ScriptPack tls = tlsList.get(i); + Main.startWork("Exporting " + (i + 1) + "/" + tlsList.size() + " " + tls.getPath() + " ..."); + tls.export(selFile, abcList, isPcode); } } else { List allNodes = new ArrayList(); @@ -1662,8 +1658,8 @@ public class MainFrame extends JFrame implements ActionListener, TreeSelectionLi return; } oldValue = tagObj; - if (tagObj instanceof TreeLeafScript) { - final TreeLeafScript scriptLeaf = (TreeLeafScript) tagObj; + if (tagObj instanceof ScriptPack) { + final ScriptPack scriptLeaf = (ScriptPack) tagObj; if (!Main.isWorking()) { Main.startWork("Decompiling..."); (new Thread() {