mirror of
https://git.huckle.dev/Huckles-Minecraft-Archive/jpexs-decompiler.git
synced 2026-06-10 23:42:33 +00:00
AS2: Decompiling classes & interfaces
This commit is contained in:
@@ -14,8 +14,6 @@
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
|
||||
package com.jpexs.asdec.action;
|
||||
|
||||
import com.jpexs.asdec.Main;
|
||||
@@ -790,6 +788,15 @@ public class Action {
|
||||
if (onTrue.isEmpty() && trueStack.size() > 0) {
|
||||
isTernar = true;
|
||||
}
|
||||
int next = (hasElse ? jumpElseIp : jumpIp);
|
||||
if (actions.size() > next) {
|
||||
Action nea = actions.get(next);
|
||||
if (nea instanceof ActionPop) {
|
||||
if (trueStack.size() > 0) {
|
||||
nea.translate(trueStack, constants, onTrue, registerNames);
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (UnknownJumpException uje) {
|
||||
if ((adr2ip(actions, uje.addr, version) >= start) && (adr2ip(actions, uje.addr, version) <= end)) {
|
||||
if (currentLoop == null) {
|
||||
@@ -996,6 +1003,213 @@ public class Action {
|
||||
}
|
||||
}
|
||||
}
|
||||
output = checkClass(output);
|
||||
return output;
|
||||
}
|
||||
|
||||
public static TreeItem getWithoutGlobal(TreeItem ti) {
|
||||
TreeItem t = ti;
|
||||
if (!(t instanceof GetMemberTreeItem)) {
|
||||
return ti;
|
||||
}
|
||||
GetMemberTreeItem lastMember = null;
|
||||
while (((GetMemberTreeItem) t).object instanceof GetMemberTreeItem) {
|
||||
lastMember = (GetMemberTreeItem) t;
|
||||
t = ((GetMemberTreeItem) t).object;
|
||||
}
|
||||
if (((GetMemberTreeItem) t).object instanceof GetVariableTreeItem) {
|
||||
GetVariableTreeItem v = (GetVariableTreeItem) ((GetMemberTreeItem) t).object;
|
||||
if (v.value instanceof DirectValueTreeItem) {
|
||||
if (((DirectValueTreeItem) v.value).value instanceof String) {
|
||||
if (((DirectValueTreeItem) v.value).value.equals("_global")) {
|
||||
GetVariableTreeItem gvt = new GetVariableTreeItem(null, ((GetMemberTreeItem) t).functionName);
|
||||
if (lastMember == null) {
|
||||
return gvt;
|
||||
} else {
|
||||
lastMember.object = gvt;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return ti;
|
||||
}
|
||||
|
||||
private static List<TreeItem> checkClass(List<TreeItem> output) {
|
||||
List<TreeItem> ret = new ArrayList<TreeItem>();
|
||||
List<FunctionTreeItem> functions = new ArrayList<FunctionTreeItem>();
|
||||
HashMap<TreeItem, TreeItem> vars = new HashMap<TreeItem, TreeItem>();
|
||||
TreeItem className;
|
||||
TreeItem extendsOp = null;
|
||||
List<TreeItem> implementsOp = new ArrayList<TreeItem>();
|
||||
boolean ok = true;
|
||||
for (TreeItem t : output) {
|
||||
if (t instanceof IfTreeItem) {
|
||||
IfTreeItem it = (IfTreeItem) t;
|
||||
if (it.expression instanceof NotTreeItem) {
|
||||
NotTreeItem nti = (NotTreeItem) it.expression;
|
||||
if (nti.value instanceof GetMemberTreeItem) {
|
||||
if (it.onFalse.isEmpty()) {
|
||||
if ((it.onTrue.size() == 1) && (it.onTrue.get(0) instanceof SetMemberTreeItem) && (((SetMemberTreeItem) it.onTrue.get(0)).value instanceof NewObjectTreeItem)) {
|
||||
//ignore
|
||||
} else {
|
||||
List<TreeItem> parts = it.onTrue;
|
||||
className = getWithoutGlobal((GetMemberTreeItem) nti.value);
|
||||
if (parts.size() >= 1) {
|
||||
if (parts.get(0) instanceof StoreRegisterTreeItem) {
|
||||
int firstReg = ((StoreRegisterTreeItem) parts.get(0)).register.number;
|
||||
if ((parts.size() >= 2) && (parts.get(1) instanceof SetMemberTreeItem)) {
|
||||
TreeItem ti1 = ((SetMemberTreeItem) parts.get(1)).value;
|
||||
TreeItem ti2 = ((StoreRegisterTreeItem) parts.get(0)).value;
|
||||
if (ti1 == ti2) {
|
||||
if (((SetMemberTreeItem) parts.get(1)).value instanceof FunctionTreeItem) {
|
||||
((FunctionTreeItem) ((SetMemberTreeItem) parts.get(1)).value).calculatedFunctionName = (className instanceof GetMemberTreeItem) ? ((GetMemberTreeItem) className).functionName : className;
|
||||
functions.add((FunctionTreeItem) ((SetMemberTreeItem) parts.get(1)).value);
|
||||
int pos = 2;
|
||||
if (parts.size() <= pos) {
|
||||
ok = false;
|
||||
break;
|
||||
}
|
||||
if (parts.get(pos) instanceof ExtendsTreeItem) {
|
||||
ExtendsTreeItem et = (ExtendsTreeItem) parts.get(pos);
|
||||
extendsOp = getWithoutGlobal(et.superclass);
|
||||
pos++;
|
||||
}
|
||||
if (parts.get(pos) instanceof StoreRegisterTreeItem) {
|
||||
if (((StoreRegisterTreeItem) parts.get(pos)).value instanceof GetMemberTreeItem) {
|
||||
TreeItem obj = ((GetMemberTreeItem) ((StoreRegisterTreeItem) parts.get(pos)).value).object;
|
||||
if (obj instanceof DirectValueTreeItem) {
|
||||
if (((DirectValueTreeItem) obj).value instanceof RegisterNumber) {
|
||||
if (((RegisterNumber) ((DirectValueTreeItem) obj).value).number == firstReg) {
|
||||
int secondReg = ((StoreRegisterTreeItem) parts.get(pos)).register.number;
|
||||
pos++;
|
||||
if (parts.size() <= pos) {
|
||||
ok = false;
|
||||
break;
|
||||
}
|
||||
if (parts.get(pos) instanceof ImplementsOpTreeItem) {
|
||||
ImplementsOpTreeItem io = (ImplementsOpTreeItem) parts.get(pos);
|
||||
implementsOp = io.superclasses;
|
||||
pos++;
|
||||
}
|
||||
while ((parts.size() > pos) && ok) {
|
||||
if (parts.get(pos) instanceof SetMemberTreeItem) {
|
||||
SetMemberTreeItem smt = (SetMemberTreeItem) parts.get(pos);
|
||||
if (smt.object instanceof DirectValueTreeItem) {
|
||||
if (((DirectValueTreeItem) smt.object).value instanceof RegisterNumber) {
|
||||
if (((RegisterNumber) ((DirectValueTreeItem) smt.object).value).number == secondReg) {
|
||||
if (smt.value instanceof FunctionTreeItem) {
|
||||
((FunctionTreeItem) smt.value).calculatedFunctionName = smt.objectName;
|
||||
functions.add((FunctionTreeItem) smt.value);
|
||||
} else {
|
||||
vars.put(smt.objectName, smt.value);
|
||||
}
|
||||
} else {
|
||||
ok = false;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
ok = false;
|
||||
}
|
||||
} else if (parts.get(pos) instanceof VoidTreeItem) {
|
||||
VoidTreeItem v = (VoidTreeItem) parts.get(pos);
|
||||
if (v.value instanceof CallFunctionTreeItem) {
|
||||
//if(((CallFunctionTreeItem)parts.get(pos)).functionName){
|
||||
if (((CallFunctionTreeItem) v.value).functionName instanceof DirectValueTreeItem) {
|
||||
if (((DirectValueTreeItem) ((CallFunctionTreeItem) v.value).functionName).value.equals("ASSetPropFlags")) {
|
||||
} else {
|
||||
ok = false;
|
||||
}
|
||||
} else {
|
||||
ok = false;
|
||||
}
|
||||
} else {
|
||||
ok = false;
|
||||
}
|
||||
|
||||
} else {
|
||||
ok = false;
|
||||
break;
|
||||
}
|
||||
pos++;
|
||||
}
|
||||
if (ok) {
|
||||
List<TreeItem> output2 = new ArrayList<TreeItem>();
|
||||
output2.add(new ClassTreeItem(className, extendsOp, implementsOp, functions, vars));
|
||||
return output2;
|
||||
}
|
||||
} else {
|
||||
ok = false;
|
||||
}
|
||||
} else {
|
||||
ok = false;
|
||||
}
|
||||
} else {
|
||||
ok = false;
|
||||
}
|
||||
} else {
|
||||
ok = false;
|
||||
}
|
||||
} else {
|
||||
ok = false;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
ok = false;
|
||||
}
|
||||
} else {
|
||||
ok = false;
|
||||
}
|
||||
} else if (parts.get(0) instanceof SetMemberTreeItem) {
|
||||
SetMemberTreeItem sm = (SetMemberTreeItem) parts.get(0);
|
||||
if (sm.value instanceof FunctionTreeItem) {
|
||||
FunctionTreeItem f = (FunctionTreeItem) sm.value;
|
||||
if (f.actions.isEmpty()) {
|
||||
|
||||
if(parts.size()==2){
|
||||
if(parts.get(1) instanceof ImplementsOpTreeItem){
|
||||
ImplementsOpTreeItem iot=(ImplementsOpTreeItem)parts.get(1);
|
||||
implementsOp=iot.superclasses;
|
||||
}else{
|
||||
ok=false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
List<TreeItem> output2 = new ArrayList<TreeItem>();
|
||||
output2.add(new InterfaceTreeItem(sm.objectName,implementsOp));
|
||||
return output2;
|
||||
} else {
|
||||
ok = false;
|
||||
}
|
||||
} else {
|
||||
ok = false;
|
||||
}
|
||||
} else {
|
||||
ok = false;
|
||||
}
|
||||
} else {
|
||||
ok = false;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
ok = false;
|
||||
}
|
||||
} else {
|
||||
ok = false;
|
||||
}
|
||||
} else {
|
||||
ok = false;
|
||||
}
|
||||
} else {
|
||||
ok = false;
|
||||
}
|
||||
if (!ok) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!ok) {
|
||||
return output;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -34,6 +34,7 @@ public class DirectValueTreeItem extends TreeItem {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toStringNoQuotes(ConstantPool constants) {
|
||||
if (value instanceof Double) {
|
||||
if (Double.compare((double) (Double) value, 0) == 0) {
|
||||
@@ -46,7 +47,7 @@ public class DirectValueTreeItem extends TreeItem {
|
||||
}
|
||||
}
|
||||
if (value instanceof String) {
|
||||
return Helper.escapeString((String) value);
|
||||
return (String)value;
|
||||
}
|
||||
if (value instanceof ConstantIndex) {
|
||||
return (this.constants.get(((ConstantIndex) value).index));
|
||||
|
||||
@@ -14,8 +14,6 @@
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
|
||||
package com.jpexs.asdec.action.treemodel;
|
||||
|
||||
import com.jpexs.asdec.action.Action;
|
||||
@@ -27,6 +25,7 @@ public class FunctionTreeItem extends TreeItem {
|
||||
public List<String> constants;
|
||||
public String functionName;
|
||||
public List<String> paramNames;
|
||||
public TreeItem calculatedFunctionName;
|
||||
|
||||
public FunctionTreeItem(Action instruction, String functionName, List<String> paramNames, List<TreeItem> actions, ConstantPool constants) {
|
||||
super(instruction, PRECEDENCE_PRIMARY);
|
||||
@@ -39,7 +38,9 @@ public class FunctionTreeItem extends TreeItem {
|
||||
@Override
|
||||
public String toString(ConstantPool constants) {
|
||||
String ret = "function";
|
||||
if (!functionName.equals("")) {
|
||||
if (calculatedFunctionName != null) {
|
||||
ret += " " + calculatedFunctionName.toStringNoQuotes(constants);
|
||||
} else if (!functionName.equals("")) {
|
||||
ret += " " + functionName;
|
||||
}
|
||||
ret += "(";
|
||||
|
||||
@@ -49,6 +49,10 @@ public abstract class TreeItem {
|
||||
}
|
||||
|
||||
public abstract String toString(ConstantPool constants);
|
||||
|
||||
public String toStringNoQuotes(ConstantPool constants){
|
||||
return toString(constants);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
|
||||
@@ -0,0 +1,79 @@
|
||||
/*
|
||||
* Copyright (C) 2010-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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.jpexs.asdec.action.treemodel.clauses;
|
||||
|
||||
import com.jpexs.asdec.action.Action;
|
||||
import com.jpexs.asdec.action.treemodel.ConstantPool;
|
||||
import com.jpexs.asdec.action.treemodel.ContinueTreeItem;
|
||||
import com.jpexs.asdec.action.treemodel.FunctionTreeItem;
|
||||
import com.jpexs.asdec.action.treemodel.TreeItem;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
|
||||
public class ClassTreeItem extends TreeItem implements Block {
|
||||
|
||||
public List<FunctionTreeItem> functions;
|
||||
public TreeItem extendsOp;
|
||||
public List<TreeItem> implementsOp;
|
||||
public TreeItem className;
|
||||
public HashMap<TreeItem, TreeItem> vars;
|
||||
|
||||
public ClassTreeItem(TreeItem className, TreeItem extendsOp, List<TreeItem> implementsOp, List<FunctionTreeItem> functions, HashMap<TreeItem, TreeItem> vars) {
|
||||
super(null, NOPRECEDENCE);
|
||||
this.className = className;
|
||||
this.functions = functions;
|
||||
this.vars = vars;
|
||||
this.extendsOp = extendsOp;
|
||||
this.implementsOp = implementsOp;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString(ConstantPool constants) {
|
||||
String ret;
|
||||
ret = "class " + className.toStringNoQuotes(constants);
|
||||
if (extendsOp != null) {
|
||||
ret += " extends " + extendsOp.toString(constants);
|
||||
}
|
||||
if (!implementsOp.isEmpty()) {
|
||||
ret += " implements ";
|
||||
boolean first = true;
|
||||
for (TreeItem t : implementsOp) {
|
||||
if (!first) {
|
||||
ret += ", ";
|
||||
}
|
||||
first = false;
|
||||
ret += Action.getWithoutGlobal(t).toString(constants);
|
||||
}
|
||||
}
|
||||
ret += "\r\n{\r\n";
|
||||
for (FunctionTreeItem f : functions) {
|
||||
ret += f.toString(constants) + "\r\n";
|
||||
}
|
||||
for (TreeItem v : vars.keySet()) {
|
||||
ret += "var " + v.toStringNoQuotes(constants) + " = " + vars.get(v).toStringNoQuotes(constants)+";\r\n";
|
||||
}
|
||||
ret += "}\r\n";
|
||||
return ret;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ContinueTreeItem> getContinues() {
|
||||
List<ContinueTreeItem> ret = new ArrayList<ContinueTreeItem>();
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
/*
|
||||
* Copyright (C) 2010-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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.jpexs.asdec.action.treemodel.clauses;
|
||||
|
||||
import com.jpexs.asdec.action.Action;
|
||||
import com.jpexs.asdec.action.treemodel.ConstantPool;
|
||||
import com.jpexs.asdec.action.treemodel.TreeItem;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public class InterfaceTreeItem extends TreeItem {
|
||||
|
||||
public TreeItem name;
|
||||
public List<TreeItem> superInterfaces;
|
||||
|
||||
public InterfaceTreeItem(TreeItem name, List<TreeItem> superInterfaces) {
|
||||
super(null, NOPRECEDENCE);
|
||||
this.name = name;
|
||||
this.superInterfaces = superInterfaces;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString(ConstantPool constants) {
|
||||
String ret = "";
|
||||
ret += "interface " + name.toStringNoQuotes(constants);
|
||||
boolean first = true;
|
||||
if(!superInterfaces.isEmpty()){
|
||||
ret+=" extends ";
|
||||
}
|
||||
for (TreeItem ti : superInterfaces) {
|
||||
if (!first) {
|
||||
ret += ", ";
|
||||
}
|
||||
first = false;
|
||||
ret += Action.getWithoutGlobal(ti).toStringNoQuotes(constants);
|
||||
}
|
||||
ret += "\r\n{\r\n}\r\n";
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
@@ -154,7 +154,7 @@ public class TagPanel extends JPanel implements ListSelectionListener {
|
||||
|
||||
@Override
|
||||
public void valueChanged(ListSelectionEvent e) {
|
||||
Tag tagObj = (Tag) tagList.getSelectedValue();
|
||||
Tag tagObj = (Tag) tagList.getSelectedValue();
|
||||
if (tagObj instanceof DefineBitsTag) {
|
||||
showCard(CARDIMAGEPANEL);
|
||||
imagePanel.setImage(((DefineBitsTag) tagObj).getFullImageData(jtt));
|
||||
|
||||
@@ -122,10 +122,8 @@ public abstract class SHAPERECORD implements Cloneable {
|
||||
}
|
||||
|
||||
/**
|
||||
* EXPERIMENTAL - convert shape to SVG
|
||||
*
|
||||
* TODO: Fix fill styles
|
||||
*
|
||||
* Convert shape to SVG
|
||||
*
|
||||
* @param shapeNum
|
||||
* @param fillStyles
|
||||
* @param lineStylesList
|
||||
|
||||
Reference in New Issue
Block a user