mirror of
https://git.huckle.dev/Huckles-Minecraft-Archive/jpexs-decompiler.git
synced 2026-06-11 15:31:56 +00:00
dissasembly progress percent view
better text tags editing - parameters
This commit is contained in:
@@ -0,0 +1,26 @@
|
||||
/*
|
||||
* Copyright (C) 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.decompiler.flash;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public interface DisassemblyListener {
|
||||
|
||||
public void progress(String phase, long pos, long total);
|
||||
}
|
||||
@@ -81,4 +81,8 @@ public class ReReadableInputStream extends InputStream {
|
||||
public int available() throws IOException {
|
||||
return (count + is.available()) - pos;
|
||||
}
|
||||
|
||||
public long length() throws IOException {
|
||||
return count + is.available();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -502,22 +502,25 @@ public class SWFInputStream extends InputStream {
|
||||
return ret;
|
||||
}
|
||||
|
||||
public List<Action> readActionList(long address, long containerSWFOffset) throws IOException {
|
||||
public List<Action> readActionList(List<DisassemblyListener> listeners, long address, long containerSWFOffset) throws IOException {
|
||||
ReReadableInputStream rri = new ReReadableInputStream(this);
|
||||
return readActionList(address, containerSWFOffset, rri, version, 0, -1);
|
||||
return readActionList(listeners, address, containerSWFOffset, rri, version, 0, -1);
|
||||
}
|
||||
|
||||
public List<Action> readActionList(long address, long containerSWFOffset, ReReadableInputStream rri, int maxlen) throws IOException {
|
||||
return readActionList(address, containerSWFOffset, rri, version, rri.getPos(), rri.getPos() + maxlen);
|
||||
public List<Action> readActionList(List<DisassemblyListener> listeners, long address, long containerSWFOffset, ReReadableInputStream rri, int maxlen) throws IOException {
|
||||
return readActionList(listeners, address, containerSWFOffset, rri, version, rri.getPos(), rri.getPos() + maxlen);
|
||||
}
|
||||
|
||||
private static void getConstantPool(ConstantPool cpool, List localData, Stack<GraphTargetItem> stack, List<GraphTargetItem> output, ActionGraphSource code, int ip, int lastIp, List<ConstantPool> constantPools, List<Integer> visited, int version, int endIp) {
|
||||
private static void getConstantPool(List<DisassemblyListener> listeners, ConstantPool cpool, List localData, Stack<GraphTargetItem> stack, List<GraphTargetItem> output, ActionGraphSource code, int ip, int lastIp, List<ConstantPool> constantPools, List<Integer> visited, int version, int endIp) {
|
||||
boolean debugMode = false;
|
||||
boolean deobfuscate = (Boolean) Configuration.getConfig("autoDeobfuscate", true);
|
||||
while (((endIp == -1) || (endIp > ip)) && (ip > -1) && ip < code.size()) {
|
||||
if (visited.contains(ip)) {
|
||||
break;
|
||||
}
|
||||
|
||||
for (DisassemblyListener listener : listeners) {
|
||||
listener.progress("constantpool", ip + 1, code.size());
|
||||
}
|
||||
lastIp = ip;
|
||||
GraphSourceItem ins = code.get(ip);
|
||||
if (ins.isIgnored()) {
|
||||
@@ -538,10 +541,12 @@ public class SWFInputStream extends InputStream {
|
||||
List localData2 = Helper.toList(new HashMap<Integer, String>(), new HashMap<String, GraphTargetItem>(), new HashMap<String, GraphTargetItem>());
|
||||
List<GraphTargetItem> output2 = new ArrayList<GraphTargetItem>();
|
||||
output2s.add(output2);
|
||||
getConstantPool(cpool, localData2, new Stack<GraphTargetItem>(), output2, code, code.adr2pos(endAddr), lastIp, constantPools, visited, version, code.adr2pos(endAddr + size));
|
||||
getConstantPool(listeners, cpool, localData2, new Stack<GraphTargetItem>(), output2, code, code.adr2pos(endAddr), lastIp, constantPools, visited, version, code.adr2pos(endAddr + size));
|
||||
endAddr += size;
|
||||
}
|
||||
cnt.translateContainer(output2s, stack, output, (HashMap<Integer, String>) localData.get(0), (HashMap<String, GraphTargetItem>) localData.get(1), (HashMap<String, GraphTargetItem>) localData.get(2));
|
||||
if (deobfuscate) {
|
||||
cnt.translateContainer(output2s, stack, output, (HashMap<Integer, String>) localData.get(0), (HashMap<String, GraphTargetItem>) localData.get(1), (HashMap<String, GraphTargetItem>) localData.get(2));
|
||||
}
|
||||
ip = code.adr2pos(endAddr);
|
||||
continue;
|
||||
}
|
||||
@@ -586,13 +591,15 @@ public class SWFInputStream extends InputStream {
|
||||
}
|
||||
|
||||
//for..in return
|
||||
if (((ins instanceof ActionEquals) || (ins instanceof ActionEquals2)) && (stack.size() == 1) && (stack.peek() instanceof DirectValueTreeItem)) {
|
||||
stack.push(new DirectValueTreeItem(null, 0, new Null(), new ArrayList<String>()));
|
||||
}
|
||||
try {
|
||||
ins.translate(localData, stack, output);
|
||||
} catch (Exception ex) {
|
||||
Logger.getLogger(SWFInputStream.class.getName()).log(Level.SEVERE, "Error during getting constantpool", ex);
|
||||
if (deobfuscate) {
|
||||
if (((ins instanceof ActionEquals) || (ins instanceof ActionEquals2)) && (stack.size() == 1) && (stack.peek() instanceof DirectValueTreeItem)) {
|
||||
stack.push(new DirectValueTreeItem(null, 0, new Null(), new ArrayList<String>()));
|
||||
}
|
||||
try {
|
||||
ins.translate(localData, stack, output);
|
||||
} catch (Exception ex) {
|
||||
Logger.getLogger(SWFInputStream.class.getName()).log(Level.SEVERE, "Error during getting constantpool", ex);
|
||||
}
|
||||
}
|
||||
if (ins.isExit()) {
|
||||
break;
|
||||
@@ -600,7 +607,7 @@ public class SWFInputStream extends InputStream {
|
||||
|
||||
if (ins.isBranch() || ins.isJump()) {
|
||||
|
||||
if ((Boolean) Configuration.getConfig("autoDeobfuscate", true) && (ins instanceof ActionIf) && !stack.isEmpty() && (stack.peek().isCompileTime() && (!stack.peek().hasSideEffect()))) {
|
||||
if (deobfuscate && (ins instanceof ActionIf) && !stack.isEmpty() && (stack.peek().isCompileTime() && (!stack.peek().hasSideEffect()))) {
|
||||
ActionIf aif = (ActionIf) ins;
|
||||
if (aif.ignoreUsed && (!aif.jumpUsed)) {
|
||||
ins.setIgnored(true);
|
||||
@@ -636,9 +643,9 @@ public class SWFInputStream extends InputStream {
|
||||
}
|
||||
}
|
||||
stack.pop();
|
||||
getConstantPool(cpool, localData, stack, output, code, condition ? (code.adr2pos(((ActionIf) ins).getAddress() + ((ActionIf) ins).getBytes(code.version).length + ((ActionIf) ins).getJumpOffset())) : ip + 1, ip, constantPools, visited, version, endIp);
|
||||
getConstantPool(listeners, cpool, localData, stack, output, code, condition ? (code.adr2pos(((ActionIf) ins).getAddress() + ((ActionIf) ins).getBytes(code.version).length + ((ActionIf) ins).getJumpOffset())) : ip + 1, ip, constantPools, visited, version, endIp);
|
||||
} else {
|
||||
if (ins instanceof ActionIf) {
|
||||
if (deobfuscate && ins instanceof ActionIf) {
|
||||
stack.pop();
|
||||
}
|
||||
visited.add(ip);
|
||||
@@ -646,7 +653,7 @@ public class SWFInputStream extends InputStream {
|
||||
for (int b : branches) {
|
||||
Stack<GraphTargetItem> brStack = (Stack<GraphTargetItem>) stack.clone();
|
||||
if (b >= 0) {
|
||||
getConstantPool(cpool, localData, brStack, output, code, b, ip, constantPools, visited, version, endIp);
|
||||
getConstantPool(listeners, cpool, localData, brStack, output, code, b, ip, constantPools, visited, version, endIp);
|
||||
} else {
|
||||
if (debugMode) {
|
||||
System.out.println("Negative branch:" + b);
|
||||
@@ -661,13 +668,16 @@ public class SWFInputStream extends InputStream {
|
||||
if (ip < 0) {
|
||||
System.out.println("Visited Negative: " + ip);
|
||||
}
|
||||
for (DisassemblyListener listener : listeners) {
|
||||
listener.progress("constantpool", ip + 1, code.size());
|
||||
}
|
||||
}
|
||||
|
||||
public static List<ConstantPool> getConstantPool(ActionGraphSource code, int addr, int version) {
|
||||
public static List<ConstantPool> getConstantPool(List<DisassemblyListener> listeners, ActionGraphSource code, int addr, int version) {
|
||||
List<ConstantPool> ret = new ArrayList<ConstantPool>();
|
||||
List localData = Helper.toList(new HashMap<Integer, String>(), new HashMap<String, GraphTargetItem>(), new HashMap<String, GraphTargetItem>());
|
||||
try {
|
||||
getConstantPool(null, localData, new Stack<GraphTargetItem>(), new ArrayList<GraphTargetItem>(), code, code.adr2pos(addr), 0, ret, new ArrayList<Integer>(), version, -1);
|
||||
getConstantPool(listeners, null, localData, new Stack<GraphTargetItem>(), new ArrayList<GraphTargetItem>(), code, code.adr2pos(addr), 0, ret, new ArrayList<Integer>(), version, -1);
|
||||
} catch (Exception ex) {
|
||||
log.log(Level.SEVERE, "Error during getting constantpool", ex);
|
||||
}
|
||||
@@ -681,7 +691,7 @@ public class SWFInputStream extends InputStream {
|
||||
* @return List of actions
|
||||
* @throws IOException
|
||||
*/
|
||||
public static List<Action> readActionList(long address, long containerSWFOffset, ReReadableInputStream rri, int version, int ip, int endip) throws IOException {
|
||||
public static List<Action> readActionList(List<DisassemblyListener> listeners, long address, long containerSWFOffset, ReReadableInputStream rri, int version, int ip, int endip) throws IOException {
|
||||
List<Action> retdups = new ArrayList<Action>();
|
||||
ConstantPool cpool = new ConstantPool();
|
||||
|
||||
@@ -699,7 +709,7 @@ public class SWFInputStream extends InputStream {
|
||||
method = 2;
|
||||
goesPrev = readActionListAtPos(true, localData, stack, cpool, sis, rri, ip, retdups, ip);
|
||||
}*/
|
||||
goesPrev = readActionListAtPos(new ArrayList<GraphTargetItem>(), new HashMap<Long, List<GraphSourceItemContainer>>(), address, containerSWFOffset, false, true, localData, stack, cpool, sis, rri, ip, retdups, ip, endip);
|
||||
goesPrev = readActionListAtPos(listeners, new ArrayList<GraphTargetItem>(), new HashMap<Long, List<GraphSourceItemContainer>>(), address, containerSWFOffset, false, true, localData, stack, cpool, sis, rri, ip, retdups, ip, endip);
|
||||
|
||||
if (goesPrev) {
|
||||
} else {
|
||||
@@ -739,7 +749,7 @@ public class SWFInputStream extends InputStream {
|
||||
br.append(((Action) ret.get(i)).getASMSource(new ArrayList<GraphSourceItem>(), new ArrayList<Long>(), cpool.constants, version, false));
|
||||
br.append("\r\n");
|
||||
}
|
||||
pools = getConstantPool(new ActionGraphSource(ret, version, new HashMap<Integer, String>(), new HashMap<String, GraphTargetItem>(), new HashMap<String, GraphTargetItem>()), ip, version);
|
||||
pools = getConstantPool(listeners, new ActionGraphSource(ret, version, new HashMap<Integer, String>(), new HashMap<String, GraphTargetItem>(), new HashMap<String, GraphTargetItem>()), ip, version);
|
||||
|
||||
if (pools.size() == 1) {
|
||||
Action.setConstantPool(ret, pools.get(0));
|
||||
@@ -766,9 +776,11 @@ public class SWFInputStream extends InputStream {
|
||||
return reta;
|
||||
}
|
||||
|
||||
private static boolean readActionListAtPos(List<GraphTargetItem> output, HashMap<Long, List<GraphSourceItemContainer>> containers, long address, long containerSWFOffset, boolean notCompileTime, boolean enableVariables, List localData, Stack<GraphTargetItem> stack, ConstantPool cpool, SWFInputStream sis, ReReadableInputStream rri, int ip, List<Action> ret, int startIp, int endip) throws IOException {
|
||||
private static boolean readActionListAtPos(List<DisassemblyListener> listeners, List<GraphTargetItem> output, HashMap<Long, List<GraphSourceItemContainer>> containers, long address, long containerSWFOffset, boolean notCompileTime, boolean enableVariables, List localData, Stack<GraphTargetItem> stack, ConstantPool cpool, SWFInputStream sis, ReReadableInputStream rri, int ip, List<Action> ret, int startIp, int endip) throws IOException {
|
||||
boolean debugMode = false;
|
||||
boolean decideBranch = false;
|
||||
|
||||
boolean deobfuscate = (Boolean) Configuration.getConfig("autoDeobfuscate", true);
|
||||
boolean retv = false;
|
||||
rri.setPos(ip);
|
||||
Action a;
|
||||
@@ -776,6 +788,9 @@ public class SWFInputStream extends InputStream {
|
||||
Scanner sc = new Scanner(System.in);
|
||||
int prevIp = ip;
|
||||
while (((endip == -1) || (endip > ip)) && (a = sis.readAction(rri)) != null) {
|
||||
for (DisassemblyListener listener : listeners) {
|
||||
listener.progress("Reading", rri.getCount(), rri.length());
|
||||
}
|
||||
if ((ip < ret.size()) && (!(ret.get(ip) instanceof ActionNop))) {
|
||||
a = ret.get(ip);
|
||||
if (a.getAddress() != ip) {
|
||||
@@ -870,9 +885,11 @@ public class SWFInputStream extends InputStream {
|
||||
try {
|
||||
if (a instanceof ActionIf) {
|
||||
aif = (ActionIf) a;
|
||||
GraphTargetItem top = null;
|
||||
top = stack.pop();
|
||||
|
||||
GraphTargetItem top = null;
|
||||
if (deobfuscate) {
|
||||
top = stack.pop();
|
||||
}
|
||||
int nip = rri.getPos() + aif.getJumpOffset();
|
||||
|
||||
if (decideBranch) {
|
||||
@@ -887,7 +904,7 @@ public class SWFInputStream extends InputStream {
|
||||
} else if (next.equals("c")) {
|
||||
goaif = true;
|
||||
}
|
||||
} else if ((Boolean) Configuration.getConfig("autoDeobfuscate", true) && top.isCompileTime() && (!top.hasSideEffect()) && ((!top.isVariableComputed()) || (top.isVariableComputed() && enableVariables && (!notCompileTime)))) {
|
||||
} else if (deobfuscate && top.isCompileTime() && (!top.hasSideEffect()) && ((!top.isVariableComputed()) || (top.isVariableComputed() && enableVariables && (!notCompileTime)))) {
|
||||
//if(top.isCompileTime()) {
|
||||
//if(false){
|
||||
if (enableVariables) {
|
||||
@@ -957,14 +974,16 @@ public class SWFInputStream extends InputStream {
|
||||
//rri.setPos(newip);
|
||||
//}
|
||||
} else if (!(a instanceof GraphSourceItemContainer)) {
|
||||
//return in for..in, TODO:Handle this better way
|
||||
if (((a instanceof ActionEquals) || (a instanceof ActionEquals2)) && (stack.size() == 1) && (stack.peek() instanceof DirectValueTreeItem)) {
|
||||
stack.push(new DirectValueTreeItem(null, 0, new Null(), new ArrayList<String>()));
|
||||
if (deobfuscate) {
|
||||
//return in for..in, TODO:Handle this better way
|
||||
if (((a instanceof ActionEquals) || (a instanceof ActionEquals2)) && (stack.size() == 1) && (stack.peek() instanceof DirectValueTreeItem)) {
|
||||
stack.push(new DirectValueTreeItem(null, 0, new Null(), new ArrayList<String>()));
|
||||
}
|
||||
if ((a instanceof ActionStoreRegister) && stack.isEmpty()) {
|
||||
stack.push(new DirectValueTreeItem(null, 0, new Null(), new ArrayList<String>()));
|
||||
}
|
||||
a.translate(localData, stack, output);
|
||||
}
|
||||
if ((a instanceof ActionStoreRegister) && stack.isEmpty()) {
|
||||
stack.push(new DirectValueTreeItem(null, 0, new Null(), new ArrayList<String>()));
|
||||
}
|
||||
a.translate(localData, stack, output);
|
||||
}
|
||||
} catch (RuntimeException ex) {
|
||||
if (!enableVariables) {
|
||||
@@ -1012,11 +1031,13 @@ public class SWFInputStream extends InputStream {
|
||||
}
|
||||
List localData2 = Helper.toList(new HashMap<Integer, String>(), new HashMap<String, GraphTargetItem>(), new HashMap<String, GraphTargetItem>());
|
||||
List<GraphTargetItem> output2 = new ArrayList<GraphTargetItem>();
|
||||
readActionListAtPos(output2, containers, address, containerSWFOffset, notCompileTime, enableVariables, localData2, new Stack<GraphTargetItem>(), cpool, sis, rri, (int) endAddr, ret, startIp, (int) (endAddr + size));
|
||||
readActionListAtPos(listeners, output2, containers, address, containerSWFOffset, notCompileTime, enableVariables, localData2, new Stack<GraphTargetItem>(), cpool, sis, rri, (int) endAddr, ret, startIp, (int) (endAddr + size));
|
||||
output2s.add(output2);
|
||||
endAddr += size;
|
||||
}
|
||||
cnt.translateContainer(output2s, stack, output, (HashMap<Integer, String>) localData.get(0), (HashMap<String, GraphTargetItem>) localData.get(1), (HashMap<String, GraphTargetItem>) localData.get(2));
|
||||
if (deobfuscate) {
|
||||
cnt.translateContainer(output2s, stack, output, (HashMap<Integer, String>) localData.get(0), (HashMap<String, GraphTargetItem>) localData.get(1), (HashMap<String, GraphTargetItem>) localData.get(2));
|
||||
}
|
||||
ip = (int) endAddr;
|
||||
prevIp = ip;
|
||||
rri.setPos(ip);
|
||||
@@ -1044,7 +1065,7 @@ public class SWFInputStream extends InputStream {
|
||||
aif.jumpUsed = true;
|
||||
int oldPos = rri.getPos();
|
||||
Stack<GraphTargetItem> substack = (Stack<GraphTargetItem>) stack.clone();
|
||||
if (readActionListAtPos(output, containers, address, containerSWFOffset, true, enableVariables, localData, substack, cpool, sis, rri, rri.getPos() + aif.getJumpOffset(), ret, startIp, endip)) {
|
||||
if (readActionListAtPos(listeners, output, containers, address, containerSWFOffset, true, enableVariables, localData, substack, cpool, sis, rri, rri.getPos() + aif.getJumpOffset(), ret, startIp, endip)) {
|
||||
retv = true;
|
||||
}
|
||||
rri.setPos(oldPos);
|
||||
@@ -1052,6 +1073,9 @@ public class SWFInputStream extends InputStream {
|
||||
}
|
||||
prevIp = ip;
|
||||
}
|
||||
for (DisassemblyListener listener : listeners) {
|
||||
listener.progress("Reading", rri.getCount(), rri.length());
|
||||
}
|
||||
return retv;
|
||||
}
|
||||
|
||||
|
||||
@@ -28,6 +28,9 @@ public class DivideTreeItem extends BinaryOpItem {
|
||||
|
||||
@Override
|
||||
public double toNumber() {
|
||||
if (Double.compare(rightSide.toNumber(), 0) == 0) {
|
||||
return Double.NaN;
|
||||
}
|
||||
return leftSide.toNumber() / rightSide.toNumber();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.action;
|
||||
|
||||
import com.jpexs.decompiler.flash.DisassemblyListener;
|
||||
import com.jpexs.decompiler.flash.SWF;
|
||||
import com.jpexs.decompiler.flash.SWFInputStream;
|
||||
import com.jpexs.decompiler.flash.SWFOutputStream;
|
||||
@@ -364,8 +365,8 @@ public class Action implements GraphSourceItem {
|
||||
* @param hex Add hexadecimal?
|
||||
* @return ASM source as String
|
||||
*/
|
||||
public static String actionsToString(long address, List<Action> list, List<Long> importantOffsets, int version, boolean hex, long swfPos) {
|
||||
return actionsToString(address, list, importantOffsets, new ArrayList<String>(), version, hex, swfPos);
|
||||
public static String actionsToString(List<DisassemblyListener> listeners, long address, List<Action> list, List<Long> importantOffsets, int version, boolean hex, long swfPos) {
|
||||
return actionsToString(listeners, address, list, importantOffsets, new ArrayList<String>(), version, hex, swfPos);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -378,8 +379,7 @@ public class Action implements GraphSourceItem {
|
||||
* @param hex Add hexadecimal?
|
||||
* @return ASM source as String
|
||||
*/
|
||||
public static String actionsToString(long address, List list, List<Long> importantOffsets, List<String> constantPool, int version, boolean hex, long swfPos) {
|
||||
String ret = "";
|
||||
public static String actionsToString(List<DisassemblyListener> listeners, long address, List list, List<Long> importantOffsets, List<String> constantPool, int version, boolean hex, long swfPos) {
|
||||
long offset;
|
||||
if (importantOffsets == null) {
|
||||
//setActionsAddresses(list, 0, version);
|
||||
@@ -391,7 +391,7 @@ public class Action implements GraphSourceItem {
|
||||
srcList.add((Action) o);
|
||||
}
|
||||
}
|
||||
List<ConstantPool> cps = SWFInputStream.getConstantPool(new ActionGraphSource(srcList, version, new HashMap<Integer, String>(), new HashMap<String, GraphTargetItem>(), new HashMap<String, GraphTargetItem>()), 0, version);
|
||||
List<ConstantPool> cps = SWFInputStream.getConstantPool(new ArrayList<DisassemblyListener>(), new ActionGraphSource(srcList, version, new HashMap<Integer, String>(), new HashMap<String, GraphTargetItem>(), new HashMap<String, GraphTargetItem>()), 0, version);
|
||||
if (!cps.isEmpty()) {
|
||||
setConstantPool(list, cps.get(cps.size() - 1));
|
||||
}
|
||||
@@ -400,14 +400,20 @@ public class Action implements GraphSourceItem {
|
||||
offset = address;
|
||||
int pos = -1;
|
||||
boolean lastPush = false;
|
||||
StringBuilder ret = new StringBuilder();
|
||||
for (GraphSourceItem s : srcList) {
|
||||
for (DisassemblyListener l : listeners) {
|
||||
l.progress("toString", pos + 2, srcList.size());
|
||||
}
|
||||
Action a = null;
|
||||
if (s instanceof Action) {
|
||||
a = (Action) s;
|
||||
}
|
||||
pos++;
|
||||
if (hex) {
|
||||
ret += "<ffdec:hex>" +/*"0x"+Helper.formatAddress(a.getFileAddress())+": "+*/ Helper.bytesToHexString(a.getBytes(version)) + "</ffdec:hex>\r\n";
|
||||
ret.append("<ffdec:hex>");/* +"0x"+Helper.formatAddress(a.getFileAddress())+": "+*/;
|
||||
ret.append(Helper.bytesToHexString(a.getBytes(version)));
|
||||
ret.append("</ffdec:hex>\r\n");
|
||||
}
|
||||
offset = a.getAddress();
|
||||
|
||||
@@ -430,10 +436,10 @@ public class Action implements GraphSourceItem {
|
||||
|
||||
if (containers.containsKey(offset)) {
|
||||
for (int i = 0; i < containers.get(offset).size(); i++) {
|
||||
ret += "}\r\n";
|
||||
ret.append("}\r\n");
|
||||
GraphSourceItemContainer cnt = containers.get(offset).get(i);
|
||||
int cntPos = containersPos.get(cnt);
|
||||
ret += cnt.getASMSourceBetween(cntPos);
|
||||
ret.append(cnt.getASMSourceBetween(cntPos));
|
||||
cntPos++;
|
||||
containersPos.put(cnt, cntPos);
|
||||
}
|
||||
@@ -441,23 +447,27 @@ public class Action implements GraphSourceItem {
|
||||
|
||||
if (importantOffsets.contains(offset)) {
|
||||
if (lastPush) {
|
||||
ret += "\r\n";
|
||||
ret.append("\r\n");
|
||||
lastPush = false;
|
||||
}
|
||||
ret += "loc" + Helper.formatAddress(offset) + ":";
|
||||
ret.append("loc");
|
||||
ret.append(Helper.formatAddress(offset));
|
||||
ret.append(":");
|
||||
}
|
||||
|
||||
|
||||
|
||||
if (a.replaceWith != null) {
|
||||
if (lastPush) {
|
||||
ret += "\r\n";
|
||||
ret.append("\r\n");
|
||||
lastPush = false;
|
||||
}
|
||||
ret += Highlighting.hilighOffset("", offset) + a.replaceWith.getASMSource(list, importantOffsets, constantPool, version, hex) + "\r\n";
|
||||
ret.append(Highlighting.hilighOffset("", offset));
|
||||
ret.append(a.replaceWith.getASMSource(list, importantOffsets, constantPool, version, hex));
|
||||
ret.append("\r\n");
|
||||
} else if (a.ignored) {
|
||||
if (lastPush) {
|
||||
ret += "\r\n";
|
||||
ret.append("\r\n");
|
||||
lastPush = false;
|
||||
}
|
||||
int len = 0;
|
||||
@@ -467,11 +477,12 @@ public class Action implements GraphSourceItem {
|
||||
len = a.getBytes(version).length;
|
||||
}
|
||||
for (int i = 0; i < len; i++) {
|
||||
ret += "Nop\r\n";
|
||||
ret.append("Nop\r\n");
|
||||
}
|
||||
} else {
|
||||
if (a.beforeInsert != null) {
|
||||
ret += a.beforeInsert.getASMSource(list, importantOffsets, constantPool, version, hex) + "\r\n";
|
||||
ret.append(a.beforeInsert.getASMSource(list, importantOffsets, constantPool, version, hex));
|
||||
ret.append("\r\n");
|
||||
}
|
||||
//if (!(a instanceof ActionNop)) {
|
||||
String add = "";
|
||||
@@ -484,12 +495,17 @@ public class Action implements GraphSourceItem {
|
||||
add = "; ofs" + Helper.formatAddress(offset) + add;
|
||||
add = "";
|
||||
if ((a instanceof ActionPush) && lastPush) {
|
||||
ret += " " + ((ActionPush) a).paramsToStringReplaced(list, importantOffsets, constantPool, version, hex);
|
||||
ret.append(" ");
|
||||
ret.append(((ActionPush) a).paramsToStringReplaced(list, importantOffsets, constantPool, version, hex));
|
||||
} else {
|
||||
if (lastPush) {
|
||||
ret += "\r\n";
|
||||
ret.append("\r\n");
|
||||
}
|
||||
ret += Highlighting.hilighOffset("", offset) + a.getASMSourceReplaced(list, importantOffsets, constantPool, version, hex) + (a.ignored ? "; ignored" : "") + add + ((a instanceof ActionPush) ? "" : "\r\n");
|
||||
ret.append(Highlighting.hilighOffset("", offset));
|
||||
ret.append(a.getASMSourceReplaced(list, importantOffsets, constantPool, version, hex));
|
||||
ret.append(a.ignored ? "; ignored" : "");
|
||||
ret.append(add);
|
||||
ret.append((a instanceof ActionPush) ? "" : "\r\n");
|
||||
}
|
||||
if (a instanceof ActionPush) {
|
||||
lastPush = true;
|
||||
@@ -498,28 +514,31 @@ public class Action implements GraphSourceItem {
|
||||
}
|
||||
//}
|
||||
if (a.afterInsert != null) {
|
||||
ret += a.afterInsert.getASMSource(list, importantOffsets, constantPool, version, hex) + "\r\n";
|
||||
ret.append(a.afterInsert.getASMSource(list, importantOffsets, constantPool, version, hex));
|
||||
ret.append("\r\n");
|
||||
}
|
||||
}
|
||||
offset += a.getBytes(version).length;
|
||||
}
|
||||
if (lastPush) {
|
||||
ret += "\r\n";
|
||||
ret.append("\r\n");
|
||||
}
|
||||
if (containers.containsKey(offset)) {
|
||||
for (int i = 0; i < containers.get(offset).size(); i++) {
|
||||
ret += "}\r\n";
|
||||
ret.append("}\r\n");
|
||||
GraphSourceItemContainer cnt = containers.get(offset).get(i);
|
||||
int cntPos = containersPos.get(cnt);
|
||||
ret += cnt.getASMSourceBetween(cntPos);
|
||||
ret.append(cnt.getASMSourceBetween(cntPos));
|
||||
cntPos++;
|
||||
containersPos.put(cnt, cntPos);
|
||||
}
|
||||
}
|
||||
if (importantOffsets.contains(offset)) {
|
||||
ret += "loc" + Helper.formatAddress(offset) + ":\r\n";
|
||||
ret.append("loc");
|
||||
ret.append(Helper.formatAddress(offset));
|
||||
ret.append(":\r\n");
|
||||
}
|
||||
return ret;
|
||||
return ret.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1216,7 +1235,7 @@ public class Action implements GraphSourceItem {
|
||||
}
|
||||
String s = null;
|
||||
try {
|
||||
s = Highlighting.stripHilights(Action.actionsToString(address, ret, null, version, false, swfPos));
|
||||
s = Highlighting.stripHilights(Action.actionsToString(new ArrayList<DisassemblyListener>(), address, ret, null, version, false, swfPos));
|
||||
|
||||
ret = ASMParser.parse(address, swfPos, true, new ByteArrayInputStream(s.getBytes()), SWF.DEFAULT_VERSION);
|
||||
} catch (Exception ex) {
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.action.gui;
|
||||
|
||||
import com.jpexs.decompiler.flash.DisassemblyListener;
|
||||
import com.jpexs.decompiler.flash.Main;
|
||||
import com.jpexs.decompiler.flash.SWF;
|
||||
import com.jpexs.decompiler.flash.abc.gui.LineMarkedEditorPane;
|
||||
@@ -93,8 +94,15 @@ public class ActionPanel extends JPanel implements ActionListener {
|
||||
lastH = h;
|
||||
}
|
||||
long offset = lastH.offset;
|
||||
editor.setText("; Getting hilights...");
|
||||
disassembledHilights = Highlighting.getInstrHighlights(text);
|
||||
editor.setText(Highlighting.stripHilights(text));
|
||||
String stripped = Highlighting.stripHilights(text);
|
||||
/*if(stripped.length()>30000){
|
||||
editor.setContentType("text/plain");
|
||||
}else{
|
||||
editor.setContentType("text/flasm");
|
||||
}*/
|
||||
editor.setText(stripped);
|
||||
for (Highlighting h : disassembledHilights) {
|
||||
if (h.offset == offset) {
|
||||
editor.setCaretPosition(h.startPos);
|
||||
@@ -117,13 +125,35 @@ public class ActionPanel extends JPanel implements ActionListener {
|
||||
public void run() {
|
||||
editor.setText("; Disassembling...");
|
||||
if (Main.DO_DECOMPILE) {
|
||||
decompiledEditor.setText("//Decompiling...");
|
||||
decompiledEditor.setText("//Waiting for dissasembly...");
|
||||
}
|
||||
DisassemblyListener listener = new DisassemblyListener() {
|
||||
int percent = 0;
|
||||
String phase = "";
|
||||
|
||||
@Override
|
||||
public void progress(String phase, long pos, long total) {
|
||||
if (total < 1) {
|
||||
return;
|
||||
}
|
||||
int newpercent = (int) (pos * 100 / total);
|
||||
if (((newpercent > percent) || (!this.phase.equals(phase))) && newpercent <= 100) {
|
||||
percent = newpercent;
|
||||
this.phase = phase;
|
||||
editor.setText("; Disassembling - " + phase + " " + percent + "%...");
|
||||
}
|
||||
}
|
||||
};
|
||||
asm.addDisassemblyListener(listener);
|
||||
lastDisasm = asm.getASMSource(SWF.DEFAULT_VERSION, true);
|
||||
asm.removeDisassemblyListener(listener);
|
||||
editor.setText("; Disassembled");
|
||||
srcWithHex = Helper.hexToComments(lastDisasm);
|
||||
srcNoHex = Helper.stripComments(lastDisasm);
|
||||
editor.setText("; Disassembling - setting");
|
||||
setHex(hexButton.isSelected());
|
||||
if (Main.DO_DECOMPILE) {
|
||||
decompiledEditor.setText("//Decompiling...");
|
||||
List<com.jpexs.decompiler.flash.action.Action> as = asm.getActions(SWF.DEFAULT_VERSION);
|
||||
lastCode = as;
|
||||
//com.jpexs.decompiler.flash.action.Action.setActionsAddresses(as, 0, SWF.DEFAULT_VERSION);
|
||||
@@ -138,13 +168,19 @@ public class ActionPanel extends JPanel implements ActionListener {
|
||||
} catch (IOException ex) {
|
||||
Logger.getLogger(ActionPanel.class.getName()).log(Level.SEVERE, null, ex);
|
||||
}*/
|
||||
decompiledEditor.setText(lastDecompiled = stripped);
|
||||
lastDecompiled = stripped;
|
||||
/*if(lastDecompiled.length()>30000){
|
||||
decompiledEditor.setContentType("text/plain");
|
||||
}else{
|
||||
decompiledEditor.setContentType("text/actionscript");
|
||||
}*/
|
||||
decompiledEditor.setText(lastDecompiled);
|
||||
|
||||
if (debugRecompile) {
|
||||
try {
|
||||
ActionScriptParser ps = new ActionScriptParser();
|
||||
|
||||
recompiledEditor.setText(Highlighting.stripHilights(com.jpexs.decompiler.flash.action.Action.actionsToString(0, ps.parse(stripped), null, SWF.DEFAULT_VERSION, false, 0)));
|
||||
recompiledEditor.setText(Highlighting.stripHilights(com.jpexs.decompiler.flash.action.Action.actionsToString(new ArrayList<DisassemblyListener>(), 0, ps.parse(stripped), null, SWF.DEFAULT_VERSION, false, 0)));
|
||||
} catch (ParseException ex) {
|
||||
Logger.getLogger(ActionPanel.class.getName()).log(Level.SEVERE, null, ex);
|
||||
} catch (IOException ex) {
|
||||
|
||||
@@ -28,6 +28,9 @@ public class ModuloTreeItem extends BinaryOpItem {
|
||||
|
||||
@Override
|
||||
public double toNumber() {
|
||||
if (Double.compare(rightSide.toNumber(), 0) == 0) {
|
||||
return Double.NaN;
|
||||
}
|
||||
return ((int) leftSide.toNumber()) % ((int) rightSide.toNumber());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -489,10 +489,24 @@ public class MainFrame extends JFrame implements ActionListener, TreeSelectionLi
|
||||
List<Object> list2 = new ArrayList<Object>();
|
||||
list2.addAll(swf.tags);
|
||||
parseCharacters(list2);
|
||||
JPanel textPanel = new JPanel(new BorderLayout());
|
||||
textPanel.add(textValue, BorderLayout.CENTER);
|
||||
JPanel textTopPanel = new JPanel(new BorderLayout());
|
||||
textTopPanel.add(textValue, BorderLayout.CENTER);
|
||||
textValue.setEditable(false);
|
||||
|
||||
|
||||
/*JPanel textBottomPanel = new JPanel();
|
||||
textBottomPanel.setLayout(new BoxLayout(textBottomPanel, BoxLayout.X_AXIS));
|
||||
textBottomPanel.add(new JLabel("Xmin:"));
|
||||
textBottomPanel.add(textRectXmin);
|
||||
textBottomPanel.add(new JLabel("Ymin:"));
|
||||
textBottomPanel.add(textRectYmin);
|
||||
textBottomPanel.add(new JLabel("Xmax:"));
|
||||
textBottomPanel.add(textRectXmax);
|
||||
textBottomPanel.add(new JLabel("Ymax:"));
|
||||
textBottomPanel.add(textRectYmax);*/
|
||||
|
||||
|
||||
|
||||
JPanel buttonsPanel = new JPanel();
|
||||
buttonsPanel.setLayout(new BoxLayout(buttonsPanel, BoxLayout.X_AXIS));
|
||||
|
||||
@@ -519,9 +533,16 @@ public class MainFrame extends JFrame implements ActionListener, TreeSelectionLi
|
||||
textSaveButton.setVisible(false);
|
||||
textCancelButton.setVisible(false);
|
||||
|
||||
textPanel.add(buttonsPanel, BorderLayout.EAST);
|
||||
textTopPanel.add(buttonsPanel, BorderLayout.EAST);
|
||||
|
||||
displayWithPreview = new JPanel(new CardLayout());
|
||||
|
||||
|
||||
JPanel textPanel = new JPanel();
|
||||
textPanel.setLayout(new BoxLayout(textPanel, BoxLayout.Y_AXIS));
|
||||
textPanel.add(textTopPanel);
|
||||
//textPanel.add(textBottomPanel);
|
||||
|
||||
displayWithPreview.add(textPanel, CARDTEXTPANEL);
|
||||
displayWithPreview.setVisible(false);
|
||||
|
||||
|
||||
@@ -16,6 +16,8 @@
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.tags;
|
||||
|
||||
import com.jpexs.decompiler.flash.Configuration;
|
||||
import com.jpexs.decompiler.flash.DisassemblyListener;
|
||||
import com.jpexs.decompiler.flash.Main;
|
||||
import com.jpexs.decompiler.flash.ReReadableInputStream;
|
||||
import com.jpexs.decompiler.flash.SWFInputStream;
|
||||
@@ -119,7 +121,7 @@ public class DefineButtonTag extends CharacterTag implements ASMSource, BoundedT
|
||||
*/
|
||||
@Override
|
||||
public String getASMSource(int version, boolean hex) {
|
||||
return Action.actionsToString(0, getActions(version), null, version, hex, getPos() + hdrSize);
|
||||
return Action.actionsToString(listeners, 0, getActions(version), null, version, hex, getPos() + hdrSize);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -151,7 +153,13 @@ public class DefineButtonTag extends CharacterTag implements ASMSource, BoundedT
|
||||
baos.write(actionBytes);
|
||||
ReReadableInputStream rri = new ReReadableInputStream(new ByteArrayInputStream(baos.toByteArray()));
|
||||
rri.setPos(prevLength);
|
||||
return Action.removeNops(0, SWFInputStream.readActionList(0, getPos() + hdrSize - prevLength, rri, version, prevLength, -1), version, getPos() + hdrSize);
|
||||
|
||||
boolean deobfuscate = (Boolean) Configuration.getConfig("autoDeobfuscate", true);
|
||||
List<Action> list = SWFInputStream.readActionList(listeners, 0, getPos() + hdrSize - prevLength, rri, version, prevLength, -1);
|
||||
if (deobfuscate) {
|
||||
list = Action.removeNops(0, list, version, getPos() + hdrSize);
|
||||
}
|
||||
return list;
|
||||
} catch (Exception ex) {
|
||||
Logger.getLogger(DoActionTag.class.getName()).log(Level.SEVERE, null, ex);
|
||||
return new ArrayList<Action>();
|
||||
@@ -197,4 +205,15 @@ public class DefineButtonTag extends CharacterTag implements ASMSource, BoundedT
|
||||
}
|
||||
return rect;
|
||||
}
|
||||
List<DisassemblyListener> listeners = new ArrayList<DisassemblyListener>();
|
||||
|
||||
@Override
|
||||
public void addDisassemblyListener(DisassemblyListener listener) {
|
||||
listeners.add(listener);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeDisassemblyListener(DisassemblyListener listener) {
|
||||
listeners.remove(listener);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,16 +22,23 @@ import com.jpexs.decompiler.flash.tags.base.BoundedTag;
|
||||
import com.jpexs.decompiler.flash.tags.base.CharacterTag;
|
||||
import com.jpexs.decompiler.flash.tags.base.TextTag;
|
||||
import com.jpexs.decompiler.flash.tags.text.ParseException;
|
||||
import com.jpexs.decompiler.flash.tags.text.ParsedSymbol;
|
||||
import com.jpexs.decompiler.flash.tags.text.TextLexer;
|
||||
import com.jpexs.decompiler.flash.types.RECT;
|
||||
import com.jpexs.decompiler.flash.types.RGBA;
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.OutputStream;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/**
|
||||
*
|
||||
@@ -71,6 +78,16 @@ public class DefineEditTextTag extends CharacterTag implements BoundedTag, TextT
|
||||
public String variableName;
|
||||
public String initialText;
|
||||
|
||||
@Override
|
||||
public RECT getBounds() {
|
||||
return bounds;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setBounds(RECT r) {
|
||||
bounds = r;
|
||||
}
|
||||
|
||||
private String stripTags(String inp) {
|
||||
boolean intag = false;
|
||||
String outp = "";
|
||||
@@ -110,16 +127,247 @@ public class DefineEditTextTag extends CharacterTag implements BoundedTag, TextT
|
||||
|
||||
@Override
|
||||
public String getFormattedText(List<Tag> tags) {
|
||||
String ret = "";
|
||||
ret += "[";
|
||||
String[] alignValues = {"left", "right", "center", "justify"};
|
||||
ret += "xmin " + bounds.Xmin + " ymin " + bounds.Ymin + " xmax " + bounds.Xmax + " ymax " + bounds.Ymax + " ";
|
||||
ret += (wordWrap ? "wordwrap 1 " : "") + (multiline ? "multiline 1 " : "")
|
||||
+ (password ? "password 1 " : "") + (readOnly ? "readonly 1 " : "")
|
||||
+ (autoSize ? "autosize 1 " : "") + (noSelect ? "noselect 1 " : "")
|
||||
+ (border ? "border 1 " : "") + (wasStatic ? "wasstatic 1 " : "")
|
||||
+ (html ? "html 1 " : "") + (useOutlines ? "useoutlines 1 " : "")
|
||||
+ (hasFont ? "font " + fontId + " " : "") + (hasTextColor ? "color " + textColor.toHexARGB() + " " : "")
|
||||
+ (hasFontClass ? "fontclass " + fontClass + " " : "") + (hasMaxLength ? "maxlength " + maxLength + " " : "")
|
||||
+ "align " + alignValues[align] + " "
|
||||
+ (hasLayout ? "leftmargin " + leftMargin + " rightmargin " + rightMargin + " indent " + indent + " leading " + leading + " " : "")
|
||||
+ (!variableName.equals("") ? "variablename " + variableName + " " : "");
|
||||
ret = ret.trim() + "]";
|
||||
if (hasText) {
|
||||
return initialText;
|
||||
ret += initialText.replace("\\", "\\\\").replace("[", "\\[").replace("]", "\\]");
|
||||
}
|
||||
return "";
|
||||
return ret;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setFormattedText(List<Tag> tags, String text) throws ParseException {
|
||||
initialText = text;
|
||||
hasText = true;
|
||||
try {
|
||||
TextLexer lexer = new TextLexer(new InputStreamReader(new ByteArrayInputStream(text.getBytes("UTF-8")), "UTF-8"));
|
||||
ParsedSymbol s = null;
|
||||
text = "";
|
||||
RECT bounds = new RECT(this.bounds);
|
||||
boolean wordWrap = false;
|
||||
boolean multiline = false;
|
||||
boolean password = false;
|
||||
boolean readOnly = false;
|
||||
boolean autoSize = false;
|
||||
boolean noSelect = false;
|
||||
boolean border = false;
|
||||
boolean wasStatic = false;
|
||||
boolean html = false;
|
||||
boolean useOutlines = false;
|
||||
int fontId = -1;
|
||||
int fontHeight = -1;
|
||||
String fontClass = null;
|
||||
RGBA textColor = null;
|
||||
int maxLength = -1;
|
||||
int align = -1;
|
||||
int leftMargin = -1;
|
||||
int rightMargin = -1;
|
||||
int indent = -1;
|
||||
int leading = -1;
|
||||
String variableName = null;
|
||||
|
||||
while ((s = lexer.yylex()) != null) {
|
||||
switch (s.type) {
|
||||
case PARAMETER:
|
||||
String paramName = (String) s.values[0];
|
||||
String paramValue = (String) s.values[1];
|
||||
if (paramName.equals("xmin")) {
|
||||
try {
|
||||
bounds.Xmin = Integer.parseInt(paramValue);
|
||||
} catch (NumberFormatException nfe) {
|
||||
throw new ParseException("Invalid xmin value. Number expected.", lexer.yyline());
|
||||
}
|
||||
} else if (paramName.equals("ymin")) {
|
||||
try {
|
||||
bounds.Ymin = Integer.parseInt(paramValue);
|
||||
} catch (NumberFormatException nfe) {
|
||||
throw new ParseException("Invalid ymin value. Number expected.", lexer.yyline());
|
||||
}
|
||||
} else if (paramName.equals("xmax")) {
|
||||
try {
|
||||
bounds.Xmax = Integer.parseInt(paramValue);
|
||||
} catch (NumberFormatException nfe) {
|
||||
throw new ParseException("Invalid xmax value. Number expected.", lexer.yyline());
|
||||
}
|
||||
} else if (paramName.equals("ymax")) {
|
||||
try {
|
||||
bounds.Ymax = Integer.parseInt(paramValue);
|
||||
} catch (NumberFormatException nfe) {
|
||||
throw new ParseException("Invalid ymax value. Number expected.", lexer.yyline());
|
||||
}
|
||||
} else if (paramName.equals("wordwrap")) {
|
||||
if (paramValue.equals("1")) {
|
||||
wordWrap = true;
|
||||
}
|
||||
} else if (paramName.equals("multiline")) {
|
||||
if (paramValue.equals("1")) {
|
||||
multiline = true;
|
||||
}
|
||||
} else if (paramName.equals("password")) {
|
||||
if (paramValue.equals("1")) {
|
||||
password = true;
|
||||
}
|
||||
} else if (paramName.equals("readonly")) {
|
||||
if (paramValue.equals("1")) {
|
||||
readOnly = true;
|
||||
}
|
||||
} else if (paramName.equals("autosize")) {
|
||||
if (paramValue.equals("1")) {
|
||||
autoSize = true;
|
||||
}
|
||||
} else if (paramName.equals("noselect")) {
|
||||
if (paramValue.equals("1")) {
|
||||
noSelect = true;
|
||||
}
|
||||
} else if (paramName.equals("border")) {
|
||||
if (paramValue.equals("1")) {
|
||||
border = true;
|
||||
}
|
||||
} else if (paramName.equals("wasstatic")) {
|
||||
if (paramValue.equals("1")) {
|
||||
wasStatic = true;
|
||||
}
|
||||
} else if (paramName.equals("html")) {
|
||||
if (paramValue.equals("1")) {
|
||||
html = true;
|
||||
}
|
||||
} else if (paramName.equals("useoutlines")) {
|
||||
if (paramValue.equals("1")) {
|
||||
useOutlines = true;
|
||||
}
|
||||
} else if (paramName.equals("font")) {
|
||||
try {
|
||||
fontId = Integer.parseInt(paramValue);
|
||||
} catch (NumberFormatException ne) {
|
||||
throw new ParseException("Invalid font value. Number expected.", lexer.yyline());
|
||||
}
|
||||
} else if (paramName.equals("fontclass")) {
|
||||
fontClass = paramValue;
|
||||
} else if (paramName.equals("height")) {
|
||||
try {
|
||||
fontHeight = Integer.parseInt(paramValue);
|
||||
} catch (NumberFormatException ne) {
|
||||
throw new ParseException("Invalid height value. Number expected.", lexer.yyline());
|
||||
}
|
||||
} else if (paramName.equals("color")) {
|
||||
Matcher m = Pattern.compile("#([0-9a-f][0-9a-f])([0-9a-f][0-9a-f])([0-9a-f][0-9a-f])([0-9a-f][0-9a-f])").matcher(paramValue);
|
||||
if (m.matches()) {
|
||||
textColor = new RGBA(Integer.parseInt(m.group(2), 16), Integer.parseInt(m.group(3), 16), Integer.parseInt(m.group(4), 16), Integer.parseInt(m.group(1), 16));
|
||||
} else {
|
||||
throw new ParseException("Invalid color. Valid format is #aarrggbb.", lexer.yyline());
|
||||
}
|
||||
} else if (paramName.equals("maxlength")) {
|
||||
try {
|
||||
maxLength = Integer.parseInt(paramValue);
|
||||
} catch (NumberFormatException ne) {
|
||||
throw new ParseException("Invalid maxLength value. Number expected.", lexer.yyline());
|
||||
}
|
||||
} else if (paramName.equals("align")) {
|
||||
if (paramValue.equals("left")) {
|
||||
align = 0;
|
||||
} else if (paramValue.equals("right")) {
|
||||
align = 1;
|
||||
} else if (paramValue.equals("center")) {
|
||||
align = 2;
|
||||
} else if (paramValue.equals("justify")) {
|
||||
align = 3;
|
||||
} else {
|
||||
throw new ParseException("Invalid align value. Expected one of: left,right,center or justify.", lexer.yyline());
|
||||
}
|
||||
|
||||
} else if (paramName.equals("leftmargin")) {
|
||||
try {
|
||||
leftMargin = Integer.parseInt(paramValue);
|
||||
} catch (NumberFormatException ne) {
|
||||
throw new ParseException("Invalid leftmargin value. Number expected.", lexer.yyline());
|
||||
}
|
||||
} else if (paramName.equals("rightmargin")) {
|
||||
try {
|
||||
rightMargin = Integer.parseInt(paramValue);
|
||||
} catch (NumberFormatException ne) {
|
||||
throw new ParseException("Invalid rightmargin value. Number expected.", lexer.yyline());
|
||||
}
|
||||
} else if (paramName.equals("indent")) {
|
||||
try {
|
||||
indent = Integer.parseInt(paramValue);
|
||||
} catch (NumberFormatException ne) {
|
||||
throw new ParseException("Invalid indent value. Number expected.", lexer.yyline());
|
||||
}
|
||||
} else if (paramName.equals("leading")) {
|
||||
try {
|
||||
leading = Integer.parseInt(paramValue);
|
||||
} catch (NumberFormatException ne) {
|
||||
throw new ParseException("Invalid leading value. Number expected.", lexer.yyline());
|
||||
}
|
||||
} else if (paramName.equals("variablename")) {
|
||||
variableName = paramValue;
|
||||
} else {
|
||||
throw new ParseException("Unrecognized parameter name", lexer.yyline());
|
||||
}
|
||||
break;
|
||||
case TEXT:
|
||||
text += (String) s.values[0];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (text.length() > 0) {
|
||||
initialText = text;
|
||||
this.hasText = true;
|
||||
} else {
|
||||
this.hasText = false;
|
||||
}
|
||||
this.wordWrap = wordWrap;
|
||||
this.multiline = multiline;
|
||||
this.password = password;
|
||||
this.readOnly = readOnly;
|
||||
if (textColor != null) {
|
||||
hasTextColor = true;
|
||||
this.textColor = textColor;
|
||||
}
|
||||
if (maxLength > -1) {
|
||||
this.maxLength = maxLength;
|
||||
hasMaxLength = true;
|
||||
}
|
||||
if (fontId > -1) {
|
||||
this.fontId = fontId;
|
||||
}
|
||||
if (fontClass != null) {
|
||||
this.fontClass = fontClass;
|
||||
hasFontClass = true;
|
||||
}
|
||||
this.autoSize = autoSize;
|
||||
if ((leftMargin > -1)
|
||||
|| (rightMargin > -1)
|
||||
|| (indent > -1)
|
||||
|| (leading > -1)) {
|
||||
this.leftMargin = leftMargin;
|
||||
this.rightMargin = rightMargin;
|
||||
this.indent = indent;
|
||||
this.leading = leading;
|
||||
hasLayout = true;
|
||||
}
|
||||
if (variableName == null) {
|
||||
variableName = "";
|
||||
}
|
||||
this.variableName = variableName;
|
||||
|
||||
} catch (IOException ex) {
|
||||
Logger.getLogger(DefineEditTextTag.class.getName()).log(Level.SEVERE, null, ex);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -69,7 +69,7 @@ public class DefineFont2Tag extends CharacterTag implements FontTag {
|
||||
if (fontFlagsHasLayout) {
|
||||
return fontAdvanceTable[glyphIndex];
|
||||
} else {
|
||||
return glyphShapeTable[glyphIndex].getBounds().getWidth();
|
||||
return getGlyphWidth(glyphIndex) + 20;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -67,7 +67,7 @@ public class DefineFont3Tag extends CharacterTag implements FontTag {
|
||||
if (fontFlagsHasLayout) {
|
||||
return fontAdvanceTable[glyphIndex] / 20;
|
||||
} else {
|
||||
return glyphShapeTable[glyphIndex].getBounds().getWidth();
|
||||
return getGlyphWidth(glyphIndex) + 20;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -26,11 +26,6 @@ import com.jpexs.decompiler.flash.tags.base.FontTag;
|
||||
import com.jpexs.decompiler.flash.tags.base.TextTag;
|
||||
import com.jpexs.decompiler.flash.tags.text.ParseException;
|
||||
import com.jpexs.decompiler.flash.tags.text.ParsedSymbol;
|
||||
import static com.jpexs.decompiler.flash.tags.text.SymbolType.COLOR;
|
||||
import static com.jpexs.decompiler.flash.tags.text.SymbolType.FONT;
|
||||
import static com.jpexs.decompiler.flash.tags.text.SymbolType.TEXT;
|
||||
import static com.jpexs.decompiler.flash.tags.text.SymbolType.X;
|
||||
import static com.jpexs.decompiler.flash.tags.text.SymbolType.Y;
|
||||
import com.jpexs.decompiler.flash.tags.text.TextLexer;
|
||||
import com.jpexs.decompiler.flash.types.GLYPHENTRY;
|
||||
import com.jpexs.decompiler.flash.types.MATRIX;
|
||||
@@ -67,6 +62,16 @@ public class DefineText2Tag extends CharacterTag implements BoundedTag, TextTag
|
||||
public int advanceBits;
|
||||
public List<TEXTRECORD> textRecords;
|
||||
|
||||
@Override
|
||||
public RECT getBounds() {
|
||||
return textBounds;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setBounds(RECT r) {
|
||||
textBounds = r;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getText(List<Tag> tags) {
|
||||
FontTag fnt = null;
|
||||
@@ -91,7 +96,24 @@ public class DefineText2Tag extends CharacterTag implements BoundedTag, TextTag
|
||||
public String getFormattedText(List<Tag> tags) {
|
||||
FontTag fnt = null;
|
||||
String ret = "";
|
||||
ret += "[xmin " + textBounds.Xmin + " ymin " + textBounds.Ymin + " xmax " + textBounds.Xmax + " ymax " + textBounds.Ymax;
|
||||
if (textMatrix.translateX != 0) {
|
||||
ret += " translatex " + textMatrix.translateX;
|
||||
}
|
||||
if (textMatrix.translateY != 0) {
|
||||
ret += " translatey " + textMatrix.translateY;
|
||||
}
|
||||
if (textMatrix.hasScale) {
|
||||
ret += " scalex " + textMatrix.scaleX;
|
||||
ret += " scaley " + textMatrix.scaleY;
|
||||
}
|
||||
if (textMatrix.hasRotate) {
|
||||
ret += " rotateskew0 " + textMatrix.rotateSkew0;
|
||||
ret += " rotateskew1 " + textMatrix.rotateSkew1;
|
||||
}
|
||||
ret += "]";
|
||||
for (TEXTRECORD rec : textRecords) {
|
||||
String params = "";
|
||||
if (rec.styleFlagsHasFont) {
|
||||
for (Tag t : tags) {
|
||||
if (t instanceof FontTag) {
|
||||
@@ -101,16 +123,19 @@ public class DefineText2Tag extends CharacterTag implements BoundedTag, TextTag
|
||||
}
|
||||
}
|
||||
}
|
||||
ret += "[font " + rec.fontId + " height " + rec.textHeight + "]";
|
||||
params += " font " + rec.fontId + " height " + rec.textHeight;
|
||||
}
|
||||
if (rec.styleFlagsHasColor) {
|
||||
ret += "[color " + rec.textColorA.toHexARGB() + "]";
|
||||
params += " color " + rec.textColorA.toHexARGB();
|
||||
}
|
||||
if (rec.styleFlagsHasXOffset) {
|
||||
ret += "[x " + rec.xOffset + "]";
|
||||
params += " x " + rec.xOffset;
|
||||
}
|
||||
if (rec.styleFlagsHasYOffset) {
|
||||
ret += "[y " + rec.yOffset + "]";
|
||||
params += " y " + rec.yOffset;
|
||||
}
|
||||
if (params.length() > 0) {
|
||||
ret += "[" + params.trim() + "]";
|
||||
}
|
||||
ret += Helper.escapeString(rec.getText(tags, fnt)).replace("[", "\\[").replace("]", "\\]");
|
||||
}
|
||||
@@ -135,39 +160,128 @@ public class DefineText2Tag extends CharacterTag implements BoundedTag, TextTag
|
||||
int advanceBits = 0;
|
||||
int maxX = Integer.MIN_VALUE;
|
||||
int minX = Integer.MAX_VALUE;
|
||||
MATRIX textMatrix = new MATRIX();
|
||||
textMatrix.hasRotate = false;
|
||||
textMatrix.hasScale = false;
|
||||
RECT textBounds = new RECT();
|
||||
while ((s = lexer.yylex()) != null) {
|
||||
switch (s.type) {
|
||||
case COLOR:
|
||||
Matcher m = Pattern.compile("([0-9a-f][0-9a-f])([0-9a-f][0-9a-f])([0-9a-f][0-9a-f])([0-9a-f][0-9a-f])").matcher(s.values[0].toString());
|
||||
if (m.matches()) {
|
||||
colorA = new RGBA(Integer.parseInt(m.group(2), 16), Integer.parseInt(m.group(3), 16), Integer.parseInt(m.group(4), 16), Integer.parseInt(m.group(1), 16));
|
||||
}
|
||||
break;
|
||||
case FONT:
|
||||
fontId = (Integer) s.values[0];
|
||||
textHeight = (Integer) s.values[1];
|
||||
for (Tag t : tags) {
|
||||
if (t instanceof FontTag) {
|
||||
if (((FontTag) t).getFontId() == fontId) {
|
||||
font = (FontTag) t;
|
||||
break;
|
||||
}
|
||||
case PARAMETER:
|
||||
String paramName = (String) s.values[0];
|
||||
String paramValue = (String) s.values[1];
|
||||
if (paramName.equals("color")) {
|
||||
Matcher m = Pattern.compile("#([0-9a-f][0-9a-f])([0-9a-f][0-9a-f])([0-9a-f][0-9a-f])([0-9a-f][0-9a-f])").matcher(s.values[0].toString());
|
||||
if (m.matches()) {
|
||||
colorA = new RGBA(Integer.parseInt(m.group(2), 16), Integer.parseInt(m.group(3), 16), Integer.parseInt(m.group(4), 16), Integer.parseInt(m.group(1), 16));
|
||||
} else {
|
||||
throw new ParseException("Invalid color. Valid format is #aarrggbb.", lexer.yyline());
|
||||
}
|
||||
}
|
||||
break;
|
||||
case X:
|
||||
x = (Integer) s.values[0];
|
||||
currentX = x;
|
||||
if (currentX < minX) {
|
||||
minX = currentX;
|
||||
if (paramName.equals("font")) {
|
||||
try {
|
||||
fontId = Integer.parseInt(paramValue);
|
||||
|
||||
for (Tag t : tags) {
|
||||
if (t instanceof FontTag) {
|
||||
if (((FontTag) t).getFontId() == fontId) {
|
||||
font = (FontTag) t;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (font == null) {
|
||||
throw new ParseException("Font not found", lexer.yyline());
|
||||
}
|
||||
} catch (NumberFormatException nfe) {
|
||||
throw new ParseException("Invalid font id - number expected.", lexer.yyline());
|
||||
}
|
||||
} else if (paramName.equals("height")) {
|
||||
try {
|
||||
textHeight = Integer.parseInt(paramValue);
|
||||
} catch (NumberFormatException nfe) {
|
||||
throw new ParseException("Invalid font height - number expected.", lexer.yyline());
|
||||
}
|
||||
} else if (paramName.equals("x")) {
|
||||
|
||||
try {
|
||||
x = Integer.parseInt(paramValue);
|
||||
currentX = x;
|
||||
} catch (NumberFormatException nfe) {
|
||||
throw new ParseException("Invalid x position - number expected.", lexer.yyline());
|
||||
}
|
||||
} else if (paramName.equals("y")) {
|
||||
|
||||
try {
|
||||
y = Integer.parseInt(paramValue);
|
||||
currentY = y;
|
||||
} catch (NumberFormatException nfe) {
|
||||
throw new ParseException("Invalid y position - number expected.", lexer.yyline());
|
||||
}
|
||||
} else if (paramName.equals("xmin")) {
|
||||
try {
|
||||
textBounds.Xmin = Integer.parseInt(paramValue);
|
||||
} catch (NumberFormatException nfe) {
|
||||
throw new ParseException("Invalid xmin position - number expected.", lexer.yyline());
|
||||
}
|
||||
} else if (paramName.equals("xmax")) {
|
||||
try {
|
||||
textBounds.Xmax = Integer.parseInt(paramValue);
|
||||
} catch (NumberFormatException nfe) {
|
||||
throw new ParseException("Invalid xmax position - number expected.", lexer.yyline());
|
||||
}
|
||||
} else if (paramName.equals("ymin")) {
|
||||
try {
|
||||
textBounds.Ymin = Integer.parseInt(paramValue);
|
||||
} catch (NumberFormatException nfe) {
|
||||
throw new ParseException("Invalid ymin position - number expected.", lexer.yyline());
|
||||
}
|
||||
} else if (paramName.equals("ymax")) {
|
||||
try {
|
||||
textBounds.Ymax = Integer.parseInt(paramValue);
|
||||
} catch (NumberFormatException nfe) {
|
||||
throw new ParseException("Invalid ymax position - number expected.", lexer.yyline());
|
||||
}
|
||||
} else if (paramName.equals("scalex")) {
|
||||
try {
|
||||
textMatrix.scaleX = Integer.parseInt(paramValue);
|
||||
textMatrix.hasScale = true;
|
||||
} catch (NumberFormatException nfe) {
|
||||
throw new ParseException("Invalid scalex value - number expected.", lexer.yyline());
|
||||
}
|
||||
} else if (paramName.equals("scaley")) {
|
||||
try {
|
||||
textMatrix.scaleY = Integer.parseInt(paramValue);
|
||||
textMatrix.hasScale = true;
|
||||
} catch (NumberFormatException nfe) {
|
||||
throw new ParseException("Invalid scalex value - number expected.", lexer.yyline());
|
||||
}
|
||||
} else if (paramName.equals("rotateskew0")) {
|
||||
try {
|
||||
textMatrix.rotateSkew0 = Integer.parseInt(paramValue);
|
||||
textMatrix.hasRotate = true;
|
||||
} catch (NumberFormatException nfe) {
|
||||
throw new ParseException("Invalid rotateskew0 value - number expected.", lexer.yyline());
|
||||
}
|
||||
} else if (paramName.equals("rotateskew1")) {
|
||||
try {
|
||||
textMatrix.rotateSkew1 = Integer.parseInt(paramValue);
|
||||
textMatrix.hasRotate = true;
|
||||
} catch (NumberFormatException nfe) {
|
||||
throw new ParseException("Invalid rotateskew1 value - number expected.", lexer.yyline());
|
||||
}
|
||||
} else if (paramName.equals("translatex")) {
|
||||
try {
|
||||
textMatrix.translateX = Integer.parseInt(paramValue);
|
||||
} catch (NumberFormatException nfe) {
|
||||
throw new ParseException("Invalid translatex value - number expected.", lexer.yyline());
|
||||
}
|
||||
} else if (paramName.equals("translatey")) {
|
||||
try {
|
||||
textMatrix.translateY = Integer.parseInt(paramValue);
|
||||
} catch (NumberFormatException nfe) {
|
||||
throw new ParseException("Invalid translatey value - number expected.", lexer.yyline());
|
||||
}
|
||||
}
|
||||
if (currentX > maxX) {
|
||||
maxX = currentX;
|
||||
}
|
||||
break;
|
||||
case Y:
|
||||
y = (Integer) s.values[0];
|
||||
currentY = y;
|
||||
break;
|
||||
case TEXT:
|
||||
if (font == null) {
|
||||
@@ -215,8 +329,8 @@ public class DefineText2Tag extends CharacterTag implements BoundedTag, TextTag
|
||||
} else {
|
||||
currentX += tr.glyphEntries[i].glyphAdvance;
|
||||
}
|
||||
if (SWFOutputStream.getNeededBitsS(tr.glyphEntries[i].glyphIndex) > glyphBits) {
|
||||
glyphBits = SWFOutputStream.getNeededBitsS(tr.glyphEntries[i].glyphIndex);
|
||||
if (SWFOutputStream.getNeededBitsU(tr.glyphEntries[i].glyphIndex) > glyphBits) {
|
||||
glyphBits = SWFOutputStream.getNeededBitsU(tr.glyphEntries[i].glyphIndex);
|
||||
}
|
||||
if (SWFOutputStream.getNeededBitsS(tr.glyphEntries[i].glyphAdvance) > advanceBits) {
|
||||
advanceBits = SWFOutputStream.getNeededBitsS(tr.glyphEntries[i].glyphAdvance);
|
||||
@@ -237,8 +351,9 @@ public class DefineText2Tag extends CharacterTag implements BoundedTag, TextTag
|
||||
this.advanceBits = advanceBits;
|
||||
this.glyphBits = glyphBits;
|
||||
this.textRecords = textRecords;
|
||||
this.textBounds.Xmin = minX;
|
||||
this.textBounds.Xmax = maxX;
|
||||
this.textBounds = textBounds;
|
||||
//this.textBounds.Xmin = minX;
|
||||
//this.textBounds.Xmax = maxX;
|
||||
} catch (UnsupportedEncodingException ex) {
|
||||
Logger.getLogger(MainFrame.class.getName()).log(Level.SEVERE, null, ex);
|
||||
} catch (IOException ex) {
|
||||
|
||||
@@ -62,6 +62,16 @@ public class DefineTextTag extends CharacterTag implements BoundedTag, TextTag {
|
||||
public int advanceBits;
|
||||
public List<TEXTRECORD> textRecords;
|
||||
|
||||
@Override
|
||||
public RECT getBounds() {
|
||||
return textBounds;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setBounds(RECT r) {
|
||||
textBounds = r;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getText(List<Tag> tags) {
|
||||
FontTag fnt = null;
|
||||
@@ -86,7 +96,24 @@ public class DefineTextTag extends CharacterTag implements BoundedTag, TextTag {
|
||||
public String getFormattedText(List<Tag> tags) {
|
||||
FontTag fnt = null;
|
||||
String ret = "";
|
||||
ret += "[xmin " + textBounds.Xmin + " ymin " + textBounds.Ymin + " xmax " + textBounds.Xmax + " ymax " + textBounds.Ymax;
|
||||
if (textMatrix.translateX != 0) {
|
||||
ret += " translatex " + textMatrix.translateX;
|
||||
}
|
||||
if (textMatrix.translateY != 0) {
|
||||
ret += " translatey " + textMatrix.translateY;
|
||||
}
|
||||
if (textMatrix.hasScale) {
|
||||
ret += " scalex " + textMatrix.scaleX;
|
||||
ret += " scaley " + textMatrix.scaleY;
|
||||
}
|
||||
if (textMatrix.hasRotate) {
|
||||
ret += " rotateskew0 " + textMatrix.rotateSkew0;
|
||||
ret += " rotateskew1 " + textMatrix.rotateSkew1;
|
||||
}
|
||||
ret += "]";
|
||||
for (TEXTRECORD rec : textRecords) {
|
||||
String params = "";
|
||||
if (rec.styleFlagsHasFont) {
|
||||
for (Tag t : tags) {
|
||||
if (t instanceof FontTag) {
|
||||
@@ -96,16 +123,19 @@ public class DefineTextTag extends CharacterTag implements BoundedTag, TextTag {
|
||||
}
|
||||
}
|
||||
}
|
||||
ret += "[font " + rec.fontId + " height " + rec.textHeight + "]";
|
||||
params += " font " + rec.fontId + " height " + rec.textHeight;
|
||||
}
|
||||
if (rec.styleFlagsHasColor) {
|
||||
ret += "[color " + rec.textColor.toHexRGB() + "]";
|
||||
params += " color " + rec.textColor.toHexRGB();
|
||||
}
|
||||
if (rec.styleFlagsHasXOffset) {
|
||||
ret += "[x " + rec.xOffset + "]";
|
||||
params += " x " + rec.xOffset;
|
||||
}
|
||||
if (rec.styleFlagsHasYOffset) {
|
||||
ret += "[y " + rec.yOffset + "]";
|
||||
params += " y " + rec.yOffset;
|
||||
}
|
||||
if (params.length() > 0) {
|
||||
ret += "[" + params.trim() + "]";
|
||||
}
|
||||
ret += Helper.escapeString(rec.getText(tags, fnt)).replace("[", "\\[").replace("]", "\\]");
|
||||
}
|
||||
@@ -130,40 +160,128 @@ public class DefineTextTag extends CharacterTag implements BoundedTag, TextTag {
|
||||
int advanceBits = 0;
|
||||
int maxX = Integer.MIN_VALUE;
|
||||
int minX = Integer.MAX_VALUE;
|
||||
MATRIX textMatrix = new MATRIX();
|
||||
textMatrix.hasRotate = false;
|
||||
textMatrix.hasScale = false;
|
||||
RECT textBounds = new RECT();
|
||||
while ((s = lexer.yylex()) != null) {
|
||||
switch (s.type) {
|
||||
case COLOR:
|
||||
Matcher m = Pattern.compile("([0-9a-f][0-9a-f])([0-9a-f][0-9a-f])([0-9a-f][0-9a-f])").matcher(s.values[0].toString());
|
||||
if (m.matches()) {
|
||||
color = new RGB(Integer.parseInt(m.group(1), 16), Integer.parseInt(m.group(2), 16), Integer.parseInt(m.group(3), 16));
|
||||
}
|
||||
break;
|
||||
case FONT:
|
||||
fontId = (Integer) s.values[0];
|
||||
textHeight = (Integer) s.values[1];
|
||||
for (Tag t : tags) {
|
||||
if (t instanceof FontTag) {
|
||||
if (((FontTag) t).getFontId() == fontId) {
|
||||
font = (FontTag) t;
|
||||
break;
|
||||
case PARAMETER:
|
||||
String paramName = (String) s.values[0];
|
||||
String paramValue = (String) s.values[1];
|
||||
if (paramName.equals("color")) {
|
||||
Matcher m = Pattern.compile("#([0-9a-f][0-9a-f])([0-9a-f][0-9a-f])([0-9a-f][0-9a-f])").matcher(paramValue);
|
||||
if (m.matches()) {
|
||||
color = new RGB(Integer.parseInt(m.group(1), 16), Integer.parseInt(m.group(2), 16), Integer.parseInt(m.group(3), 16));
|
||||
} else {
|
||||
throw new ParseException("Invalid color. Valid format is #rrggbb.", lexer.yyline());
|
||||
}
|
||||
} else if (paramName.equals("font")) {
|
||||
try {
|
||||
fontId = Integer.parseInt(paramValue);
|
||||
|
||||
for (Tag t : tags) {
|
||||
if (t instanceof FontTag) {
|
||||
if (((FontTag) t).getFontId() == fontId) {
|
||||
font = (FontTag) t;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (font == null) {
|
||||
throw new ParseException("Font not found", lexer.yyline());
|
||||
}
|
||||
} catch (NumberFormatException nfe) {
|
||||
throw new ParseException("Invalid font id - number expected.", lexer.yyline());
|
||||
}
|
||||
} else if (paramName.equals("height")) {
|
||||
try {
|
||||
textHeight = Integer.parseInt(paramValue);
|
||||
} catch (NumberFormatException nfe) {
|
||||
throw new ParseException("Invalid font height - number expected.", lexer.yyline());
|
||||
}
|
||||
} else if (paramName.equals("x")) {
|
||||
|
||||
try {
|
||||
x = Integer.parseInt(paramValue);
|
||||
currentX = x;
|
||||
} catch (NumberFormatException nfe) {
|
||||
throw new ParseException("Invalid x position - number expected.", lexer.yyline());
|
||||
}
|
||||
} else if (paramName.equals("y")) {
|
||||
|
||||
try {
|
||||
y = Integer.parseInt(paramValue);
|
||||
currentY = y;
|
||||
} catch (NumberFormatException nfe) {
|
||||
throw new ParseException("Invalid y position - number expected.", lexer.yyline());
|
||||
}
|
||||
} else if (paramName.equals("xmin")) {
|
||||
try {
|
||||
textBounds.Xmin = Integer.parseInt(paramValue);
|
||||
} catch (NumberFormatException nfe) {
|
||||
throw new ParseException("Invalid xmin position - number expected.", lexer.yyline());
|
||||
}
|
||||
} else if (paramName.equals("xmax")) {
|
||||
try {
|
||||
textBounds.Xmax = Integer.parseInt(paramValue);
|
||||
} catch (NumberFormatException nfe) {
|
||||
throw new ParseException("Invalid xmax position - number expected.", lexer.yyline());
|
||||
}
|
||||
} else if (paramName.equals("ymin")) {
|
||||
try {
|
||||
textBounds.Ymin = Integer.parseInt(paramValue);
|
||||
} catch (NumberFormatException nfe) {
|
||||
throw new ParseException("Invalid ymin position - number expected.", lexer.yyline());
|
||||
}
|
||||
} else if (paramName.equals("ymax")) {
|
||||
try {
|
||||
textBounds.Ymax = Integer.parseInt(paramValue);
|
||||
} catch (NumberFormatException nfe) {
|
||||
throw new ParseException("Invalid ymax position - number expected.", lexer.yyline());
|
||||
}
|
||||
} else if (paramName.equals("scalex")) {
|
||||
try {
|
||||
textMatrix.scaleX = Integer.parseInt(paramValue);
|
||||
textMatrix.hasScale = true;
|
||||
} catch (NumberFormatException nfe) {
|
||||
throw new ParseException("Invalid scalex value - number expected.", lexer.yyline());
|
||||
}
|
||||
} else if (paramName.equals("scaley")) {
|
||||
try {
|
||||
textMatrix.scaleY = Integer.parseInt(paramValue);
|
||||
textMatrix.hasScale = true;
|
||||
} catch (NumberFormatException nfe) {
|
||||
throw new ParseException("Invalid scalex value - number expected.", lexer.yyline());
|
||||
}
|
||||
} else if (paramName.equals("rotateskew0")) {
|
||||
try {
|
||||
textMatrix.rotateSkew0 = Integer.parseInt(paramValue);
|
||||
textMatrix.hasRotate = true;
|
||||
} catch (NumberFormatException nfe) {
|
||||
throw new ParseException("Invalid rotateskew0 value - number expected.", lexer.yyline());
|
||||
}
|
||||
} else if (paramName.equals("rotateskew1")) {
|
||||
try {
|
||||
textMatrix.rotateSkew1 = Integer.parseInt(paramValue);
|
||||
textMatrix.hasRotate = true;
|
||||
} catch (NumberFormatException nfe) {
|
||||
throw new ParseException("Invalid rotateskew1 value - number expected.", lexer.yyline());
|
||||
}
|
||||
} else if (paramName.equals("translatex")) {
|
||||
try {
|
||||
textMatrix.translateX = Integer.parseInt(paramValue);
|
||||
} catch (NumberFormatException nfe) {
|
||||
throw new ParseException("Invalid translatex value - number expected.", lexer.yyline());
|
||||
}
|
||||
} else if (paramName.equals("translatey")) {
|
||||
try {
|
||||
textMatrix.translateY = Integer.parseInt(paramValue);
|
||||
} catch (NumberFormatException nfe) {
|
||||
throw new ParseException("Invalid translatey value - number expected.", lexer.yyline());
|
||||
}
|
||||
}
|
||||
break;
|
||||
case X:
|
||||
x = (Integer) s.values[0];
|
||||
currentX = x;
|
||||
if (currentX < minX) {
|
||||
minX = currentX;
|
||||
}
|
||||
if (currentX > maxX) {
|
||||
maxX = currentX;
|
||||
}
|
||||
break;
|
||||
case Y:
|
||||
y = (Integer) s.values[0];
|
||||
currentY = y;
|
||||
break;
|
||||
case TEXT:
|
||||
if (font == null) {
|
||||
throw new ParseException("Font not defined", lexer.yyline());
|
||||
@@ -210,8 +328,8 @@ public class DefineTextTag extends CharacterTag implements BoundedTag, TextTag {
|
||||
} else {
|
||||
currentX += tr.glyphEntries[i].glyphAdvance;
|
||||
}
|
||||
if (SWFOutputStream.getNeededBitsS(tr.glyphEntries[i].glyphIndex) > glyphBits) {
|
||||
glyphBits = SWFOutputStream.getNeededBitsS(tr.glyphEntries[i].glyphIndex);
|
||||
if (SWFOutputStream.getNeededBitsU(tr.glyphEntries[i].glyphIndex) > glyphBits) {
|
||||
glyphBits = SWFOutputStream.getNeededBitsU(tr.glyphEntries[i].glyphIndex);
|
||||
}
|
||||
if (SWFOutputStream.getNeededBitsS(tr.glyphEntries[i].glyphAdvance) > advanceBits) {
|
||||
advanceBits = SWFOutputStream.getNeededBitsS(tr.glyphEntries[i].glyphAdvance);
|
||||
@@ -232,8 +350,10 @@ public class DefineTextTag extends CharacterTag implements BoundedTag, TextTag {
|
||||
this.advanceBits = advanceBits;
|
||||
this.glyphBits = glyphBits;
|
||||
this.textRecords = textRecords;
|
||||
this.textBounds.Xmin = minX;
|
||||
this.textBounds.Xmax = maxX;
|
||||
this.textMatrix = textMatrix;
|
||||
this.textBounds = textBounds;
|
||||
//this.textBounds.Xmin = minX;
|
||||
//this.textBounds.Xmax = maxX;
|
||||
} catch (UnsupportedEncodingException ex) {
|
||||
Logger.getLogger(MainFrame.class.getName()).log(Level.SEVERE, null, ex);
|
||||
} catch (IOException ex) {
|
||||
|
||||
@@ -16,6 +16,8 @@
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.tags;
|
||||
|
||||
import com.jpexs.decompiler.flash.Configuration;
|
||||
import com.jpexs.decompiler.flash.DisassemblyListener;
|
||||
import com.jpexs.decompiler.flash.ReReadableInputStream;
|
||||
import com.jpexs.decompiler.flash.SWFInputStream;
|
||||
import com.jpexs.decompiler.flash.SWFOutputStream;
|
||||
@@ -72,7 +74,7 @@ public class DoActionTag extends Tag implements ASMSource {
|
||||
*/
|
||||
@Override
|
||||
public String getASMSource(int version, boolean hex) {
|
||||
return Action.actionsToString(0, getActions(version), null, version, hex, getPos());
|
||||
return Action.actionsToString(listeners, 0, getActions(version), null, version, hex, getPos());
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -111,7 +113,12 @@ public class DoActionTag extends Tag implements ASMSource {
|
||||
baos.write(actionBytes);
|
||||
ReReadableInputStream rri = new ReReadableInputStream(new ByteArrayInputStream(baos.toByteArray()));
|
||||
rri.setPos(prevLength);
|
||||
return Action.removeNops(0, SWFInputStream.readActionList(0, getPos() - prevLength, rri, version, prevLength, -1), version, getPos());
|
||||
boolean deobfuscate = (Boolean) Configuration.getConfig("autoDeobfuscate", true);
|
||||
List<Action> list = SWFInputStream.readActionList(listeners, 0, getPos() - prevLength, rri, version, prevLength, -1);
|
||||
if (deobfuscate) {
|
||||
list = Action.removeNops(0, list, version, getPos());
|
||||
}
|
||||
return list;
|
||||
} catch (Exception ex) {
|
||||
Logger.getLogger(DoActionTag.class.getName()).log(Level.SEVERE, null, ex);
|
||||
return new ArrayList<Action>();
|
||||
@@ -132,4 +139,15 @@ public class DoActionTag extends Tag implements ASMSource {
|
||||
public void setActionBytes(byte[] actionBytes) {
|
||||
this.actionBytes = actionBytes;
|
||||
}
|
||||
List<DisassemblyListener> listeners = new ArrayList<DisassemblyListener>();
|
||||
|
||||
@Override
|
||||
public void addDisassemblyListener(DisassemblyListener listener) {
|
||||
listeners.add(listener);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeDisassemblyListener(DisassemblyListener listener) {
|
||||
listeners.remove(listener);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,6 +16,8 @@
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.tags;
|
||||
|
||||
import com.jpexs.decompiler.flash.Configuration;
|
||||
import com.jpexs.decompiler.flash.DisassemblyListener;
|
||||
import com.jpexs.decompiler.flash.ReReadableInputStream;
|
||||
import com.jpexs.decompiler.flash.SWFInputStream;
|
||||
import com.jpexs.decompiler.flash.SWFOutputStream;
|
||||
@@ -95,7 +97,7 @@ public class DoInitActionTag extends CharacterTag implements ASMSource {
|
||||
*/
|
||||
@Override
|
||||
public String getASMSource(int version, boolean hex) {
|
||||
return Action.actionsToString(0, getActions(version), null, version, hex, getPos() + 2);
|
||||
return Action.actionsToString(listeners, 0, getActions(version), null, version, hex, getPos() + 2);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -117,7 +119,12 @@ public class DoInitActionTag extends CharacterTag implements ASMSource {
|
||||
baos.write(actionBytes);
|
||||
ReReadableInputStream rri = new ReReadableInputStream(new ByteArrayInputStream(baos.toByteArray()));
|
||||
rri.setPos(prevLength);
|
||||
return Action.removeNops(0, SWFInputStream.readActionList(0, getPos() + 2 - prevLength, rri, version, prevLength, -1), version, getPos() + 2);
|
||||
boolean deobfuscate = (Boolean) Configuration.getConfig("autoDeobfuscate", true);
|
||||
List<Action> list = SWFInputStream.readActionList(listeners, 0, getPos() + 2 - prevLength, rri, version, prevLength, -1);
|
||||
if (deobfuscate) {
|
||||
list = Action.removeNops(0, list, version, getPos() + 2);
|
||||
}
|
||||
return list;
|
||||
} catch (Exception ex) {
|
||||
Logger.getLogger(DoActionTag.class.getName()).log(Level.SEVERE, null, ex);
|
||||
return new ArrayList<Action>();
|
||||
@@ -143,4 +150,15 @@ public class DoInitActionTag extends CharacterTag implements ASMSource {
|
||||
public int getCharacterID() {
|
||||
return spriteId;
|
||||
}
|
||||
List<DisassemblyListener> listeners = new ArrayList<DisassemblyListener>();
|
||||
|
||||
@Override
|
||||
public void addDisassemblyListener(DisassemblyListener listener) {
|
||||
listeners.add(listener);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeDisassemblyListener(DisassemblyListener listener) {
|
||||
listeners.remove(listener);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.tags.base;
|
||||
|
||||
import com.jpexs.decompiler.flash.DisassemblyListener;
|
||||
import com.jpexs.decompiler.flash.action.Action;
|
||||
import java.util.List;
|
||||
|
||||
@@ -63,4 +64,8 @@ public interface ASMSource {
|
||||
public void setActionBytes(byte actionBytes[]);
|
||||
|
||||
public long getPos();
|
||||
|
||||
public void addDisassemblyListener(DisassemblyListener listener);
|
||||
|
||||
public void removeDisassemblyListener(DisassemblyListener listener);
|
||||
}
|
||||
|
||||
@@ -18,6 +18,7 @@ package com.jpexs.decompiler.flash.tags.base;
|
||||
|
||||
import com.jpexs.decompiler.flash.tags.Tag;
|
||||
import com.jpexs.decompiler.flash.tags.text.ParseException;
|
||||
import com.jpexs.decompiler.flash.types.RECT;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
@@ -33,4 +34,8 @@ public interface TextTag {
|
||||
public void setFormattedText(List<Tag> tags, String text) throws ParseException;
|
||||
|
||||
public int getCharacterID();
|
||||
|
||||
public RECT getBounds();
|
||||
|
||||
public void setBounds(RECT r);
|
||||
}
|
||||
|
||||
@@ -23,8 +23,5 @@ package com.jpexs.decompiler.flash.tags.text;
|
||||
public enum SymbolType {
|
||||
|
||||
TEXT,
|
||||
FONT,
|
||||
COLOR,
|
||||
X,
|
||||
Y
|
||||
PARAMETER
|
||||
}
|
||||
|
||||
@@ -1,13 +1,26 @@
|
||||
/* The following code was generated by JFlex 1.4.3 on 28.4.13 11:46 */
|
||||
/* The following code was generated by JFlex 1.4.3 on 30.4.13 19:25 */
|
||||
|
||||
/* Flash assembler language lexer specification */
|
||||
/*
|
||||
* Copyright (C) 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.decompiler.flash.tags.text;
|
||||
|
||||
import java.util.regex.*;
|
||||
|
||||
/**
|
||||
* This class is a scanner generated by
|
||||
* <a href="http://www.jflex.de/">JFlex</a> 1.4.3 on 28.4.13 11:46 from the
|
||||
* <a href="http://www.jflex.de/">JFlex</a> 1.4.3 on 30.4.13 19:25 from the
|
||||
* specification file
|
||||
* <tt>D:/Dokumenty/Programovani/JavaSE/FFDec/trunk/src/com/jpexs/decompiler/flash/tags/text/text.flex</tt>
|
||||
*/
|
||||
@@ -25,23 +38,23 @@ public final class TextLexer {
|
||||
* lexical states
|
||||
*/
|
||||
public static final int YYINITIAL = 0;
|
||||
public static final int VALUE = 4;
|
||||
public static final int PARAMETER = 2;
|
||||
/**
|
||||
* ZZ_LEXSTATE[l] is the state in the DFA for the lexical state l
|
||||
* ZZ_LEXSTATE[l+1] is the state in the DFA for the lexical state l at the
|
||||
* beginning of a line l is of the form l = 2*k, k a non negative integer
|
||||
*/
|
||||
private static final int ZZ_LEXSTATE[] = {
|
||||
0, 0
|
||||
0, 0, 1, 1, 2, 2
|
||||
};
|
||||
/**
|
||||
* Translates characters to character classes
|
||||
*/
|
||||
private static final String ZZ_CMAP_PACKED =
|
||||
"\12\0\1\32\25\0\1\12\1\0\1\30\1\23\3\0\1\31\5\0"
|
||||
+ "\1\3\2\0\1\1\11\2\41\0\1\5\1\26\1\17\3\0\1\4"
|
||||
+ "\1\27\1\20\1\4\1\14\1\6\1\16\1\13\1\15\2\0\1\21"
|
||||
+ "\1\0\1\10\1\7\2\0\1\22\1\0\1\11\3\0\1\24\1\25"
|
||||
+ "\uff86\0";
|
||||
"\12\0\1\15\25\0\1\2\1\0\1\13\4\0\1\14\10\0\12\1"
|
||||
+ "\41\0\1\3\1\4\1\5\1\0\1\1\1\0\1\1\1\6\3\1"
|
||||
+ "\1\11\7\1\1\10\3\1\1\12\1\1\1\7\6\1\uff85\0";
|
||||
/**
|
||||
* Translates characters to character classes
|
||||
*/
|
||||
@@ -51,12 +64,12 @@ public final class TextLexer {
|
||||
*/
|
||||
private static final int[] ZZ_ACTION = zzUnpackAction();
|
||||
private static final String ZZ_ACTION_PACKED_0 =
|
||||
"\1\0\3\1\1\2\4\0\1\3\1\4\1\5\1\6"
|
||||
+ "\1\7\1\10\1\11\1\12\1\13\1\14\1\15\16\0"
|
||||
+ "\1\16\1\17\25\0\1\20\3\0\1\21";
|
||||
"\3\0\1\1\1\2\1\1\1\3\1\4\1\5\1\6"
|
||||
+ "\1\7\1\10\1\11\1\12\1\13\1\14\1\15\1\16"
|
||||
+ "\1\17\1\20\1\21";
|
||||
|
||||
private static int[] zzUnpackAction() {
|
||||
int[] result = new int[62];
|
||||
int[] result = new int[21];
|
||||
int offset = 0;
|
||||
offset = zzUnpackAction(ZZ_ACTION_PACKED_0, offset, result);
|
||||
return result;
|
||||
@@ -80,17 +93,12 @@ public final class TextLexer {
|
||||
*/
|
||||
private static final int[] ZZ_ROWMAP = zzUnpackRowMap();
|
||||
private static final String ZZ_ROWMAP_PACKED_0 =
|
||||
"\0\0\0\33\0\66\0\121\0\33\0\154\0\207\0\242"
|
||||
+ "\0\275\0\33\0\33\0\33\0\33\0\33\0\33\0\33"
|
||||
+ "\0\33\0\33\0\33\0\33\0\330\0\363\0\u010e\0\u0129"
|
||||
+ "\0\u0144\0\u015f\0\u017a\0\u0195\0\u01b0\0\u01cb\0\u01e6\0\u0201"
|
||||
+ "\0\u021c\0\u0237\0\33\0\33\0\u0252\0\u026d\0\u0288\0\u02a3"
|
||||
+ "\0\u02be\0\u02d9\0\u02f4\0\u030f\0\u032a\0\u0345\0\u0360\0\u037b"
|
||||
+ "\0\u0396\0\u03b1\0\u03cc\0\u03e7\0\u0402\0\u041d\0\u0438\0\u0453"
|
||||
+ "\0\u046e\0\33\0\u0489\0\u04a4\0\u04bf\0\33";
|
||||
"\0\0\0\16\0\34\0\52\0\52\0\70\0\52\0\106"
|
||||
+ "\0\52\0\124\0\52\0\52\0\52\0\52\0\52\0\52"
|
||||
+ "\0\52\0\52\0\52\0\52\0\52";
|
||||
|
||||
private static int[] zzUnpackRowMap() {
|
||||
int[] result = new int[62];
|
||||
int[] result = new int[21];
|
||||
int offset = 0;
|
||||
offset = zzUnpackRowMap(ZZ_ROWMAP_PACKED_0, offset, result);
|
||||
return result;
|
||||
@@ -111,36 +119,14 @@ public final class TextLexer {
|
||||
*/
|
||||
private static final int[] ZZ_TRANS = zzUnpackTrans();
|
||||
private static final String ZZ_TRANS_PACKED_0 =
|
||||
"\5\2\1\3\20\2\1\4\3\2\1\5\41\0\1\6"
|
||||
+ "\11\0\1\7\3\0\1\10\1\11\5\0\5\12\1\13"
|
||||
+ "\1\14\1\12\1\15\1\16\5\12\1\17\2\12\1\20"
|
||||
+ "\3\12\1\21\1\22\1\23\1\24\10\0\1\25\32\0"
|
||||
+ "\1\26\35\0\1\27\32\0\1\30\30\0\1\31\43\0"
|
||||
+ "\1\32\12\0\1\33\1\34\1\35\30\0\1\36\1\37"
|
||||
+ "\1\40\40\0\1\41\30\0\1\42\42\0\1\43\14\0"
|
||||
+ "\2\34\14\0\1\43\14\0\1\33\1\34\47\0\1\44"
|
||||
+ "\14\0\2\37\14\0\1\44\14\0\1\36\1\37\42\0"
|
||||
+ "\1\45\42\0\1\46\11\0\1\47\1\50\42\0\1\51"
|
||||
+ "\32\0\1\52\21\0\2\50\7\0\1\52\43\0\1\53"
|
||||
+ "\22\0\1\54\20\0\2\55\1\0\1\55\1\0\1\55"
|
||||
+ "\5\0\1\55\3\0\1\55\6\0\1\55\17\0\1\56"
|
||||
+ "\17\0\2\57\1\0\1\57\1\0\1\57\5\0\1\57"
|
||||
+ "\3\0\1\57\6\0\1\57\20\0\1\60\16\0\2\61"
|
||||
+ "\1\0\1\61\1\0\1\61\5\0\1\61\3\0\1\61"
|
||||
+ "\6\0\1\61\21\0\1\62\15\0\2\63\1\0\1\63"
|
||||
+ "\1\0\1\63\5\0\1\63\3\0\1\63\6\0\1\63"
|
||||
+ "\16\0\1\64\20\0\2\65\1\0\1\65\1\0\1\65"
|
||||
+ "\5\0\1\65\3\0\1\65\6\0\1\65\14\0\1\66"
|
||||
+ "\22\0\2\67\1\0\1\67\1\0\1\67\5\0\1\67"
|
||||
+ "\3\0\1\67\6\0\1\67\15\0\1\70\21\0\2\71"
|
||||
+ "\1\0\1\71\1\0\1\71\5\0\1\71\2\0\1\72"
|
||||
+ "\1\71\6\0\1\71\4\0\1\73\1\74\31\0\2\75"
|
||||
+ "\1\0\1\75\1\0\1\75\5\0\1\75\3\0\1\75"
|
||||
+ "\6\0\1\75\22\0\1\76\14\0\2\74\14\0\1\76"
|
||||
+ "\32\0\1\72\13\0";
|
||||
"\3\4\1\5\1\6\10\4\2\7\1\10\3\7\1\11"
|
||||
+ "\5\10\3\7\2\12\1\7\2\12\1\11\10\12\16\0"
|
||||
+ "\3\13\1\14\1\15\1\16\1\17\1\20\1\21\1\22"
|
||||
+ "\1\23\1\24\1\25\2\0\1\10\4\0\5\10\3\0"
|
||||
+ "\2\12\1\0\2\12\1\0\10\12";
|
||||
|
||||
private static int[] zzUnpackTrans() {
|
||||
int[] result = new int[1242];
|
||||
int[] result = new int[98];
|
||||
int offset = 0;
|
||||
offset = zzUnpackTrans(ZZ_TRANS_PACKED_0, offset, result);
|
||||
return result;
|
||||
@@ -177,11 +163,10 @@ public final class TextLexer {
|
||||
*/
|
||||
private static final int[] ZZ_ATTRIBUTE = zzUnpackAttribute();
|
||||
private static final String ZZ_ATTRIBUTE_PACKED_0 =
|
||||
"\1\0\1\11\2\1\1\11\4\0\13\11\16\0\2\11"
|
||||
+ "\25\0\1\11\3\0\1\11";
|
||||
"\3\0\2\11\1\1\1\11\1\1\1\11\1\1\13\11";
|
||||
|
||||
private static int[] zzUnpackAttribute() {
|
||||
int[] result = new int[62];
|
||||
int[] result = new int[21];
|
||||
int offset = 0;
|
||||
offset = zzUnpackAttribute(ZZ_ATTRIBUTE_PACKED_0, offset, result);
|
||||
return result;
|
||||
@@ -263,6 +248,7 @@ public final class TextLexer {
|
||||
/* user code: */
|
||||
StringBuffer string = null;
|
||||
boolean finish = false;
|
||||
String parameterName = null;
|
||||
|
||||
/**
|
||||
* Create an empty lexer, yyrset will be called later to reset and assign
|
||||
@@ -309,7 +295,7 @@ public final class TextLexer {
|
||||
char[] map = new char[0x10000];
|
||||
int i = 0; /* index in packed string */
|
||||
int j = 0; /* index in unpacked array */
|
||||
while (i < 82) {
|
||||
while (i < 58) {
|
||||
int count = packed.charAt(i++);
|
||||
char value = packed.charAt(i++);
|
||||
do {
|
||||
@@ -633,12 +619,12 @@ public final class TextLexer {
|
||||
}
|
||||
case 18:
|
||||
break;
|
||||
case 3: {
|
||||
case 7: {
|
||||
throw new ParseException("Illegal escape sequence \"" + yytext() + "\"", yyline + 1);
|
||||
}
|
||||
case 19:
|
||||
break;
|
||||
case 6: {
|
||||
case 13: {
|
||||
if (string == null) {
|
||||
string = new StringBuffer();
|
||||
}
|
||||
@@ -646,31 +632,25 @@ public final class TextLexer {
|
||||
}
|
||||
case 20:
|
||||
break;
|
||||
case 2: {
|
||||
yybegin(PARAMETER);
|
||||
if (string != null) {
|
||||
String ret = string.toString();
|
||||
string = null;
|
||||
return new ParsedSymbol(SymbolType.TEXT, ret.toString());
|
||||
}
|
||||
}
|
||||
case 21:
|
||||
break;
|
||||
case 11: {
|
||||
if (string == null) {
|
||||
string = new StringBuffer();
|
||||
}
|
||||
string.append('\b');
|
||||
}
|
||||
case 21:
|
||||
break;
|
||||
case 17: {
|
||||
if (string == null) {
|
||||
Pattern pat = Pattern.compile("\\[font ([0-9]+) height ([0-9]+)\\]");
|
||||
Matcher m = pat.matcher(yytext());
|
||||
if (m.matches()) {
|
||||
return new ParsedSymbol(SymbolType.FONT, Integer.parseInt(m.group(1)), Integer.parseInt(m.group(2)));
|
||||
}
|
||||
} else {
|
||||
yypushback(yylength());
|
||||
String ret = string.toString();
|
||||
string = null;
|
||||
return new ParsedSymbol(SymbolType.TEXT, ret.toString());
|
||||
}
|
||||
}
|
||||
case 22:
|
||||
break;
|
||||
case 13: {
|
||||
case 17: {
|
||||
if (string == null) {
|
||||
string = new StringBuffer();
|
||||
}
|
||||
@@ -678,99 +658,80 @@ public final class TextLexer {
|
||||
}
|
||||
case 23:
|
||||
break;
|
||||
case 16: {
|
||||
if (string == null) {
|
||||
return new ParsedSymbol(SymbolType.COLOR, yytext().substring(8, yytext().length() - 1));
|
||||
} else {
|
||||
yypushback(yylength());
|
||||
String ret = string.toString();
|
||||
string = null;
|
||||
return new ParsedSymbol(SymbolType.TEXT, ret.toString());
|
||||
}
|
||||
case 4: {
|
||||
parameterName = yytext();
|
||||
yybegin(VALUE);
|
||||
}
|
||||
case 24:
|
||||
break;
|
||||
case 8: {
|
||||
if (string == null) {
|
||||
string = new StringBuffer();
|
||||
}
|
||||
string.append(']');
|
||||
case 6: {
|
||||
yybegin(PARAMETER);
|
||||
return new ParsedSymbol(SymbolType.PARAMETER, new Object[]{parameterName, yytext()});
|
||||
}
|
||||
case 25:
|
||||
break;
|
||||
case 15: {
|
||||
if (string == null) {
|
||||
return new ParsedSymbol(SymbolType.Y, Integer.parseInt(yytext().substring(3, yytext().length() - 1)));
|
||||
} else {
|
||||
yypushback(yylength());
|
||||
String ret = string.toString();
|
||||
string = null;
|
||||
return new ParsedSymbol(SymbolType.TEXT, ret.toString());
|
||||
}
|
||||
}
|
||||
case 26:
|
||||
break;
|
||||
case 14: {
|
||||
if (string == null) {
|
||||
return new ParsedSymbol(SymbolType.X, Integer.parseInt(yytext().substring(3, yytext().length() - 1)));
|
||||
} else {
|
||||
yypushback(yylength());
|
||||
String ret = string.toString();
|
||||
string = null;
|
||||
return new ParsedSymbol(SymbolType.TEXT, ret.toString());
|
||||
}
|
||||
}
|
||||
case 27:
|
||||
break;
|
||||
case 7: {
|
||||
if (string == null) {
|
||||
string = new StringBuffer();
|
||||
}
|
||||
string.append('\t');
|
||||
}
|
||||
case 28:
|
||||
break;
|
||||
case 4: {
|
||||
if (string == null) {
|
||||
string = new StringBuffer();
|
||||
}
|
||||
string.append('[');
|
||||
}
|
||||
case 29:
|
||||
break;
|
||||
case 10: {
|
||||
if (string == null) {
|
||||
string = new StringBuffer();
|
||||
}
|
||||
string.append('\\');
|
||||
string.append(']');
|
||||
}
|
||||
case 30:
|
||||
case 26:
|
||||
break;
|
||||
case 12: {
|
||||
if (string == null) {
|
||||
string = new StringBuffer();
|
||||
}
|
||||
string.append('\"');
|
||||
string.append('\t');
|
||||
}
|
||||
case 31:
|
||||
case 27:
|
||||
break;
|
||||
case 8: {
|
||||
if (string == null) {
|
||||
string = new StringBuffer();
|
||||
}
|
||||
string.append('[');
|
||||
}
|
||||
case 28:
|
||||
break;
|
||||
case 9: {
|
||||
if (string == null) {
|
||||
string = new StringBuffer();
|
||||
}
|
||||
string.append('\\');
|
||||
}
|
||||
case 29:
|
||||
break;
|
||||
case 16: {
|
||||
if (string == null) {
|
||||
string = new StringBuffer();
|
||||
}
|
||||
string.append('\"');
|
||||
}
|
||||
case 30:
|
||||
break;
|
||||
case 15: {
|
||||
if (string == null) {
|
||||
string = new StringBuffer();
|
||||
}
|
||||
string.append('\r');
|
||||
}
|
||||
case 32:
|
||||
case 31:
|
||||
break;
|
||||
case 5: {
|
||||
case 14: {
|
||||
if (string == null) {
|
||||
string = new StringBuffer();
|
||||
}
|
||||
string.append('\f');
|
||||
}
|
||||
case 32:
|
||||
break;
|
||||
case 5: {
|
||||
yybegin(YYINITIAL);
|
||||
}
|
||||
case 33:
|
||||
break;
|
||||
case 2: {
|
||||
case 3: {
|
||||
}
|
||||
case 34:
|
||||
break;
|
||||
@@ -786,7 +747,7 @@ public final class TextLexer {
|
||||
return new ParsedSymbol(SymbolType.TEXT, string.toString());
|
||||
}
|
||||
}
|
||||
case 63:
|
||||
case 22:
|
||||
break;
|
||||
default: {
|
||||
return null;
|
||||
|
||||
@@ -1,8 +1,21 @@
|
||||
/* Flash assembler language lexer specification */
|
||||
|
||||
/*
|
||||
* Copyright (C) 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.decompiler.flash.tags.text;
|
||||
|
||||
import java.util.regex.*;
|
||||
|
||||
%%
|
||||
|
||||
@@ -20,6 +33,7 @@ import java.util.regex.*;
|
||||
|
||||
StringBuffer string = null;
|
||||
boolean finish=false;
|
||||
String parameterName=null;
|
||||
|
||||
|
||||
/**
|
||||
@@ -40,60 +54,17 @@ import java.util.regex.*;
|
||||
|
||||
%}
|
||||
|
||||
PositiveNumber = 0 | [1-9][0-9]*
|
||||
NegativeNumber = - {PositiveNumber}
|
||||
Number = {PositiveNumber}|{NegativeNumber}
|
||||
Hex = [0-9a-f][0-9a-f]
|
||||
|
||||
Font = "[font " {PositiveNumber} " height " {PositiveNumber} "]"
|
||||
Color = "[color #" {Hex}{Hex}{Hex} "]"
|
||||
ColorA = "[color #" {Hex}{Hex}{Hex}{Hex} "]"
|
||||
X = "[x " {Number} "]"
|
||||
Y = "[y " {Number} "]"
|
||||
Parameter = [a-z0-9_]+
|
||||
Value = [^ \]]+
|
||||
|
||||
%state PARAMETER,VALUE
|
||||
|
||||
%%
|
||||
|
||||
<YYINITIAL> {
|
||||
{Font} {
|
||||
if(string==null){
|
||||
Pattern pat = Pattern.compile("\\[font ([0-9]+) height ([0-9]+)\\]");
|
||||
Matcher m=pat.matcher(yytext());
|
||||
if(m.matches()){
|
||||
return new ParsedSymbol(SymbolType.FONT,Integer.parseInt(m.group(1)),Integer.parseInt(m.group(2)));
|
||||
}
|
||||
}else{
|
||||
yypushback(yylength());
|
||||
String ret=string.toString();
|
||||
string = null;
|
||||
return new ParsedSymbol(SymbolType.TEXT,ret.toString());
|
||||
}
|
||||
}
|
||||
{Color}|{ColorA} {
|
||||
if(string==null){
|
||||
return new ParsedSymbol(SymbolType.COLOR,yytext().substring(8,yytext().length()-1));
|
||||
}else{
|
||||
yypushback(yylength());
|
||||
String ret=string.toString();
|
||||
string = null;
|
||||
return new ParsedSymbol(SymbolType.TEXT,ret.toString());
|
||||
}
|
||||
}
|
||||
{X} {
|
||||
if(string==null){
|
||||
return new ParsedSymbol(SymbolType.X,Integer.parseInt(yytext().substring(3,yytext().length()-1)));
|
||||
}else{
|
||||
yypushback(yylength());
|
||||
String ret=string.toString();
|
||||
string = null;
|
||||
return new ParsedSymbol(SymbolType.TEXT,ret.toString());
|
||||
}
|
||||
}
|
||||
{Y} {
|
||||
if(string==null){
|
||||
return new ParsedSymbol(SymbolType.Y,Integer.parseInt(yytext().substring(3,yytext().length()-1)));
|
||||
}else{
|
||||
yypushback(yylength());
|
||||
"[" {
|
||||
yybegin(PARAMETER);
|
||||
if(string!=null){
|
||||
String ret=string.toString();
|
||||
string = null;
|
||||
return new ParsedSymbol(SymbolType.TEXT,ret.toString());
|
||||
@@ -117,6 +88,28 @@ Y = "[y " {Number} "]"
|
||||
<<EOF>> { if(finish){return null;}else{finish=true; return new ParsedSymbol(SymbolType.TEXT,string.toString());}}
|
||||
}
|
||||
|
||||
<PARAMETER> {
|
||||
" " {}
|
||||
{Parameter} {
|
||||
parameterName = yytext();
|
||||
yybegin(VALUE);
|
||||
}
|
||||
"]" {
|
||||
yybegin(YYINITIAL);
|
||||
}
|
||||
}
|
||||
|
||||
<VALUE> {
|
||||
" " {}
|
||||
{Value} {
|
||||
yybegin(PARAMETER);
|
||||
return new ParsedSymbol(SymbolType.PARAMETER,new Object[]{parameterName,yytext()});
|
||||
}
|
||||
"]" {
|
||||
yybegin(YYINITIAL);
|
||||
}
|
||||
}
|
||||
|
||||
/* error fallback */
|
||||
.|\n { }
|
||||
<<EOF>> { return null; }
|
||||
|
||||
@@ -16,6 +16,8 @@
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.types;
|
||||
|
||||
import com.jpexs.decompiler.flash.Configuration;
|
||||
import com.jpexs.decompiler.flash.DisassemblyListener;
|
||||
import com.jpexs.decompiler.flash.ReReadableInputStream;
|
||||
import com.jpexs.decompiler.flash.SWFInputStream;
|
||||
import com.jpexs.decompiler.flash.action.Action;
|
||||
@@ -142,7 +144,7 @@ public class BUTTONCONDACTION implements ASMSource {
|
||||
*/
|
||||
@Override
|
||||
public String getASMSource(int version, boolean hex) {
|
||||
return Action.actionsToString(0, getActions(version), null, version, hex, getPos() + 4);
|
||||
return Action.actionsToString(listeners, 0, getActions(version), null, version, hex, getPos() + 4);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -164,7 +166,13 @@ public class BUTTONCONDACTION implements ASMSource {
|
||||
@Override
|
||||
public List<Action> getActions(int version) {
|
||||
try {
|
||||
return Action.removeNops(0, SWFInputStream.readActionList(0, getPos() + 4, new ReReadableInputStream(new ByteArrayInputStream(actionBytes)), version, 0, -1), version, getPos() + 4);
|
||||
boolean deobfuscate = (Boolean) Configuration.getConfig("autoDeobfuscate", true);
|
||||
List<Action> list = SWFInputStream.readActionList(listeners, 0, getPos() + 4, new ReReadableInputStream(new ByteArrayInputStream(actionBytes)), version, 0, -1);
|
||||
if (deobfuscate) {
|
||||
list = Action.removeNops(0, list, version, getPos() + 4);
|
||||
}
|
||||
return list;
|
||||
|
||||
} catch (Exception ex) {
|
||||
Logger.getLogger(BUTTONCONDACTION.class.getName()).log(Level.SEVERE, null, ex);
|
||||
return new ArrayList<Action>();
|
||||
@@ -185,4 +193,15 @@ public class BUTTONCONDACTION implements ASMSource {
|
||||
public void setActionBytes(byte[] actionBytes) {
|
||||
this.actionBytes = actionBytes;
|
||||
}
|
||||
List<DisassemblyListener> listeners = new ArrayList<DisassemblyListener>();
|
||||
|
||||
@Override
|
||||
public void addDisassemblyListener(DisassemblyListener listener) {
|
||||
listeners.add(listener);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeDisassemblyListener(DisassemblyListener listener) {
|
||||
listeners.remove(listener);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,6 +16,8 @@
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.types;
|
||||
|
||||
import com.jpexs.decompiler.flash.Configuration;
|
||||
import com.jpexs.decompiler.flash.DisassemblyListener;
|
||||
import com.jpexs.decompiler.flash.ReReadableInputStream;
|
||||
import com.jpexs.decompiler.flash.SWFInputStream;
|
||||
import com.jpexs.decompiler.flash.action.Action;
|
||||
@@ -105,7 +107,7 @@ public class CLIPACTIONRECORD implements ASMSource {
|
||||
*/
|
||||
@Override
|
||||
public String getASMSource(int version, boolean hex) {
|
||||
return Action.actionsToString(0, getActions(version), null, version, hex, getPos() + hdrPos);
|
||||
return Action.actionsToString(listeners, 0, getActions(version), null, version, hex, getPos() + hdrPos);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -121,7 +123,12 @@ public class CLIPACTIONRECORD implements ASMSource {
|
||||
@Override
|
||||
public List<Action> getActions(int version) {
|
||||
try {
|
||||
return Action.removeNops(0, SWFInputStream.readActionList(0, getPos() + hdrPos, new ReReadableInputStream(new ByteArrayInputStream(actionBytes)), version, 0, -1), version, getPos() + hdrPos);
|
||||
boolean deobfuscate = (Boolean) Configuration.getConfig("autoDeobfuscate", true);
|
||||
List<Action> list = SWFInputStream.readActionList(listeners, 0, getPos() + hdrPos, new ReReadableInputStream(new ByteArrayInputStream(actionBytes)), version, 0, -1);
|
||||
if (deobfuscate) {
|
||||
list = Action.removeNops(0, list, version, getPos() + hdrPos);
|
||||
}
|
||||
return list;
|
||||
} catch (Exception ex) {
|
||||
Logger.getLogger(BUTTONCONDACTION.class.getName()).log(Level.SEVERE, null, ex);
|
||||
return new ArrayList<Action>();
|
||||
@@ -142,4 +149,15 @@ public class CLIPACTIONRECORD implements ASMSource {
|
||||
public void setActionBytes(byte[] actionBytes) {
|
||||
this.actionBytes = actionBytes;
|
||||
}
|
||||
List<DisassemblyListener> listeners = new ArrayList<DisassemblyListener>();
|
||||
|
||||
@Override
|
||||
public void addDisassemblyListener(DisassemblyListener listener) {
|
||||
listeners.add(listener);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeDisassemblyListener(DisassemblyListener listener) {
|
||||
listeners.remove(listener);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -51,6 +51,13 @@ public class RECT {
|
||||
public RECT() {
|
||||
}
|
||||
|
||||
public RECT(RECT r) {
|
||||
Xmin = r.Xmin;
|
||||
Xmax = r.Xmax;
|
||||
Ymin = r.Ymin;
|
||||
Ymax = r.Ymax;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "[RECT x=" + Xmin + " to " + Xmax + ", y=" + Ymin + " to " + Ymax + "]";
|
||||
|
||||
Reference in New Issue
Block a user