mirror of
https://git.huckle.dev/Huckles-Minecraft-Archive/jpexs-decompiler.git
synced 2026-09-29 20:30:55 +00:00
Merge pull request #38 from jindrapetrik/flexcompile
Flex SDK compilation, AS3 metadata compile fixes
This commit is contained in:
@@ -2502,6 +2502,7 @@ public final class SWF implements SWFContainerItem, Timelined {
|
||||
}
|
||||
|
||||
public void clearImageCache() {
|
||||
jtt = null;
|
||||
frameCache.clear();
|
||||
rectCache.clear();
|
||||
for (Tag tag : getTags()) {
|
||||
@@ -2539,10 +2540,14 @@ public final class SWF implements SWFContainerItem, Timelined {
|
||||
System.gc();
|
||||
}
|
||||
|
||||
public void clearAbcListCache() {
|
||||
abcList = null;
|
||||
}
|
||||
|
||||
public void clearAllCache() {
|
||||
characters = null;
|
||||
characterIdTags = null;
|
||||
abcList = null;
|
||||
clearAbcListCache();
|
||||
timeline = null;
|
||||
clearReadOnlyListCache();
|
||||
clearImageCache();
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -27,4 +27,27 @@ public class ABCVersion implements Comparable<ABCVersion> {
|
||||
return "" + major + "." + minor;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int hash = 7;
|
||||
hash = 53 * hash + this.major;
|
||||
hash = 53 * hash + this.minor;
|
||||
return hash;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj) {
|
||||
return true;
|
||||
}
|
||||
if (obj == null) {
|
||||
return false;
|
||||
}
|
||||
if (getClass() != obj.getClass()) {
|
||||
return false;
|
||||
}
|
||||
final ABCVersion other = (ABCVersion) obj;
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -200,12 +200,14 @@ public class ScriptPack extends AS3ClassTreeItem {
|
||||
//TODO: handle this better in GUI(?)
|
||||
writer.startTrait(GraphTextWriter.TRAIT_SCRIPT_INITIALIZER);
|
||||
writer.startMethod(script_init);
|
||||
if (!scriptInitializerIsEmpty) {
|
||||
writer.startBlock();
|
||||
abc.bodies.get(bodyIndex).toString(path +/*packageName +*/ "/.scriptinitializer", exportMode, abc, null, writer, new ArrayList<>());
|
||||
writer.endBlock();
|
||||
} else {
|
||||
writer.append(" ");
|
||||
if (exportMode != ScriptExportMode.AS_METHOD_STUBS) {
|
||||
if (!scriptInitializerIsEmpty) {
|
||||
writer.startBlock();
|
||||
abc.bodies.get(bodyIndex).toString(path +/*packageName +*/ "/.scriptinitializer", exportMode, abc, null, writer, new ArrayList<>());
|
||||
writer.endBlock();
|
||||
} else {
|
||||
writer.append(" ");
|
||||
}
|
||||
}
|
||||
writer.endMethod();
|
||||
writer.endTrait();
|
||||
|
||||
@@ -1100,6 +1100,11 @@ public class AVM2Code implements Cloneable {
|
||||
}
|
||||
}
|
||||
|
||||
public void setInstructionOperand(int ip, int operandIndex, int value, MethodBody body) {
|
||||
int oldVal = code.get(ip).operands[ip];
|
||||
code.get(ip).operands[ip] = value;
|
||||
}
|
||||
|
||||
public byte[] getBytes() {
|
||||
return getBytes(null);
|
||||
}
|
||||
@@ -1638,7 +1643,7 @@ public class AVM2Code implements Cloneable {
|
||||
}
|
||||
}//*/
|
||||
|
||||
/*if ((ip + 2 < code.size()) && (ins.definition instanceof NewCatchIns)) { // Filling local register in catch clause
|
||||
/*if ((ip + 2 < code.size()) && (ins.definition instanceof NewCatchIns)) { // Filling local register in catch clause
|
||||
if (code.get(ip + 1).definition instanceof DupIns) {
|
||||
if (code.get(ip + 2).definition instanceof SetLocalTypeIns) {
|
||||
ins.definition.translate(isStatic, classIndex, localRegs, stack, scopeStack, constants, ins, method_info, output, body, abc, localRegNames, fullyQualifiedNames);
|
||||
@@ -2145,6 +2150,38 @@ public class AVM2Code implements Cloneable {
|
||||
return list;
|
||||
}
|
||||
|
||||
public void updateInstructionByteCountByAddr(long instructionAddress, int byteDelta, MethodBody body) {
|
||||
if (byteDelta != 0) {
|
||||
updateOffsets(new OffsetUpdater() {
|
||||
|
||||
@Override
|
||||
public long updateInstructionOffset(long address) {
|
||||
if (address > instructionAddress) {
|
||||
return address + byteDelta;
|
||||
}
|
||||
return address;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int updateOperandOffset(long insAddr, long targetAddress, int offset) {
|
||||
if (targetAddress > instructionAddress && insAddr <= instructionAddress) {
|
||||
return offset + byteDelta;
|
||||
}
|
||||
if (targetAddress <= instructionAddress && insAddr > instructionAddress) {
|
||||
return offset - byteDelta;
|
||||
}
|
||||
return offset;
|
||||
}
|
||||
}, body);
|
||||
body.setModified();
|
||||
}
|
||||
}
|
||||
|
||||
public void updateInstructionByteCount(int pos, int byteDelta, MethodBody body) {
|
||||
AVM2Instruction instruction = code.get(pos);
|
||||
updateInstructionByteCountByAddr(instruction.getAddress(), byteDelta, body);
|
||||
}
|
||||
|
||||
public void updateOffsets(OffsetUpdater updater, MethodBody body) {
|
||||
for (int i = 0; i < code.size(); i++) {
|
||||
AVM2Instruction ins = code.get(i);
|
||||
@@ -2172,6 +2209,7 @@ public class AVM2Code implements Cloneable {
|
||||
}
|
||||
}
|
||||
ins.setAddress(updater.updateInstructionOffset(ins.getAddress()));
|
||||
//Note: changing operands here does not change instruction byte length as offsets are always S24 (not variable length)
|
||||
}
|
||||
|
||||
for (ABCException ex : body.exceptions) {
|
||||
|
||||
@@ -377,6 +377,14 @@ public class AVM2ConstantPool implements Cloneable {
|
||||
return null;
|
||||
}
|
||||
|
||||
public int getDecimalId(Decimal val, boolean add) {
|
||||
int id = getDecimalId(val);
|
||||
if (add && id == -1) {
|
||||
id = addDecimal(val);
|
||||
}
|
||||
return id;
|
||||
}
|
||||
|
||||
public Float getFloat(int index) {
|
||||
try {
|
||||
return constant_float.get(index);
|
||||
@@ -514,6 +522,10 @@ public class AVM2ConstantPool implements Cloneable {
|
||||
return constant_float4.indexOf(value);
|
||||
}
|
||||
|
||||
private int getDecimalId(Decimal value) {
|
||||
return constant_decimal.indexOf(value);
|
||||
}
|
||||
|
||||
private int getStringId(String value) {
|
||||
return constant_string.indexOf(value);
|
||||
}
|
||||
@@ -755,4 +767,132 @@ public class AVM2ConstantPool implements Cloneable {
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Merges second constantpool into this one
|
||||
*
|
||||
* @param secondPool
|
||||
* @param stringMap
|
||||
* @param intMap
|
||||
* @param uintMap
|
||||
* @param doubleMap
|
||||
* @param floatMap
|
||||
* @param float4Map
|
||||
* @param decimalMap
|
||||
* @param namespaceMap
|
||||
* @param namespaceSetMap
|
||||
* @param multinameMap
|
||||
*/
|
||||
public void merge(AVM2ConstantPool secondPool, Map<Integer, Integer> stringMap, Map<Integer, Integer> intMap, Map<Integer, Integer> uintMap, Map<Integer, Integer> doubleMap, Map<Integer, Integer> floatMap, Map<Integer, Integer> float4Map, Map<Integer, Integer> decimalMap, Map<Integer, Integer> namespaceMap, Map<Integer, Integer> namespaceSetMap, Map<Integer, Integer> multinameMap) {
|
||||
stringMap.put(0, 0);
|
||||
for (int i = 1; i < secondPool.constant_string.size(); i++) {
|
||||
String val = secondPool.constant_string.get(i);
|
||||
stringMap.put(i, getStringId(val, true));
|
||||
}
|
||||
intMap.put(0, 0);
|
||||
for (int i = 1; i < secondPool.constant_int.size(); i++) {
|
||||
Long val = secondPool.constant_int.get(i);
|
||||
intMap.put(i, getIntId(val, true));
|
||||
}
|
||||
uintMap.put(0, 0);
|
||||
for (int i = 1; i < secondPool.constant_uint.size(); i++) {
|
||||
Long val = secondPool.constant_uint.get(i);
|
||||
uintMap.put(i, getUIntId(val, true));
|
||||
}
|
||||
doubleMap.put(0, 0);
|
||||
for (int i = 1; i < secondPool.constant_double.size(); i++) {
|
||||
Double val = secondPool.constant_double.get(i);
|
||||
doubleMap.put(i, getDoubleId(val, true));
|
||||
}
|
||||
floatMap.put(0, 0);
|
||||
for (int i = 1; i < secondPool.constant_float.size(); i++) {
|
||||
Float val = secondPool.constant_float.get(i);
|
||||
floatMap.put(i, getFloatId(val, true));
|
||||
}
|
||||
float4Map.put(0, 0);
|
||||
for (int i = 1; i < secondPool.constant_float4.size(); i++) {
|
||||
Float4 val = secondPool.constant_float4.get(i);
|
||||
float4Map.put(i, getFloat4Id(val, true));
|
||||
}
|
||||
decimalMap.put(0, 0);
|
||||
for (int i = 1; i < secondPool.constant_decimal.size(); i++) {
|
||||
Decimal val = secondPool.constant_decimal.get(i);
|
||||
decimalMap.put(i, getDecimalId(val, true));
|
||||
}
|
||||
namespaceMap.put(0, 0);
|
||||
for (int i = 1; i < secondPool.constant_namespace.size(); i++) {
|
||||
Namespace secondNamespace = secondPool.constant_namespace.get(i);
|
||||
int mappedId;
|
||||
int newNameIndex = stringMap.get(secondNamespace.name_index);
|
||||
if (secondNamespace.kind == Namespace.KIND_PRIVATE) {//always add, this does not exists in this ABC. Conflicting private namespaces can have same names.
|
||||
mappedId = addNamespace(secondNamespace.kind, newNameIndex);
|
||||
} else {
|
||||
mappedId = getNamespaceId(secondNamespace.kind, newNameIndex, 0, true);
|
||||
}
|
||||
namespaceMap.put(i, mappedId);
|
||||
}
|
||||
namespaceSetMap.put(0, 0);
|
||||
for (int i = 1; i < secondPool.constant_namespace_set.size(); i++) {
|
||||
NamespaceSet secondNamespaceSet = secondPool.constant_namespace_set.get(i);
|
||||
int mappedsNss[] = new int[secondNamespaceSet.namespaces.length];
|
||||
for (int n = 0; n < secondNamespaceSet.namespaces.length; n++) {
|
||||
mappedsNss[n] = namespaceMap.get(secondNamespaceSet.namespaces[n]);
|
||||
}
|
||||
int mappedId = getNamespaceSetId(mappedsNss, true);
|
||||
namespaceSetMap.put(i, mappedId);
|
||||
}
|
||||
multinameMap.put(0, 0);
|
||||
for (int i = 1; i < secondPool.constant_multiname.size(); i++) {
|
||||
Multiname secondMultiname = secondPool.constant_multiname.get(i);
|
||||
Multiname newMultiname = null;
|
||||
int newNameIndex = secondMultiname.name_index <= 0 ? secondMultiname.name_index : stringMap.get(secondMultiname.name_index);
|
||||
int newNsIndex = secondMultiname.namespace_index <= 0 ? secondMultiname.namespace_index : namespaceMap.get(secondMultiname.namespace_index);
|
||||
int newNssIndex = secondMultiname.namespace_set_index <= 0 ? secondMultiname.namespace_set_index : namespaceSetMap.get(secondMultiname.namespace_set_index);
|
||||
|
||||
switch (secondMultiname.kind) {
|
||||
case Multiname.MULTINAME:
|
||||
newMultiname = Multiname.createMultiname(false, newNameIndex, newNssIndex);
|
||||
break;
|
||||
case Multiname.MULTINAMEA:
|
||||
newMultiname = Multiname.createMultiname(true, newNameIndex, newNssIndex);
|
||||
break;
|
||||
case Multiname.MULTINAMEL:
|
||||
newMultiname = Multiname.createMultinameL(false, newNssIndex);
|
||||
break;
|
||||
case Multiname.MULTINAMELA:
|
||||
newMultiname = Multiname.createMultinameL(true, newNssIndex);
|
||||
break;
|
||||
case Multiname.QNAME:
|
||||
newMultiname = Multiname.createQName(false, newNameIndex, newNsIndex);
|
||||
break;
|
||||
case Multiname.QNAMEA:
|
||||
newMultiname = Multiname.createQName(true, newNameIndex, newNsIndex);
|
||||
break;
|
||||
case Multiname.RTQNAME:
|
||||
newMultiname = Multiname.createRTQName(false, newNameIndex);
|
||||
break;
|
||||
case Multiname.RTQNAMEA:
|
||||
newMultiname = Multiname.createRTQName(true, newNameIndex);
|
||||
break;
|
||||
case Multiname.RTQNAMEL:
|
||||
newMultiname = Multiname.createRTQNameL(false);
|
||||
break;
|
||||
case Multiname.RTQNAMELA:
|
||||
newMultiname = Multiname.createRTQNameL(true);
|
||||
break;
|
||||
case Multiname.TYPENAME:
|
||||
int newQnameIndex = multinameMap.get(secondMultiname.qname_index);
|
||||
int newParams[] = new int[secondMultiname.params.length];
|
||||
for (int p = 0; p < secondMultiname.params.length; p++) {
|
||||
newParams[p] = multinameMap.get(secondMultiname.params[p]);
|
||||
}
|
||||
newMultiname = Multiname.createTypeName(newQnameIndex, newParams);
|
||||
break;
|
||||
}
|
||||
|
||||
int mappedId = getMultinameId(newMultiname, true);
|
||||
multinameMap.put(i, mappedId);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -220,7 +220,7 @@ public class AVM2DeobfuscatorRegisters extends AVM2DeobfuscatorSimple {
|
||||
|
||||
AVM2Instruction ins = code.code.get(idx);
|
||||
InstructionDefinition def = ins.definition;
|
||||
//System.err.println("" + idx + ": " + ins + " stack:" + stack.size());
|
||||
//System.err.println("" + idx + ": " + ins + " stack:" + stack.size());
|
||||
|
||||
// do not throw EmptyStackException, much faster
|
||||
int requiredStackSize = def.getStackPopCount(ins, abc);
|
||||
|
||||
+3
-4
@@ -161,7 +161,7 @@ public class AVM2DeobfuscatorSimpleOld extends SWFDecompilerAdapter {
|
||||
AVM2Instruction ins = code.code.get(i);
|
||||
if (ins.definition instanceof JumpIns) {
|
||||
long address = ins.getTargetAddress();
|
||||
jumpTargets.add( code.adr2pos(address) );
|
||||
jumpTargets.add(code.adr2pos(address));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -294,9 +294,8 @@ public class AVM2DeobfuscatorSimpleOld extends SWFDecompilerAdapter {
|
||||
|
||||
if (inlineIns.contains(ins)) {
|
||||
if (def instanceof SetLocalTypeIns) {
|
||||
InstructionDefinition prevDef = code.code.get(idx-1).definition;
|
||||
if ((prevDef instanceof DupIns && !jumpTargets.contains(idx-2)) || !jumpTargets.contains(idx-1))
|
||||
{
|
||||
InstructionDefinition prevDef = code.code.get(idx - 1).definition;
|
||||
if ((prevDef instanceof DupIns && !jumpTargets.contains(idx - 2)) || !jumpTargets.contains(idx - 1)) {
|
||||
int regId = ((SetLocalTypeIns) def).getRegisterId(ins);
|
||||
staticRegs.put(regId, localData.localRegs.get(regId).getNotCoerced());
|
||||
code.replaceInstruction(idx, new AVM2Instruction(0, DeobfuscatePopIns.getInstance(), null), body);
|
||||
|
||||
+41
@@ -27,6 +27,7 @@ import com.jpexs.decompiler.flash.abc.avm2.instructions.other.ReturnValueIns;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.other.ReturnVoidIns;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.other.ThrowIns;
|
||||
import com.jpexs.decompiler.flash.abc.types.Float4;
|
||||
import com.jpexs.decompiler.flash.abc.types.MethodBody;
|
||||
import com.jpexs.decompiler.flash.abc.types.Multiname;
|
||||
import com.jpexs.decompiler.flash.helpers.GraphTextWriter;
|
||||
import com.jpexs.decompiler.graph.DottedChain;
|
||||
@@ -488,4 +489,44 @@ public class AVM2Instruction implements Cloneable, GraphSourceItem {
|
||||
public String getFile() {
|
||||
return file;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set operand value the right way - update offsets neccessarily. Because
|
||||
* some operand types are variable length (like U30)
|
||||
*
|
||||
* @param operandIndex
|
||||
* @param newValue
|
||||
* @param code
|
||||
* @param body
|
||||
*/
|
||||
public void setOperand(int operandIndex, int newValue, AVM2Code code, MethodBody body) {
|
||||
int oldByteCount = getBytesLength();
|
||||
operands[operandIndex] = newValue;
|
||||
int newByteCount = getBytesLength();
|
||||
int byteDelta = newByteCount - oldByteCount;
|
||||
if (byteDelta != 0) {
|
||||
code.updateInstructionByteCountByAddr(address, byteDelta, body);
|
||||
}
|
||||
body.setModified();
|
||||
}
|
||||
|
||||
/**
|
||||
* Set operand values the right way - update offsets neccessarily. Because
|
||||
* some operand types are variable length (like U30)
|
||||
*
|
||||
* @param operands
|
||||
* @param code
|
||||
* @param body
|
||||
*/
|
||||
public void setOperands(int operands[], AVM2Code code, MethodBody body) {
|
||||
int oldByteCount = getBytesLength();
|
||||
this.operands = operands;
|
||||
int newByteCount = getBytesLength();
|
||||
int byteDelta = newByteCount - oldByteCount;
|
||||
if (byteDelta != 0) {
|
||||
code.updateInstructionByteCountByAddr(address, byteDelta, body);
|
||||
}
|
||||
body.setModified();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -108,8 +108,9 @@ public abstract class AVM2Item extends GraphTargetItem {
|
||||
}
|
||||
if (propertyName instanceof FullMultinameAVM2Item) {
|
||||
if (((FullMultinameAVM2Item) propertyName).name != null) {
|
||||
if (((FullMultinameAVM2Item) propertyName).namespace != null)
|
||||
if (((FullMultinameAVM2Item) propertyName).namespace != null) {
|
||||
writer.append(".");
|
||||
}
|
||||
return propertyName.toString(writer, localData);
|
||||
} else {
|
||||
writer.append(".");
|
||||
|
||||
+1
-1
@@ -77,7 +77,7 @@ public class ForEachInAVM2Item extends LoopItem implements Block {
|
||||
|
||||
|
||||
*/
|
||||
/*
|
||||
/*
|
||||
if (!commands.isEmpty()) {
|
||||
GraphTargetItem firstAssign = commands.get(0);
|
||||
if (firstAssign instanceof SetTypeAVM2Item) {
|
||||
|
||||
+56
-47
@@ -1,6 +1,6 @@
|
||||
/* The following code was generated by JFlex 1.6.0 */
|
||||
|
||||
/*
|
||||
/*
|
||||
* Copyright (C) 2010-2016 JPEXS, All rights reserved.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
@@ -16,7 +16,7 @@
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library.
|
||||
*/
|
||||
/* Flash assembler language lexer specification */
|
||||
/* Flash assembler language lexer specification */
|
||||
package com.jpexs.decompiler.flash.abc.avm2.parser.pcode;
|
||||
|
||||
import com.jpexs.decompiler.flash.abc.avm2.parser.AVM2ParseException;
|
||||
@@ -24,8 +24,7 @@ import java.util.Stack;
|
||||
|
||||
/**
|
||||
* This class is a scanner generated by
|
||||
* <a href="http://www.jflex.de/">JFlex</a> 1.6.0
|
||||
* from the specification file
|
||||
* <a href="http://www.jflex.de/">JFlex</a> 1.6.0 from the specification file
|
||||
* <tt>C:/FFDec/jpexs-decompiler/libsrc/ffdec_lib/lexers/actionscript3_pcode.flex</tt>
|
||||
*/
|
||||
public final class Flasm3Lexer {
|
||||
@@ -51,9 +50,8 @@ public final class Flasm3Lexer {
|
||||
|
||||
/**
|
||||
* 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
|
||||
* 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, 1, 1, 2, 2
|
||||
@@ -272,9 +270,11 @@ public final class Flasm3Lexer {
|
||||
}
|
||||
|
||||
private static int zzUnpackAction(String packed, int offset, int[] result) {
|
||||
int i = 0; /* index in packed string */
|
||||
int i = 0;
|
||||
/* index in packed string */
|
||||
|
||||
int j = offset; /* index in unpacked array */
|
||||
int j = offset;
|
||||
/* index in unpacked array */
|
||||
|
||||
int l = packed.length();
|
||||
while (i < l) {
|
||||
@@ -380,9 +380,11 @@ public final class Flasm3Lexer {
|
||||
}
|
||||
|
||||
private static int zzUnpackRowMap(String packed, int offset, int[] result) {
|
||||
int i = 0; /* index in packed string */
|
||||
int i = 0;
|
||||
/* index in packed string */
|
||||
|
||||
int j = offset; /* index in unpacked array */
|
||||
int j = offset;
|
||||
/* index in unpacked array */
|
||||
|
||||
int l = packed.length();
|
||||
while (i < l) {
|
||||
@@ -2479,9 +2481,11 @@ public final class Flasm3Lexer {
|
||||
}
|
||||
|
||||
private static int zzUnpackTrans(String packed, int offset, int[] result) {
|
||||
int i = 0; /* index in packed string */
|
||||
int i = 0;
|
||||
/* index in packed string */
|
||||
|
||||
int j = offset; /* index in unpacked array */
|
||||
int j = offset;
|
||||
/* index in unpacked array */
|
||||
|
||||
int l = packed.length();
|
||||
while (i < l) {
|
||||
@@ -2550,9 +2554,11 @@ public final class Flasm3Lexer {
|
||||
}
|
||||
|
||||
private static int zzUnpackAttribute(String packed, int offset, int[] result) {
|
||||
int i = 0; /* index in packed string */
|
||||
int i = 0;
|
||||
/* index in packed string */
|
||||
|
||||
int j = offset; /* index in unpacked array */
|
||||
int j = offset;
|
||||
/* index in unpacked array */
|
||||
|
||||
int l = packed.length();
|
||||
while (i < l) {
|
||||
@@ -2581,8 +2587,8 @@ public final class Flasm3Lexer {
|
||||
private int zzLexicalState = YYINITIAL;
|
||||
|
||||
/**
|
||||
* this buffer contains the current text to be matched and is
|
||||
* the source of the yytext() string
|
||||
* this buffer contains the current text to be matched and is the source of
|
||||
* the yytext() string
|
||||
*/
|
||||
private char zzBuffer[] = new char[ZZ_BUFFERSIZE];
|
||||
|
||||
@@ -2602,8 +2608,8 @@ public final class Flasm3Lexer {
|
||||
private int zzStartRead;
|
||||
|
||||
/**
|
||||
* endRead marks the last character in the buffer, that has been read
|
||||
* from input
|
||||
* endRead marks the last character in the buffer, that has been read from
|
||||
* input
|
||||
*/
|
||||
private int zzEndRead;
|
||||
|
||||
@@ -2639,10 +2645,10 @@ public final class Flasm3Lexer {
|
||||
private boolean zzEOFDone;
|
||||
|
||||
/**
|
||||
* The number of occupied positions in zzBuffer beyond zzEndRead.
|
||||
* When a lead/high surrogate has been read from the input stream
|
||||
* into the final zzBuffer position, this will have a value of 1;
|
||||
* otherwise, it will have a value of 0.
|
||||
* The number of occupied positions in zzBuffer beyond zzEndRead. When a
|
||||
* lead/high surrogate has been read from the input stream into the final
|
||||
* zzBuffer position, this will have a value of 1; otherwise, it will have a
|
||||
* value of 0.
|
||||
*/
|
||||
private int zzFinalHighSurrogate = 0;
|
||||
|
||||
@@ -2705,9 +2711,11 @@ public final class Flasm3Lexer {
|
||||
*/
|
||||
private static char[] zzUnpackCMap(String packed) {
|
||||
char[] map = new char[0x110000];
|
||||
int i = 0; /* index in packed string */
|
||||
int i = 0;
|
||||
/* index in packed string */
|
||||
|
||||
int j = 0; /* index in unpacked array */
|
||||
int j = 0;
|
||||
/* index in unpacked array */
|
||||
|
||||
while (i < 2916) {
|
||||
int count = packed.charAt(i++);
|
||||
@@ -2766,7 +2774,8 @@ public final class Flasm3Lexer {
|
||||
|
||||
if (totalRead > 0) {
|
||||
zzEndRead += totalRead;
|
||||
if (totalRead == requested) { /* possibly more input available */
|
||||
if (totalRead == requested) {
|
||||
/* possibly more input available */
|
||||
|
||||
if (Character.isHighSurrogate(zzBuffer[zzEndRead - 1])) {
|
||||
--zzEndRead;
|
||||
@@ -2784,9 +2793,11 @@ public final class Flasm3Lexer {
|
||||
* Closes the input stream.
|
||||
*/
|
||||
public final void yyclose() throws java.io.IOException {
|
||||
zzAtEOF = true; /* indicate end of file */
|
||||
zzAtEOF = true;
|
||||
/* indicate end of file */
|
||||
|
||||
zzEndRead = zzStartRead; /* invalidate buffer */
|
||||
zzEndRead = zzStartRead;
|
||||
/* invalidate buffer */
|
||||
|
||||
if (zzReader != null) {
|
||||
zzReader.close();
|
||||
@@ -2794,12 +2805,12 @@ public final class Flasm3Lexer {
|
||||
}
|
||||
|
||||
/**
|
||||
* Resets the scanner to read from a new input stream.
|
||||
* Does not close the old reader.
|
||||
* Resets the scanner to read from a new input stream. Does not close the
|
||||
* old reader.
|
||||
*
|
||||
* All internal variables are reset, the old input stream
|
||||
* <b>cannot</b> be reused (internal buffer is discarded and lost).
|
||||
* Lexical state is set to <tt>ZZ_INITIAL</tt>.
|
||||
* <b>cannot</b> be reused (internal buffer is discarded and lost). Lexical
|
||||
* state is set to <tt>ZZ_INITIAL</tt>.
|
||||
*
|
||||
* Internal scan buffer is resized down to its initial length, if it has
|
||||
* grown.
|
||||
@@ -2845,13 +2856,12 @@ public final class Flasm3Lexer {
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the character at position <tt>pos</tt> from the
|
||||
* matched text.
|
||||
* Returns the character at position <tt>pos</tt> from the matched text.
|
||||
*
|
||||
* It is equivalent to yytext().charAt(pos), but faster
|
||||
*
|
||||
* @param pos the position of the character to fetch.
|
||||
* A value from 0 to yylength()-1.
|
||||
* @param pos the position of the character to fetch. A value from 0 to
|
||||
* yylength()-1.
|
||||
*
|
||||
* @return the character at position pos
|
||||
*/
|
||||
@@ -2869,14 +2879,13 @@ public final class Flasm3Lexer {
|
||||
/**
|
||||
* Reports an error that occured while scanning.
|
||||
*
|
||||
* In a wellformed scanner (no or only correct usage of
|
||||
* yypushback(int) and a match-all fallback rule) this method
|
||||
* will only be called with things that "Can't Possibly Happen".
|
||||
* If this method is called, something is seriously wrong
|
||||
* (e.g. a JFlex bug producing a faulty scanner etc.).
|
||||
* In a wellformed scanner (no or only correct usage of yypushback(int) and
|
||||
* a match-all fallback rule) this method will only be called with things
|
||||
* that "Can't Possibly Happen". If this method is called, something is
|
||||
* seriously wrong (e.g. a JFlex bug producing a faulty scanner etc.).
|
||||
*
|
||||
* Usual syntax/scanner level error handling should be done
|
||||
* in error fallback rules.
|
||||
* Usual syntax/scanner level error handling should be done in error
|
||||
* fallback rules.
|
||||
*
|
||||
* @param errorCode the code of the errormessage to display
|
||||
*/
|
||||
@@ -2896,8 +2905,8 @@ public final class Flasm3Lexer {
|
||||
*
|
||||
* They will be read again by then next call of the scanning method
|
||||
*
|
||||
* @param number the number of characters to be read again.
|
||||
* This number must not be greater than yylength()!
|
||||
* @param number the number of characters to be read again. This number must
|
||||
* not be greater than yylength()!
|
||||
*/
|
||||
public void yypushback(int number) {
|
||||
if (number > yylength()) {
|
||||
@@ -2908,8 +2917,8 @@ public final class Flasm3Lexer {
|
||||
}
|
||||
|
||||
/**
|
||||
* Resumes scanning until the next regular expression is matched,
|
||||
* the end of input is encountered or an I/O-Error occurs.
|
||||
* Resumes scanning until the next regular expression is matched, the end of
|
||||
* input is encountered or an I/O-Error occurs.
|
||||
*
|
||||
* @return the next token
|
||||
* @exception java.io.IOException if any I/O-Error occurs
|
||||
|
||||
+2693
-2682
File diff suppressed because it is too large
Load Diff
+59
-48
@@ -1,6 +1,6 @@
|
||||
/* The following code was generated by JFlex 1.6.0 */
|
||||
|
||||
/*
|
||||
/*
|
||||
* Copyright (C) 2010-2016 JPEXS, All rights reserved.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
@@ -26,8 +26,7 @@ import java.util.Stack;
|
||||
|
||||
/**
|
||||
* This class is a scanner generated by
|
||||
* <a href="http://www.jflex.de/">JFlex</a> 1.6.0
|
||||
* from the specification file
|
||||
* <a href="http://www.jflex.de/">JFlex</a> 1.6.0 from the specification file
|
||||
* <tt>C:/FFDec/jpexs-decompiler/libsrc/ffdec_lib/lexers/actionscript3_script.flex</tt>
|
||||
*/
|
||||
public final class ActionScriptLexer {
|
||||
@@ -69,9 +68,8 @@ public final class ActionScriptLexer {
|
||||
|
||||
/**
|
||||
* 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
|
||||
* 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, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7,
|
||||
@@ -295,9 +293,11 @@ public final class ActionScriptLexer {
|
||||
}
|
||||
|
||||
private static int zzUnpackAction(String packed, int offset, int[] result) {
|
||||
int i = 0; /* index in packed string */
|
||||
int i = 0;
|
||||
/* index in packed string */
|
||||
|
||||
int j = offset; /* index in unpacked array */
|
||||
int j = offset;
|
||||
/* index in unpacked array */
|
||||
|
||||
int l = packed.length();
|
||||
while (i < l) {
|
||||
@@ -383,9 +383,11 @@ public final class ActionScriptLexer {
|
||||
}
|
||||
|
||||
private static int zzUnpackRowMap(String packed, int offset, int[] result) {
|
||||
int i = 0; /* index in packed string */
|
||||
int i = 0;
|
||||
/* index in packed string */
|
||||
|
||||
int j = offset; /* index in unpacked array */
|
||||
int j = offset;
|
||||
/* index in unpacked array */
|
||||
|
||||
int l = packed.length();
|
||||
while (i < l) {
|
||||
@@ -833,9 +835,11 @@ public final class ActionScriptLexer {
|
||||
}
|
||||
|
||||
private static int zzUnpackTrans(String packed, int offset, int[] result) {
|
||||
int i = 0; /* index in packed string */
|
||||
int i = 0;
|
||||
/* index in packed string */
|
||||
|
||||
int j = offset; /* index in unpacked array */
|
||||
int j = offset;
|
||||
/* index in unpacked array */
|
||||
|
||||
int l = packed.length();
|
||||
while (i < l) {
|
||||
@@ -894,9 +898,11 @@ public final class ActionScriptLexer {
|
||||
}
|
||||
|
||||
private static int zzUnpackAttribute(String packed, int offset, int[] result) {
|
||||
int i = 0; /* index in packed string */
|
||||
int i = 0;
|
||||
/* index in packed string */
|
||||
|
||||
int j = offset; /* index in unpacked array */
|
||||
int j = offset;
|
||||
/* index in unpacked array */
|
||||
|
||||
int l = packed.length();
|
||||
while (i < l) {
|
||||
@@ -925,8 +931,8 @@ public final class ActionScriptLexer {
|
||||
private int zzLexicalState = YYINITIAL;
|
||||
|
||||
/**
|
||||
* this buffer contains the current text to be matched and is
|
||||
* the source of the yytext() string
|
||||
* this buffer contains the current text to be matched and is the source of
|
||||
* the yytext() string
|
||||
*/
|
||||
private char zzBuffer[] = new char[ZZ_BUFFERSIZE];
|
||||
|
||||
@@ -946,8 +952,8 @@ public final class ActionScriptLexer {
|
||||
private int zzStartRead;
|
||||
|
||||
/**
|
||||
* endRead marks the last character in the buffer, that has been read
|
||||
* from input
|
||||
* endRead marks the last character in the buffer, that has been read from
|
||||
* input
|
||||
*/
|
||||
private int zzEndRead;
|
||||
|
||||
@@ -983,10 +989,10 @@ public final class ActionScriptLexer {
|
||||
private boolean zzEOFDone;
|
||||
|
||||
/**
|
||||
* The number of occupied positions in zzBuffer beyond zzEndRead.
|
||||
* When a lead/high surrogate has been read from the input stream
|
||||
* into the final zzBuffer position, this will have a value of 1;
|
||||
* otherwise, it will have a value of 0.
|
||||
* The number of occupied positions in zzBuffer beyond zzEndRead. When a
|
||||
* lead/high surrogate has been read from the input stream into the final
|
||||
* zzBuffer position, this will have a value of 1; otherwise, it will have a
|
||||
* value of 0.
|
||||
*/
|
||||
private int zzFinalHighSurrogate = 0;
|
||||
|
||||
@@ -1080,9 +1086,11 @@ public final class ActionScriptLexer {
|
||||
*/
|
||||
private static char[] zzUnpackCMap(String packed) {
|
||||
char[] map = new char[0x110000];
|
||||
int i = 0; /* index in packed string */
|
||||
int i = 0;
|
||||
/* index in packed string */
|
||||
|
||||
int j = 0; /* index in unpacked array */
|
||||
int j = 0;
|
||||
/* index in unpacked array */
|
||||
|
||||
while (i < 3136) {
|
||||
int count = packed.charAt(i++);
|
||||
@@ -1141,7 +1149,8 @@ public final class ActionScriptLexer {
|
||||
|
||||
if (totalRead > 0) {
|
||||
zzEndRead += totalRead;
|
||||
if (totalRead == requested) { /* possibly more input available */
|
||||
if (totalRead == requested) {
|
||||
/* possibly more input available */
|
||||
|
||||
if (Character.isHighSurrogate(zzBuffer[zzEndRead - 1])) {
|
||||
--zzEndRead;
|
||||
@@ -1159,9 +1168,11 @@ public final class ActionScriptLexer {
|
||||
* Closes the input stream.
|
||||
*/
|
||||
public final void yyclose() throws java.io.IOException {
|
||||
zzAtEOF = true; /* indicate end of file */
|
||||
zzAtEOF = true;
|
||||
/* indicate end of file */
|
||||
|
||||
zzEndRead = zzStartRead; /* invalidate buffer */
|
||||
zzEndRead = zzStartRead;
|
||||
/* invalidate buffer */
|
||||
|
||||
if (zzReader != null) {
|
||||
zzReader.close();
|
||||
@@ -1169,12 +1180,12 @@ public final class ActionScriptLexer {
|
||||
}
|
||||
|
||||
/**
|
||||
* Resets the scanner to read from a new input stream.
|
||||
* Does not close the old reader.
|
||||
* Resets the scanner to read from a new input stream. Does not close the
|
||||
* old reader.
|
||||
*
|
||||
* All internal variables are reset, the old input stream
|
||||
* <b>cannot</b> be reused (internal buffer is discarded and lost).
|
||||
* Lexical state is set to <tt>ZZ_INITIAL</tt>.
|
||||
* <b>cannot</b> be reused (internal buffer is discarded and lost). Lexical
|
||||
* state is set to <tt>ZZ_INITIAL</tt>.
|
||||
*
|
||||
* Internal scan buffer is resized down to its initial length, if it has
|
||||
* grown.
|
||||
@@ -1220,13 +1231,12 @@ public final class ActionScriptLexer {
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the character at position <tt>pos</tt> from the
|
||||
* matched text.
|
||||
* Returns the character at position <tt>pos</tt> from the matched text.
|
||||
*
|
||||
* It is equivalent to yytext().charAt(pos), but faster
|
||||
*
|
||||
* @param pos the position of the character to fetch.
|
||||
* A value from 0 to yylength()-1.
|
||||
* @param pos the position of the character to fetch. A value from 0 to
|
||||
* yylength()-1.
|
||||
*
|
||||
* @return the character at position pos
|
||||
*/
|
||||
@@ -1244,14 +1254,13 @@ public final class ActionScriptLexer {
|
||||
/**
|
||||
* Reports an error that occured while scanning.
|
||||
*
|
||||
* In a wellformed scanner (no or only correct usage of
|
||||
* yypushback(int) and a match-all fallback rule) this method
|
||||
* will only be called with things that "Can't Possibly Happen".
|
||||
* If this method is called, something is seriously wrong
|
||||
* (e.g. a JFlex bug producing a faulty scanner etc.).
|
||||
* In a wellformed scanner (no or only correct usage of yypushback(int) and
|
||||
* a match-all fallback rule) this method will only be called with things
|
||||
* that "Can't Possibly Happen". If this method is called, something is
|
||||
* seriously wrong (e.g. a JFlex bug producing a faulty scanner etc.).
|
||||
*
|
||||
* Usual syntax/scanner level error handling should be done
|
||||
* in error fallback rules.
|
||||
* Usual syntax/scanner level error handling should be done in error
|
||||
* fallback rules.
|
||||
*
|
||||
* @param errorCode the code of the errormessage to display
|
||||
*/
|
||||
@@ -1271,8 +1280,8 @@ public final class ActionScriptLexer {
|
||||
*
|
||||
* They will be read again by then next call of the scanning method
|
||||
*
|
||||
* @param number the number of characters to be read again.
|
||||
* This number must not be greater than yylength()!
|
||||
* @param number the number of characters to be read again. This number must
|
||||
* not be greater than yylength()!
|
||||
*/
|
||||
public void yypushback(int number) {
|
||||
if (number > yylength()) {
|
||||
@@ -1283,8 +1292,8 @@ public final class ActionScriptLexer {
|
||||
}
|
||||
|
||||
/**
|
||||
* Resumes scanning until the next regular expression is matched,
|
||||
* the end of input is encountered or an I/O-Error occurs.
|
||||
* Resumes scanning until the next regular expression is matched, the end of
|
||||
* input is encountered or an I/O-Error occurs.
|
||||
*
|
||||
* @return the next token
|
||||
* @exception java.io.IOException if any I/O-Error occurs
|
||||
@@ -1380,7 +1389,8 @@ public final class ActionScriptLexer {
|
||||
}
|
||||
case 167:
|
||||
break;
|
||||
case 3: { /*ignore*/
|
||||
case 3: {
|
||||
/*ignore*/
|
||||
|
||||
}
|
||||
case 168:
|
||||
@@ -1794,7 +1804,8 @@ public final class ActionScriptLexer {
|
||||
}
|
||||
case 242:
|
||||
break;
|
||||
case 78: { /* ignore illegal character escape */
|
||||
case 78: {
|
||||
/* ignore illegal character escape */
|
||||
|
||||
}
|
||||
case 243:
|
||||
|
||||
+3
-3
@@ -220,9 +220,9 @@ public class NameAVM2Item extends AssignableAVM2Item {
|
||||
return toSourceMerge(localData, generator,
|
||||
ins(AVM2Instructions.GetScopeObject, slotScope),
|
||||
assignedValue, !(("" + assignedValue.returnType()).equals("" + type) && (basicTypes.contains("" + type))) ? generateCoerce(localData, generator, type) : null, needsReturn
|
||||
? dupSetTemp(localData, generator, ret_temp) : null, generateSetLoc(regNumber), slotNumber > -1
|
||||
? ins(AVM2Instructions.SetSlot, slotNumber)
|
||||
: null,
|
||||
? dupSetTemp(localData, generator, ret_temp) : null, generateSetLoc(regNumber), slotNumber > -1
|
||||
? ins(AVM2Instructions.SetSlot, slotNumber)
|
||||
: null,
|
||||
needsReturn ? getTemp(localData, generator, ret_temp) : null,
|
||||
killTemp(localData, generator, Arrays.asList(ret_temp)));
|
||||
} else {
|
||||
|
||||
+21
-23
@@ -180,30 +180,28 @@ public class NamespacedAVM2Item extends AssignableAVM2Item {
|
||||
killTemp(localData, generator, Arrays.asList(obj_temp))
|
||||
);
|
||||
}
|
||||
} else if (assignedValue != null) {
|
||||
return toSourceMerge(localData, generator,
|
||||
obj == null ? ns : null, obj == null ? NameAVM2Item.generateCoerce(localData, generator, new TypeItem(DottedChain.NAMESPACE)) : null, obj != null ? obj : ins(AVM2Instructions.FindPropertyStrict, constants.getMultinameId(Multiname.createRTQName(attr, constants.getStringId(name, true)), true)),
|
||||
ns, NameAVM2Item.generateCoerce(localData, generator, new TypeItem(DottedChain.NAMESPACE)), assignedValue,
|
||||
needsReturn ? dupSetTemp(localData, generator, ret_temp) : null,
|
||||
ins(AVM2Instructions.SetProperty, constants.getMultinameId(Multiname.createRTQName(attr, constants.getStringId(name, true)), true)),
|
||||
needsReturn ? getTemp(localData, generator, ret_temp) : null,
|
||||
killTemp(localData, generator, Arrays.asList(ns_temp, index_temp, ret_temp))
|
||||
);
|
||||
} else {
|
||||
if (assignedValue != null) {
|
||||
return toSourceMerge(localData, generator,
|
||||
obj == null ? ns : null, obj == null ? NameAVM2Item.generateCoerce(localData, generator, new TypeItem(DottedChain.NAMESPACE)) : null, obj != null ? obj : ins(AVM2Instructions.FindPropertyStrict, constants.getMultinameId(Multiname.createRTQName(attr, constants.getStringId(name, true)), true)),
|
||||
ns, NameAVM2Item.generateCoerce(localData, generator, new TypeItem(DottedChain.NAMESPACE)), assignedValue,
|
||||
needsReturn ? dupSetTemp(localData, generator, ret_temp) : null,
|
||||
ins(AVM2Instructions.SetProperty, constants.getMultinameId(Multiname.createRTQName(attr, constants.getStringId(name, true)), true)),
|
||||
needsReturn ? getTemp(localData, generator, ret_temp) : null,
|
||||
killTemp(localData, generator, Arrays.asList(ns_temp, index_temp, ret_temp))
|
||||
);
|
||||
} else {
|
||||
return toSourceMerge(localData, generator,
|
||||
obj == null ? ns : null, obj == null ? NameAVM2Item.generateCoerce(localData, generator, new TypeItem(DottedChain.NAMESPACE)) : null, obj != null ? obj : ins(AVM2Instructions.FindPropertyStrict, constants.getMultinameId(Multiname.createRTQName(attr, constants.getStringId(name, true)), true)),
|
||||
call ? dupSetTemp(localData, generator, obj_temp) : null,
|
||||
ns, NameAVM2Item.generateCoerce(localData, generator, new TypeItem(DottedChain.NAMESPACE)),
|
||||
construct ? callargs : null,
|
||||
ins(construct ? AVM2Instructions.ConstructProp : delete ? AVM2Instructions.DeleteProperty : AVM2Instructions.GetProperty, constants.getMultinameId(Multiname.createRTQName(attr, constants.getStringId(name, true)), true), construct ? callargs.size() : null),
|
||||
call ? getTemp(localData, generator, obj_temp) : null,
|
||||
call ? callargs : null,
|
||||
call ? ins(AVM2Instructions.Call, callargs.size()) : null,
|
||||
needsReturn ? null : ins(AVM2Instructions.Pop),
|
||||
killTemp(localData, generator, Arrays.asList(obj_temp))
|
||||
);
|
||||
}
|
||||
return toSourceMerge(localData, generator,
|
||||
obj == null ? ns : null, obj == null ? NameAVM2Item.generateCoerce(localData, generator, new TypeItem(DottedChain.NAMESPACE)) : null, obj != null ? obj : ins(AVM2Instructions.FindPropertyStrict, constants.getMultinameId(Multiname.createRTQName(attr, constants.getStringId(name, true)), true)),
|
||||
call ? dupSetTemp(localData, generator, obj_temp) : null,
|
||||
ns, NameAVM2Item.generateCoerce(localData, generator, new TypeItem(DottedChain.NAMESPACE)),
|
||||
construct ? callargs : null,
|
||||
ins(construct ? AVM2Instructions.ConstructProp : delete ? AVM2Instructions.DeleteProperty : AVM2Instructions.GetProperty, constants.getMultinameId(Multiname.createRTQName(attr, constants.getStringId(name, true)), true), construct ? callargs.size() : null),
|
||||
call ? getTemp(localData, generator, obj_temp) : null,
|
||||
call ? callargs : null,
|
||||
call ? ins(AVM2Instructions.Call, callargs.size()) : null,
|
||||
needsReturn ? null : ins(AVM2Instructions.Pop),
|
||||
killTemp(localData, generator, Arrays.asList(obj_temp))
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -116,12 +116,12 @@ public class UnresolvedAVM2Item extends AssignableAVM2Item {
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*
|
||||
public GraphTargetItem getNs() {
|
||||
return ns;
|
||||
}
|
||||
*/
|
||||
|
||||
public void appendName(String name) {
|
||||
this.name = this.name.add(name);
|
||||
}
|
||||
|
||||
+56
-47
@@ -1,6 +1,6 @@
|
||||
/* The following code was generated by JFlex 1.6.0 */
|
||||
|
||||
/*
|
||||
/*
|
||||
* Copyright (C) 2010-2016 JPEXS, All rights reserved.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
@@ -16,13 +16,12 @@
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library.
|
||||
*/
|
||||
/* Method info lexer specification */
|
||||
/* Method info lexer specification */
|
||||
package com.jpexs.decompiler.flash.abc.methodinfo_parser;
|
||||
|
||||
/**
|
||||
* This class is a scanner generated by
|
||||
* <a href="http://www.jflex.de/">JFlex</a> 1.6.0
|
||||
* from the specification file
|
||||
* <a href="http://www.jflex.de/">JFlex</a> 1.6.0 from the specification file
|
||||
* <tt>C:/FFDec/jpexs-decompiler/libsrc/ffdec_lib/lexers/actionscript3_methodinfo.flex</tt>
|
||||
*/
|
||||
public final class MethodInfoLexer {
|
||||
@@ -46,9 +45,8 @@ public final class MethodInfoLexer {
|
||||
|
||||
/**
|
||||
* 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
|
||||
* 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, 1, 1
|
||||
@@ -231,9 +229,11 @@ public final class MethodInfoLexer {
|
||||
}
|
||||
|
||||
private static int zzUnpackAction(String packed, int offset, int[] result) {
|
||||
int i = 0; /* index in packed string */
|
||||
int i = 0;
|
||||
/* index in packed string */
|
||||
|
||||
int j = offset; /* index in unpacked array */
|
||||
int j = offset;
|
||||
/* index in unpacked array */
|
||||
|
||||
int l = packed.length();
|
||||
while (i < l) {
|
||||
@@ -279,9 +279,11 @@ public final class MethodInfoLexer {
|
||||
}
|
||||
|
||||
private static int zzUnpackRowMap(String packed, int offset, int[] result) {
|
||||
int i = 0; /* index in packed string */
|
||||
int i = 0;
|
||||
/* index in packed string */
|
||||
|
||||
int j = offset; /* index in unpacked array */
|
||||
int j = offset;
|
||||
/* index in unpacked array */
|
||||
|
||||
int l = packed.length();
|
||||
while (i < l) {
|
||||
@@ -466,9 +468,11 @@ public final class MethodInfoLexer {
|
||||
}
|
||||
|
||||
private static int zzUnpackTrans(String packed, int offset, int[] result) {
|
||||
int i = 0; /* index in packed string */
|
||||
int i = 0;
|
||||
/* index in packed string */
|
||||
|
||||
int j = offset; /* index in unpacked array */
|
||||
int j = offset;
|
||||
/* index in unpacked array */
|
||||
|
||||
int l = packed.length();
|
||||
while (i < l) {
|
||||
@@ -518,9 +522,11 @@ public final class MethodInfoLexer {
|
||||
}
|
||||
|
||||
private static int zzUnpackAttribute(String packed, int offset, int[] result) {
|
||||
int i = 0; /* index in packed string */
|
||||
int i = 0;
|
||||
/* index in packed string */
|
||||
|
||||
int j = offset; /* index in unpacked array */
|
||||
int j = offset;
|
||||
/* index in unpacked array */
|
||||
|
||||
int l = packed.length();
|
||||
while (i < l) {
|
||||
@@ -549,8 +555,8 @@ public final class MethodInfoLexer {
|
||||
private int zzLexicalState = YYINITIAL;
|
||||
|
||||
/**
|
||||
* this buffer contains the current text to be matched and is
|
||||
* the source of the yytext() string
|
||||
* this buffer contains the current text to be matched and is the source of
|
||||
* the yytext() string
|
||||
*/
|
||||
private char zzBuffer[] = new char[ZZ_BUFFERSIZE];
|
||||
|
||||
@@ -570,8 +576,8 @@ public final class MethodInfoLexer {
|
||||
private int zzStartRead;
|
||||
|
||||
/**
|
||||
* endRead marks the last character in the buffer, that has been read
|
||||
* from input
|
||||
* endRead marks the last character in the buffer, that has been read from
|
||||
* input
|
||||
*/
|
||||
private int zzEndRead;
|
||||
|
||||
@@ -607,10 +613,10 @@ public final class MethodInfoLexer {
|
||||
private boolean zzEOFDone;
|
||||
|
||||
/**
|
||||
* The number of occupied positions in zzBuffer beyond zzEndRead.
|
||||
* When a lead/high surrogate has been read from the input stream
|
||||
* into the final zzBuffer position, this will have a value of 1;
|
||||
* otherwise, it will have a value of 0.
|
||||
* The number of occupied positions in zzBuffer beyond zzEndRead. When a
|
||||
* lead/high surrogate has been read from the input stream into the final
|
||||
* zzBuffer position, this will have a value of 1; otherwise, it will have a
|
||||
* value of 0.
|
||||
*/
|
||||
private int zzFinalHighSurrogate = 0;
|
||||
|
||||
@@ -654,9 +660,11 @@ public final class MethodInfoLexer {
|
||||
*/
|
||||
private static char[] zzUnpackCMap(String packed) {
|
||||
char[] map = new char[0x110000];
|
||||
int i = 0; /* index in packed string */
|
||||
int i = 0;
|
||||
/* index in packed string */
|
||||
|
||||
int j = 0; /* index in unpacked array */
|
||||
int j = 0;
|
||||
/* index in unpacked array */
|
||||
|
||||
while (i < 2868) {
|
||||
int count = packed.charAt(i++);
|
||||
@@ -715,7 +723,8 @@ public final class MethodInfoLexer {
|
||||
|
||||
if (totalRead > 0) {
|
||||
zzEndRead += totalRead;
|
||||
if (totalRead == requested) { /* possibly more input available */
|
||||
if (totalRead == requested) {
|
||||
/* possibly more input available */
|
||||
|
||||
if (Character.isHighSurrogate(zzBuffer[zzEndRead - 1])) {
|
||||
--zzEndRead;
|
||||
@@ -733,9 +742,11 @@ public final class MethodInfoLexer {
|
||||
* Closes the input stream.
|
||||
*/
|
||||
public final void yyclose() throws java.io.IOException {
|
||||
zzAtEOF = true; /* indicate end of file */
|
||||
zzAtEOF = true;
|
||||
/* indicate end of file */
|
||||
|
||||
zzEndRead = zzStartRead; /* invalidate buffer */
|
||||
zzEndRead = zzStartRead;
|
||||
/* invalidate buffer */
|
||||
|
||||
if (zzReader != null) {
|
||||
zzReader.close();
|
||||
@@ -743,12 +754,12 @@ public final class MethodInfoLexer {
|
||||
}
|
||||
|
||||
/**
|
||||
* Resets the scanner to read from a new input stream.
|
||||
* Does not close the old reader.
|
||||
* Resets the scanner to read from a new input stream. Does not close the
|
||||
* old reader.
|
||||
*
|
||||
* All internal variables are reset, the old input stream
|
||||
* <b>cannot</b> be reused (internal buffer is discarded and lost).
|
||||
* Lexical state is set to <tt>ZZ_INITIAL</tt>.
|
||||
* <b>cannot</b> be reused (internal buffer is discarded and lost). Lexical
|
||||
* state is set to <tt>ZZ_INITIAL</tt>.
|
||||
*
|
||||
* Internal scan buffer is resized down to its initial length, if it has
|
||||
* grown.
|
||||
@@ -794,13 +805,12 @@ public final class MethodInfoLexer {
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the character at position <tt>pos</tt> from the
|
||||
* matched text.
|
||||
* Returns the character at position <tt>pos</tt> from the matched text.
|
||||
*
|
||||
* It is equivalent to yytext().charAt(pos), but faster
|
||||
*
|
||||
* @param pos the position of the character to fetch.
|
||||
* A value from 0 to yylength()-1.
|
||||
* @param pos the position of the character to fetch. A value from 0 to
|
||||
* yylength()-1.
|
||||
*
|
||||
* @return the character at position pos
|
||||
*/
|
||||
@@ -818,14 +828,13 @@ public final class MethodInfoLexer {
|
||||
/**
|
||||
* Reports an error that occured while scanning.
|
||||
*
|
||||
* In a wellformed scanner (no or only correct usage of
|
||||
* yypushback(int) and a match-all fallback rule) this method
|
||||
* will only be called with things that "Can't Possibly Happen".
|
||||
* If this method is called, something is seriously wrong
|
||||
* (e.g. a JFlex bug producing a faulty scanner etc.).
|
||||
* In a wellformed scanner (no or only correct usage of yypushback(int) and
|
||||
* a match-all fallback rule) this method will only be called with things
|
||||
* that "Can't Possibly Happen". If this method is called, something is
|
||||
* seriously wrong (e.g. a JFlex bug producing a faulty scanner etc.).
|
||||
*
|
||||
* Usual syntax/scanner level error handling should be done
|
||||
* in error fallback rules.
|
||||
* Usual syntax/scanner level error handling should be done in error
|
||||
* fallback rules.
|
||||
*
|
||||
* @param errorCode the code of the errormessage to display
|
||||
*/
|
||||
@@ -845,8 +854,8 @@ public final class MethodInfoLexer {
|
||||
*
|
||||
* They will be read again by then next call of the scanning method
|
||||
*
|
||||
* @param number the number of characters to be read again.
|
||||
* This number must not be greater than yylength()!
|
||||
* @param number the number of characters to be read again. This number must
|
||||
* not be greater than yylength()!
|
||||
*/
|
||||
public void yypushback(int number) {
|
||||
if (number > yylength()) {
|
||||
@@ -857,8 +866,8 @@ public final class MethodInfoLexer {
|
||||
}
|
||||
|
||||
/**
|
||||
* Resumes scanning until the next regular expression is matched,
|
||||
* the end of input is encountered or an I/O-Error occurs.
|
||||
* Resumes scanning until the next regular expression is matched, the end of
|
||||
* input is encountered or an I/O-Error occurs.
|
||||
*
|
||||
* @return the next token
|
||||
* @exception java.io.IOException if any I/O-Error occurs
|
||||
|
||||
@@ -424,6 +424,10 @@ public final class MethodBody implements Cloneable {
|
||||
|
||||
@Override
|
||||
public MethodBody clone() {
|
||||
return clone(false);
|
||||
}
|
||||
|
||||
public MethodBody clone(boolean deepTraits) {
|
||||
try {
|
||||
MethodBody ret = (MethodBody) super.clone();
|
||||
if (code != null) {
|
||||
@@ -437,10 +441,9 @@ public final class MethodBody implements Cloneable {
|
||||
}
|
||||
}
|
||||
|
||||
// maybe deep clone traits
|
||||
/*if (traits != null) {
|
||||
ret.traits = traits.clone();
|
||||
}*/
|
||||
if (deepTraits && traits != null) {
|
||||
ret.traits = traits.clone();
|
||||
}
|
||||
ret.convertedItems = null;
|
||||
ret.convertException = null;
|
||||
|
||||
|
||||
@@ -386,4 +386,17 @@ public class MethodInfo {
|
||||
}
|
||||
return writer.hilightSpecial(rname, HighlightSpecialType.RETURNS);
|
||||
}
|
||||
|
||||
public String getReturnTypeRaw(AVM2ConstantPool constants, List<DottedChain> fullyQualifiedNames) {
|
||||
String rname = "*";
|
||||
if (ret_type > 0) {
|
||||
Multiname multiname = constants.getMultiname(ret_type);
|
||||
if (multiname.kind != Multiname.TYPENAME && multiname.name_index > 0 && constants.getString(multiname.name_index).equals("void")) {
|
||||
rname = "void";
|
||||
} else {
|
||||
rname = multiname.getName(constants, fullyQualifiedNames, false);
|
||||
}
|
||||
}
|
||||
return rname;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,7 +25,7 @@ import com.jpexs.helpers.Helper;
|
||||
*/
|
||||
public class ValueKind {
|
||||
|
||||
public static final int CONSTANT_Decimal = 0x02; //decimal
|
||||
public static final int CONSTANT_DecimalOrFloat = 0x02; //decimal or float depending on ABC version
|
||||
|
||||
public static final int CONSTANT_Int = 0x03;// integer
|
||||
|
||||
@@ -57,6 +57,8 @@ public class ValueKind {
|
||||
|
||||
public static final int CONSTANT_PrivateNs = 0x05;// namespace
|
||||
|
||||
public static final int CONSTANT_Float4 = 0x1E;// float4
|
||||
|
||||
private static final int[] optionalKinds = new int[]{0x03, 0x04, 0x06, 0x02, 0x01, 0x0B, 0x0A, 0x0C, 0x00, 0x08, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x05};
|
||||
|
||||
private static final String[] optionalKindNames = new String[]{"Int", "UInt", "Double", "Decimal", "Utf8", "True", "False", "Null", "Undefined", "Namespace", "PackageNamespace", "PackageInternalNs", "ProtectedNamespace", "ExplicitNamespace", "StaticProtectedNs", "PrivateNamespace"};
|
||||
@@ -137,7 +139,7 @@ public class ValueKind {
|
||||
case CONSTANT_Double:
|
||||
ret = "" + constants.getDouble(value_index);
|
||||
break;
|
||||
case CONSTANT_Decimal:
|
||||
case CONSTANT_DecimalOrFloat:
|
||||
ret = "" + constants.getDecimal(value_index);
|
||||
break;
|
||||
case CONSTANT_Utf8:
|
||||
@@ -179,7 +181,7 @@ public class ValueKind {
|
||||
case CONSTANT_Double:
|
||||
ret = "Double(" + constants.getDouble(value_index) + ")";
|
||||
break;
|
||||
case CONSTANT_Decimal:
|
||||
case CONSTANT_DecimalOrFloat:
|
||||
ret = "Decimal(" + constants.getDecimal(value_index) + ")";
|
||||
break;
|
||||
case CONSTANT_Utf8:
|
||||
|
||||
@@ -42,6 +42,9 @@ import com.jpexs.decompiler.flash.abc.types.NamespaceSet;
|
||||
import com.jpexs.decompiler.flash.abc.types.ScriptInfo;
|
||||
import com.jpexs.decompiler.flash.configuration.Configuration;
|
||||
import com.jpexs.decompiler.flash.exporters.modes.ScriptExportMode;
|
||||
import com.jpexs.decompiler.flash.exporters.script.Dependency;
|
||||
import com.jpexs.decompiler.flash.exporters.script.DependencyParser;
|
||||
import com.jpexs.decompiler.flash.exporters.script.DependencyType;
|
||||
import com.jpexs.decompiler.flash.helpers.GraphTextWriter;
|
||||
import com.jpexs.decompiler.flash.helpers.NulWriter;
|
||||
import com.jpexs.decompiler.flash.tags.ABCContainerTag;
|
||||
@@ -50,6 +53,8 @@ import com.jpexs.helpers.Helper;
|
||||
import java.io.Serializable;
|
||||
import java.util.AbstractMap.SimpleEntry;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
@@ -169,129 +174,18 @@ public abstract class Trait implements Cloneable, Serializable {
|
||||
return ret;
|
||||
}
|
||||
|
||||
protected void parseImportsUsagesFromMultiname(String ignoredCustom, ABC abc, List<DottedChain> imports, List<String> uses, Multiname m, DottedChain ignorePackage, List<DottedChain> fullyQualifiedNames) {
|
||||
if (m != null) {
|
||||
if (m.kind == Multiname.TYPENAME) {
|
||||
if (m.qname_index != 0) {
|
||||
parseImportsUsagesFromMultiname(ignoredCustom, abc, imports, uses, abc.constants.getMultiname(m.qname_index), ignorePackage, fullyQualifiedNames);
|
||||
}
|
||||
for (Integer i : m.params) {
|
||||
if (i != 0) {
|
||||
parseImportsUsagesFromMultiname(ignoredCustom, abc, imports, uses, abc.constants.getMultiname(i), ignorePackage, fullyQualifiedNames);
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
Namespace ns = m.getNamespace(abc.constants);
|
||||
String name = m.getName(abc.constants, fullyQualifiedNames, true);
|
||||
NamespaceSet nss = m.getNamespaceSet(abc.constants);
|
||||
if (ns != null) {
|
||||
parseImportsUsagesFromNS(ignoredCustom, abc, imports, uses, m.namespace_index, ignorePackage, name);
|
||||
}
|
||||
if (nss != null) {
|
||||
for (int n : nss.namespaces) {
|
||||
parseImportsUsagesFromNS(ignoredCustom, abc, imports, uses, n, ignorePackage, nss.namespaces.length > 1 ? "" : name);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private boolean parseUsagesFromNS(String ignoredCustom, ABC abc, List<DottedChain> imports, List<String> uses, int namespace_index, DottedChain ignorePackage, String name) {
|
||||
Namespace ns = abc.constants.getNamespace(namespace_index);
|
||||
|
||||
if (ns.kind == Namespace.KIND_NAMESPACE) {
|
||||
String nsVal = ns.getName(abc.constants).toRawString();
|
||||
for (ABCContainerTag abcTag : abc.getAbcTags()) {
|
||||
DottedChain nsimport = abcTag.getABC().nsValueToName(nsVal);
|
||||
if (nsimport.equals(AVM2Deobfuscation.BUILTIN)) {
|
||||
return true; //handled, but import/use not added
|
||||
}
|
||||
if (!nsimport.isEmpty()) {
|
||||
|
||||
if (!nsimport.getWithoutLast().equals(ignorePackage) && !imports.contains(nsimport)) {
|
||||
imports.add(nsimport);
|
||||
}
|
||||
if (ignoredCustom != null && nsVal.equals(ignoredCustom)) {
|
||||
return true;
|
||||
}
|
||||
if (!uses.contains(nsimport.getLast())) {
|
||||
uses.add(nsimport.getLast());
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
protected void parseImportsUsagesFromNS(String ignoredCustom, ABC abc, List<DottedChain> imports, List<String> uses, int namespace_index, DottedChain ignorePackage, String name) {
|
||||
Namespace ns = abc.constants.getNamespace(namespace_index);
|
||||
if (name.isEmpty()) {
|
||||
name = "*";
|
||||
}
|
||||
DottedChain newimport = ns.getName(abc.constants);
|
||||
|
||||
if (parseUsagesFromNS(ignoredCustom, abc, imports, uses, namespace_index, ignorePackage, name)) {
|
||||
return;
|
||||
} else if ((ns.kind != Namespace.KIND_PACKAGE) && (ns.kind != Namespace.KIND_PACKAGE_INTERNAL)) {
|
||||
return;
|
||||
}
|
||||
newimport = newimport.add(name);
|
||||
if (!imports.contains(newimport)) {
|
||||
DottedChain pkg = newimport.getWithoutLast(); //.substring(0, newimport.lastIndexOf('.'));
|
||||
if (pkg.equals(InitVectorAVM2Item.VECTOR_PACKAGE)) { //special case - is imported always
|
||||
return;
|
||||
}
|
||||
if (!pkg.equals(ignorePackage)) {
|
||||
imports.add(newimport);
|
||||
}
|
||||
}
|
||||
//}
|
||||
}
|
||||
|
||||
protected void parseUsagesFromMultiname(String ignoredCustom, ABC abc, List<DottedChain> imports, List<String> uses, Multiname m, DottedChain ignorePackage, List<DottedChain> fullyQualifiedNames) {
|
||||
if (m != null) {
|
||||
if (m.kind == Multiname.TYPENAME) {
|
||||
if (m.qname_index != 0) {
|
||||
parseUsagesFromMultiname(ignoredCustom, abc, imports, uses, abc.constants.getMultiname(m.qname_index), ignorePackage, fullyQualifiedNames);
|
||||
}
|
||||
for (Integer i : m.params) {
|
||||
if (i != 0) {
|
||||
parseUsagesFromMultiname(ignoredCustom, abc, imports, uses, abc.constants.getMultiname(i), ignorePackage, fullyQualifiedNames);
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
Namespace ns = m.getNamespace(abc.constants);
|
||||
String name = m.getName(abc.constants, fullyQualifiedNames, false);
|
||||
NamespaceSet nss = m.getNamespaceSet(abc.constants);
|
||||
if (ns != null) {
|
||||
parseUsagesFromNS(ignoredCustom, abc, imports, uses, m.namespace_index, ignorePackage, name);
|
||||
}
|
||||
if (nss != null) {
|
||||
if (nss.namespaces.length == 1) {
|
||||
parseUsagesFromNS(ignoredCustom, abc, imports, uses, nss.namespaces[0], ignorePackage, name);
|
||||
} else {
|
||||
for (int n : nss.namespaces) {
|
||||
parseUsagesFromNS(ignoredCustom, abc, imports, uses, n, ignorePackage, "");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected DottedChain getPackage(ABC abc) {
|
||||
return getName(abc).getNamespace(abc.constants).getName(abc.constants);
|
||||
}
|
||||
|
||||
public void getImportsUsages(String ignoredCustom, ABC abc, List<DottedChain> imports, List<String> uses, DottedChain ignorePackage, List<DottedChain> fullyQualifiedNames) {
|
||||
public void getDependencies(String ignoredCustom, ABC abc, List<Dependency> dependencies, List<String> uses, DottedChain ignorePackage, List<DottedChain> fullyQualifiedNames) {
|
||||
if (ignoredCustom == null) {
|
||||
Namespace n = getName(abc).getNamespace(abc.constants);
|
||||
if (n.kind == Namespace.KIND_NAMESPACE) {
|
||||
ignoredCustom = n.getName(abc.constants).toRawString();
|
||||
}
|
||||
}
|
||||
parseUsagesFromMultiname(ignoredCustom, abc, imports, uses, getName(abc), ignorePackage, fullyQualifiedNames);
|
||||
DependencyParser.parseUsagesFromMultiname(ignoredCustom, abc, dependencies, uses, getName(abc), ignorePackage, fullyQualifiedNames, DependencyType.NAMESPACE);
|
||||
}
|
||||
|
||||
private static final String[] builtInClasses = {"ArgumentError", "arguments", "Array", "Boolean", "Class", "Date", "DefinitionError", "Error", "EvalError", "Function", "int", "JSON", "Math", "Namespace", "Number", "Object", "QName", "RangeError", "ReferenceError", "RegExp", "SecurityError", "String", "SyntaxError", "TypeError", "uint", "URIError", "VerifyError", "XML", "XMLList"};
|
||||
@@ -320,21 +214,34 @@ public abstract class Trait implements Cloneable, Serializable {
|
||||
}
|
||||
|
||||
//imports
|
||||
List<DottedChain> imports = new ArrayList<>();
|
||||
List<Dependency> dependencies = new ArrayList<>();
|
||||
List<String> uses = new ArrayList<>();
|
||||
String customNs = null;
|
||||
Namespace ns = getName(abc).getNamespace(abc.constants);
|
||||
if (ns.kind == Namespace.KIND_NAMESPACE) {
|
||||
customNs = ns.getName(abc.constants).toRawString();
|
||||
}
|
||||
getImportsUsages(customNs, abc, imports, uses, ignorePackage, new ArrayList<>());
|
||||
getDependencies(customNs, abc, dependencies, uses, ignorePackage, new ArrayList<>());
|
||||
|
||||
List<DottedChain> imports = new ArrayList<>();
|
||||
for (Dependency d : dependencies) {
|
||||
if (!imports.contains(d.getId())) {
|
||||
imports.add(d.getId());
|
||||
}
|
||||
}
|
||||
|
||||
List<String> importnames = new ArrayList<>();
|
||||
importnames.addAll(namesInThisPackage);
|
||||
importnames.addAll(Arrays.asList(builtInClasses));
|
||||
for (int i = 0; i < imports.size(); i++) {
|
||||
DottedChain ipath = imports.get(i);
|
||||
if (ipath.getWithoutLast().equals(ignorePackage)) { //do not check classes from same package, they are imported automatically
|
||||
imports.remove(i);
|
||||
i--;
|
||||
continue;
|
||||
}
|
||||
String name = ipath.getLast();
|
||||
if (importnames.contains(name) || isBuiltInClass(name)) {
|
||||
if (importnames.contains(name)) {
|
||||
imports.remove(i);
|
||||
i--;
|
||||
fullyQualifiedNames.add(new DottedChain(name));
|
||||
@@ -358,6 +265,7 @@ public abstract class Trait implements Cloneable, Serializable {
|
||||
}
|
||||
|
||||
boolean hasImport = false;
|
||||
Collections.sort(imports);
|
||||
for (DottedChain imp : imports) {
|
||||
if (imp.size() > 1) { //No imports from root package
|
||||
writer.appendNoHilight("import " + imp.toPrintableString(true) + ";").newLine();
|
||||
@@ -375,64 +283,6 @@ public abstract class Trait implements Cloneable, Serializable {
|
||||
}
|
||||
}
|
||||
|
||||
protected void parseImportsUsagesFromMethodInfo(String ignoredCustom, ABC abc, int method_index, List<DottedChain> imports, List<String> uses, DottedChain ignorePackage, List<DottedChain> fullyQualifiedNames, List<Integer> visitedMethods) {
|
||||
if ((method_index < 0) || (method_index >= abc.method_info.size())) {
|
||||
return;
|
||||
}
|
||||
visitedMethods.add(method_index);
|
||||
if (abc.method_info.get(method_index).ret_type != 0) {
|
||||
parseImportsUsagesFromMultiname(ignoredCustom, abc, imports, uses, abc.constants.getMultiname(abc.method_info.get(method_index).ret_type), ignorePackage, fullyQualifiedNames);
|
||||
}
|
||||
for (int t : abc.method_info.get(method_index).param_types) {
|
||||
if (t != 0) {
|
||||
parseImportsUsagesFromMultiname(ignoredCustom, abc, imports, uses, abc.constants.getMultiname(t), ignorePackage, fullyQualifiedNames);
|
||||
}
|
||||
}
|
||||
MethodBody body = abc.findBody(method_index);
|
||||
if (body != null) {
|
||||
body.traits.getImportsUsages(ignoredCustom, abc, imports, uses, ignorePackage, fullyQualifiedNames);
|
||||
for (ABCException ex : body.exceptions) {
|
||||
parseImportsUsagesFromMultiname(ignoredCustom, abc, imports, uses, abc.constants.getMultiname(ex.type_index), ignorePackage, fullyQualifiedNames);
|
||||
}
|
||||
for (AVM2Instruction ins : body.getCode().code) {
|
||||
if (ins.definition instanceof AlchemyTypeIns) {
|
||||
DottedChain nimport = AlchemyTypeIns.ALCHEMY_PACKAGE.add(ins.definition.instructionName);
|
||||
if (!imports.contains(nimport)) {
|
||||
imports.add(nimport);
|
||||
}
|
||||
}
|
||||
if (ins.definition instanceof NewFunctionIns) {
|
||||
if (ins.operands[0] != method_index) {
|
||||
if (!visitedMethods.contains(ins.operands[0])) {
|
||||
parseImportsUsagesFromMethodInfo(ignoredCustom, abc, ins.operands[0], imports, uses, ignorePackage, fullyQualifiedNames, visitedMethods);
|
||||
}
|
||||
}
|
||||
}
|
||||
if ((ins.definition instanceof FindPropertyStrictIns)
|
||||
|| (ins.definition instanceof FindPropertyIns)
|
||||
|| (ins.definition instanceof GetLexIns)
|
||||
|| (ins.definition instanceof CoerceIns)
|
||||
|| (ins.definition instanceof AsTypeIns)) {
|
||||
int m = ins.operands[0];
|
||||
if (m != 0) {
|
||||
if (m < abc.constants.getMultinameCount()) {
|
||||
parseImportsUsagesFromMultiname(ignoredCustom, abc, imports, uses, abc.constants.getMultiname(m), ignorePackage, fullyQualifiedNames);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (int k = 0; k < ins.definition.operands.length; k++) {
|
||||
if (ins.definition.operands[k] == AVM2Code.DAT_MULTINAME_INDEX) {
|
||||
int multinameIndex = ins.operands[k];
|
||||
if (multinameIndex < abc.constants.getMultinameCount()) {
|
||||
parseUsagesFromMultiname(ignoredCustom, abc, imports, uses, abc.constants.getMultiname(multinameIndex), ignorePackage, fullyQualifiedNames);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public final GraphTextWriter getMetaData(Trait parent, ConvertData convertData, ABC abc, GraphTextWriter writer) {
|
||||
List<Entry<String, Map<String, String>>> md = getMetaDataTable(parent, convertData, abc);
|
||||
for (Entry<String, Map<String, String>> en : md) {
|
||||
|
||||
@@ -25,6 +25,9 @@ import com.jpexs.decompiler.flash.abc.types.MethodBody;
|
||||
import com.jpexs.decompiler.flash.abc.types.Multiname;
|
||||
import com.jpexs.decompiler.flash.abc.types.Namespace;
|
||||
import com.jpexs.decompiler.flash.exporters.modes.ScriptExportMode;
|
||||
import com.jpexs.decompiler.flash.exporters.script.Dependency;
|
||||
import com.jpexs.decompiler.flash.exporters.script.DependencyParser;
|
||||
import com.jpexs.decompiler.flash.exporters.script.DependencyType;
|
||||
import com.jpexs.decompiler.flash.helpers.GraphTextWriter;
|
||||
import com.jpexs.decompiler.flash.helpers.NulWriter;
|
||||
import com.jpexs.decompiler.graph.DottedChain;
|
||||
@@ -48,22 +51,7 @@ public class TraitClass extends Trait implements TraitWithSlot {
|
||||
|
||||
@Override
|
||||
public void delete(ABC abc, boolean d) {
|
||||
ClassInfo classInfo = abc.class_info.get(class_info);
|
||||
classInfo.deleted = d;
|
||||
InstanceInfo instanceInfo = abc.instance_info.get(class_info);
|
||||
instanceInfo.deleted = d;
|
||||
|
||||
classInfo.static_traits.delete(abc, d);
|
||||
abc.method_info.get(classInfo.cinit_index).delete(abc, d);
|
||||
|
||||
instanceInfo.instance_traits.delete(abc, d);
|
||||
abc.method_info.get(instanceInfo.iinit_index).delete(abc, d);
|
||||
|
||||
int protectedNS = instanceInfo.protectedNS;
|
||||
if (protectedNS != 0) {
|
||||
abc.constants.getNamespace(protectedNS).deleted = d;
|
||||
}
|
||||
|
||||
abc.deleteClass(class_info, d);
|
||||
abc.constants.getMultiname(name_index).deleted = d;
|
||||
}
|
||||
|
||||
@@ -78,32 +66,31 @@ public class TraitClass extends Trait implements TraitWithSlot {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void getImportsUsages(String customNs, ABC abc, List<DottedChain> imports, List<String> uses, DottedChain ignorePackage, List<DottedChain> fullyQualifiedNames) {
|
||||
super.getImportsUsages(customNs, abc, imports, uses, ignorePackage == null ? getPackage(abc) : ignorePackage, fullyQualifiedNames);
|
||||
public void getDependencies(String customNs, ABC abc, List<Dependency> dependencies, List<String> uses, DottedChain ignorePackage, List<DottedChain> fullyQualifiedNames) {
|
||||
super.getDependencies(customNs, abc, dependencies, uses, ignorePackage == null ? getPackage(abc) : ignorePackage, fullyQualifiedNames);
|
||||
ClassInfo classInfo = abc.class_info.get(class_info);
|
||||
InstanceInfo instanceInfo = abc.instance_info.get(class_info);
|
||||
DottedChain packageName = instanceInfo.getName(abc.constants).getNamespace(abc.constants).getName(abc.constants); //assume not null name
|
||||
|
||||
parseImportsUsagesFromMultiname(customNs, abc, imports, uses, abc.constants.getMultiname(instanceInfo.name_index), packageName, fullyQualifiedNames);
|
||||
|
||||
//DependencyParser.parseDependenciesFromMultiname(customNs, abc, dependencies, uses, abc.constants.getMultiname(instanceInfo.name_index), packageName, fullyQualifiedNames);
|
||||
if (instanceInfo.super_index > 0) {
|
||||
parseImportsUsagesFromMultiname(customNs, abc, imports, uses, abc.constants.getMultiname(instanceInfo.super_index), packageName, fullyQualifiedNames);
|
||||
DependencyParser.parseDependenciesFromMultiname(customNs, abc, dependencies, uses, abc.constants.getMultiname(instanceInfo.super_index), packageName, fullyQualifiedNames, DependencyType.INHERITANCE);
|
||||
}
|
||||
for (int i : instanceInfo.interfaces) {
|
||||
parseImportsUsagesFromMultiname(customNs, abc, imports, uses, abc.constants.getMultiname(i), packageName, fullyQualifiedNames);
|
||||
DependencyParser.parseDependenciesFromMultiname(customNs, abc, dependencies, uses, abc.constants.getMultiname(i), packageName, fullyQualifiedNames, DependencyType.INHERITANCE);
|
||||
}
|
||||
|
||||
//static
|
||||
classInfo.static_traits.getImportsUsages(customNs, abc, imports, uses, packageName, fullyQualifiedNames);
|
||||
classInfo.static_traits.getDependencies(customNs, abc, dependencies, uses, packageName, fullyQualifiedNames);
|
||||
|
||||
//static initializer
|
||||
parseImportsUsagesFromMethodInfo(customNs, abc, classInfo.cinit_index, imports, uses, packageName, fullyQualifiedNames, new ArrayList<>());
|
||||
DependencyParser.parseDependenciesFromMethodInfo(customNs, abc, classInfo.cinit_index, dependencies, uses, packageName, fullyQualifiedNames, new ArrayList<>());
|
||||
|
||||
//instance
|
||||
instanceInfo.instance_traits.getImportsUsages(customNs, abc, imports, uses, packageName, fullyQualifiedNames);
|
||||
instanceInfo.instance_traits.getDependencies(customNs, abc, dependencies, uses, packageName, fullyQualifiedNames);
|
||||
|
||||
//instance initializer
|
||||
parseImportsUsagesFromMethodInfo(customNs, abc, instanceInfo.iinit_index, imports, uses, packageName, fullyQualifiedNames, new ArrayList<>());
|
||||
DependencyParser.parseDependenciesFromMethodInfo(customNs, abc, instanceInfo.iinit_index, dependencies, uses, packageName, fullyQualifiedNames, new ArrayList<>());
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -144,14 +131,16 @@ public class TraitClass extends Trait implements TraitWithSlot {
|
||||
if (bodyIndex != -1) {
|
||||
writer.startTrait(GraphTextWriter.TRAIT_CLASS_INITIALIZER);
|
||||
writer.startMethod(classInfo.cinit_index);
|
||||
if (!classInitializerIsEmpty) {
|
||||
writer.startBlock();
|
||||
abc.bodies.get(bodyIndex).toString(path +/*packageName +*/ "/" + instanceInfoName + ".staticinitializer", exportMode, abc, this, writer, fullyQualifiedNames);
|
||||
writer.endBlock();
|
||||
} else {
|
||||
//Note: There must be trait/method highlight even if the initializer is empty to TraitList in GUI to work correctly
|
||||
//TODO: handle this better in GUI(?)
|
||||
writer.append(" ").newLine();
|
||||
if (exportMode != ScriptExportMode.AS_METHOD_STUBS) {
|
||||
if (!classInitializerIsEmpty) {
|
||||
writer.startBlock();
|
||||
abc.bodies.get(bodyIndex).toString(path +/*packageName +*/ "/" + instanceInfoName + ".staticinitializer", exportMode, abc, this, writer, fullyQualifiedNames);
|
||||
writer.endBlock();
|
||||
} else {
|
||||
//Note: There must be trait/method highlight even if the initializer is empty to TraitList in GUI to work correctly
|
||||
//TODO: handle this better in GUI(?)
|
||||
writer.append(" ").newLine();
|
||||
}
|
||||
}
|
||||
writer.endMethod();
|
||||
writer.endTrait();
|
||||
@@ -191,8 +180,10 @@ public class TraitClass extends Trait implements TraitWithSlot {
|
||||
MethodBody body = bodyIndex == -1 ? null : abc.bodies.get(bodyIndex);
|
||||
abc.method_info.get(instanceInfo.iinit_index).getParamStr(writer, abc.constants, body, abc, fullyQualifiedNames);
|
||||
writer.appendNoHilight(")").startBlock();
|
||||
if (body != null) {
|
||||
body.toString(path +/*packageName +*/ "/" + instanceInfoName + ".initializer", exportMode, abc, this, writer, fullyQualifiedNames);
|
||||
if (exportMode != ScriptExportMode.AS_METHOD_STUBS) {
|
||||
if (body != null) {
|
||||
body.toString(path +/*packageName +*/ "/" + instanceInfoName + ".initializer", exportMode, abc, this, writer, fullyQualifiedNames);
|
||||
}
|
||||
}
|
||||
|
||||
writer.endBlock().newLine();
|
||||
|
||||
@@ -20,6 +20,8 @@ import com.jpexs.decompiler.flash.abc.ABC;
|
||||
import com.jpexs.decompiler.flash.abc.types.ConvertData;
|
||||
import com.jpexs.decompiler.flash.abc.types.MethodBody;
|
||||
import com.jpexs.decompiler.flash.exporters.modes.ScriptExportMode;
|
||||
import com.jpexs.decompiler.flash.exporters.script.Dependency;
|
||||
import com.jpexs.decompiler.flash.exporters.script.DependencyParser;
|
||||
import com.jpexs.decompiler.flash.helpers.GraphTextWriter;
|
||||
import com.jpexs.decompiler.flash.helpers.NulWriter;
|
||||
import com.jpexs.decompiler.flash.helpers.hilight.HighlightSpecialType;
|
||||
@@ -123,14 +125,14 @@ public class TraitFunction extends Trait implements TraitWithSlot {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void getImportsUsages(String customNs, ABC abc, List<DottedChain> imports, List<String> uses, DottedChain ignorePackage, List<DottedChain> fullyQualifiedNames) {
|
||||
public void getDependencies(String customNs, ABC abc, List<Dependency> dependencies, List<String> uses, DottedChain ignorePackage, List<DottedChain> fullyQualifiedNames) {
|
||||
if (ignorePackage == null) {
|
||||
ignorePackage = getPackage(abc);
|
||||
}
|
||||
super.getImportsUsages(customNs, abc, imports, uses, ignorePackage, fullyQualifiedNames);
|
||||
super.getDependencies(customNs, abc, dependencies, uses, ignorePackage, fullyQualifiedNames);
|
||||
//if (method_info != 0)
|
||||
{
|
||||
parseImportsUsagesFromMethodInfo(customNs, abc, method_info, imports, uses, ignorePackage, fullyQualifiedNames, new ArrayList<>());
|
||||
DependencyParser.parseDependenciesFromMethodInfo(customNs, abc, method_info, dependencies, uses, ignorePackage, fullyQualifiedNames, new ArrayList<>());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+35
-8
@@ -23,8 +23,11 @@ import com.jpexs.decompiler.flash.abc.types.MethodInfo;
|
||||
import com.jpexs.decompiler.flash.abc.types.Namespace;
|
||||
import com.jpexs.decompiler.flash.configuration.Configuration;
|
||||
import com.jpexs.decompiler.flash.exporters.modes.ScriptExportMode;
|
||||
import com.jpexs.decompiler.flash.exporters.script.Dependency;
|
||||
import com.jpexs.decompiler.flash.exporters.script.DependencyParser;
|
||||
import com.jpexs.decompiler.flash.helpers.GraphTextWriter;
|
||||
import com.jpexs.decompiler.flash.helpers.NulWriter;
|
||||
import com.jpexs.decompiler.flash.helpers.hilight.HighlightData;
|
||||
import com.jpexs.decompiler.flash.helpers.hilight.HighlightSpecialType;
|
||||
import com.jpexs.decompiler.graph.DottedChain;
|
||||
import com.jpexs.decompiler.graph.ScopeStack;
|
||||
@@ -58,11 +61,11 @@ public class TraitMethodGetterSetter extends Trait {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void getImportsUsages(String customNs, ABC abc, List<DottedChain> imports, List<String> uses, DottedChain ignorePackage, List<DottedChain> fullyQualifiedNames) {
|
||||
public void getDependencies(String customNs, ABC abc, List<Dependency> dependencies, List<String> uses, DottedChain ignorePackage, List<DottedChain> fullyQualifiedNames) {
|
||||
if (ignorePackage == null) {
|
||||
ignorePackage = getPackage(abc);
|
||||
}
|
||||
super.getImportsUsages(customNs, abc, imports, uses, ignorePackage, fullyQualifiedNames);
|
||||
super.getDependencies(customNs, abc, dependencies, uses, ignorePackage, fullyQualifiedNames);
|
||||
|
||||
if (customNs == null) {
|
||||
Namespace n = getName(abc).getNamespace(abc.constants);
|
||||
@@ -72,7 +75,7 @@ public class TraitMethodGetterSetter extends Trait {
|
||||
}
|
||||
//if (method_info != 0)
|
||||
{
|
||||
parseImportsUsagesFromMethodInfo(customNs, abc, method_info, imports, uses, ignorePackage, fullyQualifiedNames, new ArrayList<>());
|
||||
DependencyParser.parseDependenciesFromMethodInfo(customNs, abc, method_info, dependencies, uses, ignorePackage, fullyQualifiedNames, new ArrayList<>());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -110,9 +113,11 @@ public class TraitMethodGetterSetter extends Trait {
|
||||
path = path + "." + getName(abc).getName(abc.constants, fullyQualifiedNames, false);
|
||||
convertHeader(parent, convertData, path, abc, isStatic, exportMode, scriptIndex, classIndex, writer, fullyQualifiedNames, parallel);
|
||||
int bodyIndex = abc.findBodyIndex(method_info);
|
||||
if (!(classIndex != -1 && abc.instance_info.get(classIndex).isInterface() || bodyIndex == -1)) {
|
||||
if (bodyIndex != -1) {
|
||||
abc.bodies.get(bodyIndex).convert(convertData, path, exportMode, isStatic, method_info, scriptIndex, classIndex, abc, this, new ScopeStack(), 0, writer, fullyQualifiedNames, null, true);
|
||||
if (exportMode != ScriptExportMode.AS_METHOD_STUBS) {
|
||||
if (!(classIndex != -1 && abc.instance_info.get(classIndex).isInterface() || bodyIndex == -1)) {
|
||||
if (bodyIndex != -1) {
|
||||
abc.bodies.get(bodyIndex).convert(convertData, path, exportMode, isStatic, method_info, scriptIndex, classIndex, abc, this, new ScopeStack(), 0, writer, fullyQualifiedNames, null, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
writer.endMethod();
|
||||
@@ -133,8 +138,30 @@ public class TraitMethodGetterSetter extends Trait {
|
||||
writer.appendNoHilight(";");
|
||||
} else {
|
||||
writer.startBlock();
|
||||
if (bodyIndex != -1) {
|
||||
abc.bodies.get(bodyIndex).toString(path, exportMode, abc, this, writer, fullyQualifiedNames);
|
||||
if (exportMode != ScriptExportMode.AS_METHOD_STUBS) {
|
||||
if (bodyIndex != -1) {
|
||||
abc.bodies.get(bodyIndex).toString(path, exportMode, abc, this, writer, fullyQualifiedNames);
|
||||
}
|
||||
} else {
|
||||
String retTypeRaw = abc.method_info.get(method_info).getReturnTypeRaw(abc.constants, fullyQualifiedNames);
|
||||
switch (retTypeRaw) {
|
||||
case "void":
|
||||
break;
|
||||
case "int":
|
||||
case "uint":
|
||||
writer.append("return 0; //autogenerated").newLine();
|
||||
break;
|
||||
case "double":
|
||||
case "float":
|
||||
writer.append("return 0.0; //autogenerated").newLine();
|
||||
break;
|
||||
case "String":
|
||||
writer.append("return \"\"; //autogenerated").newLine();
|
||||
break;
|
||||
default:
|
||||
writer.append("return null; //autogenerated").newLine();
|
||||
break;
|
||||
}
|
||||
}
|
||||
writer.endBlock();
|
||||
}
|
||||
|
||||
+12
-8
@@ -26,6 +26,9 @@ import com.jpexs.decompiler.flash.abc.types.Namespace;
|
||||
import com.jpexs.decompiler.flash.abc.types.ValueKind;
|
||||
import com.jpexs.decompiler.flash.configuration.Configuration;
|
||||
import com.jpexs.decompiler.flash.exporters.modes.ScriptExportMode;
|
||||
import com.jpexs.decompiler.flash.exporters.script.Dependency;
|
||||
import com.jpexs.decompiler.flash.exporters.script.DependencyParser;
|
||||
import com.jpexs.decompiler.flash.exporters.script.DependencyType;
|
||||
import com.jpexs.decompiler.flash.helpers.GraphTextWriter;
|
||||
import com.jpexs.decompiler.flash.helpers.NulWriter;
|
||||
import com.jpexs.decompiler.flash.helpers.hilight.HighlightSpecialType;
|
||||
@@ -103,7 +106,7 @@ public class TraitSlotConst extends Trait implements TraitWithSlot {
|
||||
return writer;
|
||||
}
|
||||
|
||||
public void getValueStr(Trait parent, ConvertData convertData, GraphTextWriter writer, ABC abc, List<DottedChain> fullyQualifiedNames) throws InterruptedException {
|
||||
public void getValueStr(ScriptExportMode exportMode, Trait parent, ConvertData convertData, GraphTextWriter writer, ABC abc, List<DottedChain> fullyQualifiedNames) throws InterruptedException {
|
||||
if (convertData.assignedValues.containsKey(this)) {
|
||||
|
||||
AssignedValue assignment = convertData.assignedValues.get(this);
|
||||
@@ -116,8 +119,9 @@ public class TraitSlotConst extends Trait implements TraitWithSlot {
|
||||
writer.appendNoHilight(assignment.method);
|
||||
writer.newLine();
|
||||
}
|
||||
|
||||
assignment.value.toString(writer, LocalData.create(abc.constants, new HashMap<>(), fullyQualifiedNames));
|
||||
if (exportMode != ScriptExportMode.AS_METHOD_STUBS) {
|
||||
assignment.value.toString(writer, LocalData.create(abc.constants, new HashMap<>(), fullyQualifiedNames));
|
||||
}
|
||||
writer.endMethod();
|
||||
writer.endTrait();
|
||||
return;
|
||||
@@ -162,7 +166,7 @@ public class TraitSlotConst extends Trait implements TraitWithSlot {
|
||||
getNameStr(writer, abc, fullyQualifiedNames);
|
||||
if (value_kind != 0 || convertData.assignedValues.containsKey(this)) {
|
||||
writer.appendNoHilight(" = ");
|
||||
getValueStr(parent, convertData, writer, abc, fullyQualifiedNames);
|
||||
getValueStr(exportMode, parent, convertData, writer, abc, fullyQualifiedNames);
|
||||
}
|
||||
return writer.appendNoHilight(";").newLine();
|
||||
}
|
||||
@@ -171,7 +175,7 @@ public class TraitSlotConst extends Trait implements TraitWithSlot {
|
||||
public void convert(Trait parent, ConvertData convertData, String path, ABC abc, boolean isStatic, ScriptExportMode exportMode, int scriptIndex, int classIndex, NulWriter writer, List<DottedChain> fullyQualifiedNames, boolean parallel) throws InterruptedException {
|
||||
getNameStr(writer, abc, fullyQualifiedNames);
|
||||
if (value_kind != 0 || convertData.assignedValues.containsKey(this)) {
|
||||
getValueStr(parent, convertData, writer, abc, fullyQualifiedNames);
|
||||
getValueStr(exportMode, parent, convertData, writer, abc, fullyQualifiedNames);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -196,12 +200,12 @@ public class TraitSlotConst extends Trait implements TraitWithSlot {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void getImportsUsages(String customNs, ABC abc, List<DottedChain> imports, List<String> uses, DottedChain ignorePackage, List<DottedChain> fullyQualifiedNames) {
|
||||
public void getDependencies(String customNs, ABC abc, List<Dependency> dependencies, List<String> uses, DottedChain ignorePackage, List<DottedChain> fullyQualifiedNames) {
|
||||
if (ignorePackage == null) {
|
||||
ignorePackage = getPackage(abc);
|
||||
}
|
||||
super.getImportsUsages(customNs, abc, imports, uses, ignorePackage, fullyQualifiedNames);
|
||||
parseImportsUsagesFromMultiname(customNs, abc, imports, uses, abc.constants.getMultiname(type_index), getPackage(abc), fullyQualifiedNames);
|
||||
super.getDependencies(customNs, abc, dependencies, uses, ignorePackage, fullyQualifiedNames);
|
||||
DependencyParser.parseDependenciesFromMultiname(customNs, abc, dependencies, uses, abc.constants.getMultiname(type_index), getPackage(abc), fullyQualifiedNames, DependencyType.SIGNATURE);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -20,6 +20,7 @@ import com.jpexs.decompiler.flash.abc.ABC;
|
||||
import com.jpexs.decompiler.flash.abc.types.ConvertData;
|
||||
import com.jpexs.decompiler.flash.configuration.Configuration;
|
||||
import com.jpexs.decompiler.flash.exporters.modes.ScriptExportMode;
|
||||
import com.jpexs.decompiler.flash.exporters.script.Dependency;
|
||||
import com.jpexs.decompiler.flash.helpers.GraphTextWriter;
|
||||
import com.jpexs.decompiler.flash.helpers.NulWriter;
|
||||
import com.jpexs.decompiler.graph.DottedChain;
|
||||
@@ -244,9 +245,9 @@ public class Traits implements Cloneable, Serializable {
|
||||
}
|
||||
}
|
||||
|
||||
public void getImportsUsages(String customNs, ABC abc, List<DottedChain> imports, List<String> uses, DottedChain ignorePackage, List<DottedChain> fullyQualifiedNames) {
|
||||
public void getDependencies(String customNs, ABC abc, List<Dependency> dependencies, List<String> uses, DottedChain ignorePackage, List<DottedChain> fullyQualifiedNames) {
|
||||
for (Trait t : traits) {
|
||||
t.getImportsUsages(customNs, abc, imports, uses, ignorePackage, fullyQualifiedNames);
|
||||
t.getDependencies(customNs, abc, dependencies, uses, ignorePackage, fullyQualifiedNames);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -568,7 +568,7 @@ public abstract class Action implements GraphSourceItem {
|
||||
|
||||
writer.appendNoHilight(Helper.byteToHex(fileData[(int) (fileOffset + i)]));
|
||||
}
|
||||
|
||||
|
||||
writer.appendNoHilight(")");
|
||||
}
|
||||
|
||||
@@ -1114,7 +1114,7 @@ public abstract class Action implements GraphSourceItem {
|
||||
}
|
||||
|
||||
/*ActionJump && ActionIf removed*/
|
||||
/*if ((action instanceof ActionEnumerate2) || (action instanceof ActionEnumerate)) {
|
||||
/*if ((action instanceof ActionEnumerate2) || (action instanceof ActionEnumerate)) {
|
||||
loopStart = ip + 1;
|
||||
isForIn = true;
|
||||
ip += 4;
|
||||
|
||||
+5
-9
@@ -308,16 +308,12 @@ public class FunctionActionItem extends ActionItem {
|
||||
} else {
|
||||
v.setBoxedValue(new DirectValueActionItem(new RegisterNumber(registerNames.indexOf(varName), varName)));
|
||||
}
|
||||
} else if (v.isDefinition()) {
|
||||
v.setBoxedValue(new DefineLocalActionItem(null, null, ((ActionSourceGenerator) generator).pushConstTargetItem(varName), stored));
|
||||
} else if (stored != null) {
|
||||
v.setBoxedValue(new SetVariableActionItem(null, null, ((ActionSourceGenerator) generator).pushConstTargetItem(varName), stored));
|
||||
} else {
|
||||
if (v.isDefinition()) {
|
||||
v.setBoxedValue(new DefineLocalActionItem(null, null, ((ActionSourceGenerator) generator).pushConstTargetItem(varName), stored));
|
||||
} else {
|
||||
if (stored != null) {
|
||||
v.setBoxedValue(new SetVariableActionItem(null, null, ((ActionSourceGenerator) generator).pushConstTargetItem(varName), stored));
|
||||
} else {
|
||||
v.setBoxedValue(new GetVariableActionItem(null, null, ((ActionSourceGenerator) generator).pushConstTargetItem(varName)));
|
||||
}
|
||||
}
|
||||
v.setBoxedValue(new GetVariableActionItem(null, null, ((ActionSourceGenerator) generator).pushConstTargetItem(varName)));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+56
-47
@@ -1,6 +1,6 @@
|
||||
/* The following code was generated by JFlex 1.6.0 */
|
||||
|
||||
/*
|
||||
/*
|
||||
* Copyright (C) 2010-2016 JPEXS, All rights reserved.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
@@ -16,7 +16,7 @@
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library.
|
||||
*/
|
||||
/* Flash assembler language lexer specification */
|
||||
/* Flash assembler language lexer specification */
|
||||
package com.jpexs.decompiler.flash.action.parser.pcode;
|
||||
|
||||
import com.jpexs.decompiler.flash.action.parser.ActionParseException;
|
||||
@@ -27,8 +27,7 @@ import com.jpexs.decompiler.flash.ecma.Undefined;
|
||||
|
||||
/**
|
||||
* This class is a scanner generated by
|
||||
* <a href="http://www.jflex.de/">JFlex</a> 1.6.0
|
||||
* from the specification file
|
||||
* <a href="http://www.jflex.de/">JFlex</a> 1.6.0 from the specification file
|
||||
* <tt>C:/Dropbox/Programovani/JavaSE/FFDec/libsrc/ffdec_lib/lexers/actionscript_pcode.flex</tt>
|
||||
*/
|
||||
public final class FlasmLexer {
|
||||
@@ -54,9 +53,8 @@ public final class FlasmLexer {
|
||||
|
||||
/**
|
||||
* 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
|
||||
* 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, 1, 1, 2, 2
|
||||
@@ -238,9 +236,11 @@ public final class FlasmLexer {
|
||||
}
|
||||
|
||||
private static int zzUnpackAction(String packed, int offset, int[] result) {
|
||||
int i = 0; /* index in packed string */
|
||||
int i = 0;
|
||||
/* index in packed string */
|
||||
|
||||
int j = offset; /* index in unpacked array */
|
||||
int j = offset;
|
||||
/* index in unpacked array */
|
||||
|
||||
int l = packed.length();
|
||||
while (i < l) {
|
||||
@@ -282,9 +282,11 @@ public final class FlasmLexer {
|
||||
}
|
||||
|
||||
private static int zzUnpackRowMap(String packed, int offset, int[] result) {
|
||||
int i = 0; /* index in packed string */
|
||||
int i = 0;
|
||||
/* index in packed string */
|
||||
|
||||
int j = offset; /* index in unpacked array */
|
||||
int j = offset;
|
||||
/* index in unpacked array */
|
||||
|
||||
int l = packed.length();
|
||||
while (i < l) {
|
||||
@@ -458,9 +460,11 @@ public final class FlasmLexer {
|
||||
}
|
||||
|
||||
private static int zzUnpackTrans(String packed, int offset, int[] result) {
|
||||
int i = 0; /* index in packed string */
|
||||
int i = 0;
|
||||
/* index in packed string */
|
||||
|
||||
int j = offset; /* index in unpacked array */
|
||||
int j = offset;
|
||||
/* index in unpacked array */
|
||||
|
||||
int l = packed.length();
|
||||
while (i < l) {
|
||||
@@ -510,9 +514,11 @@ public final class FlasmLexer {
|
||||
}
|
||||
|
||||
private static int zzUnpackAttribute(String packed, int offset, int[] result) {
|
||||
int i = 0; /* index in packed string */
|
||||
int i = 0;
|
||||
/* index in packed string */
|
||||
|
||||
int j = offset; /* index in unpacked array */
|
||||
int j = offset;
|
||||
/* index in unpacked array */
|
||||
|
||||
int l = packed.length();
|
||||
while (i < l) {
|
||||
@@ -541,8 +547,8 @@ public final class FlasmLexer {
|
||||
private int zzLexicalState = YYINITIAL;
|
||||
|
||||
/**
|
||||
* this buffer contains the current text to be matched and is
|
||||
* the source of the yytext() string
|
||||
* this buffer contains the current text to be matched and is the source of
|
||||
* the yytext() string
|
||||
*/
|
||||
private char zzBuffer[] = new char[ZZ_BUFFERSIZE];
|
||||
|
||||
@@ -562,8 +568,8 @@ public final class FlasmLexer {
|
||||
private int zzStartRead;
|
||||
|
||||
/**
|
||||
* endRead marks the last character in the buffer, that has been read
|
||||
* from input
|
||||
* endRead marks the last character in the buffer, that has been read from
|
||||
* input
|
||||
*/
|
||||
private int zzEndRead;
|
||||
|
||||
@@ -599,10 +605,10 @@ public final class FlasmLexer {
|
||||
private boolean zzEOFDone;
|
||||
|
||||
/**
|
||||
* The number of occupied positions in zzBuffer beyond zzEndRead.
|
||||
* When a lead/high surrogate has been read from the input stream
|
||||
* into the final zzBuffer position, this will have a value of 1;
|
||||
* otherwise, it will have a value of 0.
|
||||
* The number of occupied positions in zzBuffer beyond zzEndRead. When a
|
||||
* lead/high surrogate has been read from the input stream into the final
|
||||
* zzBuffer position, this will have a value of 1; otherwise, it will have a
|
||||
* value of 0.
|
||||
*/
|
||||
private int zzFinalHighSurrogate = 0;
|
||||
|
||||
@@ -642,9 +648,11 @@ public final class FlasmLexer {
|
||||
*/
|
||||
private static char[] zzUnpackCMap(String packed) {
|
||||
char[] map = new char[0x110000];
|
||||
int i = 0; /* index in packed string */
|
||||
int i = 0;
|
||||
/* index in packed string */
|
||||
|
||||
int j = 0; /* index in unpacked array */
|
||||
int j = 0;
|
||||
/* index in unpacked array */
|
||||
|
||||
while (i < 2854) {
|
||||
int count = packed.charAt(i++);
|
||||
@@ -703,7 +711,8 @@ public final class FlasmLexer {
|
||||
|
||||
if (totalRead > 0) {
|
||||
zzEndRead += totalRead;
|
||||
if (totalRead == requested) { /* possibly more input available */
|
||||
if (totalRead == requested) {
|
||||
/* possibly more input available */
|
||||
|
||||
if (Character.isHighSurrogate(zzBuffer[zzEndRead - 1])) {
|
||||
--zzEndRead;
|
||||
@@ -721,9 +730,11 @@ public final class FlasmLexer {
|
||||
* Closes the input stream.
|
||||
*/
|
||||
public final void yyclose() throws java.io.IOException {
|
||||
zzAtEOF = true; /* indicate end of file */
|
||||
zzAtEOF = true;
|
||||
/* indicate end of file */
|
||||
|
||||
zzEndRead = zzStartRead; /* invalidate buffer */
|
||||
zzEndRead = zzStartRead;
|
||||
/* invalidate buffer */
|
||||
|
||||
if (zzReader != null) {
|
||||
zzReader.close();
|
||||
@@ -731,12 +742,12 @@ public final class FlasmLexer {
|
||||
}
|
||||
|
||||
/**
|
||||
* Resets the scanner to read from a new input stream.
|
||||
* Does not close the old reader.
|
||||
* Resets the scanner to read from a new input stream. Does not close the
|
||||
* old reader.
|
||||
*
|
||||
* All internal variables are reset, the old input stream
|
||||
* <b>cannot</b> be reused (internal buffer is discarded and lost).
|
||||
* Lexical state is set to <tt>ZZ_INITIAL</tt>.
|
||||
* <b>cannot</b> be reused (internal buffer is discarded and lost). Lexical
|
||||
* state is set to <tt>ZZ_INITIAL</tt>.
|
||||
*
|
||||
* Internal scan buffer is resized down to its initial length, if it has
|
||||
* grown.
|
||||
@@ -782,13 +793,12 @@ public final class FlasmLexer {
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the character at position <tt>pos</tt> from the
|
||||
* matched text.
|
||||
* Returns the character at position <tt>pos</tt> from the matched text.
|
||||
*
|
||||
* It is equivalent to yytext().charAt(pos), but faster
|
||||
*
|
||||
* @param pos the position of the character to fetch.
|
||||
* A value from 0 to yylength()-1.
|
||||
* @param pos the position of the character to fetch. A value from 0 to
|
||||
* yylength()-1.
|
||||
*
|
||||
* @return the character at position pos
|
||||
*/
|
||||
@@ -806,14 +816,13 @@ public final class FlasmLexer {
|
||||
/**
|
||||
* Reports an error that occured while scanning.
|
||||
*
|
||||
* In a wellformed scanner (no or only correct usage of
|
||||
* yypushback(int) and a match-all fallback rule) this method
|
||||
* will only be called with things that "Can't Possibly Happen".
|
||||
* If this method is called, something is seriously wrong
|
||||
* (e.g. a JFlex bug producing a faulty scanner etc.).
|
||||
* In a wellformed scanner (no or only correct usage of yypushback(int) and
|
||||
* a match-all fallback rule) this method will only be called with things
|
||||
* that "Can't Possibly Happen". If this method is called, something is
|
||||
* seriously wrong (e.g. a JFlex bug producing a faulty scanner etc.).
|
||||
*
|
||||
* Usual syntax/scanner level error handling should be done
|
||||
* in error fallback rules.
|
||||
* Usual syntax/scanner level error handling should be done in error
|
||||
* fallback rules.
|
||||
*
|
||||
* @param errorCode the code of the errormessage to display
|
||||
*/
|
||||
@@ -833,8 +842,8 @@ public final class FlasmLexer {
|
||||
*
|
||||
* They will be read again by then next call of the scanning method
|
||||
*
|
||||
* @param number the number of characters to be read again.
|
||||
* This number must not be greater than yylength()!
|
||||
* @param number the number of characters to be read again. This number must
|
||||
* not be greater than yylength()!
|
||||
*/
|
||||
public void yypushback(int number) {
|
||||
if (number > yylength()) {
|
||||
@@ -845,8 +854,8 @@ public final class FlasmLexer {
|
||||
}
|
||||
|
||||
/**
|
||||
* Resumes scanning until the next regular expression is matched,
|
||||
* the end of input is encountered or an I/O-Error occurs.
|
||||
* Resumes scanning until the next regular expression is matched, the end of
|
||||
* input is encountered or an I/O-Error occurs.
|
||||
*
|
||||
* @return the next token
|
||||
* @exception java.io.IOException if any I/O-Error occurs
|
||||
|
||||
+59
-48
@@ -1,6 +1,6 @@
|
||||
/* The following code was generated by JFlex 1.6.0 */
|
||||
|
||||
/*
|
||||
/*
|
||||
* Copyright (C) 2010-2016 JPEXS, All rights reserved.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
@@ -25,8 +25,7 @@ import java.util.Stack;
|
||||
|
||||
/**
|
||||
* This class is a scanner generated by
|
||||
* <a href="http://www.jflex.de/">JFlex</a> 1.6.0
|
||||
* from the specification file
|
||||
* <a href="http://www.jflex.de/">JFlex</a> 1.6.0 from the specification file
|
||||
* <tt>D:/Dropbox/Programovani/JavaSE/FFDec/libsrc/ffdec_lib/lexers/actionscript_script.flex</tt>
|
||||
*/
|
||||
public final class ActionScriptLexer {
|
||||
@@ -58,9 +57,8 @@ public final class ActionScriptLexer {
|
||||
|
||||
/**
|
||||
* 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
|
||||
* 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, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5
|
||||
@@ -278,9 +276,11 @@ public final class ActionScriptLexer {
|
||||
}
|
||||
|
||||
private static int zzUnpackAction(String packed, int offset, int[] result) {
|
||||
int i = 0; /* index in packed string */
|
||||
int i = 0;
|
||||
/* index in packed string */
|
||||
|
||||
int j = offset; /* index in unpacked array */
|
||||
int j = offset;
|
||||
/* index in unpacked array */
|
||||
|
||||
int l = packed.length();
|
||||
while (i < l) {
|
||||
@@ -395,9 +395,11 @@ public final class ActionScriptLexer {
|
||||
}
|
||||
|
||||
private static int zzUnpackRowMap(String packed, int offset, int[] result) {
|
||||
int i = 0; /* index in packed string */
|
||||
int i = 0;
|
||||
/* index in packed string */
|
||||
|
||||
int j = offset; /* index in unpacked array */
|
||||
int j = offset;
|
||||
/* index in unpacked array */
|
||||
|
||||
int l = packed.length();
|
||||
while (i < l) {
|
||||
@@ -1100,9 +1102,11 @@ public final class ActionScriptLexer {
|
||||
}
|
||||
|
||||
private static int zzUnpackTrans(String packed, int offset, int[] result) {
|
||||
int i = 0; /* index in packed string */
|
||||
int i = 0;
|
||||
/* index in packed string */
|
||||
|
||||
int j = offset; /* index in unpacked array */
|
||||
int j = offset;
|
||||
/* index in unpacked array */
|
||||
|
||||
int l = packed.length();
|
||||
while (i < l) {
|
||||
@@ -1157,9 +1161,11 @@ public final class ActionScriptLexer {
|
||||
}
|
||||
|
||||
private static int zzUnpackAttribute(String packed, int offset, int[] result) {
|
||||
int i = 0; /* index in packed string */
|
||||
int i = 0;
|
||||
/* index in packed string */
|
||||
|
||||
int j = offset; /* index in unpacked array */
|
||||
int j = offset;
|
||||
/* index in unpacked array */
|
||||
|
||||
int l = packed.length();
|
||||
while (i < l) {
|
||||
@@ -1188,8 +1194,8 @@ public final class ActionScriptLexer {
|
||||
private int zzLexicalState = YYINITIAL;
|
||||
|
||||
/**
|
||||
* this buffer contains the current text to be matched and is
|
||||
* the source of the yytext() string
|
||||
* this buffer contains the current text to be matched and is the source of
|
||||
* the yytext() string
|
||||
*/
|
||||
private char zzBuffer[] = new char[ZZ_BUFFERSIZE];
|
||||
|
||||
@@ -1209,8 +1215,8 @@ public final class ActionScriptLexer {
|
||||
private int zzStartRead;
|
||||
|
||||
/**
|
||||
* endRead marks the last character in the buffer, that has been read
|
||||
* from input
|
||||
* endRead marks the last character in the buffer, that has been read from
|
||||
* input
|
||||
*/
|
||||
private int zzEndRead;
|
||||
|
||||
@@ -1246,10 +1252,10 @@ public final class ActionScriptLexer {
|
||||
private boolean zzEOFDone;
|
||||
|
||||
/**
|
||||
* The number of occupied positions in zzBuffer beyond zzEndRead.
|
||||
* When a lead/high surrogate has been read from the input stream
|
||||
* into the final zzBuffer position, this will have a value of 1;
|
||||
* otherwise, it will have a value of 0.
|
||||
* The number of occupied positions in zzBuffer beyond zzEndRead. When a
|
||||
* lead/high surrogate has been read from the input stream into the final
|
||||
* zzBuffer position, this will have a value of 1; otherwise, it will have a
|
||||
* value of 0.
|
||||
*/
|
||||
private int zzFinalHighSurrogate = 0;
|
||||
|
||||
@@ -1326,9 +1332,11 @@ public final class ActionScriptLexer {
|
||||
*/
|
||||
private static char[] zzUnpackCMap(String packed) {
|
||||
char[] map = new char[0x110000];
|
||||
int i = 0; /* index in packed string */
|
||||
int i = 0;
|
||||
/* index in packed string */
|
||||
|
||||
int j = 0; /* index in unpacked array */
|
||||
int j = 0;
|
||||
/* index in unpacked array */
|
||||
|
||||
while (i < 2916) {
|
||||
int count = packed.charAt(i++);
|
||||
@@ -1387,7 +1395,8 @@ public final class ActionScriptLexer {
|
||||
|
||||
if (totalRead > 0) {
|
||||
zzEndRead += totalRead;
|
||||
if (totalRead == requested) { /* possibly more input available */
|
||||
if (totalRead == requested) {
|
||||
/* possibly more input available */
|
||||
|
||||
if (Character.isHighSurrogate(zzBuffer[zzEndRead - 1])) {
|
||||
--zzEndRead;
|
||||
@@ -1405,9 +1414,11 @@ public final class ActionScriptLexer {
|
||||
* Closes the input stream.
|
||||
*/
|
||||
public final void yyclose() throws java.io.IOException {
|
||||
zzAtEOF = true; /* indicate end of file */
|
||||
zzAtEOF = true;
|
||||
/* indicate end of file */
|
||||
|
||||
zzEndRead = zzStartRead; /* invalidate buffer */
|
||||
zzEndRead = zzStartRead;
|
||||
/* invalidate buffer */
|
||||
|
||||
if (zzReader != null) {
|
||||
zzReader.close();
|
||||
@@ -1415,12 +1426,12 @@ public final class ActionScriptLexer {
|
||||
}
|
||||
|
||||
/**
|
||||
* Resets the scanner to read from a new input stream.
|
||||
* Does not close the old reader.
|
||||
* Resets the scanner to read from a new input stream. Does not close the
|
||||
* old reader.
|
||||
*
|
||||
* All internal variables are reset, the old input stream
|
||||
* <b>cannot</b> be reused (internal buffer is discarded and lost).
|
||||
* Lexical state is set to <tt>ZZ_INITIAL</tt>.
|
||||
* <b>cannot</b> be reused (internal buffer is discarded and lost). Lexical
|
||||
* state is set to <tt>ZZ_INITIAL</tt>.
|
||||
*
|
||||
* Internal scan buffer is resized down to its initial length, if it has
|
||||
* grown.
|
||||
@@ -1466,13 +1477,12 @@ public final class ActionScriptLexer {
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the character at position <tt>pos</tt> from the
|
||||
* matched text.
|
||||
* Returns the character at position <tt>pos</tt> from the matched text.
|
||||
*
|
||||
* It is equivalent to yytext().charAt(pos), but faster
|
||||
*
|
||||
* @param pos the position of the character to fetch.
|
||||
* A value from 0 to yylength()-1.
|
||||
* @param pos the position of the character to fetch. A value from 0 to
|
||||
* yylength()-1.
|
||||
*
|
||||
* @return the character at position pos
|
||||
*/
|
||||
@@ -1490,14 +1500,13 @@ public final class ActionScriptLexer {
|
||||
/**
|
||||
* Reports an error that occured while scanning.
|
||||
*
|
||||
* In a wellformed scanner (no or only correct usage of
|
||||
* yypushback(int) and a match-all fallback rule) this method
|
||||
* will only be called with things that "Can't Possibly Happen".
|
||||
* If this method is called, something is seriously wrong
|
||||
* (e.g. a JFlex bug producing a faulty scanner etc.).
|
||||
* In a wellformed scanner (no or only correct usage of yypushback(int) and
|
||||
* a match-all fallback rule) this method will only be called with things
|
||||
* that "Can't Possibly Happen". If this method is called, something is
|
||||
* seriously wrong (e.g. a JFlex bug producing a faulty scanner etc.).
|
||||
*
|
||||
* Usual syntax/scanner level error handling should be done
|
||||
* in error fallback rules.
|
||||
* Usual syntax/scanner level error handling should be done in error
|
||||
* fallback rules.
|
||||
*
|
||||
* @param errorCode the code of the errormessage to display
|
||||
*/
|
||||
@@ -1517,8 +1526,8 @@ public final class ActionScriptLexer {
|
||||
*
|
||||
* They will be read again by then next call of the scanning method
|
||||
*
|
||||
* @param number the number of characters to be read again.
|
||||
* This number must not be greater than yylength()!
|
||||
* @param number the number of characters to be read again. This number must
|
||||
* not be greater than yylength()!
|
||||
*/
|
||||
public void yypushback(int number) {
|
||||
if (number > yylength()) {
|
||||
@@ -1529,8 +1538,8 @@ public final class ActionScriptLexer {
|
||||
}
|
||||
|
||||
/**
|
||||
* Resumes scanning until the next regular expression is matched,
|
||||
* the end of input is encountered or an I/O-Error occurs.
|
||||
* Resumes scanning until the next regular expression is matched, the end of
|
||||
* input is encountered or an I/O-Error occurs.
|
||||
*
|
||||
* @return the next token
|
||||
* @exception java.io.IOException if any I/O-Error occurs
|
||||
@@ -1626,7 +1635,8 @@ public final class ActionScriptLexer {
|
||||
}
|
||||
case 185:
|
||||
break;
|
||||
case 3: { /*ignore*/
|
||||
case 3: {
|
||||
/*ignore*/
|
||||
|
||||
}
|
||||
case 186:
|
||||
@@ -1963,7 +1973,8 @@ public final class ActionScriptLexer {
|
||||
case 250:
|
||||
break;
|
||||
case 68: {
|
||||
string.append('\\'); /*illegal escape sequence*/
|
||||
string.append('\\');
|
||||
/*illegal escape sequence*/
|
||||
|
||||
}
|
||||
case 251:
|
||||
|
||||
@@ -539,6 +539,11 @@ public class Configuration {
|
||||
@ConfigurationFile(".*\\.swc$")
|
||||
public static final ConfigurationItem<String> playerLibLocation = null;
|
||||
|
||||
@ConfigurationDefaultString("")
|
||||
@ConfigurationCategory("paths")
|
||||
@ConfigurationDirectory
|
||||
public static final ConfigurationItem<String> flexSdkLocation = null;
|
||||
|
||||
@ConfigurationDefaultDouble(0.7)
|
||||
@ConfigurationName("gui.avm2.splitPane.vars.dividerLocationPercent")
|
||||
@ConfigurationInternal
|
||||
@@ -608,6 +613,10 @@ public class Configuration {
|
||||
@ConfigurationInternal
|
||||
public static final ConfigurationItem<Double> guiAvm2DocsSplitPaneDividerLocationPercent = null;
|
||||
|
||||
@ConfigurationDefaultBoolean(false)
|
||||
@ConfigurationCategory("script")
|
||||
public static final ConfigurationItem<Boolean> useFlexAs3Compiler = null;
|
||||
|
||||
private enum OSId {
|
||||
|
||||
WINDOWS, OSX, UNIX
|
||||
|
||||
@@ -1,152 +1,152 @@
|
||||
function bind(el, evt, func) {
|
||||
if (el.addEventListener){
|
||||
if (el.addEventListener) {
|
||||
el.addEventListener(evt, func, false);
|
||||
} else if (el.attachEvent) {
|
||||
el.attachEvent('on' + evt, func);
|
||||
}
|
||||
}
|
||||
|
||||
function showhide(e,show){
|
||||
var cls = " "+e.className+" ";
|
||||
if(show && cls.indexOf(" hidden ") > -1){
|
||||
cls = cls.replace(" hidden "," ");
|
||||
}else if(!show && cls.indexOf(" hidden ") == -1 ){
|
||||
cls = cls + "hidden ";
|
||||
}
|
||||
cls = cls.trim();
|
||||
e.className = cls;
|
||||
}
|
||||
|
||||
function hideNoName(name){
|
||||
var lis = document.getElementsByTagName("li");
|
||||
loopi:for(var i=0;i<lis.length;i++) {
|
||||
if(lis[i].className == "instruction-item"){
|
||||
if ((typeof name) != "undefined" && name.trim()!="") {
|
||||
var ss = lis[i].getElementsByTagName("strong");
|
||||
for(var s=0;s<ss.length;s++){
|
||||
if(ss[s].className=="instruction-name")
|
||||
{
|
||||
var insName = ss[s].innerHTML;
|
||||
if(insName.toLowerCase().indexOf(name.toLowerCase())!=0){ //does not start with desired name
|
||||
showhide(lis[i],false);
|
||||
continue loopi;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
function showhide(e, show) {
|
||||
var cls = " " + e.className + " ";
|
||||
if (show && cls.indexOf(" hidden ") > -1) {
|
||||
cls = cls.replace(" hidden ", " ");
|
||||
} else if (!show && cls.indexOf(" hidden ") == -1) {
|
||||
cls = cls + "hidden ";
|
||||
}
|
||||
}
|
||||
cls = cls.trim();
|
||||
e.className = cls;
|
||||
}
|
||||
|
||||
function showFlags(show,flagType){
|
||||
function hideNoName(name) {
|
||||
var lis = document.getElementsByTagName("li");
|
||||
loopi:for (var i = 0; i < lis.length; i++) {
|
||||
if (lis[i].className == "instruction-item") {
|
||||
if ((typeof name) != "undefined" && name.trim() != "") {
|
||||
var ss = lis[i].getElementsByTagName("strong");
|
||||
for (var s = 0; s < ss.length; s++) {
|
||||
if (ss[s].className == "instruction-name")
|
||||
{
|
||||
var insName = ss[s].innerHTML;
|
||||
if (insName.toLowerCase().indexOf(name.toLowerCase()) != 0) { //does not start with desired name
|
||||
showhide(lis[i], false);
|
||||
continue loopi;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function showFlags(show, flagType) {
|
||||
var lis = document.getElementsByTagName("div");
|
||||
loopi:for(var i=0;i<lis.length;i++){
|
||||
var cls = " "+lis[i].className+" ";
|
||||
if ((typeof flagType) != "undefined"){
|
||||
if(cls.indexOf("instruction-flag-"+flagType) == -1){
|
||||
loopi:for (var i = 0; i < lis.length; i++) {
|
||||
var cls = " " + lis[i].className + " ";
|
||||
if ((typeof flagType) != "undefined") {
|
||||
if (cls.indexOf("instruction-flag-" + flagType) == -1) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
showhide(lis[i].parentNode,show);
|
||||
}
|
||||
showhide(lis[i].parentNode, show);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function sortInstructions(order){
|
||||
var newUl = document.createElement("ul");
|
||||
newUl.className = "instruction-list";
|
||||
|
||||
|
||||
var smallestItem = null;
|
||||
var smallestVal = null;
|
||||
var originalUl = null;
|
||||
|
||||
do {
|
||||
smallestItem = null;
|
||||
smallestVal = null;
|
||||
var lis = document.getElementsByTagName("li");
|
||||
loopi:for(var i=0;i<lis.length;i++) {
|
||||
var cls = " "+lis[i].className+" ";
|
||||
if(cls.indexOf(" instruction-item ") != -1) {
|
||||
var ss = lis[i].getElementsByTagName(order == "code"?"span":"strong");
|
||||
for(var s=0;s<ss.length;s++){
|
||||
if(ss[s].className=="instruction-"+order)
|
||||
function sortInstructions(order) {
|
||||
var newUl = document.createElement("ul");
|
||||
newUl.className = "instruction-list";
|
||||
|
||||
|
||||
var smallestItem = null;
|
||||
var smallestVal = null;
|
||||
var originalUl = null;
|
||||
|
||||
do {
|
||||
smallestItem = null;
|
||||
smallestVal = null;
|
||||
var lis = document.getElementsByTagName("li");
|
||||
loopi:for (var i = 0; i < lis.length; i++) {
|
||||
var cls = " " + lis[i].className + " ";
|
||||
if (cls.indexOf(" instruction-item ") != -1) {
|
||||
var ss = lis[i].getElementsByTagName(order == "code" ? "span" : "strong");
|
||||
for (var s = 0; s < ss.length; s++) {
|
||||
if (ss[s].className == "instruction-" + order)
|
||||
{
|
||||
var checkedVal = ss[s].innerHTML;
|
||||
if(smallestVal == null || smallestVal > checkedVal)
|
||||
if (smallestVal == null || smallestVal > checkedVal)
|
||||
{
|
||||
smallestItem = lis[i];
|
||||
smallestVal = checkedVal;
|
||||
}
|
||||
break;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if(smallestItem != null){
|
||||
originalUl = smallestItem.parentNode;
|
||||
originalUl.removeChild(smallestItem);
|
||||
newUl.appendChild(smallestItem);
|
||||
}
|
||||
}while(smallestItem != null);
|
||||
originalUl.parentNode.replaceChild(newUl,originalUl);
|
||||
|
||||
if (smallestItem != null) {
|
||||
originalUl = smallestItem.parentNode;
|
||||
originalUl.removeChild(smallestItem);
|
||||
newUl.appendChild(smallestItem);
|
||||
}
|
||||
} while (smallestItem != null);
|
||||
originalUl.parentNode.replaceChild(newUl, originalUl);
|
||||
|
||||
}
|
||||
|
||||
function applyFilter() {
|
||||
var order_new = document.getElementById("filter_order").value;
|
||||
if(order_set != order_new) {
|
||||
order_set = order_new;
|
||||
sortInstructions(order_new);
|
||||
if (order_set != order_new) {
|
||||
order_set = order_new;
|
||||
sortInstructions(order_new);
|
||||
}
|
||||
showFlags(true);
|
||||
hideNoName(document.getElementById("filter-byname").value);
|
||||
var inputs = document.getElementsByTagName("input");
|
||||
for(var i=0;i<inputs.length;i++){
|
||||
if(inputs[i].type == "checkbox" && inputs[i].className == "filter" && inputs[i].hasAttribute("data-flag")){
|
||||
for (var i = 0; i < inputs.length; i++) {
|
||||
if (inputs[i].type == "checkbox" && inputs[i].className == "filter" && inputs[i].hasAttribute("data-flag")) {
|
||||
var flag = inputs[i].getAttribute("data-flag");
|
||||
if(inputs[i].checked){
|
||||
showFlags(false,flag);
|
||||
}
|
||||
if (inputs[i].checked) {
|
||||
showFlags(false, flag);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function init(){
|
||||
function init() {
|
||||
var js_switcher = document.getElementById("js-switcher");
|
||||
if(!js_switcher){
|
||||
if (!js_switcher) {
|
||||
return;
|
||||
}
|
||||
var t = "";
|
||||
t += "<div class=\"filter\">";
|
||||
|
||||
|
||||
t += "<div class=\"filter-item\">";
|
||||
t += "<label for=\"filter-byname\"><strong class=\"filter-byname-title\">"+txt_filter_byname+"</strong></label>";
|
||||
t += "<label for=\"filter-byname\"><strong class=\"filter-byname-title\">" + txt_filter_byname + "</strong></label>";
|
||||
t += "<input onkeydown=\"applyFilter();\" onkeyup=\"applyFilter();\" onkeypress=\"applyFilter();\" type=\"text\" id=\"filter-byname\" size=\"15\" />";
|
||||
t += "</div>";
|
||||
|
||||
|
||||
t += "<div class=\"filter-item\">";
|
||||
t += "<strong class=\"filter-hide-title\">"+txt_filter_hide+"</strong><br />";
|
||||
for(var flag in flags){
|
||||
t += "<strong class=\"filter-hide-title\">" + txt_filter_hide + "</strong><br />";
|
||||
for (var flag in flags) {
|
||||
var flagDesc = flags[flag];
|
||||
var flagSet = flags_set[flag];
|
||||
t+= '<input class="filter" data-flag="'+flag+'" onchange="applyFilter();" type="checkbox"'+(flagSet?' checked="checked"':'')+' id="flag-'+flag+'-switch"/><label for="flag-'+flag+'-switch">'+flagDesc+'</label><br />';
|
||||
t += '<input class="filter" data-flag="' + flag + '" onchange="applyFilter();" type="checkbox"' + (flagSet ? ' checked="checked"' : '') + ' id="flag-' + flag + '-switch"/><label for="flag-' + flag + '-switch">' + flagDesc + '</label><br />';
|
||||
}
|
||||
|
||||
|
||||
t += "<div class=\"filter-item\">";
|
||||
t += "<label for=\"filter-order\"><strong class=\"filter-order-title\">"+txt_filter_order+"</strong></label>";
|
||||
t += "<label for=\"filter-order\"><strong class=\"filter-order-title\">" + txt_filter_order + "</strong></label>";
|
||||
t += "<select id=\"filter_order\" onchange=\"applyFilter();\">";
|
||||
t += "<option value=\"code\""+(order_set=="code"?' selected="selected"':'')+">"+txt_filter_order_code+"</option>";
|
||||
t += "<option value=\"name\""+(order_set=="name"?' selected="selected"':'')+">"+txt_filter_order_name+"</option>";
|
||||
t += "<option value=\"code\"" + (order_set == "code" ? ' selected="selected"' : '') + ">" + txt_filter_order_code + "</option>";
|
||||
t += "<option value=\"name\"" + (order_set == "name" ? ' selected="selected"' : '') + ">" + txt_filter_order_name + "</option>";
|
||||
t += "</select>";
|
||||
t += "</div>";
|
||||
t += "</div>";
|
||||
|
||||
t += "</div>";
|
||||
t += "</div>";
|
||||
|
||||
t += "</div>"; //.filter
|
||||
|
||||
|
||||
|
||||
|
||||
js_switcher.innerHTML = t;
|
||||
applyFilter();
|
||||
}
|
||||
|
||||
bind(window,"load",init);
|
||||
bind(window, "load", init);
|
||||
@@ -655,7 +655,7 @@ public class EcmaFloatingDecimal {
|
||||
* We keep track of powers of 2 and powers of 5.
|
||||
*/
|
||||
|
||||
/*
|
||||
/*
|
||||
* Estimate decimal exponent. (If it is small-ish,
|
||||
* we could double-check.)
|
||||
*
|
||||
@@ -973,64 +973,60 @@ public class EcmaFloatingDecimal {
|
||||
if (isExceptional) {
|
||||
System.arraycopy(digits, 0, result, i, nDigits);
|
||||
i += nDigits;
|
||||
} else {
|
||||
if (decExponent > 0 && decExponent < 22) {
|
||||
// print digits.digits.
|
||||
int charLength = Math.min(nDigits, decExponent);
|
||||
System.arraycopy(digits, 0, result, i, charLength);
|
||||
} else if (decExponent > 0 && decExponent < 22) {
|
||||
// print digits.digits.
|
||||
int charLength = Math.min(nDigits, decExponent);
|
||||
System.arraycopy(digits, 0, result, i, charLength);
|
||||
i += charLength;
|
||||
if (charLength < decExponent) {
|
||||
charLength = decExponent - charLength;
|
||||
System.arraycopy(zero, 0, result, i, charLength);
|
||||
i += charLength;
|
||||
if (charLength < decExponent) {
|
||||
charLength = decExponent - charLength;
|
||||
System.arraycopy(zero, 0, result, i, charLength);
|
||||
i += charLength;
|
||||
} else {
|
||||
if (charLength < nDigits) {
|
||||
result[i++] = '.';
|
||||
int t = nDigits - charLength;
|
||||
System.arraycopy(digits, charLength, result, i, t);
|
||||
i += t;
|
||||
}
|
||||
}
|
||||
} else if (decExponent <= 0 && decExponent > -5) {
|
||||
result[i++] = '0';
|
||||
if (digits != zero) {
|
||||
result[i++] = '.';
|
||||
if (decExponent != 0) {
|
||||
System.arraycopy(zero, 0, result, i, -decExponent);
|
||||
i -= decExponent;
|
||||
}
|
||||
System.arraycopy(digits, 0, result, i, nDigits);
|
||||
i += nDigits;
|
||||
}
|
||||
} else {
|
||||
result[i++] = digits[0];
|
||||
} else if (charLength < nDigits) {
|
||||
result[i++] = '.';
|
||||
if (nDigits > 1) {
|
||||
System.arraycopy(digits, 1, result, i, nDigits - 1);
|
||||
i += nDigits - 1;
|
||||
} else {
|
||||
result[i++] = '0';
|
||||
}
|
||||
result[i++] = 'e';
|
||||
int e;
|
||||
if (decExponent <= 0) {
|
||||
result[i++] = '-';
|
||||
e = -decExponent + 1;
|
||||
} else {
|
||||
e = decExponent - 1;
|
||||
}
|
||||
// decExponent has 1, 2, or 3, digits
|
||||
if (e <= 9) {
|
||||
result[i++] = (char) (e + '0');
|
||||
} else if (e <= 99) {
|
||||
result[i++] = (char) (e / 10 + '0');
|
||||
result[i++] = (char) (e % 10 + '0');
|
||||
} else {
|
||||
result[i++] = (char) (e / 100 + '0');
|
||||
e %= 100;
|
||||
result[i++] = (char) (e / 10 + '0');
|
||||
result[i++] = (char) (e % 10 + '0');
|
||||
int t = nDigits - charLength;
|
||||
System.arraycopy(digits, charLength, result, i, t);
|
||||
i += t;
|
||||
}
|
||||
} else if (decExponent <= 0 && decExponent > -5) {
|
||||
result[i++] = '0';
|
||||
if (digits != zero) {
|
||||
result[i++] = '.';
|
||||
if (decExponent != 0) {
|
||||
System.arraycopy(zero, 0, result, i, -decExponent);
|
||||
i -= decExponent;
|
||||
}
|
||||
System.arraycopy(digits, 0, result, i, nDigits);
|
||||
i += nDigits;
|
||||
}
|
||||
} else {
|
||||
result[i++] = digits[0];
|
||||
result[i++] = '.';
|
||||
if (nDigits > 1) {
|
||||
System.arraycopy(digits, 1, result, i, nDigits - 1);
|
||||
i += nDigits - 1;
|
||||
} else {
|
||||
result[i++] = '0';
|
||||
}
|
||||
result[i++] = 'e';
|
||||
int e;
|
||||
if (decExponent <= 0) {
|
||||
result[i++] = '-';
|
||||
e = -decExponent + 1;
|
||||
} else {
|
||||
e = decExponent - 1;
|
||||
}
|
||||
// decExponent has 1, 2, or 3, digits
|
||||
if (e <= 9) {
|
||||
result[i++] = (char) (e + '0');
|
||||
} else if (e <= 99) {
|
||||
result[i++] = (char) (e / 10 + '0');
|
||||
result[i++] = (char) (e % 10 + '0');
|
||||
} else {
|
||||
result[i++] = (char) (e / 100 + '0');
|
||||
e %= 100;
|
||||
result[i++] = (char) (e / 10 + '0');
|
||||
result[i++] = (char) (e % 10 + '0');
|
||||
}
|
||||
}
|
||||
return i;
|
||||
@@ -1185,8 +1181,8 @@ public class EcmaFloatingDecimal {
|
||||
}
|
||||
|
||||
/**
|
||||
* Extract a hexadecimal digit from position <code>position</code>
|
||||
* of string <code>s</code>.
|
||||
* Extract a hexadecimal digit from position <code>position</code> of string
|
||||
* <code>s</code>.
|
||||
*/
|
||||
static int getHexDigit(String s, int position) {
|
||||
int value = Character.digit(s.charAt(position), 16);
|
||||
@@ -1567,8 +1563,8 @@ class FDBigInt {
|
||||
} else {
|
||||
return 1; // b not big, answer is obvious;
|
||||
}
|
||||
} else {
|
||||
// a is not really big
|
||||
} else // a is not really big
|
||||
{
|
||||
if (b < 0) {
|
||||
// but b is really big
|
||||
return -1;
|
||||
|
||||
@@ -63,7 +63,7 @@ public class ShapeExporter {
|
||||
return ret;
|
||||
}
|
||||
|
||||
File foutdir = new File(outdir);
|
||||
File foutdir = new File(outdir);
|
||||
Path.createDirectorySafe(foutdir);
|
||||
|
||||
int count = 0;
|
||||
|
||||
+1
-1
@@ -22,5 +22,5 @@ package com.jpexs.decompiler.flash.exporters.modes;
|
||||
*/
|
||||
public enum ScriptExportMode {
|
||||
|
||||
AS, PCODE, PCODE_HEX, HEX, CONSTANTS;
|
||||
AS, PCODE, PCODE_HEX, HEX, CONSTANTS, AS_METHOD_STUBS;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,58 @@
|
||||
package com.jpexs.decompiler.flash.exporters.script;
|
||||
|
||||
import com.jpexs.decompiler.graph.DottedChain;
|
||||
import java.util.Objects;
|
||||
|
||||
public class Dependency {
|
||||
|
||||
private DottedChain id;
|
||||
private DependencyType type;
|
||||
|
||||
public Dependency(DottedChain id, DependencyType type) {
|
||||
this.id = id;
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
public DottedChain getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public DependencyType getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return id.toString() + " (" + type + ")";
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int hash = 5;
|
||||
hash = 79 * hash + Objects.hashCode(this.id);
|
||||
hash = 79 * hash + Objects.hashCode(this.type);
|
||||
return hash;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj) {
|
||||
return true;
|
||||
}
|
||||
if (obj == null) {
|
||||
return false;
|
||||
}
|
||||
if (getClass() != obj.getClass()) {
|
||||
return false;
|
||||
}
|
||||
final Dependency other = (Dependency) obj;
|
||||
if (!Objects.equals(this.id, other.id)) {
|
||||
return false;
|
||||
}
|
||||
if (this.type != other.type) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
+215
@@ -0,0 +1,215 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2016 JPEXS, All rights reserved.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 3.0 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library.
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.exporters.script;
|
||||
|
||||
import com.jpexs.decompiler.flash.abc.ABC;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.AVM2Code;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.AVM2Deobfuscation;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.AVM2Instruction;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.alchemy.AlchemyTypeIns;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.construction.NewFunctionIns;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.other.FindPropertyIns;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.other.FindPropertyStrictIns;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.other.GetLexIns;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.types.AsTypeIns;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.types.CoerceIns;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.model.InitVectorAVM2Item;
|
||||
import com.jpexs.decompiler.flash.abc.types.ABCException;
|
||||
import com.jpexs.decompiler.flash.abc.types.MethodBody;
|
||||
import com.jpexs.decompiler.flash.abc.types.Multiname;
|
||||
import com.jpexs.decompiler.flash.abc.types.Namespace;
|
||||
import com.jpexs.decompiler.flash.abc.types.NamespaceSet;
|
||||
import com.jpexs.decompiler.flash.tags.ABCContainerTag;
|
||||
import com.jpexs.decompiler.graph.DottedChain;
|
||||
import java.util.List;
|
||||
|
||||
public class DependencyParser {
|
||||
|
||||
public static void parseDependenciesFromNS(String ignoredCustom, ABC abc, List<Dependency> dependencies, List<String> uses, int namespace_index, DottedChain ignorePackage, String name, DependencyType dependencyType) {
|
||||
Namespace ns = abc.constants.getNamespace(namespace_index);
|
||||
if (name.isEmpty()) {
|
||||
name = "*";
|
||||
}
|
||||
DottedChain newimport = ns.getName(abc.constants);
|
||||
|
||||
if (parseUsagesFromNS(ignoredCustom, abc, dependencies, uses, namespace_index, ignorePackage, name)) {
|
||||
return;
|
||||
} else if ((ns.kind != Namespace.KIND_PACKAGE) && (ns.kind != Namespace.KIND_PACKAGE_INTERNAL)) {
|
||||
return;
|
||||
}
|
||||
newimport = newimport.add(name);
|
||||
Dependency dep = new Dependency(newimport, dependencyType);
|
||||
|
||||
if (!dependencies.contains(dep)) {
|
||||
DottedChain pkg = newimport.getWithoutLast(); //.substring(0, newimport.lastIndexOf('.'));
|
||||
if (pkg.equals(InitVectorAVM2Item.VECTOR_PACKAGE)) { //special case - is imported always
|
||||
return;
|
||||
}
|
||||
if (!pkg.equals(ignorePackage)) {
|
||||
dependencies.add(dep);
|
||||
}
|
||||
}
|
||||
//}
|
||||
}
|
||||
|
||||
public static void parseDependenciesFromMultiname(String ignoredCustom, ABC abc, List<Dependency> dependencies, List<String> uses, Multiname m, DottedChain ignorePackage, List<DottedChain> fullyQualifiedNames, DependencyType dependencyType) {
|
||||
if (m != null) {
|
||||
if (m.kind == Multiname.TYPENAME) {
|
||||
if (m.qname_index != 0) {
|
||||
parseDependenciesFromMultiname(ignoredCustom, abc, dependencies, uses, abc.constants.getMultiname(m.qname_index), ignorePackage, fullyQualifiedNames, dependencyType);
|
||||
}
|
||||
for (Integer i : m.params) {
|
||||
if (i != 0) {
|
||||
parseDependenciesFromMultiname(ignoredCustom, abc, dependencies, uses, abc.constants.getMultiname(i), ignorePackage, fullyQualifiedNames, dependencyType);
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
Namespace ns = m.getNamespace(abc.constants);
|
||||
String name = m.getName(abc.constants, fullyQualifiedNames, true);
|
||||
NamespaceSet nss = m.getNamespaceSet(abc.constants);
|
||||
if (ns != null) {
|
||||
parseDependenciesFromNS(ignoredCustom, abc, dependencies, uses, m.namespace_index, ignorePackage, name, dependencyType);
|
||||
}
|
||||
if (nss != null) {
|
||||
for (int n : nss.namespaces) {
|
||||
parseDependenciesFromNS(ignoredCustom, abc, dependencies, uses, n, ignorePackage, nss.namespaces.length > 1 ? "" : name, dependencyType);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void parseDependenciesFromMethodInfo(String ignoredCustom, ABC abc, int method_index, List<Dependency> dependencies, List<String> uses, DottedChain ignorePackage, List<DottedChain> fullyQualifiedNames, List<Integer> visitedMethods) {
|
||||
if ((method_index < 0) || (method_index >= abc.method_info.size())) {
|
||||
return;
|
||||
}
|
||||
visitedMethods.add(method_index);
|
||||
if (abc.method_info.get(method_index).ret_type != 0) {
|
||||
parseDependenciesFromMultiname(ignoredCustom, abc, dependencies, uses, abc.constants.getMultiname(abc.method_info.get(method_index).ret_type), ignorePackage, fullyQualifiedNames, DependencyType.SIGNATURE);
|
||||
}
|
||||
for (int t : abc.method_info.get(method_index).param_types) {
|
||||
if (t != 0) {
|
||||
parseDependenciesFromMultiname(ignoredCustom, abc, dependencies, uses, abc.constants.getMultiname(t), ignorePackage, fullyQualifiedNames, DependencyType.SIGNATURE);
|
||||
}
|
||||
}
|
||||
MethodBody body = abc.findBody(method_index);
|
||||
if (body != null) {
|
||||
body.traits.getDependencies(ignoredCustom, abc, dependencies, uses, ignorePackage, fullyQualifiedNames);
|
||||
for (ABCException ex : body.exceptions) {
|
||||
parseDependenciesFromMultiname(ignoredCustom, abc, dependencies, uses, abc.constants.getMultiname(ex.type_index), ignorePackage, fullyQualifiedNames, DependencyType.EXPRESSION /* or signature?*/);
|
||||
}
|
||||
for (AVM2Instruction ins : body.getCode().code) {
|
||||
if (ins.definition instanceof AlchemyTypeIns) {
|
||||
DottedChain nimport = AlchemyTypeIns.ALCHEMY_PACKAGE.add(ins.definition.instructionName);
|
||||
Dependency depExp = new Dependency(nimport, DependencyType.EXPRESSION);
|
||||
if (!dependencies.contains(depExp)) {
|
||||
dependencies.add(depExp);
|
||||
}
|
||||
}
|
||||
if (ins.definition instanceof NewFunctionIns) {
|
||||
if (ins.operands[0] != method_index) {
|
||||
if (!visitedMethods.contains(ins.operands[0])) {
|
||||
parseDependenciesFromMethodInfo(ignoredCustom, abc, ins.operands[0], dependencies, uses, ignorePackage, fullyQualifiedNames, visitedMethods);
|
||||
}
|
||||
}
|
||||
}
|
||||
if ((ins.definition instanceof FindPropertyStrictIns)
|
||||
|| (ins.definition instanceof FindPropertyIns)
|
||||
|| (ins.definition instanceof GetLexIns)
|
||||
|| (ins.definition instanceof CoerceIns)
|
||||
|| (ins.definition instanceof AsTypeIns)) {
|
||||
int m = ins.operands[0];
|
||||
if (m != 0) {
|
||||
if (m < abc.constants.getMultinameCount()) {
|
||||
parseDependenciesFromMultiname(ignoredCustom, abc, dependencies, uses, abc.constants.getMultiname(m), ignorePackage, fullyQualifiedNames, DependencyType.EXPRESSION);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (int k = 0; k < ins.definition.operands.length; k++) {
|
||||
if (ins.definition.operands[k] == AVM2Code.DAT_MULTINAME_INDEX) {
|
||||
int multinameIndex = ins.operands[k];
|
||||
if (multinameIndex < abc.constants.getMultinameCount()) {
|
||||
parseUsagesFromMultiname(ignoredCustom, abc, dependencies, uses, abc.constants.getMultiname(multinameIndex), ignorePackage, fullyQualifiedNames, DependencyType.EXPRESSION);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void parseUsagesFromMultiname(String ignoredCustom, ABC abc, List<Dependency> dependencies, List<String> uses, Multiname m, DottedChain ignorePackage, List<DottedChain> fullyQualifiedNames, DependencyType dependencyType) {
|
||||
if (m != null) {
|
||||
if (m.kind == Multiname.TYPENAME) {
|
||||
if (m.qname_index != 0) {
|
||||
parseUsagesFromMultiname(ignoredCustom, abc, dependencies, uses, abc.constants.getMultiname(m.qname_index), ignorePackage, fullyQualifiedNames, dependencyType);
|
||||
}
|
||||
for (Integer i : m.params) {
|
||||
if (i != 0) {
|
||||
parseUsagesFromMultiname(ignoredCustom, abc, dependencies, uses, abc.constants.getMultiname(i), ignorePackage, fullyQualifiedNames, dependencyType);
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
Namespace ns = m.getNamespace(abc.constants);
|
||||
String name = m.getName(abc.constants, fullyQualifiedNames, false);
|
||||
NamespaceSet nss = m.getNamespaceSet(abc.constants);
|
||||
if (ns != null) {
|
||||
parseUsagesFromNS(ignoredCustom, abc, dependencies, uses, m.namespace_index, ignorePackage, name);
|
||||
}
|
||||
if (nss != null) {
|
||||
if (nss.namespaces.length == 1) {
|
||||
parseUsagesFromNS(ignoredCustom, abc, dependencies, uses, nss.namespaces[0], ignorePackage, name);
|
||||
} else {
|
||||
for (int n : nss.namespaces) {
|
||||
parseUsagesFromNS(ignoredCustom, abc, dependencies, uses, n, ignorePackage, "");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean parseUsagesFromNS(String ignoredCustom, ABC abc, List<Dependency> dependencies, List<String> uses, int namespace_index, DottedChain ignorePackage, String name) {
|
||||
Namespace ns = abc.constants.getNamespace(namespace_index);
|
||||
|
||||
if (ns.kind == Namespace.KIND_NAMESPACE) {
|
||||
String nsVal = ns.getName(abc.constants).toRawString();
|
||||
for (ABCContainerTag abcTag : abc.getAbcTags()) {
|
||||
DottedChain nsimport = abcTag.getABC().nsValueToName(nsVal);
|
||||
if (nsimport.equals(AVM2Deobfuscation.BUILTIN)) {
|
||||
return true; //handled, but import/use not added
|
||||
}
|
||||
if (!nsimport.isEmpty()) {
|
||||
|
||||
Dependency depNs = new Dependency(nsimport, DependencyType.NAMESPACE);
|
||||
if (!nsimport.getWithoutLast().equals(ignorePackage) && !dependencies.contains(depNs)) {
|
||||
dependencies.add(depNs);
|
||||
}
|
||||
if (ignoredCustom != null && nsVal.equals(ignoredCustom)) {
|
||||
return true;
|
||||
}
|
||||
if (!uses.contains(nsimport.getLast())) {
|
||||
uses.add(nsimport.getLast());
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
package com.jpexs.decompiler.flash.exporters.script;
|
||||
|
||||
public enum DependencyType {
|
||||
INHERITANCE, NAMESPACE, SIGNATURE, EXPRESSION
|
||||
}
|
||||
+189
@@ -0,0 +1,189 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2016 JPEXS, All rights reserved.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 3.0 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library.
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.exporters.script;
|
||||
|
||||
import com.jpexs.decompiler.flash.EventListener;
|
||||
import com.jpexs.decompiler.flash.SWF;
|
||||
import com.jpexs.decompiler.flash.abc.ABC;
|
||||
import com.jpexs.decompiler.flash.abc.ScriptPack;
|
||||
import com.jpexs.decompiler.flash.abc.types.ClassInfo;
|
||||
import com.jpexs.decompiler.flash.abc.types.InstanceInfo;
|
||||
import com.jpexs.decompiler.flash.abc.types.Multiname;
|
||||
import com.jpexs.decompiler.flash.abc.types.Namespace;
|
||||
import com.jpexs.decompiler.flash.abc.types.NamespaceSet;
|
||||
import com.jpexs.decompiler.flash.abc.types.ScriptInfo;
|
||||
import com.jpexs.decompiler.flash.abc.types.traits.Trait;
|
||||
import com.jpexs.decompiler.flash.abc.types.traits.TraitClass;
|
||||
import com.jpexs.decompiler.graph.DottedChain;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* Class LinkReportExporter - generates Linker reports similar to Flex
|
||||
* -link-report, but for SWF files
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public class LinkReportExporter {
|
||||
|
||||
private String newLineChar = "\n";
|
||||
private String indentStr = " ";
|
||||
|
||||
/**
|
||||
* Constructs reporter with LF as newline, two spaces as indent
|
||||
*/
|
||||
public LinkReportExporter() {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs reporter with custom newline char, two spaces as indent
|
||||
*
|
||||
* @param newLineChar
|
||||
*/
|
||||
public LinkReportExporter(String newLineChar) {
|
||||
this.newLineChar = newLineChar;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs reporter with custom newline char and indent string
|
||||
*
|
||||
* @param newLineChar
|
||||
* @param indentStr
|
||||
*/
|
||||
public LinkReportExporter(String newLineChar, String indentStr) {
|
||||
this.newLineChar = newLineChar;
|
||||
this.indentStr = indentStr;
|
||||
|
||||
}
|
||||
|
||||
private String indent(int cnt) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
for (int i = 0; i < cnt; i++) {
|
||||
sb.append(indentStr);
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
public String generateReport(SWF swf, List<ScriptPack> as3scripts, EventListener evl) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
Set<String> extDeps = new HashSet<>();
|
||||
sb.append("<report>").append(newLineChar);
|
||||
sb.append(indent(1)).append("<scripts>").append(newLineChar);
|
||||
List<ScriptPack> revList = new ArrayList<>(as3scripts);
|
||||
Collections.reverse(revList);
|
||||
|
||||
List<DottedChain> existingObjects = new ArrayList<>();
|
||||
for (ScriptPack sp : as3scripts) {
|
||||
existingObjects.add(sp.getClassPath().packageStr.add(sp.getClassPath().className));
|
||||
}
|
||||
|
||||
for (ScriptPack sp : revList) {
|
||||
String scriptName = "script" + sp.scriptIndex;
|
||||
sb.append(indent(2)).append("<script name=\"").append(scriptName).append("\">").append(newLineChar);
|
||||
//TODO: additional atributes - mod="1469951734131" size="525" optimizedsize="508
|
||||
ScriptInfo script = sp.abc.script_info.get(sp.scriptIndex);
|
||||
for (int traitIndex : sp.traitIndices) {
|
||||
Trait trait = script.traits.traits.get(traitIndex);
|
||||
sb.append(reportTrait(extDeps, existingObjects, swf, sp.abc, trait));
|
||||
}
|
||||
//how about script_init method(?)
|
||||
sb.append(indent(2)).append("</script>").append(newLineChar);
|
||||
}
|
||||
sb.append(indent(1)).append("</scripts>").append(newLineChar);
|
||||
sb.append("</report>").append(newLineChar);
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
private String multiNameToId(ABC abc, Multiname multiName) {
|
||||
Namespace ns = multiName.getNamespace(abc.constants);
|
||||
NamespaceSet nss = multiName.getNamespaceSet(abc.constants);
|
||||
if (nss != null && nss.namespaces.length == 1) {
|
||||
ns = abc.constants.getNamespace(nss.namespaces[0]);
|
||||
}
|
||||
String pkgName = ns == null ? "" : ns.getName(abc.constants).toRawString();
|
||||
String clsName = multiName.getName(abc.constants, new ArrayList<>(), true);
|
||||
return pkgName.isEmpty() ? clsName : pkgName + ":" + clsName;
|
||||
}
|
||||
|
||||
private String dottedChainToId(DottedChain dc) {
|
||||
if (dc.getWithoutLast().isEmpty()) {
|
||||
return dc.getLast();
|
||||
}
|
||||
return dc.getWithoutLast().toRawString() + ":" + dc.getLast();
|
||||
}
|
||||
|
||||
private String reportTrait(Set<String> externalDefs, List<DottedChain> existingObjects, SWF swf, ABC abc, Trait t) {
|
||||
//TODO: handle externalDefs - <external-defs> <ext id="..." /> </external-defs>
|
||||
StringBuilder sb = new StringBuilder();
|
||||
if (t instanceof TraitClass) {
|
||||
TraitClass tc = (TraitClass) t;
|
||||
sb.append(indent(3)).append("<def id=\"").append(multiNameToId(abc, tc.getName(abc))).append("\" />").append(newLineChar);
|
||||
ClassInfo ci = abc.class_info.get(tc.class_info);
|
||||
InstanceInfo ii = abc.instance_info.get(tc.class_info);
|
||||
|
||||
Set<String> allDeps = new HashSet<>();
|
||||
|
||||
String superPre;
|
||||
if (ii.super_index != 0) {
|
||||
superPre = multiNameToId(abc, abc.constants.getMultiname(ii.super_index));
|
||||
} else {
|
||||
superPre = "Object";
|
||||
}
|
||||
allDeps.add(superPre);
|
||||
sb.append(indent(3)).append("<pre id=\"").append(superPre).append("\" />").append(newLineChar);
|
||||
|
||||
for (int iface : ii.interfaces) {
|
||||
String ifacePre = multiNameToId(abc, abc.constants.getMultiname(iface));
|
||||
allDeps.add(ifacePre);
|
||||
sb.append(indent(3)).append("<pre id=\"").append(ifacePre).append("\" />").append(newLineChar);
|
||||
}
|
||||
|
||||
for (Trait ct : ci.static_traits.traits) {
|
||||
reportTrait(externalDefs, existingObjects, swf, abc, ct);
|
||||
}
|
||||
for (Trait it : ii.instance_traits.traits) {
|
||||
reportTrait(externalDefs, existingObjects, swf, abc, it);
|
||||
}
|
||||
List<Dependency> dependencies = new ArrayList<>();
|
||||
List<String> uses = new ArrayList<>();
|
||||
|
||||
sb.append(indent(3)).append("<dep id=\"AS3\" />").append(newLineChar); //Automatic
|
||||
|
||||
tc.getDependencies(null, abc, dependencies, uses, new DottedChain("FAKE!PACKAGE"), new ArrayList<>());
|
||||
for (Dependency dependency : dependencies) {
|
||||
DottedChain dc = dependency.getId();
|
||||
if (!"*".equals(dc.getLast())) {
|
||||
//some toplevel "imports" can be only method calls
|
||||
if (dc.getWithoutLast().isEmpty() && !existingObjects.contains(dc)) {
|
||||
continue;
|
||||
}
|
||||
String reportDepId = dottedChainToId(dc);
|
||||
if (!allDeps.contains(reportDepId)) {
|
||||
sb.append(indent(3)).append("<dep id=\"").append(reportDepId).append("\" />").append(newLineChar);
|
||||
allDeps.add(reportDepId);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
}
|
||||
+1
@@ -41,6 +41,7 @@ public class ScriptExportSettings {
|
||||
public String getFileExtension() {
|
||||
switch (mode) {
|
||||
case AS:
|
||||
case AS_METHOD_STUBS:
|
||||
return ".as";
|
||||
case PCODE:
|
||||
case PCODE_HEX:
|
||||
|
||||
@@ -0,0 +1,308 @@
|
||||
package com.jpexs.decompiler.flash.exporters.swf;
|
||||
|
||||
import com.jpexs.decompiler.flash.ReadOnlyTagList;
|
||||
import com.jpexs.decompiler.flash.SWC;
|
||||
import com.jpexs.decompiler.flash.SWF;
|
||||
import com.jpexs.decompiler.flash.abc.ABC;
|
||||
import com.jpexs.decompiler.flash.abc.ClassPath;
|
||||
import com.jpexs.decompiler.flash.abc.ScriptPack;
|
||||
import com.jpexs.decompiler.flash.configuration.Configuration;
|
||||
import com.jpexs.decompiler.flash.exporters.script.Dependency;
|
||||
import com.jpexs.decompiler.flash.exporters.script.DependencyType;
|
||||
import com.jpexs.decompiler.flash.importers.SwfXmlImporter;
|
||||
import com.jpexs.decompiler.flash.tags.ABCContainerTag;
|
||||
import com.jpexs.decompiler.flash.tags.DoABC2Tag;
|
||||
import com.jpexs.decompiler.flash.tags.SymbolClassTag;
|
||||
import com.jpexs.decompiler.graph.DottedChain;
|
||||
import com.jpexs.helpers.Helper;
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.math.BigInteger;
|
||||
import java.security.MessageDigest;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.zip.ZipEntry;
|
||||
import java.util.zip.ZipOutputStream;
|
||||
|
||||
public class SwfToSwcExporter {
|
||||
|
||||
private static final String DEPENDENCY_NAMESPACE = "n";
|
||||
private static final String DEPENDENCY_INHERITANCE = "i";
|
||||
private static final String DEPENDENCY_EXPRESSION = "e";
|
||||
private static final String DEPENDENCY_SIGNATURE = "s";
|
||||
|
||||
private static String sha256(InputStream is) {
|
||||
String output;
|
||||
int read;
|
||||
byte[] buffer = new byte[8192];
|
||||
|
||||
try {
|
||||
MessageDigest digest = MessageDigest.getInstance("SHA-256");
|
||||
while ((read = is.read(buffer)) > 0) {
|
||||
digest.update(buffer, 0, read);
|
||||
}
|
||||
byte[] hash = digest.digest();
|
||||
BigInteger bigInt = new BigInteger(1, hash);
|
||||
output = bigInt.toString(16);
|
||||
while (output.length() < 32) {
|
||||
output = "0" + output;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
public SwfToSwcExporter() {
|
||||
|
||||
}
|
||||
|
||||
private String dottedChainToId(DottedChain dc) {
|
||||
if (dc.getWithoutLast().isEmpty()) {
|
||||
return dc.getLast();
|
||||
}
|
||||
return dc.getWithoutLast().toRawString() + ":" + dc.getLast();
|
||||
}
|
||||
|
||||
private String generateCatalog(SWF swf, byte[] swfBytes, boolean skipDependencies) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
|
||||
final String libraryFileName = "library.swf";
|
||||
|
||||
final String SWC_VERSION = "1.2";
|
||||
final String FLEX_VERSION = "4.6.0";
|
||||
final String FLEX_BUILD = "23201";
|
||||
final String MINIMUM_SUPPORTED_VERSION = "3.0.0";
|
||||
|
||||
sb.append("<?xml version=\"1.0\" encoding =\"utf-8\"?>\n")
|
||||
.append("<swc xmlns=\"http://www.adobe.com/flash/swccatalog/9\">\n")
|
||||
.append(" <versions>\n")
|
||||
.append(" <swc version=\"").append(SWC_VERSION).append("\" />\n")
|
||||
.append(" <flex version=\"").append(FLEX_VERSION).append("\" build=\"").append(FLEX_BUILD).append("\" minimumSupportedVersion=\"").append(MINIMUM_SUPPORTED_VERSION).append("\" />\n")
|
||||
.append(" </versions>\n")
|
||||
.append(" <features>\n")
|
||||
.append(" <feature-script-deps />\n")
|
||||
.append(" <feature-files />\n")
|
||||
.append(" </features>\n")
|
||||
.append(" <libraries>\n")
|
||||
.append(" <library path=\"").append(libraryFileName).append("\">\n");
|
||||
|
||||
final long TIME_NOW = new Date().getTime();
|
||||
|
||||
Set<DottedChain> definedObjects = new HashSet<>();
|
||||
|
||||
List<ABCContainerTag> abcTagList = swf.getAbcList();
|
||||
|
||||
List<ScriptPack> packs = swf.getAS3Packs();
|
||||
|
||||
for (ScriptPack pack : packs) {
|
||||
ClassPath cp = pack.getClassPath();
|
||||
definedObjects.add(cp.packageStr.add(cp.className));
|
||||
}
|
||||
|
||||
List<ABC> allAbcList = new ArrayList<>();
|
||||
for (int i = 0; i < abcTagList.size(); i++) {
|
||||
allAbcList.add(abcTagList.get(i).getABC());
|
||||
}
|
||||
|
||||
for (ABCContainerTag abcContainer : abcTagList) {
|
||||
if (!(abcContainer instanceof DoABC2Tag)) {
|
||||
continue; //DoABCTag 1 does not have name
|
||||
}
|
||||
DoABC2Tag abcTag = (DoABC2Tag) abcContainer;
|
||||
String scriptName = abcTag.name;
|
||||
sb.append(" <script name=\"").append(scriptName).append("\" mod=\"").append(TIME_NOW).append("\">\n");
|
||||
List<ScriptPack> tagPacks = abcTag.getABC().getScriptPacks(null, allAbcList);
|
||||
|
||||
for (ScriptPack pack : tagPacks) {
|
||||
ClassPath cp = pack.getClassPath();
|
||||
String defId = dottedChainToId(cp.packageStr.add(cp.className));
|
||||
|
||||
sb.append(" <def id=\"").append(defId).append("\" />\n");
|
||||
|
||||
Set<DottedChain> allDeps = new HashSet<>();
|
||||
allDeps.add(new DottedChain("AS3"));
|
||||
sb.append(" <dep id=\"AS3\" type=\"").append(DEPENDENCY_NAMESPACE).append("\" />\n");
|
||||
if (!skipDependencies) {
|
||||
List<Dependency> dependencies = new ArrayList<>();
|
||||
List<String> uses = new ArrayList<>();
|
||||
pack.abc.script_info.get(pack.scriptIndex).traits.getDependencies(null, pack.abc, dependencies, uses, new DottedChain("NO:PACKAGE"), new ArrayList<>());
|
||||
|
||||
for (Dependency d : dependencies) {
|
||||
if ("*".equals(d.getId().getLast())) {
|
||||
continue;
|
||||
}
|
||||
//some toplevel "imports" can be only method calls
|
||||
if (d.getId().getWithoutLast().isEmpty() && !definedObjects.contains(d.getId())) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (allDeps.contains(d.getId())) {
|
||||
continue;
|
||||
}
|
||||
sb.append(" <dep id=\"").append(dottedChainToId(d.getId())).append("\" type=\"").append(getDependencyStr(d.getType())).append("\" />\n");
|
||||
|
||||
allDeps.add(d.getId());
|
||||
}
|
||||
}
|
||||
}
|
||||
sb.append(" </script>\n");
|
||||
}
|
||||
String sha256Hash = sha256(new ByteArrayInputStream(swfBytes));
|
||||
sb.append(" <digests>\n")
|
||||
.append(" <digest type=\"SHA-256\" signed=\"false\" value=\"").append(sha256Hash).append("\" />\n")
|
||||
.append(" </digests>\n")
|
||||
.append(" </library>\n")
|
||||
.append(" </libraries>\n")
|
||||
.append(" <files>\n")
|
||||
.append(" </files>\n")
|
||||
.append("</swc>\n");
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
private static String getDependencyStr(DependencyType depType) {
|
||||
switch (depType) {
|
||||
case EXPRESSION:
|
||||
return DEPENDENCY_EXPRESSION;
|
||||
case INHERITANCE:
|
||||
return DEPENDENCY_INHERITANCE;
|
||||
case SIGNATURE:
|
||||
return DEPENDENCY_SIGNATURE;
|
||||
case NAMESPACE:
|
||||
return DEPENDENCY_NAMESPACE;
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private SWF recompileSWF(SWF swf) throws IOException, InterruptedException {
|
||||
ByteArrayOutputStream swfOrigBaos = new ByteArrayOutputStream();
|
||||
swf.saveTo(swfOrigBaos);
|
||||
return new SWF(new ByteArrayInputStream(swfOrigBaos.toByteArray()), Configuration.parallelSpeedUp.get(), false);
|
||||
}
|
||||
|
||||
private static void printDelay(String title, long t1, long t2) {
|
||||
//System.out.println("time " + title + ": " + (t2 - t1));
|
||||
}
|
||||
|
||||
public void exportSwf(SWF swf, File outSwcFile, boolean skipDependencies) throws IOException {
|
||||
long t4 = 0;
|
||||
//Make local copy of SWF so we do not modify original
|
||||
try {
|
||||
long t1 = System.currentTimeMillis();
|
||||
swf = recompileSWF(swf);
|
||||
long t2 = System.currentTimeMillis();
|
||||
printDelay("swc.recompile", t1, t2);
|
||||
|
||||
final String HASH = "myhash";
|
||||
String abcTagXml = new String(Helper.readStream(SwfToSwcExporter.class.getResourceAsStream("/com/jpexs/decompiler/flash/exporters/swf/swc_main_abctag.xml")), "UTF-8");
|
||||
abcTagXml = abcTagXml.replace("%hash%", HASH);
|
||||
SwfXmlImporter xmlImporter = new SwfXmlImporter();
|
||||
DoABC2Tag mainAbcTag = (DoABC2Tag) xmlImporter.importObject(abcTagXml, DoABC2Tag.class, swf);
|
||||
ReadOnlyTagList list = swf.getTags();
|
||||
final String documentClassStub = "_%hash%_flash_display_Sprite";
|
||||
String documentClass = documentClassStub.replace("%hash%", HASH);
|
||||
boolean documentClassSet = false;
|
||||
for (int i = 0; i < list.size(); i++) {
|
||||
if (list.get(i) instanceof ABCContainerTag) {
|
||||
swf.addTag(i, mainAbcTag);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < list.size(); i++) {
|
||||
if (list.get(i) instanceof SymbolClassTag) {
|
||||
SymbolClassTag sct = (SymbolClassTag) list.get(i);
|
||||
for (int j = 0; j < sct.tags.size(); j++) {
|
||||
if (sct.tags.get(j) == 0) {
|
||||
sct.names.set(j, documentClass);
|
||||
documentClassSet = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
long t3 = System.currentTimeMillis();
|
||||
printDelay("swc.documentTag", t2, t3);
|
||||
|
||||
if (!documentClassSet) {
|
||||
throw new IOException("Original document class not found!");
|
||||
}
|
||||
swf = recompileSWF(swf);
|
||||
t4 = System.currentTimeMillis();
|
||||
printDelay("swc.recompile2", t3, t4);
|
||||
|
||||
} catch (Exception ex) {
|
||||
ex.printStackTrace();
|
||||
System.exit(0);
|
||||
throw new RuntimeException(ex);
|
||||
}
|
||||
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
swf.saveTo(baos);
|
||||
byte[] swfBytes = baos.toByteArray();
|
||||
long t5 = System.currentTimeMillis();
|
||||
printDelay("swc.getBytes", t4, t5);
|
||||
|
||||
String catalogStr = generateCatalog(swf, swfBytes, skipDependencies);
|
||||
|
||||
long t6 = System.currentTimeMillis();
|
||||
printDelay("swc.generateCatalog", t5, t6);
|
||||
|
||||
File tempFile = new File((outSwcFile.getAbsolutePath()) + ".tmp");
|
||||
FileOutputStream fos = null;
|
||||
ZipOutputStream zos = null;
|
||||
try {
|
||||
fos = new FileOutputStream(tempFile);
|
||||
zos = new ZipOutputStream(fos);
|
||||
|
||||
ZipEntry libraryEntry = new ZipEntry("library.swf");
|
||||
zos.putNextEntry(libraryEntry);
|
||||
zos.write(swfBytes);
|
||||
zos.closeEntry();
|
||||
|
||||
ZipEntry catalogEntry = new ZipEntry("catalog.xml");
|
||||
zos.putNextEntry(catalogEntry);
|
||||
zos.write(catalogStr.getBytes("UTF-8"));
|
||||
zos.closeEntry();
|
||||
|
||||
zos.close();
|
||||
zos = null;
|
||||
fos.close();
|
||||
fos = null;
|
||||
outSwcFile.delete();
|
||||
tempFile.renameTo(outSwcFile);
|
||||
} finally {
|
||||
if (zos != null) {
|
||||
try {
|
||||
zos.close();
|
||||
} catch (IOException ex) {
|
||||
//ignore
|
||||
}
|
||||
|
||||
}
|
||||
if (fos != null) {
|
||||
try {
|
||||
fos.close();
|
||||
} catch (IOException ex) {
|
||||
//ignore
|
||||
}
|
||||
}
|
||||
if (tempFile.exists()) {
|
||||
tempFile.delete();
|
||||
}
|
||||
}
|
||||
long t7 = System.currentTimeMillis();
|
||||
printDelay("swc.zip", t6, t7);
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,216 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!-- Stub for generating Main tag of SWC file -->
|
||||
<item flags="1" name="_%hash%_flash_display_Sprite" type="DoABC2Tag">
|
||||
<abc type="ABC">
|
||||
<version major="46" minor="16" type="ABCVersion"/>
|
||||
<constants type="AVM2ConstantPool">
|
||||
<constant_int/>
|
||||
<constant_uint/>
|
||||
<constant_double/>
|
||||
<constant_decimal/>
|
||||
<constant_float/>
|
||||
<constant_float4/>
|
||||
<constant_string>
|
||||
<item isNull="true"/>
|
||||
<item>_%hash%_flash_display_Sprite</item>
|
||||
<item/>
|
||||
<item>_%hash%_flash_display_Sprite/_%hash%_flash_display_Sprite</item>
|
||||
<item>Security</item>
|
||||
<item>flash.system</item>
|
||||
<item>allowDomain</item>
|
||||
<item>apply</item>
|
||||
<item>http://adobe.com/AS3/2006/builtin</item>
|
||||
<item>_%hash%_flash_display_Sprite/allowDomainInRSL</item>
|
||||
<item>void</item>
|
||||
<item>domains</item>
|
||||
<item>allowInsecureDomain</item>
|
||||
<item>_%hash%_flash_display_Sprite/allowInsecureDomainInRSL</item>
|
||||
<item>allowDomainInRSL</item>
|
||||
<item>__go_to_definition_help</item>
|
||||
<item>pos</item>
|
||||
<item>602</item>
|
||||
<item>allowInsecureDomainInRSL</item>
|
||||
<item>922</item>
|
||||
<item>flash.display</item>
|
||||
<item>Sprite</item>
|
||||
<item>Object</item>
|
||||
<item>EventDispatcher</item>
|
||||
<item>flash.events</item>
|
||||
<item>DisplayObject</item>
|
||||
<item>InteractiveObject</item>
|
||||
<item>DisplayObjectContainer</item>
|
||||
<item>ExcludeClass</item>
|
||||
<item>__go_to_ctor_definition_help</item>
|
||||
<item>275</item>
|
||||
<item>130</item>
|
||||
</constant_string>
|
||||
<constant_namespace>
|
||||
<item isNull="true"/>
|
||||
<item kind="5" name_index="1" type="Namespace"/>
|
||||
<item kind="22" name_index="5" type="Namespace"/>
|
||||
<item kind="22" name_index="2" type="Namespace"/>
|
||||
<item kind="8" name_index="8" type="Namespace"/>
|
||||
<item kind="22" name_index="20" type="Namespace"/>
|
||||
<item kind="24" name_index="1" type="Namespace"/>
|
||||
<item kind="22" name_index="24" type="Namespace"/>
|
||||
<item kind="22" name_index="2" type="Namespace"/>
|
||||
</constant_namespace>
|
||||
<constant_namespace_set/>
|
||||
<constant_multiname>
|
||||
<item isNull="true"/>
|
||||
<item kind="7" name_index="4" namespace_index="2" namespace_set_index="0" qname_index="0" type="Multiname"/>
|
||||
<item kind="7" name_index="6" namespace_index="3" namespace_set_index="0" qname_index="0" type="Multiname"/>
|
||||
<item kind="7" name_index="7" namespace_index="4" namespace_set_index="0" qname_index="0" type="Multiname"/>
|
||||
<item kind="7" name_index="10" namespace_index="3" namespace_set_index="0" qname_index="0" type="Multiname"/>
|
||||
<item kind="7" name_index="12" namespace_index="3" namespace_set_index="0" qname_index="0" type="Multiname"/>
|
||||
<item kind="7" name_index="14" namespace_index="3" namespace_set_index="0" qname_index="0" type="Multiname"/>
|
||||
<item kind="7" name_index="18" namespace_index="3" namespace_set_index="0" qname_index="0" type="Multiname"/>
|
||||
<item kind="7" name_index="1" namespace_index="3" namespace_set_index="0" qname_index="0" type="Multiname"/>
|
||||
<item kind="7" name_index="21" namespace_index="5" namespace_set_index="0" qname_index="0" type="Multiname"/>
|
||||
<item kind="7" name_index="22" namespace_index="3" namespace_set_index="0" qname_index="0" type="Multiname"/>
|
||||
<item kind="7" name_index="23" namespace_index="7" namespace_set_index="0" qname_index="0" type="Multiname"/>
|
||||
<item kind="7" name_index="25" namespace_index="5" namespace_set_index="0" qname_index="0" type="Multiname"/>
|
||||
<item kind="7" name_index="26" namespace_index="5" namespace_set_index="0" qname_index="0" type="Multiname"/>
|
||||
<item kind="7" name_index="27" namespace_index="5" namespace_set_index="0" qname_index="0" type="Multiname"/>
|
||||
</constant_multiname>
|
||||
</constants>
|
||||
<method_info>
|
||||
<item flags="0" name_index="2" ret_type="0" type="MethodInfo">
|
||||
<param_types/>
|
||||
<optional/>
|
||||
<paramNames/>
|
||||
</item>
|
||||
<item flags="0" name_index="3" ret_type="0" type="MethodInfo">
|
||||
<param_types/>
|
||||
<optional/>
|
||||
<paramNames/>
|
||||
</item>
|
||||
<item flags="132" name_index="9" ret_type="4" type="MethodInfo">
|
||||
<param_types/>
|
||||
<optional/>
|
||||
<paramNames/>
|
||||
</item>
|
||||
<item flags="132" name_index="13" ret_type="4" type="MethodInfo">
|
||||
<param_types/>
|
||||
<optional/>
|
||||
<paramNames/>
|
||||
</item>
|
||||
<item flags="0" name_index="2" ret_type="0" type="MethodInfo">
|
||||
<param_types/>
|
||||
<optional/>
|
||||
<paramNames/>
|
||||
</item>
|
||||
</method_info>
|
||||
<metadata_info>
|
||||
<item name_index="15" type="MetadataInfo">
|
||||
<keys>
|
||||
<item>16</item>
|
||||
</keys>
|
||||
<values>
|
||||
<item>17</item>
|
||||
</values>
|
||||
</item>
|
||||
<item name_index="15" type="MetadataInfo">
|
||||
<keys>
|
||||
<item>16</item>
|
||||
</keys>
|
||||
<values>
|
||||
<item>19</item>
|
||||
</values>
|
||||
</item>
|
||||
<item name_index="28" type="MetadataInfo">
|
||||
<keys/>
|
||||
<values/>
|
||||
</item>
|
||||
<item name_index="29" type="MetadataInfo">
|
||||
<keys>
|
||||
<item>16</item>
|
||||
</keys>
|
||||
<values>
|
||||
<item>30</item>
|
||||
</values>
|
||||
</item>
|
||||
<item name_index="15" type="MetadataInfo">
|
||||
<keys>
|
||||
<item>16</item>
|
||||
</keys>
|
||||
<values>
|
||||
<item>31</item>
|
||||
</values>
|
||||
</item>
|
||||
</metadata_info>
|
||||
<instance_info>
|
||||
<item flags="9" iinit_index="1" name_index="8" protectedNS="6" super_index="9" type="InstanceInfo">
|
||||
<interfaces/>
|
||||
<instance_traits type="Traits">
|
||||
<traits>
|
||||
<item bytes="064100020100" disp_id="0" fileOffset="1994" kindFlags="4" kindType="1" method_info="2" name_index="6" type="TraitMethodGetterSetter">
|
||||
<metadata>
|
||||
<item>0</item>
|
||||
</metadata>
|
||||
</item>
|
||||
<item bytes="074100030101" disp_id="0" fileOffset="2000" kindFlags="4" kindType="1" method_info="3" name_index="7" type="TraitMethodGetterSetter">
|
||||
<metadata>
|
||||
<item>1</item>
|
||||
</metadata>
|
||||
</item>
|
||||
</traits>
|
||||
</instance_traits>
|
||||
</item>
|
||||
</instance_info>
|
||||
<class_info>
|
||||
<item cinit_index="0" type="ClassInfo">
|
||||
<static_traits type="Traits">
|
||||
<traits/>
|
||||
</static_traits>
|
||||
</item>
|
||||
</class_info>
|
||||
<script_info>
|
||||
<item init_index="4" type="ScriptInfo">
|
||||
<traits type="Traits">
|
||||
<traits>
|
||||
<item bytes="0844010003020304" class_info="0" fileOffset="2011" kindFlags="4" kindType="4" name_index="8" slot_id="1" type="TraitClass">
|
||||
<metadata>
|
||||
<item>2</item>
|
||||
<item>3</item>
|
||||
<item>4</item>
|
||||
</metadata>
|
||||
</item>
|
||||
</traits>
|
||||
</traits>
|
||||
</item>
|
||||
</script_info>
|
||||
<bodies>
|
||||
<item codeBytes="d03047" init_scope_depth="8" max_regs="1" max_scope_depth="9" max_stack="1" method_info="0" type="MethodBody">
|
||||
<exceptions/>
|
||||
<traits type="Traits">
|
||||
<traits/>
|
||||
</traits>
|
||||
</item>
|
||||
<item codeBytes="d030d0490047" init_scope_depth="9" max_regs="1" max_scope_depth="10" max_stack="1" method_info="1" type="MethodBody">
|
||||
<exceptions/>
|
||||
<traits type="Traits">
|
||||
<traits/>
|
||||
</traits>
|
||||
</item>
|
||||
<item codeBytes="d0305d016601660220d14603022947" init_scope_depth="9" max_regs="2" max_scope_depth="10" max_stack="3" method_info="2" type="MethodBody">
|
||||
<exceptions/>
|
||||
<traits type="Traits">
|
||||
<traits/>
|
||||
</traits>
|
||||
</item>
|
||||
<item codeBytes="d0305d016601660520d14603022947" init_scope_depth="9" max_regs="2" max_scope_depth="10" max_stack="3" method_info="3" type="MethodBody">
|
||||
<exceptions/>
|
||||
<traits type="Traits">
|
||||
<traits/>
|
||||
</traits>
|
||||
</item>
|
||||
<item codeBytes="d03065005d0a660a305d0b660b305d0c660c305d0d660d305d0e660e305d096609305d09660958001d1d1d1d1d1d680847" init_scope_depth="1" max_regs="1" max_scope_depth="8" max_stack="2" method_info="4" type="MethodBody">
|
||||
<exceptions/>
|
||||
<traits type="Traits">
|
||||
<traits/>
|
||||
</traits>
|
||||
</item>
|
||||
</bodies>
|
||||
</abc>
|
||||
</item>
|
||||
@@ -0,0 +1,311 @@
|
||||
package com.jpexs.decompiler.flash.flexsdk;
|
||||
|
||||
import com.jpexs.decompiler.flash.SWF;
|
||||
import com.jpexs.decompiler.flash.abc.ABC;
|
||||
import com.jpexs.decompiler.flash.abc.ScriptPack;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.parser.AVM2ParseException;
|
||||
import com.jpexs.decompiler.flash.abc.types.InstanceInfo;
|
||||
import com.jpexs.decompiler.flash.abc.types.ScriptInfo;
|
||||
import com.jpexs.decompiler.flash.abc.types.traits.Trait;
|
||||
import com.jpexs.decompiler.flash.abc.types.traits.TraitClass;
|
||||
import com.jpexs.decompiler.flash.configuration.Configuration;
|
||||
import com.jpexs.decompiler.flash.exporters.modes.ScriptExportMode;
|
||||
import com.jpexs.decompiler.flash.exporters.script.AS3ScriptExporter;
|
||||
import com.jpexs.decompiler.flash.exporters.script.LinkReportExporter;
|
||||
import com.jpexs.decompiler.flash.exporters.settings.ScriptExportSettings;
|
||||
import com.jpexs.decompiler.flash.exporters.swf.SwfToSwcExporter;
|
||||
import com.jpexs.decompiler.flash.importers.As3ScriptReplaceException;
|
||||
import com.jpexs.decompiler.flash.importers.As3ScriptReplaceExceptionItem;
|
||||
import com.jpexs.decompiler.flash.tags.ABCContainerTag;
|
||||
import com.jpexs.decompiler.flash.tags.Tag;
|
||||
import com.jpexs.decompiler.graph.CompilationException;
|
||||
import com.jpexs.decompiler.graph.DottedChain;
|
||||
import com.jpexs.helpers.Helper;
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import com.jpexs.decompiler.flash.importers.As3ScriptReplacerInterface;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
public class MxmlcAs3ScriptReplacer extends MxmlcRunner implements As3ScriptReplacerInterface {
|
||||
|
||||
private ScriptPack initedPack;
|
||||
private File tempDir;
|
||||
private File pkgDir;
|
||||
private File swcFile;
|
||||
|
||||
public MxmlcAs3ScriptReplacer(String flexSdkPath) {
|
||||
super(flexSdkPath);
|
||||
}
|
||||
|
||||
private synchronized boolean isInited(ScriptPack pack) {
|
||||
return tempDir != null && initedPack == pack;
|
||||
}
|
||||
|
||||
private static void deleteFolder(File folder) {
|
||||
File[] files = folder.listFiles();
|
||||
if (files != null) { //some JVMs return null for empty dirs
|
||||
for (File f : files) {
|
||||
if (f.isDirectory()) {
|
||||
deleteFolder(f);
|
||||
} else {
|
||||
f.delete();
|
||||
}
|
||||
}
|
||||
}
|
||||
folder.delete();
|
||||
}
|
||||
|
||||
private SWF recompileSWF(SWF swf) throws IOException, InterruptedException {
|
||||
ByteArrayOutputStream swfOrigBaos = new ByteArrayOutputStream();
|
||||
swf.saveTo(swfOrigBaos);
|
||||
return new SWF(new ByteArrayInputStream(swfOrigBaos.toByteArray()), Configuration.parallelSpeedUp.get(), false);
|
||||
}
|
||||
|
||||
private boolean isParentDeleted(ABC abc, List<ABC> allAbcs, DottedChain className) {
|
||||
int class_index = abc.findClassByName(className);
|
||||
if (class_index == -1) {
|
||||
for (ABC a : allAbcs) {
|
||||
class_index = abc.findClassByName(className);
|
||||
if (class_index != -1) {
|
||||
abc = a;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (class_index == -1) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
InstanceInfo ii = abc.instance_info.get(class_index);
|
||||
if (ii.deleted) {
|
||||
return true;
|
||||
}
|
||||
if (ii.super_index != 0 && isParentDeleted(abc, allAbcs, abc.constants.getMultiname(ii.super_index).getNameWithNamespace(abc.constants))) {
|
||||
return true;
|
||||
}
|
||||
for (int iface : ii.interfaces) {
|
||||
if (isParentDeleted(abc, allAbcs, abc.constants.getMultiname(iface).getNameWithNamespace(abc.constants))) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void replaceScript(ScriptPack pack, String text) throws As3ScriptReplaceException, IOException, InterruptedException {
|
||||
if (!pack.isSimple) {
|
||||
throw new IOException("Cannot compile such file"); //Alchemy, etc. TODO: handle better
|
||||
}
|
||||
|
||||
if (!isInited(pack)) {
|
||||
initReplacement(pack);
|
||||
}
|
||||
|
||||
File scriptFileToCompile = new File(pkgDir, pack.getClassPath().className + ".as");
|
||||
//Write new script
|
||||
Helper.writeFile(scriptFileToCompile.getAbsolutePath(), text.getBytes("UTF-8"));
|
||||
File compiledSwfFile = new File(pkgDir, "out.swf");
|
||||
|
||||
try {
|
||||
//Compile it (and subclasses stubs)
|
||||
mxmlc("-strict=false", "-include-inheritance-dependencies-only", "-warnings=false", "-library-path", swcFile.getAbsolutePath(), "-source-path", tempDir.getAbsolutePath(), "-output", compiledSwfFile.getAbsolutePath(), "-debug=true", scriptFileToCompile.getAbsolutePath());
|
||||
} catch (MxmlcException ex1) {
|
||||
//String compiledFilePath = scriptFileToCompile.getAbsolutePath();
|
||||
Pattern errPattern = Pattern.compile("^" + Pattern.quote(tempDir.getAbsolutePath()) + "(?<file>.*)\\((?<line>[0-9]+)\\): col: (?<col>[0-9]+) (?<message>.*)$");
|
||||
String err = ex1.getMxmlcErrorOutput();
|
||||
String errLines[] = err.split("\r?\n");
|
||||
List<As3ScriptReplaceExceptionItem> errorItems = new ArrayList<>();
|
||||
for (int i = 0; i < errLines.length; i++) {
|
||||
String line = errLines[i].trim();
|
||||
Matcher m = errPattern.matcher(line);
|
||||
if (m.matches()) {
|
||||
String errFile = m.group("file");
|
||||
int errLine = Integer.parseInt(m.group("line"));
|
||||
int errCol = Integer.parseInt(m.group("col"));
|
||||
String errMsg = m.group("message");
|
||||
errorItems.add(new As3ScriptReplaceExceptionItem(errFile, errMsg, errLine, errCol));
|
||||
}
|
||||
}
|
||||
throw new As3ScriptReplaceException(errorItems);
|
||||
}
|
||||
|
||||
try (FileInputStream fis = new FileInputStream(compiledSwfFile)) {
|
||||
SWF newSWF = new SWF(fis, false, false);
|
||||
List<ABCContainerTag> newTags = newSWF.getAbcList();
|
||||
int oldScriptIndex = pack.scriptIndex;
|
||||
int oldClassIndex = -1;
|
||||
|
||||
ScriptInfo oldScriptInfo = pack.abc.script_info.get(pack.scriptIndex);
|
||||
for (Trait t : oldScriptInfo.traits.traits) {
|
||||
if (t instanceof TraitClass) {
|
||||
int traitClassIndex = ((TraitClass) t).class_info;
|
||||
if (oldClassIndex == -1 || traitClassIndex < oldClassIndex) {
|
||||
oldClassIndex = traitClassIndex;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (pack.isSimple) {
|
||||
oldScriptInfo.delete(pack.abc, true);
|
||||
} else {
|
||||
//NOO
|
||||
}
|
||||
pack.abc.pack(); // removes old classes/methods/scripts
|
||||
ABCContainerTag newTagsLast = newTags.get(newTags.size() - 1);
|
||||
ABC newLastAbc = newTagsLast.getABC();
|
||||
Map<Integer, Integer> classesMap = new HashMap<>();
|
||||
Map<Integer, Integer> scriptsMap = new HashMap<>();
|
||||
|
||||
pack.abc.mergeABC(newLastAbc,
|
||||
new HashMap<>(),
|
||||
new HashMap<>(),
|
||||
new HashMap<>(),
|
||||
new HashMap<>(),
|
||||
new HashMap<>(),
|
||||
new HashMap<>(),
|
||||
new HashMap<>(),
|
||||
new HashMap<>(),
|
||||
new HashMap<>(),
|
||||
new HashMap<>(),
|
||||
new HashMap<>(),
|
||||
new HashMap<>(),
|
||||
classesMap,
|
||||
new HashMap<>(),
|
||||
scriptsMap
|
||||
);
|
||||
|
||||
//Reorder newly created scripts to be in place
|
||||
//where old script was
|
||||
List<Integer> addedScriptIndices = new ArrayList<>(scriptsMap.values());
|
||||
Collections.sort(addedScriptIndices);
|
||||
List<ScriptInfo> addedScripts = new ArrayList<>();
|
||||
for (int i = addedScriptIndices.size() - 1; i >= 0; i--) {
|
||||
int newScriptIndex = addedScriptIndices.get(i);
|
||||
addedScripts.add(0, pack.abc.script_info.remove(newScriptIndex));
|
||||
}
|
||||
for (int i = 0; i < addedScripts.size(); i++) {
|
||||
pack.abc.script_info.add(oldScriptIndex + i, addedScripts.get(i));
|
||||
}
|
||||
|
||||
//IMPORTANT: Map newly created classes to their position as they
|
||||
//were in original script because FlashPlayer needs
|
||||
//parent class to be defined earlier
|
||||
if (oldClassIndex > -1) {
|
||||
List<Integer> addedClassIndices = new ArrayList<>(classesMap.values());
|
||||
Collections.sort(addedClassIndices);
|
||||
int totalClassCount = pack.abc.class_info.size();
|
||||
Map<Integer, Integer> classesRemap = new HashMap<>();
|
||||
for (int i = 0; i < addedClassIndices.size(); i++) {
|
||||
classesRemap.put(addedClassIndices.get(i), oldClassIndex + i);
|
||||
}
|
||||
int mappingStart = oldClassIndex;
|
||||
for (int i = oldClassIndex; i < totalClassCount; i++) {
|
||||
if (!classesRemap.containsKey(i)) {
|
||||
for (int j = mappingStart; j < totalClassCount; j++) {
|
||||
if (!classesRemap.containsValue(j)) {
|
||||
classesRemap.put(i, j);
|
||||
mappingStart = j + 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
pack.abc.reorganizeClasses(classesRemap);
|
||||
}
|
||||
((Tag) pack.abc.parentTag).setModified(true);
|
||||
deinitReplacement(pack);//successfull finish
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAvailable() {
|
||||
String flexLocation = Configuration.flexSdkLocation.get();
|
||||
return !(flexLocation.isEmpty() || (!new File(MxmlcRunner.getMxmlcPath(flexLocation)).exists()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void initReplacement(ScriptPack pack) {
|
||||
if (tempDir != null) {
|
||||
deinitReplacement(pack);
|
||||
}
|
||||
try {
|
||||
tempDir = Files.createTempDirectory("ffdec-mxmlc-replace").toFile();
|
||||
pkgDir = tempDir;
|
||||
for (String pkgPart : pack.getClassPath().packageStr.toList()) {
|
||||
if (!pkgPart.isEmpty()) {
|
||||
pkgDir = new File(pkgDir, pkgPart);
|
||||
}
|
||||
}
|
||||
pkgDir.mkdirs();
|
||||
|
||||
swcFile = new File(pkgDir, "out.swc");
|
||||
|
||||
//Make copy without the old script
|
||||
SWF swfCopy = recompileSWF(pack.getSwf());
|
||||
|
||||
List<ABC> modAbcs = new ArrayList<>();
|
||||
|
||||
List<ScriptPack> copyPacks = swfCopy.getAS3Packs();
|
||||
for (ScriptPack sp : copyPacks) {
|
||||
if (sp.getClassPath().equals(pack.getClassPath())) {
|
||||
sp.abc.script_info.get(sp.scriptIndex).delete(sp.abc, true);
|
||||
((Tag) sp.abc.parentTag).setModified(true);
|
||||
modAbcs.add(sp.abc);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
List<ScriptPack> removedPacks = new ArrayList<>();
|
||||
|
||||
//remove all subclasses from the SWC
|
||||
for (ScriptPack sp : copyPacks) {
|
||||
DottedChain dc = sp.getPathPackage().add(sp.getPathScriptName());
|
||||
if (isParentDeleted(sp.abc, sp.allABCs, dc)) {
|
||||
sp.abc.script_info.get(sp.scriptIndex).delete(sp.abc, true);
|
||||
modAbcs.add(sp.abc);
|
||||
removedPacks.add(sp);
|
||||
}
|
||||
}
|
||||
|
||||
//Export subclasses so they can be compiled by Flex, but ONLY STUBS.
|
||||
//No method code to avoid code compilation problems.
|
||||
//This compiled code won't be used at all in original SWF,
|
||||
//it is used only by Flex to properly compile current script
|
||||
AS3ScriptExporter ex = new AS3ScriptExporter();
|
||||
ex.exportActionScript3(swfCopy, null, tempDir.getAbsolutePath(), removedPacks, new ScriptExportSettings(ScriptExportMode.AS_METHOD_STUBS, false), false, null);
|
||||
|
||||
//now really remove the classes from SWF copy
|
||||
for (ABC a : modAbcs) {
|
||||
a.pack();
|
||||
}
|
||||
|
||||
//Generate SWC file from the modified SWF file.
|
||||
//Flex then uses the code already present in the SWC, no need to decompile it (hurray!)
|
||||
SwfToSwcExporter swcExport = new SwfToSwcExporter();
|
||||
swcExport.exportSwf(swfCopy, swcFile, true);
|
||||
|
||||
} catch (IOException iex) {
|
||||
//ignore
|
||||
} catch (InterruptedException ex) {
|
||||
//ignore
|
||||
}
|
||||
this.initedPack = pack;
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void deinitReplacement(ScriptPack pack) {
|
||||
if (tempDir != null && tempDir.exists()) {
|
||||
deleteFolder(tempDir);
|
||||
}
|
||||
tempDir = null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
package com.jpexs.decompiler.flash.flexsdk;
|
||||
|
||||
public class MxmlcException extends Exception {
|
||||
|
||||
private String mxmlcErrorOutput;
|
||||
|
||||
public MxmlcException(String mxmlcErrorOutput) {
|
||||
this.mxmlcErrorOutput = mxmlcErrorOutput;
|
||||
}
|
||||
|
||||
public String getMxmlcErrorOutput() {
|
||||
return mxmlcErrorOutput;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
package com.jpexs.decompiler.flash.flexsdk;
|
||||
|
||||
import com.jpexs.helpers.Helper;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
public class MxmlcRunner {
|
||||
|
||||
private String flexSdkPath;
|
||||
|
||||
public MxmlcRunner(String flexSdkPath) {
|
||||
this.flexSdkPath = flexSdkPath;
|
||||
}
|
||||
|
||||
public static String getMxmlcPath(String flexSdkPath) {
|
||||
boolean isWin = System.getProperty("os.name").toLowerCase().contains("win");
|
||||
return flexSdkPath + File.separator + "bin" + File.separator + "mxmlc" + (isWin ? ".exe" : "");
|
||||
}
|
||||
|
||||
public void mxmlc(String... arguments) throws MxmlcException, InterruptedException, IOException {
|
||||
String runArgs[] = new String[arguments.length + 1];
|
||||
runArgs[0] = getMxmlcPath(flexSdkPath);
|
||||
System.arraycopy(arguments, 0, runArgs, 1, arguments.length);
|
||||
//System.out.println("" + String.join(" ", runArgs));
|
||||
Process proc = null;
|
||||
try {
|
||||
proc = Runtime.getRuntime().exec(runArgs);
|
||||
Helper.readStream(proc.getInputStream());
|
||||
String errstring = "";
|
||||
try {
|
||||
errstring = new String(Helper.readStream(proc.getErrorStream()), "UTF-8");
|
||||
} catch (UnsupportedEncodingException ex) {
|
||||
//should not happen
|
||||
}
|
||||
proc.waitFor();
|
||||
int exitValue = proc.exitValue();
|
||||
if (exitValue > 0) {
|
||||
throw new MxmlcException(errstring);
|
||||
}
|
||||
} finally {
|
||||
if (proc != null) {
|
||||
try {
|
||||
proc.destroy();
|
||||
} catch (Exception ex2) {
|
||||
//ignore
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -92,6 +92,7 @@ public class BMPFile extends Component {
|
||||
b.save(image, image.getWidth(null), image.getHeight(null));
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* The saveMethod is the main method of the process. This method
|
||||
* will call the convertImage method to convert the memory image to
|
||||
@@ -100,7 +101,6 @@ public class BMPFile extends Component {
|
||||
* information header; and writeBitmap writes the image.
|
||||
*
|
||||
*/
|
||||
|
||||
private void save(Image parImage, int parWidth, int parHeight) throws IOException {
|
||||
convertImage(parImage, parWidth, parHeight);
|
||||
writeBitmapFileHeader();
|
||||
@@ -108,12 +108,12 @@ public class BMPFile extends Component {
|
||||
writeBitmap();
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* convertImage converts the memory image to the bitmap format (BRG).
|
||||
* It also computes some information for the bitmap info header.
|
||||
*
|
||||
*/
|
||||
|
||||
private boolean convertImage(Image parImage, int parWidth, int parHeight) {
|
||||
int pad;
|
||||
bitmap = new int[parWidth * parHeight];
|
||||
@@ -133,6 +133,7 @@ public class BMPFile extends Component {
|
||||
biHeight = parHeight;
|
||||
return (true);
|
||||
}
|
||||
|
||||
/*
|
||||
* writeBitmap converts the image returned from the pixel grabber to
|
||||
* the format required. Remember: scan lines are inverted in
|
||||
@@ -140,7 +141,6 @@ public class BMPFile extends Component {
|
||||
*
|
||||
* Each scan line must be padded to an even 4-byte boundary.
|
||||
*/
|
||||
|
||||
private void writeBitmap() throws IOException {
|
||||
byte[] rgb = new byte[3];
|
||||
int width = biWidth;
|
||||
@@ -165,11 +165,11 @@ public class BMPFile extends Component {
|
||||
bfSize += padCount;
|
||||
biSizeImage += padCount;
|
||||
}
|
||||
|
||||
/*
|
||||
* writeBitmapFileHeader writes the bitmap file header to the file.
|
||||
*
|
||||
*/
|
||||
|
||||
private void writeBitmapFileHeader() throws IOException {
|
||||
|
||||
fo.write(bfType);
|
||||
@@ -178,13 +178,13 @@ public class BMPFile extends Component {
|
||||
fo.write(intToWord(bfReserved2));
|
||||
fo.write(intToDWord(bfOffBits));
|
||||
}
|
||||
|
||||
/*
|
||||
*
|
||||
* writeBitmapInfoHeader writes the bitmap information header
|
||||
* to the file.
|
||||
*
|
||||
*/
|
||||
|
||||
private void writeBitmapInfoHeader() throws IOException {
|
||||
|
||||
fo.write(intToDWord(biSize));
|
||||
@@ -200,26 +200,26 @@ public class BMPFile extends Component {
|
||||
fo.write(intToDWord(biClrImportant));
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
*
|
||||
* intToWord converts an int to a word, where the return
|
||||
* value is stored in a 2-byte array.
|
||||
*
|
||||
*/
|
||||
|
||||
private byte[] intToWord(int parValue) {
|
||||
byte[] retValue = new byte[2];
|
||||
retValue[0] = (byte) (parValue & 0x00FF);
|
||||
retValue[1] = (byte) ((parValue >> 8) & 0x00FF);
|
||||
return (retValue);
|
||||
}
|
||||
|
||||
/*
|
||||
*
|
||||
* intToDWord converts an int to a double word, where the return
|
||||
* value is stored in a 4-byte array.
|
||||
*
|
||||
*/
|
||||
|
||||
private byte[] intToDWord(int parValue) {
|
||||
byte[] retValue = new byte[4];
|
||||
retValue[0] = (byte) (parValue & 0x00FF);
|
||||
|
||||
@@ -243,10 +243,8 @@ public abstract class GraphTextWriter {
|
||||
if (formatting.spaceBeforeParenthesesMethodCallParentheses) {
|
||||
space();
|
||||
}
|
||||
} else {
|
||||
if (formatting.spaceBeforeParenthesesMethodCallEmptyParentheses) {
|
||||
space();
|
||||
}
|
||||
} else if (formatting.spaceBeforeParenthesesMethodCallEmptyParentheses) {
|
||||
space();
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -103,19 +103,17 @@ public class ImageHelper {
|
||||
String formatName = getImageFormatString(format).toUpperCase(Locale.ENGLISH);
|
||||
if (format == ImageFormat.JPEG) {
|
||||
image = fixImageIOJpegBug(image);
|
||||
} else {
|
||||
if (image.getType() == BufferedImage.TYPE_INT_ARGB_PRE) {
|
||||
BufferedImage image2 = new BufferedImage(image.getWidth(), image.getHeight(), BufferedImage.TYPE_INT_ARGB);
|
||||
int[] pixels = ((DataBufferInt) image.getRaster().getDataBuffer()).getData();
|
||||
divideAlpha(pixels);
|
||||
} else if (image.getType() == BufferedImage.TYPE_INT_ARGB_PRE) {
|
||||
BufferedImage image2 = new BufferedImage(image.getWidth(), image.getHeight(), BufferedImage.TYPE_INT_ARGB);
|
||||
int[] pixels = ((DataBufferInt) image.getRaster().getDataBuffer()).getData();
|
||||
divideAlpha(pixels);
|
||||
|
||||
int[] pixels2 = ((DataBufferInt) image2.getRaster().getDataBuffer()).getData();
|
||||
for (int i = 0; i < pixels.length; i++) {
|
||||
pixels2[i] = pixels[i];
|
||||
}
|
||||
|
||||
image = image2;
|
||||
int[] pixels2 = ((DataBufferInt) image2.getRaster().getDataBuffer()).getData();
|
||||
for (int i = 0; i < pixels.length; i++) {
|
||||
pixels2[i] = pixels[i];
|
||||
}
|
||||
|
||||
image = image2;
|
||||
}
|
||||
|
||||
try {
|
||||
|
||||
@@ -36,7 +36,7 @@ public class AS3ScriptImporter {
|
||||
|
||||
private static final Logger logger = Logger.getLogger(AS3ScriptImporter.class.getName());
|
||||
|
||||
public int importScripts(String scriptsFolder, List<ScriptPack> packs) {
|
||||
public int importScripts(As3ScriptReplacerInterface scriptReplacer, String scriptsFolder, List<ScriptPack> packs) {
|
||||
if (!scriptsFolder.endsWith(File.separator)) {
|
||||
scriptsFolder += File.separator;
|
||||
}
|
||||
@@ -50,11 +50,11 @@ public class AS3ScriptImporter {
|
||||
String txt = Helper.readTextFile(fileName);
|
||||
|
||||
try {
|
||||
pack.abc.replaceScriptPack(pack, txt);
|
||||
} catch (AVM2ParseException ex) {
|
||||
logger.log(Level.SEVERE, "%error% on line %line%, file: %file%".replace("%error%", ex.text).replace("%line%", Long.toString(ex.line)).replace("%file%", fileName));
|
||||
} catch (CompilationException ex) {
|
||||
logger.log(Level.SEVERE, "%error% on line %line%, file: %file%".replace("%error%", ex.text).replace("%line%", Long.toString(ex.line)).replace("%file%", fileName));
|
||||
pack.abc.replaceScriptPack(scriptReplacer, pack, txt);
|
||||
} catch (As3ScriptReplaceException asre) {
|
||||
for (As3ScriptReplaceExceptionItem item : asre.getExceptionItems()) {
|
||||
logger.log(Level.SEVERE, "%error% on line %line%, column %col%, file: %file%".replace("%error%", item.getMessage()).replace("%line%", Long.toString(item.getLine())).replace("%file%", fileName).replace("%col%", "" + item.getCol()));
|
||||
}
|
||||
} catch (InterruptedException ex) {
|
||||
logger.log(Level.SEVERE, "error during script import, file: %file%".replace("%file%", fileName), ex);
|
||||
}
|
||||
|
||||
+27
@@ -0,0 +1,27 @@
|
||||
package com.jpexs.decompiler.flash.importers;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public class As3ScriptReplaceException extends Exception {
|
||||
|
||||
private List<As3ScriptReplaceExceptionItem> exceptionItems;
|
||||
|
||||
public As3ScriptReplaceException(List<As3ScriptReplaceExceptionItem> exceptionItems) {
|
||||
this.exceptionItems = exceptionItems;
|
||||
}
|
||||
|
||||
public As3ScriptReplaceException(As3ScriptReplaceExceptionItem exceptionItem) {
|
||||
this.exceptionItems = new ArrayList<>();
|
||||
this.exceptionItems.add(exceptionItem);
|
||||
}
|
||||
|
||||
public List<As3ScriptReplaceExceptionItem> getExceptionItems() {
|
||||
return exceptionItems;
|
||||
}
|
||||
|
||||
}
|
||||
+44
@@ -0,0 +1,44 @@
|
||||
package com.jpexs.decompiler.flash.importers;
|
||||
|
||||
public class As3ScriptReplaceExceptionItem {
|
||||
|
||||
private String file;
|
||||
private int line;
|
||||
private int col;
|
||||
private String message;
|
||||
|
||||
public static final int COL_UNKNOWN = -1;
|
||||
public static final int LINE_UNKNOWN = -1;
|
||||
|
||||
public As3ScriptReplaceExceptionItem(String file, String message, int line) {
|
||||
this(file, message, line, COL_UNKNOWN);
|
||||
}
|
||||
|
||||
public As3ScriptReplaceExceptionItem(String file, String message) {
|
||||
this(file, message, LINE_UNKNOWN, COL_UNKNOWN);
|
||||
}
|
||||
|
||||
public As3ScriptReplaceExceptionItem(String file, String message, int line, int col) {
|
||||
this.file = file;
|
||||
this.line = line;
|
||||
this.col = col;
|
||||
this.message = message;
|
||||
}
|
||||
|
||||
public String getFile() {
|
||||
return file;
|
||||
}
|
||||
|
||||
public int getLine() {
|
||||
return line;
|
||||
}
|
||||
|
||||
public String getMessage() {
|
||||
return message;
|
||||
}
|
||||
|
||||
public int getCol() {
|
||||
return col;
|
||||
}
|
||||
|
||||
}
|
||||
+23
@@ -0,0 +1,23 @@
|
||||
package com.jpexs.decompiler.flash.importers;
|
||||
|
||||
import com.jpexs.decompiler.flash.configuration.Configuration;
|
||||
import com.jpexs.decompiler.flash.flexsdk.MxmlcAs3ScriptReplacer;
|
||||
|
||||
public class As3ScriptReplacerFactory {
|
||||
|
||||
public static As3ScriptReplacerInterface createByConfig() {
|
||||
if (Configuration.useFlexAs3Compiler.get()) {
|
||||
return createFlex();
|
||||
} else {
|
||||
return createFFDec();
|
||||
}
|
||||
}
|
||||
|
||||
public static As3ScriptReplacerInterface createFlex() {
|
||||
return new MxmlcAs3ScriptReplacer(Configuration.flexSdkLocation.get());
|
||||
}
|
||||
|
||||
public static As3ScriptReplacerInterface createFFDec() {
|
||||
return new FFDecAs3ScriptReplacer();
|
||||
}
|
||||
}
|
||||
+15
@@ -0,0 +1,15 @@
|
||||
package com.jpexs.decompiler.flash.importers;
|
||||
|
||||
import com.jpexs.decompiler.flash.abc.ScriptPack;
|
||||
import java.io.IOException;
|
||||
|
||||
public interface As3ScriptReplacerInterface {
|
||||
|
||||
public boolean isAvailable();
|
||||
|
||||
public void initReplacement(ScriptPack pack);
|
||||
|
||||
public void replaceScript(ScriptPack pack, String text) throws As3ScriptReplaceException, IOException, InterruptedException;
|
||||
|
||||
public void deinitReplacement(ScriptPack pack);
|
||||
}
|
||||
@@ -0,0 +1,89 @@
|
||||
package com.jpexs.decompiler.flash.importers;
|
||||
|
||||
import com.jpexs.decompiler.flash.SWF;
|
||||
import com.jpexs.decompiler.flash.abc.ABC;
|
||||
import com.jpexs.decompiler.flash.abc.ScriptPack;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.parser.AVM2ParseException;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.parser.script.ActionScript3Parser;
|
||||
import com.jpexs.decompiler.flash.abc.types.ScriptInfo;
|
||||
import com.jpexs.decompiler.flash.abc.types.traits.TraitClass;
|
||||
import com.jpexs.decompiler.flash.configuration.Configuration;
|
||||
import com.jpexs.decompiler.flash.tags.Tag;
|
||||
import com.jpexs.decompiler.graph.CompilationException;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.TreeSet;
|
||||
|
||||
public class FFDecAs3ScriptReplacer implements As3ScriptReplacerInterface {
|
||||
|
||||
@Override
|
||||
public void replaceScript(ScriptPack pack, String text) throws As3ScriptReplaceException, IOException, InterruptedException {
|
||||
ABC abc = pack.abc;
|
||||
SWF swf = pack.abc.getSwf();
|
||||
String scriptName = pack.getPathScriptName() + ".as";
|
||||
int oldIndex = pack.scriptIndex;
|
||||
int newIndex = abc.script_info.size();
|
||||
try {
|
||||
String documentClass = swf.getDocumentClass();
|
||||
boolean isDocumentClass = documentClass != null && documentClass.equals(pack.getClassPath().toString());
|
||||
|
||||
ScriptInfo si = abc.script_info.get(oldIndex);
|
||||
if (pack.isSimple) {
|
||||
si.delete(abc, true);
|
||||
} else {
|
||||
for (int t : pack.traitIndices) {
|
||||
si.traits.traits.get(t).delete(abc, true);
|
||||
}
|
||||
}
|
||||
|
||||
int newClassIndex = abc.instance_info.size();
|
||||
for (int t : pack.traitIndices) {
|
||||
if (si.traits.traits.get(t) instanceof TraitClass) {
|
||||
TraitClass tc = (TraitClass) si.traits.traits.get(t);
|
||||
newClassIndex = tc.class_info + 1;
|
||||
}
|
||||
|
||||
}
|
||||
List<ABC> otherAbcs = new ArrayList<>(pack.allABCs);
|
||||
|
||||
otherAbcs.remove(abc);
|
||||
abc.script_info.get(oldIndex).delete(abc, true);
|
||||
|
||||
ActionScript3Parser.compile(text, abc, otherAbcs, isDocumentClass, scriptName, newClassIndex, oldIndex);
|
||||
if (pack.isSimple) {
|
||||
// Move newly added script to its position
|
||||
abc.script_info.set(oldIndex, abc.script_info.get(newIndex));
|
||||
abc.script_info.remove(newIndex);
|
||||
} else {
|
||||
//???
|
||||
}
|
||||
abc.script_info.get(oldIndex).setModified(true);
|
||||
abc.pack();//remove old deleted items
|
||||
((Tag) abc.parentTag).setModified(true);
|
||||
} catch (AVM2ParseException ex) {
|
||||
abc.script_info.get(oldIndex).delete(abc, false);
|
||||
throw new As3ScriptReplaceException(new As3ScriptReplaceExceptionItem(null, ex.text, (int) ex.line));
|
||||
} catch (CompilationException ex) {
|
||||
abc.script_info.get(oldIndex).delete(abc, false);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAvailable() {
|
||||
File swc = Configuration.getPlayerSWC();
|
||||
return !(swc == null || !swc.exists());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initReplacement(ScriptPack pack) {
|
||||
//empty
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deinitReplacement(ScriptPack pack) {
|
||||
//empty
|
||||
}
|
||||
|
||||
}
|
||||
@@ -151,6 +151,18 @@ public class SwfXmlImporter {
|
||||
}
|
||||
}
|
||||
|
||||
public Object importObject(String xml, Class requiredType, SWF swf) throws IOException {
|
||||
DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();
|
||||
try {
|
||||
DocumentBuilder docBuilder = docFactory.newDocumentBuilder();
|
||||
Document doc = docBuilder.parse(new InputSource(new StringReader(xml)));
|
||||
return processObject(doc.getDocumentElement(), requiredType, swf, null);
|
||||
} catch (ParserConfigurationException | SAXException | IllegalArgumentException | IllegalAccessException | NoSuchMethodException | InstantiationException | InvocationTargetException ex) {
|
||||
Logger.getLogger(SwfXmlImporter.class.getName()).log(Level.SEVERE, null, ex);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private Field getField(Class cls, String name) throws NoSuchFieldException {
|
||||
Field field;
|
||||
try {
|
||||
@@ -243,7 +255,7 @@ public class SwfXmlImporter {
|
||||
setFieldValue(field, obj, childObj);
|
||||
}
|
||||
} catch (NoSuchFieldException | SecurityException | IllegalArgumentException | IllegalAccessException | NoSuchMethodException | InstantiationException | InvocationTargetException ex) {
|
||||
logger.log(Level.SEVERE, null, ex);
|
||||
logger.log(Level.SEVERE, "Error while getting val from class " + cls + " field: " + name, ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -60,10 +60,8 @@ public class TextImporter {
|
||||
int id = Integer.parseInt(idLine.substring(3).trim());
|
||||
String[] records = textArr[1].split(recordSeparator);
|
||||
result.put(id, records);
|
||||
} else {
|
||||
if (errorHandler.handle(null)) {
|
||||
return null;
|
||||
}
|
||||
} else if (errorHandler.handle(null)) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
@@ -142,11 +140,9 @@ public class TextImporter {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (textTag != null) {
|
||||
if (!saveText(textTag, newText, null)) {
|
||||
return false;
|
||||
}
|
||||
} else if (textTag != null) {
|
||||
if (!saveText(textTag, newText, null)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+983
-912
File diff suppressed because it is too large
Load Diff
@@ -500,7 +500,7 @@ public class DefineFont2Tag extends FontTag {
|
||||
pos = i;
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -524,7 +524,7 @@ public class DefineFont2Tag extends FontTag {
|
||||
getSwf().clearImageCache();
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void setAdvanceValues(Font font) {
|
||||
boolean hasLayout = fontFlagsHasLayout;
|
||||
|
||||
@@ -485,7 +485,7 @@ public class DefineFont3Tag extends FontTag {
|
||||
|
||||
@Override
|
||||
public boolean removeCharacter(char character) {
|
||||
|
||||
|
||||
//Font Align Zones will be removed as removing character zones is not supported:-(
|
||||
for (int i = 0; i < swf.getTags().size(); i++) {
|
||||
Tag t = swf.getTags().get(i);
|
||||
@@ -523,13 +523,13 @@ public class DefineFont3Tag extends FontTag {
|
||||
}
|
||||
|
||||
shiftGlyphIndices(fontID, pos + 1, false);
|
||||
|
||||
|
||||
checkWideParameters();
|
||||
setModified(true);
|
||||
getSwf().clearImageCache();
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void setAdvanceValues(Font font) {
|
||||
boolean hasLayout = fontFlagsHasLayout;
|
||||
|
||||
@@ -312,7 +312,7 @@ public class DefineFontTag extends FontTag {
|
||||
if (fontInfoTag == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
int code = (int) character;
|
||||
int pos = -1;
|
||||
List<Integer> codeTable = fontInfoTag.getCodeTable();
|
||||
@@ -335,12 +335,12 @@ public class DefineFontTag extends FontTag {
|
||||
fontInfoTag.removeFontCharacter(pos);
|
||||
|
||||
shiftGlyphIndices(fontId, pos + 1, false);
|
||||
|
||||
|
||||
setModified(true);
|
||||
getSwf().clearImageCache();
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void setAdvanceValues(Font font) {
|
||||
throw new UnsupportedOperationException("Setting the advance values for DefineFontTag is not supported.");
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/* The following code was generated by JFlex 1.6.0 */
|
||||
|
||||
/*
|
||||
/*
|
||||
* Copyright (C) 2010-2016 JPEXS, All rights reserved.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
@@ -20,8 +20,7 @@ package com.jpexs.decompiler.flash.tags.text;
|
||||
|
||||
/**
|
||||
* This class is a scanner generated by
|
||||
* <a href="http://www.jflex.de/">JFlex</a> 1.6.0
|
||||
* from the specification file
|
||||
* <a href="http://www.jflex.de/">JFlex</a> 1.6.0 from the specification file
|
||||
* <tt>C:/Dropbox/Programovani/JavaSE/FFDec/libsrc/ffdec_lib/lexers/text.flex</tt>
|
||||
*/
|
||||
public final class TextLexer {
|
||||
@@ -47,9 +46,8 @@ public final class TextLexer {
|
||||
|
||||
/**
|
||||
* 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
|
||||
* 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, 1, 1, 2, 2
|
||||
@@ -88,9 +86,11 @@ public final class TextLexer {
|
||||
}
|
||||
|
||||
private static int zzUnpackAction(String packed, int offset, int[] result) {
|
||||
int i = 0; /* index in packed string */
|
||||
int i = 0;
|
||||
/* index in packed string */
|
||||
|
||||
int j = offset; /* index in unpacked array */
|
||||
int j = offset;
|
||||
/* index in unpacked array */
|
||||
|
||||
int l = packed.length();
|
||||
while (i < l) {
|
||||
@@ -122,9 +122,11 @@ public final class TextLexer {
|
||||
}
|
||||
|
||||
private static int zzUnpackRowMap(String packed, int offset, int[] result) {
|
||||
int i = 0; /* index in packed string */
|
||||
int i = 0;
|
||||
/* index in packed string */
|
||||
|
||||
int j = offset; /* index in unpacked array */
|
||||
int j = offset;
|
||||
/* index in unpacked array */
|
||||
|
||||
int l = packed.length();
|
||||
while (i < l) {
|
||||
@@ -158,9 +160,11 @@ public final class TextLexer {
|
||||
}
|
||||
|
||||
private static int zzUnpackTrans(String packed, int offset, int[] result) {
|
||||
int i = 0; /* index in packed string */
|
||||
int i = 0;
|
||||
/* index in packed string */
|
||||
|
||||
int j = offset; /* index in unpacked array */
|
||||
int j = offset;
|
||||
/* index in unpacked array */
|
||||
|
||||
int l = packed.length();
|
||||
while (i < l) {
|
||||
@@ -206,9 +210,11 @@ public final class TextLexer {
|
||||
}
|
||||
|
||||
private static int zzUnpackAttribute(String packed, int offset, int[] result) {
|
||||
int i = 0; /* index in packed string */
|
||||
int i = 0;
|
||||
/* index in packed string */
|
||||
|
||||
int j = offset; /* index in unpacked array */
|
||||
int j = offset;
|
||||
/* index in unpacked array */
|
||||
|
||||
int l = packed.length();
|
||||
while (i < l) {
|
||||
@@ -237,8 +243,8 @@ public final class TextLexer {
|
||||
private int zzLexicalState = YYINITIAL;
|
||||
|
||||
/**
|
||||
* this buffer contains the current text to be matched and is
|
||||
* the source of the yytext() string
|
||||
* this buffer contains the current text to be matched and is the source of
|
||||
* the yytext() string
|
||||
*/
|
||||
private char zzBuffer[] = new char[ZZ_BUFFERSIZE];
|
||||
|
||||
@@ -258,8 +264,8 @@ public final class TextLexer {
|
||||
private int zzStartRead;
|
||||
|
||||
/**
|
||||
* endRead marks the last character in the buffer, that has been read
|
||||
* from input
|
||||
* endRead marks the last character in the buffer, that has been read from
|
||||
* input
|
||||
*/
|
||||
private int zzEndRead;
|
||||
|
||||
@@ -295,10 +301,10 @@ public final class TextLexer {
|
||||
private boolean zzEOFDone;
|
||||
|
||||
/**
|
||||
* The number of occupied positions in zzBuffer beyond zzEndRead.
|
||||
* When a lead/high surrogate has been read from the input stream
|
||||
* into the final zzBuffer position, this will have a value of 1;
|
||||
* otherwise, it will have a value of 0.
|
||||
* The number of occupied positions in zzBuffer beyond zzEndRead. When a
|
||||
* lead/high surrogate has been read from the input stream into the final
|
||||
* zzBuffer position, this will have a value of 1; otherwise, it will have a
|
||||
* value of 0.
|
||||
*/
|
||||
private int zzFinalHighSurrogate = 0;
|
||||
|
||||
@@ -344,9 +350,11 @@ public final class TextLexer {
|
||||
*/
|
||||
private static char[] zzUnpackCMap(String packed) {
|
||||
char[] map = new char[0x110000];
|
||||
int i = 0; /* index in packed string */
|
||||
int i = 0;
|
||||
/* index in packed string */
|
||||
|
||||
int j = 0; /* index in unpacked array */
|
||||
int j = 0;
|
||||
/* index in unpacked array */
|
||||
|
||||
while (i < 114) {
|
||||
int count = packed.charAt(i++);
|
||||
@@ -405,7 +413,8 @@ public final class TextLexer {
|
||||
|
||||
if (totalRead > 0) {
|
||||
zzEndRead += totalRead;
|
||||
if (totalRead == requested) { /* possibly more input available */
|
||||
if (totalRead == requested) {
|
||||
/* possibly more input available */
|
||||
|
||||
if (Character.isHighSurrogate(zzBuffer[zzEndRead - 1])) {
|
||||
--zzEndRead;
|
||||
@@ -423,9 +432,11 @@ public final class TextLexer {
|
||||
* Closes the input stream.
|
||||
*/
|
||||
public final void yyclose() throws java.io.IOException {
|
||||
zzAtEOF = true; /* indicate end of file */
|
||||
zzAtEOF = true;
|
||||
/* indicate end of file */
|
||||
|
||||
zzEndRead = zzStartRead; /* invalidate buffer */
|
||||
zzEndRead = zzStartRead;
|
||||
/* invalidate buffer */
|
||||
|
||||
if (zzReader != null) {
|
||||
zzReader.close();
|
||||
@@ -433,12 +444,12 @@ public final class TextLexer {
|
||||
}
|
||||
|
||||
/**
|
||||
* Resets the scanner to read from a new input stream.
|
||||
* Does not close the old reader.
|
||||
* Resets the scanner to read from a new input stream. Does not close the
|
||||
* old reader.
|
||||
*
|
||||
* All internal variables are reset, the old input stream
|
||||
* <b>cannot</b> be reused (internal buffer is discarded and lost).
|
||||
* Lexical state is set to <tt>ZZ_INITIAL</tt>.
|
||||
* <b>cannot</b> be reused (internal buffer is discarded and lost). Lexical
|
||||
* state is set to <tt>ZZ_INITIAL</tt>.
|
||||
*
|
||||
* Internal scan buffer is resized down to its initial length, if it has
|
||||
* grown.
|
||||
@@ -484,13 +495,12 @@ public final class TextLexer {
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the character at position <tt>pos</tt> from the
|
||||
* matched text.
|
||||
* Returns the character at position <tt>pos</tt> from the matched text.
|
||||
*
|
||||
* It is equivalent to yytext().charAt(pos), but faster
|
||||
*
|
||||
* @param pos the position of the character to fetch.
|
||||
* A value from 0 to yylength()-1.
|
||||
* @param pos the position of the character to fetch. A value from 0 to
|
||||
* yylength()-1.
|
||||
*
|
||||
* @return the character at position pos
|
||||
*/
|
||||
@@ -508,14 +518,13 @@ public final class TextLexer {
|
||||
/**
|
||||
* Reports an error that occured while scanning.
|
||||
*
|
||||
* In a wellformed scanner (no or only correct usage of
|
||||
* yypushback(int) and a match-all fallback rule) this method
|
||||
* will only be called with things that "Can't Possibly Happen".
|
||||
* If this method is called, something is seriously wrong
|
||||
* (e.g. a JFlex bug producing a faulty scanner etc.).
|
||||
* In a wellformed scanner (no or only correct usage of yypushback(int) and
|
||||
* a match-all fallback rule) this method will only be called with things
|
||||
* that "Can't Possibly Happen". If this method is called, something is
|
||||
* seriously wrong (e.g. a JFlex bug producing a faulty scanner etc.).
|
||||
*
|
||||
* Usual syntax/scanner level error handling should be done
|
||||
* in error fallback rules.
|
||||
* Usual syntax/scanner level error handling should be done in error
|
||||
* fallback rules.
|
||||
*
|
||||
* @param errorCode the code of the errormessage to display
|
||||
*/
|
||||
@@ -535,8 +544,8 @@ public final class TextLexer {
|
||||
*
|
||||
* They will be read again by then next call of the scanning method
|
||||
*
|
||||
* @param number the number of characters to be read again.
|
||||
* This number must not be greater than yylength()!
|
||||
* @param number the number of characters to be read again. This number must
|
||||
* not be greater than yylength()!
|
||||
*/
|
||||
public void yypushback(int number) {
|
||||
if (number > yylength()) {
|
||||
@@ -547,8 +556,8 @@ public final class TextLexer {
|
||||
}
|
||||
|
||||
/**
|
||||
* Resumes scanning until the next regular expression is matched,
|
||||
* the end of input is encountered or an I/O-Error occurs.
|
||||
* Resumes scanning until the next regular expression is matched, the end of
|
||||
* input is encountered or an I/O-Error occurs.
|
||||
*
|
||||
* @return the next token
|
||||
* @exception java.io.IOException if any I/O-Error occurs
|
||||
|
||||
+55
-46
@@ -1,6 +1,6 @@
|
||||
/* The following code was generated by JFlex 1.6.0 */
|
||||
|
||||
/*
|
||||
/*
|
||||
* Copyright (C) 2010-2016 JPEXS, All rights reserved.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
@@ -22,8 +22,7 @@ import java.util.Stack;
|
||||
|
||||
/**
|
||||
* This class is a scanner generated by
|
||||
* <a href="http://www.jflex.de/">JFlex</a> 1.6.0
|
||||
* from the specification file
|
||||
* <a href="http://www.jflex.de/">JFlex</a> 1.6.0 from the specification file
|
||||
* <tt>C:/FFDec/jpexs-decompiler/libsrc/ffdec_lib/lexers/tag_conditions.flex</tt>
|
||||
*/
|
||||
public final class ConditionLexer {
|
||||
@@ -45,9 +44,8 @@ public final class ConditionLexer {
|
||||
|
||||
/**
|
||||
* 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
|
||||
* 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
|
||||
@@ -84,9 +82,11 @@ public final class ConditionLexer {
|
||||
}
|
||||
|
||||
private static int zzUnpackAction(String packed, int offset, int[] result) {
|
||||
int i = 0; /* index in packed string */
|
||||
int i = 0;
|
||||
/* index in packed string */
|
||||
|
||||
int j = offset; /* index in unpacked array */
|
||||
int j = offset;
|
||||
/* index in unpacked array */
|
||||
|
||||
int l = packed.length();
|
||||
while (i < l) {
|
||||
@@ -116,9 +116,11 @@ public final class ConditionLexer {
|
||||
}
|
||||
|
||||
private static int zzUnpackRowMap(String packed, int offset, int[] result) {
|
||||
int i = 0; /* index in packed string */
|
||||
int i = 0;
|
||||
/* index in packed string */
|
||||
|
||||
int j = offset; /* index in unpacked array */
|
||||
int j = offset;
|
||||
/* index in unpacked array */
|
||||
|
||||
int l = packed.length();
|
||||
while (i < l) {
|
||||
@@ -145,9 +147,11 @@ public final class ConditionLexer {
|
||||
}
|
||||
|
||||
private static int zzUnpackTrans(String packed, int offset, int[] result) {
|
||||
int i = 0; /* index in packed string */
|
||||
int i = 0;
|
||||
/* index in packed string */
|
||||
|
||||
int j = offset; /* index in unpacked array */
|
||||
int j = offset;
|
||||
/* index in unpacked array */
|
||||
|
||||
int l = packed.length();
|
||||
while (i < l) {
|
||||
@@ -192,9 +196,11 @@ public final class ConditionLexer {
|
||||
}
|
||||
|
||||
private static int zzUnpackAttribute(String packed, int offset, int[] result) {
|
||||
int i = 0; /* index in packed string */
|
||||
int i = 0;
|
||||
/* index in packed string */
|
||||
|
||||
int j = offset; /* index in unpacked array */
|
||||
int j = offset;
|
||||
/* index in unpacked array */
|
||||
|
||||
int l = packed.length();
|
||||
while (i < l) {
|
||||
@@ -223,8 +229,8 @@ public final class ConditionLexer {
|
||||
private int zzLexicalState = YYINITIAL;
|
||||
|
||||
/**
|
||||
* this buffer contains the current text to be matched and is
|
||||
* the source of the yytext() string
|
||||
* this buffer contains the current text to be matched and is the source of
|
||||
* the yytext() string
|
||||
*/
|
||||
private char zzBuffer[] = new char[ZZ_BUFFERSIZE];
|
||||
|
||||
@@ -244,8 +250,8 @@ public final class ConditionLexer {
|
||||
private int zzStartRead;
|
||||
|
||||
/**
|
||||
* endRead marks the last character in the buffer, that has been read
|
||||
* from input
|
||||
* endRead marks the last character in the buffer, that has been read from
|
||||
* input
|
||||
*/
|
||||
private int zzEndRead;
|
||||
|
||||
@@ -281,10 +287,10 @@ public final class ConditionLexer {
|
||||
private boolean zzEOFDone;
|
||||
|
||||
/**
|
||||
* The number of occupied positions in zzBuffer beyond zzEndRead.
|
||||
* When a lead/high surrogate has been read from the input stream
|
||||
* into the final zzBuffer position, this will have a value of 1;
|
||||
* otherwise, it will have a value of 0.
|
||||
* The number of occupied positions in zzBuffer beyond zzEndRead. When a
|
||||
* lead/high surrogate has been read from the input stream into the final
|
||||
* zzBuffer position, this will have a value of 1; otherwise, it will have a
|
||||
* value of 0.
|
||||
*/
|
||||
private int zzFinalHighSurrogate = 0;
|
||||
|
||||
@@ -338,9 +344,11 @@ public final class ConditionLexer {
|
||||
*/
|
||||
private static char[] zzUnpackCMap(String packed) {
|
||||
char[] map = new char[0x110000];
|
||||
int i = 0; /* index in packed string */
|
||||
int i = 0;
|
||||
/* index in packed string */
|
||||
|
||||
int j = 0; /* index in unpacked array */
|
||||
int j = 0;
|
||||
/* index in unpacked array */
|
||||
|
||||
while (i < 96) {
|
||||
int count = packed.charAt(i++);
|
||||
@@ -399,7 +407,8 @@ public final class ConditionLexer {
|
||||
|
||||
if (totalRead > 0) {
|
||||
zzEndRead += totalRead;
|
||||
if (totalRead == requested) { /* possibly more input available */
|
||||
if (totalRead == requested) {
|
||||
/* possibly more input available */
|
||||
|
||||
if (Character.isHighSurrogate(zzBuffer[zzEndRead - 1])) {
|
||||
--zzEndRead;
|
||||
@@ -417,9 +426,11 @@ public final class ConditionLexer {
|
||||
* Closes the input stream.
|
||||
*/
|
||||
public final void yyclose() throws java.io.IOException {
|
||||
zzAtEOF = true; /* indicate end of file */
|
||||
zzAtEOF = true;
|
||||
/* indicate end of file */
|
||||
|
||||
zzEndRead = zzStartRead; /* invalidate buffer */
|
||||
zzEndRead = zzStartRead;
|
||||
/* invalidate buffer */
|
||||
|
||||
if (zzReader != null) {
|
||||
zzReader.close();
|
||||
@@ -427,12 +438,12 @@ public final class ConditionLexer {
|
||||
}
|
||||
|
||||
/**
|
||||
* Resets the scanner to read from a new input stream.
|
||||
* Does not close the old reader.
|
||||
* Resets the scanner to read from a new input stream. Does not close the
|
||||
* old reader.
|
||||
*
|
||||
* All internal variables are reset, the old input stream
|
||||
* <b>cannot</b> be reused (internal buffer is discarded and lost).
|
||||
* Lexical state is set to <tt>ZZ_INITIAL</tt>.
|
||||
* <b>cannot</b> be reused (internal buffer is discarded and lost). Lexical
|
||||
* state is set to <tt>ZZ_INITIAL</tt>.
|
||||
*
|
||||
* Internal scan buffer is resized down to its initial length, if it has
|
||||
* grown.
|
||||
@@ -478,13 +489,12 @@ public final class ConditionLexer {
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the character at position <tt>pos</tt> from the
|
||||
* matched text.
|
||||
* Returns the character at position <tt>pos</tt> from the matched text.
|
||||
*
|
||||
* It is equivalent to yytext().charAt(pos), but faster
|
||||
*
|
||||
* @param pos the position of the character to fetch.
|
||||
* A value from 0 to yylength()-1.
|
||||
* @param pos the position of the character to fetch. A value from 0 to
|
||||
* yylength()-1.
|
||||
*
|
||||
* @return the character at position pos
|
||||
*/
|
||||
@@ -502,14 +512,13 @@ public final class ConditionLexer {
|
||||
/**
|
||||
* Reports an error that occured while scanning.
|
||||
*
|
||||
* In a wellformed scanner (no or only correct usage of
|
||||
* yypushback(int) and a match-all fallback rule) this method
|
||||
* will only be called with things that "Can't Possibly Happen".
|
||||
* If this method is called, something is seriously wrong
|
||||
* (e.g. a JFlex bug producing a faulty scanner etc.).
|
||||
* In a wellformed scanner (no or only correct usage of yypushback(int) and
|
||||
* a match-all fallback rule) this method will only be called with things
|
||||
* that "Can't Possibly Happen". If this method is called, something is
|
||||
* seriously wrong (e.g. a JFlex bug producing a faulty scanner etc.).
|
||||
*
|
||||
* Usual syntax/scanner level error handling should be done
|
||||
* in error fallback rules.
|
||||
* Usual syntax/scanner level error handling should be done in error
|
||||
* fallback rules.
|
||||
*
|
||||
* @param errorCode the code of the errormessage to display
|
||||
*/
|
||||
@@ -529,8 +538,8 @@ public final class ConditionLexer {
|
||||
*
|
||||
* They will be read again by then next call of the scanning method
|
||||
*
|
||||
* @param number the number of characters to be read again.
|
||||
* This number must not be greater than yylength()!
|
||||
* @param number the number of characters to be read again. This number must
|
||||
* not be greater than yylength()!
|
||||
*/
|
||||
public void yypushback(int number) {
|
||||
if (number > yylength()) {
|
||||
@@ -541,8 +550,8 @@ public final class ConditionLexer {
|
||||
}
|
||||
|
||||
/**
|
||||
* Resumes scanning until the next regular expression is matched,
|
||||
* the end of input is encountered or an I/O-Error occurs.
|
||||
* Resumes scanning until the next regular expression is matched, the end of
|
||||
* input is encountered or an I/O-Error occurs.
|
||||
*
|
||||
* @return the next token
|
||||
* @exception java.io.IOException if any I/O-Error occurs
|
||||
|
||||
@@ -29,11 +29,11 @@ public enum FLAVersion {
|
||||
CS5_5("CS5.5", "Flash CS 5.5", "2.1", 11),
|
||||
CS6("CS6", "Flash CS 6", "2.2", 17),
|
||||
CC("CC", "Flash CC", "2.4", Integer.MAX_VALUE) {
|
||||
@Override
|
||||
public int minASVersion() {
|
||||
return 3; //AS 1/2 not supported anymore
|
||||
}
|
||||
};
|
||||
@Override
|
||||
public int minASVersion() {
|
||||
return 3; //AS 1/2 not supported anymore
|
||||
}
|
||||
};
|
||||
|
||||
private final String xflVersion;
|
||||
|
||||
|
||||
@@ -28,7 +28,7 @@ import java.util.List;
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public class DottedChain implements Serializable {
|
||||
public class DottedChain implements Serializable, Comparable<DottedChain> {
|
||||
|
||||
public static final DottedChain EMPTY = new DottedChain(true);
|
||||
|
||||
@@ -278,4 +278,9 @@ public class DottedChain implements Serializable {
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compareTo(DottedChain o) {
|
||||
return toRawString().compareTo(o.toRawString());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -171,19 +171,15 @@ public class GraphPart implements Serializable {
|
||||
for (GraphPart p : nextParts) {
|
||||
if (p == part) {
|
||||
return true;
|
||||
} else {
|
||||
if (p.leadsTo(localData, gr, code, part, visited, loops)) {
|
||||
return true;
|
||||
}
|
||||
} else if (p.leadsTo(localData, gr, code, part, visited, loops)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
for (GraphPart p : throwParts) {
|
||||
if (p == part) {
|
||||
return true;
|
||||
} else {
|
||||
if (p.leadsTo(localData, gr, code, part, visited, loops)) {
|
||||
return true;
|
||||
}
|
||||
} else if (p.leadsTo(localData, gr, code, part, visited, loops)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
|
||||
@@ -957,8 +957,7 @@ function doDrag(e) {
|
||||
if (dragWidth) {
|
||||
canvas.width = (startWidth + e.clientX - startX);
|
||||
canvas.height = canvas.width * originalHeight / originalWidth;
|
||||
}
|
||||
else if (dragHeight) {
|
||||
} else if (dragHeight) {
|
||||
canvas.height = (startHeight + e.clientY - startY);
|
||||
canvas.width = canvas.height * originalWidth / originalHeight;
|
||||
}
|
||||
|
||||
@@ -175,7 +175,8 @@ public class ActionScript2ModificationTest extends ActionScript2TestBase {
|
||||
+ "Return\n"
|
||||
+ "}\n"
|
||||
+ "Push 2\n"
|
||||
+ "Jump label_1\n" + // remove this action
|
||||
+ "Jump label_1\n"
|
||||
+ // remove this action
|
||||
"label_1:Push 3";
|
||||
String expectedResult
|
||||
= "ConstantPool\n"
|
||||
|
||||
@@ -27,6 +27,7 @@ import com.jpexs.decompiler.flash.configuration.Configuration;
|
||||
import com.jpexs.decompiler.flash.exporters.modes.ScriptExportMode;
|
||||
import com.jpexs.decompiler.flash.helpers.CodeFormatting;
|
||||
import com.jpexs.decompiler.flash.helpers.HighlightedTextWriter;
|
||||
import com.jpexs.decompiler.flash.importers.FFDecAs3ScriptReplacer;
|
||||
import com.jpexs.decompiler.flash.tags.ABCContainerTag;
|
||||
import com.jpexs.decompiler.flash.tags.base.ASMSource;
|
||||
import com.jpexs.decompiler.graph.CompilationException;
|
||||
@@ -90,7 +91,7 @@ public class DirectEditingTest extends FileTestBase {
|
||||
try {
|
||||
en.toSource(htw, abc.script_info.get(s).traits.traits, new ConvertData(), ScriptExportMode.AS, false);
|
||||
String original = htw.toString();
|
||||
abc.replaceScriptPack(en, original);
|
||||
abc.replaceScriptPack(new FFDecAs3ScriptReplacer() /*TODO: test the otherone*/, en, original);
|
||||
} catch (Exception ex) {
|
||||
fail("Exception during decompilation - file: " + filePath + " class: " + classPathString, ex);
|
||||
throw ex;
|
||||
|
||||
@@ -0,0 +1,50 @@
|
||||
package com.jpexs.decompiler.flash.flexsdk;
|
||||
|
||||
import com.jpexs.decompiler.flash.SWF;
|
||||
import com.jpexs.decompiler.flash.abc.ScriptPack;
|
||||
import com.jpexs.decompiler.flash.configuration.Configuration;
|
||||
import com.jpexs.helpers.Helper;
|
||||
import java.io.BufferedInputStream;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
public class As3ScriptReplacerTest {
|
||||
|
||||
//Commented out yet... there's no Flex SDK on build server
|
||||
//@Test
|
||||
public void testReplace() throws IOException, InterruptedException, Exception {
|
||||
MxmlcAs3ScriptReplacer replacer = new MxmlcAs3ScriptReplacer(Configuration.flexSdkLocation.get());
|
||||
SWF swf = new SWF(new BufferedInputStream(new FileInputStream("testdata/as3/as3.swf")), false);
|
||||
String replacement = "package classes\n"
|
||||
+ "{\n"
|
||||
+ "\n"
|
||||
+ " public dynamic class TestClass1\n"
|
||||
+ " {\n"
|
||||
+ " public var attrib:int = 5;\n"
|
||||
+ " public var sons:Array;\n"
|
||||
+ "\n"
|
||||
+ " public function testHello()\n"
|
||||
+ " {\n"
|
||||
+ " trace(\"helloA\");\n"
|
||||
+ " }\n"
|
||||
+ "\n"
|
||||
+ " public function method(i:int):int\n"
|
||||
+ " {\n"
|
||||
+ " trace(\"methodB\");\n"
|
||||
+ " return 7;\n"
|
||||
+ " }\n"
|
||||
+ " }\n"
|
||||
+ "}";
|
||||
List<String> classNames = new ArrayList<>();
|
||||
classNames.add("classes.TestClass1");
|
||||
List<ScriptPack> packs = swf.getScriptPacksByClassNames(classNames);
|
||||
for (ScriptPack sp : packs) {
|
||||
replacer.replaceScript(sp, replacement);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
BIN
Binary file not shown.
+24
@@ -0,0 +1,24 @@
|
||||
package {
|
||||
|
||||
import flash.display.MovieClip;
|
||||
import flash.text.TextField;
|
||||
import pkg.MyClass;
|
||||
|
||||
|
||||
public class Main extends MovieClip {
|
||||
|
||||
private var mc:MyClass;
|
||||
|
||||
|
||||
public function Main() {
|
||||
this.mc = new MyClass(5);
|
||||
var display_txt:TextField = new TextField();
|
||||
display_txt.text = "Hello myclass: "+this.mc.getVal()+" char:"+this.mc.getAChar();
|
||||
display_txt.width = 300;
|
||||
addChild(display_txt);
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
BIN
Binary file not shown.
+49
@@ -0,0 +1,49 @@
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
|
||||
<head>
|
||||
<title>Main</title>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
||||
<style type="text/css" media="screen">
|
||||
html, body { height:100%; background-color: #ffffff;}
|
||||
body { margin:0; padding:0; overflow:hidden; }
|
||||
#flashContent { width:100%; height:100%; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div id="flashContent">
|
||||
<object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" width="550" height="400" id="Main" align="middle">
|
||||
<param name="movie" value="Main.swf" />
|
||||
<param name="quality" value="high" />
|
||||
<param name="bgcolor" value="#ffffff" />
|
||||
<param name="play" value="true" />
|
||||
<param name="loop" value="true" />
|
||||
<param name="wmode" value="window" />
|
||||
<param name="scale" value="showall" />
|
||||
<param name="menu" value="true" />
|
||||
<param name="devicefont" value="false" />
|
||||
<param name="salign" value="" />
|
||||
<param name="allowScriptAccess" value="sameDomain" />
|
||||
<!--[if !IE]>-->
|
||||
<object type="application/x-shockwave-flash" data="Main.swf" width="550" height="400">
|
||||
<param name="movie" value="Main.swf" />
|
||||
<param name="quality" value="high" />
|
||||
<param name="bgcolor" value="#ffffff" />
|
||||
<param name="play" value="true" />
|
||||
<param name="loop" value="true" />
|
||||
<param name="wmode" value="window" />
|
||||
<param name="scale" value="showall" />
|
||||
<param name="menu" value="true" />
|
||||
<param name="devicefont" value="false" />
|
||||
<param name="salign" value="" />
|
||||
<param name="allowScriptAccess" value="sameDomain" />
|
||||
<!--<![endif]-->
|
||||
<a href="http://www.adobe.com/go/getflash">
|
||||
<img src="http://www.adobe.com/images/shared/download_buttons/get_flash_player.gif" alt="Get Adobe Flash player" />
|
||||
</a>
|
||||
<!--[if !IE]>-->
|
||||
</object>
|
||||
<!--<![endif]-->
|
||||
</object>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
BIN
Binary file not shown.
@@ -0,0 +1,17 @@
|
||||
package pkg {
|
||||
|
||||
public class MyClass extends ParentClass {
|
||||
|
||||
private var val:int;
|
||||
|
||||
public function MyClass(val) {
|
||||
this.val = val;
|
||||
}
|
||||
|
||||
public function getVal():int{
|
||||
return this.val;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
package pkg {
|
||||
|
||||
public class ParentClass extends ParentParentClass {
|
||||
|
||||
public function ParentClass() {
|
||||
// constructor code
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
package pkg {
|
||||
|
||||
public class ParentParentClass {
|
||||
|
||||
//Reference to subclass: (circular reference)
|
||||
private var other:ParentClass;
|
||||
|
||||
public function ParentParentClass() {
|
||||
// constructor code
|
||||
}
|
||||
|
||||
public function setOther(other:ParentClass){
|
||||
this.other = other;
|
||||
}
|
||||
|
||||
public function getAChar():String{
|
||||
return "A";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -75,6 +75,7 @@ import com.jpexs.decompiler.flash.exporters.modes.ShapeExportMode;
|
||||
import com.jpexs.decompiler.flash.exporters.modes.SoundExportMode;
|
||||
import com.jpexs.decompiler.flash.exporters.modes.SpriteExportMode;
|
||||
import com.jpexs.decompiler.flash.exporters.modes.TextExportMode;
|
||||
import com.jpexs.decompiler.flash.exporters.script.LinkReportExporter;
|
||||
import com.jpexs.decompiler.flash.exporters.settings.BinaryDataExportSettings;
|
||||
import com.jpexs.decompiler.flash.exporters.settings.ButtonExportSettings;
|
||||
import com.jpexs.decompiler.flash.exporters.settings.FontExportSettings;
|
||||
@@ -87,18 +88,26 @@ import com.jpexs.decompiler.flash.exporters.settings.ShapeExportSettings;
|
||||
import com.jpexs.decompiler.flash.exporters.settings.SoundExportSettings;
|
||||
import com.jpexs.decompiler.flash.exporters.settings.SpriteExportSettings;
|
||||
import com.jpexs.decompiler.flash.exporters.settings.TextExportSettings;
|
||||
import com.jpexs.decompiler.flash.exporters.swf.SwfToSwcExporter;
|
||||
import com.jpexs.decompiler.flash.exporters.swf.SwfXmlExporter;
|
||||
import com.jpexs.decompiler.flash.flexsdk.MxmlcAs3ScriptReplacer;
|
||||
import com.jpexs.decompiler.flash.gui.AppStrings;
|
||||
import com.jpexs.decompiler.flash.gui.Main;
|
||||
import com.jpexs.decompiler.flash.gui.SearchInMemory;
|
||||
import com.jpexs.decompiler.flash.gui.SearchInMemoryListener;
|
||||
import com.jpexs.decompiler.flash.gui.SwfInMemory;
|
||||
import com.jpexs.decompiler.flash.gui.View;
|
||||
import com.jpexs.decompiler.flash.gui.helpers.CheckResources;
|
||||
import com.jpexs.decompiler.flash.helpers.FileTextWriter;
|
||||
import com.jpexs.decompiler.flash.helpers.SWFDecompilerPlugin;
|
||||
import com.jpexs.decompiler.flash.importers.AS2ScriptImporter;
|
||||
import com.jpexs.decompiler.flash.importers.AS3ScriptImporter;
|
||||
import com.jpexs.decompiler.flash.importers.As3ScriptReplaceException;
|
||||
import com.jpexs.decompiler.flash.importers.As3ScriptReplaceExceptionItem;
|
||||
import com.jpexs.decompiler.flash.importers.As3ScriptReplacerFactory;
|
||||
import com.jpexs.decompiler.flash.importers.As3ScriptReplacerInterface;
|
||||
import com.jpexs.decompiler.flash.importers.BinaryDataImporter;
|
||||
import com.jpexs.decompiler.flash.importers.FFDecAs3ScriptReplacer;
|
||||
import com.jpexs.decompiler.flash.importers.FontImporter;
|
||||
import com.jpexs.decompiler.flash.importers.ImageImporter;
|
||||
import com.jpexs.decompiler.flash.importers.MorphShapeImporter;
|
||||
@@ -107,6 +116,7 @@ import com.jpexs.decompiler.flash.importers.SwfXmlImporter;
|
||||
import com.jpexs.decompiler.flash.importers.TextImporter;
|
||||
import com.jpexs.decompiler.flash.importers.amf.amf3.Amf3Importer;
|
||||
import com.jpexs.decompiler.flash.importers.amf.amf3.Amf3ParseException;
|
||||
import com.jpexs.decompiler.flash.tags.ABCContainerTag;
|
||||
import com.jpexs.decompiler.flash.tags.DefineBinaryDataTag;
|
||||
import com.jpexs.decompiler.flash.tags.DefineBitsJPEG2Tag;
|
||||
import com.jpexs.decompiler.flash.tags.DefineBitsJPEG3Tag;
|
||||
@@ -192,6 +202,7 @@ import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
import javax.swing.JOptionPane;
|
||||
|
||||
/**
|
||||
*
|
||||
@@ -577,6 +588,27 @@ public class CommandLineArgumentParser {
|
||||
out.println(" ...<swffile>: SWF file to search instance in");
|
||||
}
|
||||
|
||||
if (filter == null || filter.equals("linkreport")) {
|
||||
out.println(" " + (cnt++) + ") -linkReport [-outfile <outfile>] <swffile>");
|
||||
out.println(" ...generates linker report for the swffile");
|
||||
out.println(" ...-outfile <outfile> (optional): Saves XML report to <outfile>. When ommited, the report is printed to stdout.");
|
||||
out.println(" ...<swffile>: SWF file to search instance in");
|
||||
}
|
||||
|
||||
if (filter == null || filter.equals("swf2swc")) {
|
||||
out.println(" " + (cnt++) + ") -swf2swc <outfile> <swffile>");
|
||||
out.println(" ...generates SWC file from SWF");
|
||||
out.println(" ...<outfile>: Where to save SWC file");
|
||||
out.println(" ...<swffile>: Input SWF file");
|
||||
}
|
||||
|
||||
if (filter == null || filter.equals("abcmerge")) {
|
||||
out.println(" " + (cnt++) + ") -abcmerge <outfile> <swffile>");
|
||||
out.println(" ...merge all ABC tags in SWF file to one");
|
||||
out.println(" ...<outfile>: Where to save merged file");
|
||||
out.println(" ...<swffile>: Input SWF file");
|
||||
}
|
||||
|
||||
printCmdLineUsageExamples(out, filter);
|
||||
}
|
||||
|
||||
@@ -792,7 +824,13 @@ public class CommandLineArgumentParser {
|
||||
command = nextParam.substring(1);
|
||||
}
|
||||
|
||||
if (command.equals("getinstancemetadata")) {
|
||||
if (command.equals("abcmerge")) {
|
||||
parseAbcMerge(args);
|
||||
} else if (command.equals("swf2swc")) {
|
||||
parseSwf2Swc(args);
|
||||
} else if (command.equals("linkreport")) {
|
||||
parseLinkReport(selectionClasses, args);
|
||||
} else if (command.equals("getinstancemetadata")) {
|
||||
parseGetInstanceMetadata(args);
|
||||
} else if (command.equals("setinstancemetadata")) {
|
||||
parseSetInstanceMetadata(args);
|
||||
@@ -987,6 +1025,83 @@ public class CommandLineArgumentParser {
|
||||
setConfigurations(args.pop());
|
||||
}
|
||||
|
||||
private static void parseAbcMerge(Stack<String> args) {
|
||||
if (args.size() < 2) {
|
||||
badArguments("abcmerge");
|
||||
}
|
||||
final File outFile = new File(args.pop());
|
||||
final File swfFile = new File(args.pop());
|
||||
processModifySWF(swfFile, outFile, null, (SWF swf, OutputStream stdout) -> {
|
||||
List<ABCContainerTag> abcList = swf.getAbcList();
|
||||
if (!abcList.isEmpty() && abcList.size() > 1) {
|
||||
ABC firstAbc = abcList.get(0).getABC();
|
||||
for (int i = 1; i < abcList.size(); i++) {
|
||||
firstAbc.mergeABC(abcList.get(i).getABC());
|
||||
}
|
||||
for (int i = 1; i < abcList.size(); i++) {
|
||||
swf.removeTag((Tag) abcList.get(i));
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
private static void parseSwf2Swc(Stack<String> args) {
|
||||
if (args.size() < 2) {
|
||||
badArguments("swf2swc");
|
||||
}
|
||||
final File outFile = new File(args.pop());
|
||||
final File swfFile = new File(args.pop());
|
||||
processReadSWF(swfFile, null, (SWF swf, OutputStream stdout) -> {
|
||||
SwfToSwcExporter exporter = new SwfToSwcExporter();
|
||||
exporter.exportSwf(swf, outFile, false);
|
||||
});
|
||||
}
|
||||
|
||||
private static void parseLinkReport(List<String> selectionClasses, Stack<String> args) {
|
||||
if (args.isEmpty()) {
|
||||
badArguments("linkreport");
|
||||
}
|
||||
File stdOutFile = null;
|
||||
File swfFile = null;
|
||||
while (!args.isEmpty()) {
|
||||
String paramName = args.pop().toLowerCase();
|
||||
switch (paramName) {
|
||||
case "-outfile":
|
||||
if (args.empty()) {
|
||||
System.err.println("Missing output file");
|
||||
badArguments("linkreport");
|
||||
}
|
||||
stdOutFile = new File(args.pop());
|
||||
break;
|
||||
default:
|
||||
if (!args.isEmpty()) {
|
||||
badArguments("linkreport");
|
||||
}
|
||||
swfFile = new File(paramName);
|
||||
}
|
||||
}
|
||||
if (swfFile == null) {
|
||||
System.err.println("No SWF file specified");
|
||||
badArguments("getinstancemetadata");
|
||||
}
|
||||
processReadSWF(swfFile, stdOutFile, (SWF swf, OutputStream stdout) -> {
|
||||
LinkReportExporter lre = new LinkReportExporter();
|
||||
|
||||
List<ScriptPack> reportPacks;
|
||||
try {
|
||||
reportPacks = selectionClasses != null ? swf.getScriptPacksByClassNames(selectionClasses) : swf.getAS3Packs();
|
||||
} catch (Exception ex) {
|
||||
System.err.println("Error while getting packs");
|
||||
System.exit(1);
|
||||
return;
|
||||
}
|
||||
|
||||
String reportStr = lre.generateReport(swf, reportPacks, null);
|
||||
stdout.write(reportStr.getBytes("UTF-8"));
|
||||
});
|
||||
}
|
||||
|
||||
private static void parseGetInstanceMetadata(Stack<String> args) {
|
||||
if (args.size() < 3) {
|
||||
badArguments("getinstancemetadata");
|
||||
@@ -3294,6 +3409,13 @@ public class CommandLineArgumentParser {
|
||||
}
|
||||
|
||||
private static void parseImportScript(Stack<String> args) {
|
||||
|
||||
String flexLocation = Configuration.flexSdkLocation.get();
|
||||
if (flexLocation.isEmpty() || (!new File(flexLocation).exists())) {
|
||||
System.err.println("Flex SDK path not set");
|
||||
System.exit(1);
|
||||
}
|
||||
|
||||
if (args.size() < 3) {
|
||||
badArguments("importscript");
|
||||
}
|
||||
@@ -3305,7 +3427,7 @@ public class CommandLineArgumentParser {
|
||||
SWF swf = new SWF(is, Configuration.parallelSpeedUp.get());
|
||||
String scriptsFolder = Path.combine(args.pop(), ScriptExportSettings.EXPORT_FOLDER_NAME);
|
||||
new AS2ScriptImporter().importScripts(scriptsFolder, swf.getASMs(true));
|
||||
new AS3ScriptImporter().importScripts(scriptsFolder, swf.getAS3Packs());
|
||||
new AS3ScriptImporter().importScripts(As3ScriptReplacerFactory.createByConfig(), scriptsFolder, swf.getAS3Packs());
|
||||
|
||||
try {
|
||||
try (OutputStream fos = new BufferedOutputStream(new FileOutputStream(outFile))) {
|
||||
@@ -3436,23 +3558,35 @@ public class CommandLineArgumentParser {
|
||||
private static void replaceAS3(String as, ScriptPack pack) throws IOException, InterruptedException {
|
||||
System.out.println("Replace AS3");
|
||||
System.out.println("Warning: This feature is EXPERIMENTAL");
|
||||
File swc = Configuration.getPlayerSWC();
|
||||
if (swc == null) {
|
||||
final String adobePage = "http://www.adobe.com/support/flashplayer/downloads.html";
|
||||
System.err.println("For ActionScript 3 direct editation, a library called \"PlayerGlobal.swc\" needs to be downloaded from Adobe homepage:");
|
||||
System.err.println(adobePage);
|
||||
System.err.println("Download the library called PlayerGlobal(.swc), and place it to directory");
|
||||
System.err.println(Configuration.getFlashLibPath().getAbsolutePath());
|
||||
As3ScriptReplacerInterface scriptReplacer = As3ScriptReplacerFactory.createByConfig();
|
||||
if (!scriptReplacer.isAvailable()) {
|
||||
System.err.println("Current script replacer is not available.");
|
||||
if (scriptReplacer instanceof FFDecAs3ScriptReplacer) {
|
||||
System.err.println("Current replacer: FFDec");
|
||||
final String adobePage = "http://www.adobe.com/support/flashplayer/downloads.html";
|
||||
System.err.println("For ActionScript 3 direct editation, a library called \"PlayerGlobal.swc\" needs to be downloaded from Adobe homepage:");
|
||||
System.err.println(adobePage);
|
||||
System.err.println("Download the library called PlayerGlobal(.swc), and place it to directory");
|
||||
System.err.println(Configuration.getFlashLibPath().getAbsolutePath());
|
||||
} else if (scriptReplacer instanceof MxmlcAs3ScriptReplacer) {
|
||||
System.err.println("Current replacer: Flex SDK");
|
||||
final String flexPage = "http://www.adobe.com/devnet/flex/flex-sdk-download.html";
|
||||
System.err.println("For ActionScript 3 direct editation, Flex SDK needs to be download");
|
||||
System.err.println(flexPage);
|
||||
System.err.println("Download FLEX Sdk, unzip it to some directory and set its directory path in the configuration");
|
||||
|
||||
} else {
|
||||
|
||||
}
|
||||
System.exit(1);
|
||||
}
|
||||
|
||||
try {
|
||||
pack.abc.replaceScriptPack(pack, as);
|
||||
} catch (AVM2ParseException ex) {
|
||||
System.err.println("%error% on line %line%".replace("%error%", ex.text).replace("%line%", Long.toString(ex.line)));
|
||||
System.exit(1);
|
||||
} catch (CompilationException ex) {
|
||||
System.err.println("%error% on line %line%".replace("%error%", ex.text).replace("%line%", Long.toString(ex.line)));
|
||||
pack.abc.replaceScriptPack(scriptReplacer, pack, as);
|
||||
} catch (As3ScriptReplaceException asre) {
|
||||
for (As3ScriptReplaceExceptionItem item : asre.getExceptionItems()) {
|
||||
logger.log(Level.SEVERE, "%error% on line %line%, column %col%, file: %file%".replace("%error%", item.getMessage()).replace("%line%", Long.toString(item.getLine())).replace("%file%", item.getFile()).replace("%col%", "" + item.getCol()));
|
||||
}
|
||||
System.exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -57,6 +57,7 @@ import javax.swing.Icon;
|
||||
import javax.swing.JButton;
|
||||
import javax.swing.JCheckBox;
|
||||
import javax.swing.JComboBox;
|
||||
import javax.swing.JEditorPane;
|
||||
import javax.swing.JFileChooser;
|
||||
import javax.swing.JFrame;
|
||||
import javax.swing.JLabel;
|
||||
@@ -68,6 +69,8 @@ import javax.swing.JTabbedPane;
|
||||
import javax.swing.JTextField;
|
||||
import javax.swing.SpringLayout;
|
||||
import javax.swing.WindowConstants;
|
||||
import javax.swing.event.HyperlinkEvent;
|
||||
import javax.swing.event.HyperlinkListener;
|
||||
import javax.swing.filechooser.FileFilter;
|
||||
import javax.swing.table.DefaultTableModel;
|
||||
import org.pushingpixels.substance.api.ColorSchemeAssociationKind;
|
||||
@@ -479,24 +482,19 @@ public class AdvancedSettingsDialog extends AppDialog {
|
||||
itemCount, 2, //rows, cols
|
||||
6, 6, //initX, initY
|
||||
6, 6); //xPad, yPad
|
||||
//https://www.adobe.com/support/flashplayer/debug_downloads.html
|
||||
if (resourceBundle.containsKey("config.group.tip." + cat)) {
|
||||
String tip = resourceBundle.getString("config.group.tip." + cat);
|
||||
String url = null;
|
||||
String urls[] = new String[0];
|
||||
if (resourceBundle.containsKey("config.group.link." + cat)) {
|
||||
url = resourceBundle.getString("config.group.link." + cat);
|
||||
urls = resourceBundle.getString("config.group.link." + cat).split(" ");
|
||||
}
|
||||
for (int i = 0; i < urls.length; i++) {
|
||||
tip = tip.replace("%link" + (i + 1) + "%", urls[i]);
|
||||
}
|
||||
JPanel p = new JPanel(new BorderLayout());
|
||||
p.add(configPanel, BorderLayout.CENTER);
|
||||
JPanel tipPanel = new JPanel(new FlowLayout());
|
||||
tipPanel.add(new JLabel("<html><b>" + resourceBundle.getString("tip") + "</b>" + tip + "</html>"));
|
||||
if (url != null) {
|
||||
String linkText = url;
|
||||
if (resourceBundle.containsKey("config.group.linkText." + cat)) {
|
||||
linkText = resourceBundle.getString("config.group.linkText." + cat);
|
||||
}
|
||||
tipPanel.add(new LinkLabel(linkText, url));
|
||||
}
|
||||
tipPanel.add(new HtmlLabel("<b>" + resourceBundle.getString("tip") + "</b>" + tip));
|
||||
p.add(tipPanel, BorderLayout.SOUTH);
|
||||
configPanel = p;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,63 @@
|
||||
/*
|
||||
* Copyright (C) 2016 Jindra
|
||||
*
|
||||
* 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.gui;
|
||||
|
||||
import java.awt.Color;
|
||||
import javax.swing.JEditorPane;
|
||||
import javax.swing.JLabel;
|
||||
import javax.swing.event.HyperlinkEvent;
|
||||
|
||||
public class HtmlLabel extends JEditorPane {
|
||||
|
||||
private JLabel label = new JLabel();
|
||||
private String rawText;
|
||||
|
||||
public HtmlLabel() {
|
||||
this("");
|
||||
}
|
||||
|
||||
public HtmlLabel(String text) {
|
||||
super("text/html", "");
|
||||
setText(text);
|
||||
setEditable(false);
|
||||
setFocusable(false);
|
||||
setOpaque(false);
|
||||
addHyperlinkListener((HyperlinkEvent hle) -> {
|
||||
if (HyperlinkEvent.EventType.ACTIVATED.equals(hle.getEventType())) {
|
||||
View.navigateUrl(hle.getURL().toString());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setText(String t) {
|
||||
String modText = t;
|
||||
if (!t.equals("")) {
|
||||
Color fgColor = label.getForeground();
|
||||
|
||||
modText = "<body style=\"font-size:" + label.getFont().getSize() + "pt; font-family: " + label.getFont().getFamily() + "; color:rgb(" + fgColor.getRed() + "," + fgColor.getGreen() + "," + fgColor.getBlue() + ");\">" + t + "</body>";
|
||||
}
|
||||
this.rawText = t;
|
||||
super.setText(modText);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getText() {
|
||||
return rawText;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -99,50 +99,48 @@ public class LicenseUpdater {
|
||||
for (File f : files) {
|
||||
if (f.isDirectory()) {
|
||||
updateLicenseInDir(f, lgpl);
|
||||
} else {
|
||||
if (f.getName().endsWith(".java")) {
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
PrintWriter pw = new Utf8PrintWriter(baos);
|
||||
try {
|
||||
try (BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(f), Utf8Helper.charset))) {
|
||||
String s;
|
||||
boolean packageFound = false;
|
||||
String author = defaultAuthor;
|
||||
String yearStr = defaultYearStr;
|
||||
while ((s = br.readLine()) != null) {
|
||||
if (!packageFound) {
|
||||
if (s.trim().startsWith("package")) {
|
||||
packageFound = true;
|
||||
pw.println(license.replace("{year}", yearStr).replace("{author}", author));
|
||||
} else {
|
||||
Matcher mAuthor = Pattern.compile(lgpl ? "^.*Copyright \\(C\\) ([0-9]+)(-[0-9]+)? (.*), All rights reserved.*" : "^.*Copyright \\(C\\) ([0-9]+)(-[0-9]+)? (.*)$").matcher(s);
|
||||
if (mAuthor.matches()) {
|
||||
author = mAuthor.group(3).trim();
|
||||
int startYear = Integer.parseInt(mAuthor.group(1).trim());
|
||||
if (startYear == defaultFinalYear) {
|
||||
yearStr = Integer.toString(startYear);
|
||||
} else {
|
||||
yearStr = Integer.toString(startYear) + "-" + defaultFinalYear;
|
||||
}
|
||||
if (!author.equals(defaultAuthor)) {
|
||||
System.out.println("Detected nodefault author:" + author + " in " + f.getAbsolutePath());
|
||||
}
|
||||
} else if (f.getName().endsWith(".java")) {
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
PrintWriter pw = new Utf8PrintWriter(baos);
|
||||
try {
|
||||
try (BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(f), Utf8Helper.charset))) {
|
||||
String s;
|
||||
boolean packageFound = false;
|
||||
String author = defaultAuthor;
|
||||
String yearStr = defaultYearStr;
|
||||
while ((s = br.readLine()) != null) {
|
||||
if (!packageFound) {
|
||||
if (s.trim().startsWith("package")) {
|
||||
packageFound = true;
|
||||
pw.println(license.replace("{year}", yearStr).replace("{author}", author));
|
||||
} else {
|
||||
Matcher mAuthor = Pattern.compile(lgpl ? "^.*Copyright \\(C\\) ([0-9]+)(-[0-9]+)? (.*), All rights reserved.*" : "^.*Copyright \\(C\\) ([0-9]+)(-[0-9]+)? (.*)$").matcher(s);
|
||||
if (mAuthor.matches()) {
|
||||
author = mAuthor.group(3).trim();
|
||||
int startYear = Integer.parseInt(mAuthor.group(1).trim());
|
||||
if (startYear == defaultFinalYear) {
|
||||
yearStr = Integer.toString(startYear);
|
||||
} else {
|
||||
yearStr = Integer.toString(startYear) + "-" + defaultFinalYear;
|
||||
}
|
||||
if (!author.equals(defaultAuthor)) {
|
||||
System.out.println("Detected nodefault author:" + author + " in " + f.getAbsolutePath());
|
||||
}
|
||||
}
|
||||
}
|
||||
if (packageFound) {
|
||||
pw.println(s);
|
||||
}
|
||||
}
|
||||
if (packageFound) {
|
||||
pw.println(s);
|
||||
}
|
||||
}
|
||||
pw.close();
|
||||
} catch (IOException ex) {
|
||||
}
|
||||
pw.close();
|
||||
} catch (IOException ex) {
|
||||
}
|
||||
|
||||
try (OutputStream fos = new BufferedOutputStream(new FileOutputStream(f))) {
|
||||
fos.write(baos.toByteArray());
|
||||
} catch (IOException ex) {
|
||||
}
|
||||
try (OutputStream fos = new BufferedOutputStream(new FileOutputStream(f))) {
|
||||
fos.write(baos.toByteArray());
|
||||
} catch (IOException ex) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -100,10 +100,8 @@ public class LoadingDialog extends AppDialog {
|
||||
public void windowClosing(WindowEvent e) {
|
||||
if (Main.shouldCloseWhenClosingLoadingDialog) {
|
||||
System.exit(0);
|
||||
} else {
|
||||
if (worker != null) {
|
||||
worker.cancel(true);
|
||||
}
|
||||
} else if (worker != null) {
|
||||
worker.cancel(true);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
@@ -73,6 +73,7 @@ import com.jpexs.decompiler.flash.exporters.settings.SpriteExportSettings;
|
||||
import com.jpexs.decompiler.flash.exporters.settings.TextExportSettings;
|
||||
import com.jpexs.decompiler.flash.exporters.swf.SwfJavaExporter;
|
||||
import com.jpexs.decompiler.flash.exporters.swf.SwfXmlExporter;
|
||||
import com.jpexs.decompiler.flash.flexsdk.MxmlcAs3ScriptReplacer;
|
||||
import com.jpexs.decompiler.flash.gui.abc.ABCPanel;
|
||||
import com.jpexs.decompiler.flash.gui.abc.ABCPanelSearchResult;
|
||||
import com.jpexs.decompiler.flash.gui.abc.ClassesListTreeModel;
|
||||
@@ -94,7 +95,10 @@ import com.jpexs.decompiler.flash.helpers.FileTextWriter;
|
||||
import com.jpexs.decompiler.flash.helpers.Freed;
|
||||
import com.jpexs.decompiler.flash.importers.AS2ScriptImporter;
|
||||
import com.jpexs.decompiler.flash.importers.AS3ScriptImporter;
|
||||
import com.jpexs.decompiler.flash.importers.As3ScriptReplacerFactory;
|
||||
import com.jpexs.decompiler.flash.importers.As3ScriptReplacerInterface;
|
||||
import com.jpexs.decompiler.flash.importers.BinaryDataImporter;
|
||||
import com.jpexs.decompiler.flash.importers.FFDecAs3ScriptReplacer;
|
||||
import com.jpexs.decompiler.flash.importers.ImageImporter;
|
||||
import com.jpexs.decompiler.flash.importers.ShapeImporter;
|
||||
import com.jpexs.decompiler.flash.importers.SwfXmlImporter;
|
||||
@@ -861,11 +865,7 @@ public final class MainPanel extends JPanel implements TreeSelectionListener, Se
|
||||
? translate("message.confirm.closeAll")
|
||||
: translate("message.confirm.close").replace("{swfName}", swfList.toString());
|
||||
|
||||
if (View.showConfirmDialog(this, message, translate("message.warning"), JOptionPane.OK_CANCEL_OPTION, Configuration.showCloseConfirmation, JOptionPane.OK_OPTION) != JOptionPane.OK_OPTION) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
return View.showConfirmDialog(this, message, translate("message.warning"), JOptionPane.OK_CANCEL_OPTION, Configuration.showCloseConfirmation, JOptionPane.OK_OPTION) == JOptionPane.OK_OPTION;
|
||||
}
|
||||
|
||||
public boolean isModified() {
|
||||
@@ -2143,7 +2143,32 @@ public final class MainPanel extends JPanel implements TreeSelectionListener, Se
|
||||
}
|
||||
}
|
||||
|
||||
public As3ScriptReplacerInterface getAs3ScriptReplacer() {
|
||||
As3ScriptReplacerInterface r = As3ScriptReplacerFactory.createByConfig();
|
||||
if (!r.isAvailable()) {
|
||||
if (r instanceof MxmlcAs3ScriptReplacer) {
|
||||
if (View.showConfirmDialog(null, AppStrings.translate("message.flexpath.notset"), AppStrings.translate("error"), JOptionPane.OK_CANCEL_OPTION, JOptionPane.WARNING_MESSAGE) == JOptionPane.OK_OPTION) {
|
||||
Main.advancedSettings("paths");
|
||||
}
|
||||
} else if (r instanceof FFDecAs3ScriptReplacer) {
|
||||
if (View.showConfirmDialog(this, AppStrings.translate("message.playerpath.lib.notset"), AppStrings.translate("message.action.playerglobal.title"), JOptionPane.OK_CANCEL_OPTION, JOptionPane.WARNING_MESSAGE) == JOptionPane.OK_OPTION) {
|
||||
Main.advancedSettings("paths");
|
||||
}
|
||||
} else {
|
||||
//Not translated yet - just in case there are more Script replacers in the future. Unused now.
|
||||
View.showConfirmDialog(this, "Current script replacer is not available", "Script replacer not available", JOptionPane.OK_OPTION, JOptionPane.ERROR_MESSAGE);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
public void importScript(final SWF swf) {
|
||||
As3ScriptReplacerInterface as3ScriptReplacer = getAs3ScriptReplacer();
|
||||
if (as3ScriptReplacer == null) {
|
||||
return;
|
||||
}
|
||||
String flexLocation = Configuration.flexSdkLocation.get();
|
||||
JFileChooser chooser = new JFileChooser();
|
||||
chooser.setCurrentDirectory(new File(Configuration.lastExportDir.get()));
|
||||
chooser.setDialogTitle(translate("import.select.directory"));
|
||||
@@ -2154,7 +2179,7 @@ public final class MainPanel extends JPanel implements TreeSelectionListener, Se
|
||||
String scriptsFolder = Path.combine(selFile, ScriptExportSettings.EXPORT_FOLDER_NAME);
|
||||
|
||||
int countAs2 = new AS2ScriptImporter().importScripts(scriptsFolder, swf.getASMs(true));
|
||||
int countAs3 = new AS3ScriptImporter().importScripts(scriptsFolder, swf.getAS3Packs());
|
||||
int countAs3 = new AS3ScriptImporter().importScripts(as3ScriptReplacer, scriptsFolder, swf.getAS3Packs());
|
||||
|
||||
if (countAs3 > 0) {
|
||||
updateClassesList();
|
||||
|
||||
@@ -55,65 +55,65 @@ public class MyRibbonApplicationMenuPopupPanelUI extends BasicRibbonApplicationM
|
||||
super.installComponents();
|
||||
Border newBorder = new CompoundBorder(new SubstanceBorder(new Insets(2,
|
||||
2, 2, 2)), new Border() {
|
||||
@Override
|
||||
public boolean isBorderOpaque() {
|
||||
return true;
|
||||
}
|
||||
@Override
|
||||
public boolean isBorderOpaque() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Insets getBorderInsets(Component c) {
|
||||
return new Insets(18, 0, 0, 0);
|
||||
}
|
||||
@Override
|
||||
public Insets getBorderInsets(Component c) {
|
||||
return new Insets(18, 0, 0, 0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void paintBorder(Component c, Graphics g, int x, int y,
|
||||
int width, int height) {
|
||||
SubstanceColorScheme bgFillScheme = SubstanceColorSchemeUtilities
|
||||
@Override
|
||||
public void paintBorder(Component c, Graphics g, int x, int y,
|
||||
int width, int height) {
|
||||
SubstanceColorScheme bgFillScheme = SubstanceColorSchemeUtilities
|
||||
.getColorScheme(c,
|
||||
ColorSchemeAssociationKind.HIGHLIGHT,
|
||||
ComponentState.ENABLED);
|
||||
SubstanceColorScheme bgBorderScheme = SubstanceColorSchemeUtilities
|
||||
SubstanceColorScheme bgBorderScheme = SubstanceColorSchemeUtilities
|
||||
.getColorScheme(c,
|
||||
ColorSchemeAssociationKind.HIGHLIGHT_BORDER,
|
||||
ComponentState.ENABLED);
|
||||
HighlightPainterUtils.paintHighlight(g, null, c, new Rectangle(
|
||||
x, y, width, height), 0.0f, null, bgFillScheme,
|
||||
bgBorderScheme);
|
||||
HighlightPainterUtils.paintHighlight(g, null, c, new Rectangle(
|
||||
x, y, width, height), 0.0f, null, bgFillScheme,
|
||||
bgBorderScheme);
|
||||
|
||||
// draw the application menu button
|
||||
JRibbonApplicationMenuButton rendererButton = new JRibbonApplicationMenuButton(
|
||||
applicationMenuPopupPanel.getAppMenuButton()
|
||||
.getRibbon());
|
||||
// draw the application menu button
|
||||
JRibbonApplicationMenuButton rendererButton = new JRibbonApplicationMenuButton(
|
||||
applicationMenuPopupPanel.getAppMenuButton()
|
||||
.getRibbon());
|
||||
|
||||
JRibbonApplicationMenuButton appMenuButton = applicationMenuPopupPanel
|
||||
JRibbonApplicationMenuButton appMenuButton = applicationMenuPopupPanel
|
||||
.getAppMenuButton();
|
||||
rendererButton.applyComponentOrientation(appMenuButton
|
||||
.getComponentOrientation());
|
||||
rendererButton.applyComponentOrientation(appMenuButton
|
||||
.getComponentOrientation());
|
||||
|
||||
rendererButton.setPopupKeyTip(appMenuButton.getPopupKeyTip());
|
||||
rendererButton.getPopupModel().setPopupShowing(true);
|
||||
rendererButton.setDisplayState(appMenuButton.getDisplayState());
|
||||
rendererButton.setPopupKeyTip(appMenuButton.getPopupKeyTip());
|
||||
rendererButton.getPopupModel().setPopupShowing(true);
|
||||
rendererButton.setDisplayState(appMenuButton.getDisplayState());
|
||||
|
||||
rendererButton.getPopupModel().setRollover(false);
|
||||
rendererButton.getPopupModel().setPressed(true);
|
||||
rendererButton.getPopupModel().setArmed(true);
|
||||
rendererButton.getPopupModel().setRollover(false);
|
||||
rendererButton.getPopupModel().setPressed(true);
|
||||
rendererButton.getPopupModel().setArmed(true);
|
||||
|
||||
CellRendererPane buttonRendererPane = new CellRendererPane();
|
||||
Point buttonLoc = appMenuButton.getLocationOnScreen();
|
||||
Point panelLoc = c.getLocationOnScreen();
|
||||
CellRendererPane buttonRendererPane = new CellRendererPane();
|
||||
Point buttonLoc = appMenuButton.getLocationOnScreen();
|
||||
Point panelLoc = c.getLocationOnScreen();
|
||||
|
||||
buttonRendererPane.setBounds(panelLoc.x - buttonLoc.x,
|
||||
panelLoc.y - buttonLoc.y, appMenuButton.getWidth(),
|
||||
appMenuButton.getHeight());
|
||||
buttonRendererPane.setBounds(panelLoc.x - buttonLoc.x,
|
||||
panelLoc.y - buttonLoc.y, appMenuButton.getWidth(),
|
||||
appMenuButton.getHeight());
|
||||
|
||||
buttonRendererPane.paintComponent(g, rendererButton,
|
||||
(Container) c, -panelLoc.x + buttonLoc.x, -panelLoc.y
|
||||
+ buttonLoc.y, appMenuButton.getWidth(),
|
||||
appMenuButton.getHeight(), true);
|
||||
/*g.setColor(Color.red);
|
||||
buttonRendererPane.paintComponent(g, rendererButton,
|
||||
(Container) c, -panelLoc.x + buttonLoc.x, -panelLoc.y
|
||||
+ buttonLoc.y, appMenuButton.getWidth(),
|
||||
appMenuButton.getHeight(), true);
|
||||
/*g.setColor(Color.red);
|
||||
g.fillRect(0, 0, width,height);*/
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
this.applicationMenuPopupPanel.setBorder(newBorder);
|
||||
|
||||
this.panelLevel2.setBorder(new Border() {
|
||||
|
||||
@@ -186,13 +186,13 @@ public class OceanicSkin extends SubstanceSkin {
|
||||
|
||||
this.addOverlayPainter(new BottomLineOverlayPainter(
|
||||
new ColorSchemeSingleColorQuery() {
|
||||
@Override
|
||||
public Color query(SubstanceColorScheme scheme) {
|
||||
Color fg = scheme.getForegroundColor();
|
||||
return new Color(fg.getRed(), fg.getGreen(), fg
|
||||
.getBlue(), 72);
|
||||
}
|
||||
}), DecorationAreaType.PRIMARY_TITLE_PANE,
|
||||
@Override
|
||||
public Color query(SubstanceColorScheme scheme) {
|
||||
Color fg = scheme.getForegroundColor();
|
||||
return new Color(fg.getRed(), fg.getGreen(), fg
|
||||
.getBlue(), 72);
|
||||
}
|
||||
}), DecorationAreaType.PRIMARY_TITLE_PANE,
|
||||
DecorationAreaType.SECONDARY_TITLE_PANE);
|
||||
|
||||
this.buttonShaper = new ClassicButtonShaper();
|
||||
@@ -216,12 +216,12 @@ public class OceanicSkin extends SubstanceSkin {
|
||||
"Oceanic Inner", outerBorderPainter, new int[]{
|
||||
0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF},
|
||||
new ColorSchemeTransform() {
|
||||
@Override
|
||||
public SubstanceColorScheme transform(
|
||||
SubstanceColorScheme scheme) {
|
||||
return scheme.tint(0.8f);
|
||||
}
|
||||
});
|
||||
@Override
|
||||
public SubstanceColorScheme transform(
|
||||
SubstanceColorScheme scheme) {
|
||||
return scheme.tint(0.8f);
|
||||
}
|
||||
});
|
||||
this.borderPainter = new CompositeBorderPainter("Oceanic",
|
||||
outerBorderPainter, innerBorderPainter);
|
||||
|
||||
|
||||
@@ -27,7 +27,6 @@ import com.jpexs.decompiler.flash.abc.ScriptPack;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.AVM2Code;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.AVM2Instruction;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.AVM2Instructions;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.parser.AVM2ParseException;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.parser.script.Reference;
|
||||
import com.jpexs.decompiler.flash.abc.types.ABCException;
|
||||
import com.jpexs.decompiler.flash.abc.types.MethodBody;
|
||||
@@ -69,10 +68,12 @@ import com.jpexs.decompiler.flash.gui.abc.tablemodels.UIntTableModel;
|
||||
import com.jpexs.decompiler.flash.gui.controls.JPersistentSplitPane;
|
||||
import com.jpexs.decompiler.flash.gui.editor.LinkHandler;
|
||||
import com.jpexs.decompiler.flash.gui.tagtree.TagTreeModel;
|
||||
import com.jpexs.decompiler.flash.importers.As3ScriptReplaceException;
|
||||
import com.jpexs.decompiler.flash.importers.As3ScriptReplaceExceptionItem;
|
||||
import com.jpexs.decompiler.flash.importers.As3ScriptReplacerInterface;
|
||||
import com.jpexs.decompiler.flash.tags.ABCContainerTag;
|
||||
import com.jpexs.decompiler.flash.tags.Tag;
|
||||
import com.jpexs.decompiler.flash.treeitems.TreeItem;
|
||||
import com.jpexs.decompiler.graph.CompilationException;
|
||||
import com.jpexs.helpers.CancellableWorker;
|
||||
import com.jpexs.helpers.Helper;
|
||||
import de.hameister.treetable.MyTreeTable;
|
||||
@@ -116,6 +117,7 @@ import javax.swing.JTabbedPane;
|
||||
import javax.swing.JTable;
|
||||
import javax.swing.JToggleButton;
|
||||
import javax.swing.SwingConstants;
|
||||
import javax.swing.SwingWorker;
|
||||
import javax.swing.border.BevelBorder;
|
||||
import javax.swing.event.EventListenerList;
|
||||
import javax.swing.event.TableModelListener;
|
||||
@@ -134,6 +136,9 @@ import jsyntaxpane.TokenType;
|
||||
*/
|
||||
public class ABCPanel extends JPanel implements ItemListener, SearchListener<ABCPanelSearchResult>, TagEditorPanel {
|
||||
|
||||
private As3ScriptReplacerInterface scriptReplacer = null;
|
||||
private ScriptPack pack = null;
|
||||
|
||||
private final MainPanel mainPanel;
|
||||
|
||||
public final TraitsList navigator;
|
||||
@@ -1150,36 +1155,40 @@ public class ABCPanel extends JPanel implements ItemListener, SearchListener<ABC
|
||||
}
|
||||
|
||||
private void editDecompiledButtonActionPerformed(ActionEvent evt) {
|
||||
File swc = Configuration.getPlayerSWC();
|
||||
if (swc == null || !swc.exists()) {
|
||||
if (View.showConfirmDialog(this, AppStrings.translate("message.playerpath.lib.notset"), AppStrings.translate("message.action.playerglobal.title"), JOptionPane.OK_CANCEL_OPTION, JOptionPane.INFORMATION_MESSAGE) == JOptionPane.OK_OPTION) {
|
||||
Main.advancedSettings("paths");
|
||||
return;
|
||||
}
|
||||
scriptReplacer = mainPanel.getAs3ScriptReplacer();
|
||||
if (scriptReplacer == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (View.showConfirmDialog(null, AppStrings.translate("message.confirm.experimental.function"), AppStrings.translate("message.warning"), JOptionPane.OK_CANCEL_OPTION, JOptionPane.WARNING_MESSAGE, Configuration.warningExperimentalAS3Edit, JOptionPane.OK_OPTION) == JOptionPane.OK_OPTION) {
|
||||
pack = decompiledTextArea.getScriptLeaf();
|
||||
setDecompiledEditMode(true);
|
||||
SwingWorker initReplaceWorker = new SwingWorker() {
|
||||
@Override
|
||||
protected Object doInBackground() throws Exception {
|
||||
scriptReplacer.initReplacement(pack);
|
||||
return null;
|
||||
}
|
||||
};
|
||||
initReplaceWorker.execute();
|
||||
}
|
||||
}
|
||||
|
||||
private void cancelDecompiledButtonActionPerformed(ActionEvent evt) {
|
||||
setDecompiledEditMode(false);
|
||||
if (scriptReplacer != null) {
|
||||
scriptReplacer.deinitReplacement(pack);
|
||||
}
|
||||
}
|
||||
|
||||
private void saveDecompiledButtonActionPerformed(ActionEvent evt) {
|
||||
ScriptPack pack = decompiledTextArea.getScriptLeaf();
|
||||
int oldIndex = pack.scriptIndex;
|
||||
SWF.uncache(pack);
|
||||
|
||||
try {
|
||||
String oldSp = pack.getClassPath().toRawString();
|
||||
/*List<ScriptPack> packs = abc.script_info.get(oldIndex).getPacks(abc, oldIndex, null, pack.allABCs);
|
||||
if (!packs.isEmpty()) {
|
||||
|
||||
}*/
|
||||
|
||||
String as = decompiledTextArea.getText();
|
||||
abc.replaceScriptPack(pack, as);
|
||||
abc.replaceScriptPack(scriptReplacer, pack, as);
|
||||
scriptReplacer.deinitReplacement(pack);
|
||||
lastDecompiled = as;
|
||||
setDecompiledEditMode(false);
|
||||
mainPanel.updateClassesList();
|
||||
@@ -1190,20 +1199,35 @@ public class ABCPanel extends JPanel implements ItemListener, SearchListener<ABC
|
||||
|
||||
reload();
|
||||
View.showMessageDialog(this, AppStrings.translate("message.action.saved"), AppStrings.translate("dialog.message.title"), JOptionPane.INFORMATION_MESSAGE, Configuration.showCodeSavedMessage);
|
||||
} catch (AVM2ParseException ex) {
|
||||
} catch (As3ScriptReplaceException asre) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
int firstErrorLine = As3ScriptReplaceExceptionItem.LINE_UNKNOWN;
|
||||
int firstErrorCol = As3ScriptReplaceExceptionItem.COL_UNKNOWN;
|
||||
abc.script_info.get(oldIndex).delete(abc, false);
|
||||
decompiledTextArea.gotoLine((int) ex.line);
|
||||
decompiledTextArea.markError();
|
||||
View.showMessageDialog(this, AppStrings.translate("error.action.save").replace("%error%", ex.text).replace("%line%", Long.toString(ex.line)), AppStrings.translate("error"), JOptionPane.ERROR_MESSAGE);
|
||||
} catch (CompilationException ex) {
|
||||
abc.script_info.get(oldIndex).delete(abc, false);
|
||||
decompiledTextArea.gotoLine((int) ex.line);
|
||||
decompiledTextArea.markError();
|
||||
View.showMessageDialog(this, AppStrings.translate("error.action.save").replace("%error%", ex.text).replace("%line%", Long.toString(ex.line)), AppStrings.translate("error"), JOptionPane.ERROR_MESSAGE);
|
||||
|
||||
for (As3ScriptReplaceExceptionItem item : asre.getExceptionItems()) {
|
||||
if (firstErrorLine == As3ScriptReplaceExceptionItem.LINE_UNKNOWN) {
|
||||
firstErrorLine = item.getLine();
|
||||
firstErrorCol = item.getCol();
|
||||
}
|
||||
sb.append(item.getFile()).append(":").append(item.getLine()).append(" (column ").append(item.getCol()).append(")").append(":").append("\n");
|
||||
sb.append(" ").append(item.getMessage());
|
||||
sb.append("\n");
|
||||
sb.append("\n");
|
||||
}
|
||||
if (firstErrorLine != As3ScriptReplaceExceptionItem.LINE_UNKNOWN) {
|
||||
if (firstErrorCol != As3ScriptReplaceExceptionItem.COL_UNKNOWN) {
|
||||
decompiledTextArea.gotoLineCol(firstErrorLine, firstErrorCol);
|
||||
} else {
|
||||
decompiledTextArea.gotoLine(firstErrorLine);
|
||||
}
|
||||
decompiledTextArea.markError();
|
||||
}
|
||||
//View.showMessageDialog(this, AppStrings.translate("error.action.save").replace("%error%", ex.text).replace("%line%", Long.toString(ex.line)), AppStrings.translate("error"), JOptionPane.ERROR_MESSAGE);
|
||||
View.showMessageDialog(this, sb.toString(), AppStrings.translate("error"), JOptionPane.ERROR_MESSAGE);
|
||||
decompiledTextArea.requestFocus();
|
||||
} catch (Throwable ex) {
|
||||
Logger.getLogger(ABCPanel.class
|
||||
.getName()).log(Level.SEVERE, null, ex);
|
||||
Logger.getLogger(ABCPanel.class.getName()).log(Level.SEVERE, null, ex);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -225,10 +225,8 @@ public class DetailPanel extends JPanel implements TagEditorPanel {
|
||||
selectedLabel.setText(AppStrings.translate(name));
|
||||
if (trait == null) {
|
||||
traitNameLabel.setText("-");
|
||||
} else {
|
||||
if (abcPanel != null) {
|
||||
traitNameLabel.setText(trait.getName(abcPanel.abc).getName(abcPanel.abc.constants, null, false));
|
||||
}
|
||||
} else if (abcPanel != null) {
|
||||
traitNameLabel.setText(trait.getName(abcPanel.abc).getName(abcPanel.abc.constants, null, false));
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
@@ -218,6 +218,10 @@ public class LineMarkedEditorPane extends UndoFixedEditorPane implements LinkHan
|
||||
setCaretPosition(ActionUtils.getDocumentPosition(this, line, 0));
|
||||
}
|
||||
|
||||
public void gotoLineCol(int line, int column) {
|
||||
setCaretPosition(ActionUtils.getDocumentPosition(this, line, column));
|
||||
}
|
||||
|
||||
public Point getLineLocation(int line) {
|
||||
int pos = ActionUtils.getDocumentPosition(this, line + 1, 0);
|
||||
if (pos < 0) {
|
||||
|
||||
@@ -114,11 +114,9 @@ public class UndoFixedEditorPane extends JEditorPane {
|
||||
contentType = "text/plain";
|
||||
originalContentType = getContentType();
|
||||
changeContentType(contentType);
|
||||
} else {
|
||||
if (originalContentType != null) {
|
||||
changeContentType(originalContentType);
|
||||
originalContentType = null;
|
||||
}
|
||||
} else if (originalContentType != null) {
|
||||
changeContentType(originalContentType);
|
||||
originalContentType = null;
|
||||
}
|
||||
|
||||
Stopwatch sw = Stopwatch.startNew();
|
||||
|
||||
@@ -379,9 +379,8 @@ config.description.lastSessionFileTitles = Contains the opened file titles from
|
||||
|
||||
config.group.name.paths = Paths
|
||||
config.group.description.paths = Location of needed files
|
||||
config.group.tip.paths = You can download these files on adobe webpage
|
||||
config.group.link.paths = https://www.adobe.com/support/flashplayer/debug_downloads.html
|
||||
config.group.linkText.paths = [visit]
|
||||
config.group.tip.paths = Download projector and Playerglobal on <a href="%link1%">adobe webpage</a>. Flex SDK can be downloaded on <a href="%link2%">adobe devnet</a>.
|
||||
config.group.link.paths = https://www.adobe.com/support/flashplayer/debug_downloads.html http://www.adobe.com/devnet/flex/flex-sdk-download.html
|
||||
|
||||
config.name.playerLocation = 1) Flash Player projector path
|
||||
config.description.playerLocation = Location of standalone flash player executable. Used for Run action.
|
||||
@@ -432,3 +431,9 @@ config.description.simplifyExpressions = Evaluate and simplify expressions to ma
|
||||
|
||||
config.name.resetLetterSpacingOnTextImport = Reset Letter Spacing on text import
|
||||
config.description.resetLetterSpacingOnTextImport = Useful for cyrillic fonts, because they are wider
|
||||
|
||||
config.name.flexSdkLocation = 4) Flex SDK directory path
|
||||
config.description.flexSdkLocation = Location of Adobe Flex SDK. It is used mostly for AS3 compilation.
|
||||
|
||||
config.name.useFlexAs3Compiler = Use Flex SDK AS3 compiler
|
||||
config.description.useFlexAs3Compiler = Use AS3 compiler from Flex SDK while ActionScript direct editation (Flex SDK directory needs to be set)
|
||||
@@ -363,9 +363,8 @@ config.description.lastSessionFileTitles = Obsahuje titulky souboru z naposledy
|
||||
config.group.name.paths = Cesty
|
||||
config.group.description.paths = Um\u00edst\u011bn\u00ed pot\u0159ebn\u00fdch soubor\u016f
|
||||
|
||||
config.group.tip.paths = Tyto soubory m\u016f\u017eete st\u00e1hnout na str\u00e1nk\u00e1ch adobe
|
||||
config.group.link.paths = https://www.adobe.com/support/flashplayer/debug_downloads.html
|
||||
config.group.linkText.paths = [nav\u0161t\u00edvit]
|
||||
config.group.tip.paths = Stahn\u011bte si projector a Playerglobal na <a href="%link1%">str\u00e1nk\u00e1ch adobe</a>. Flex SDK lze stahnout na <a href="%link2%">webu adobe devnet</a>.
|
||||
config.group.link.paths = https://www.adobe.com/support/flashplayer/debug_downloads.html http://www.adobe.com/devnet/flex/flex-sdk-download.html
|
||||
|
||||
config.name.playerLocation = 1) Cesta k Flash Player projectoru
|
||||
config.description.playerLocation = Um\u00edst\u011bn\u00ed spustiteln\u00e9ho flash playeru. Pou\u017e\u00edvan\u00e9 pro akci Spustit.
|
||||
|
||||
@@ -379,9 +379,10 @@ config.description.lastSessionFileTitles = Contiene los t\u00edtulos de archivoa
|
||||
|
||||
config.group.name.paths = Rutas
|
||||
config.group.description.paths = Ubicaci\u00f3n de los archivos necesarios
|
||||
config.group.tip.paths = Usted puede bajar estos archivos desde la p\u00e1gina web de Adobe
|
||||
config.group.link.paths = https://www.adobe.com/support/flashplayer/debug_downloads.html
|
||||
config.group.linkText.paths = [visita]
|
||||
#config.group.tip.paths = Usted puede bajar estos archivos desde la p\u00e1gina web de Adobe
|
||||
#TODO: translate again:
|
||||
config.group.tip.paths = Download projector and Playerglobal on <a href="%link1%">adobe webpage</a>. Flex SDK can be downloaded on <a href="%link2%">adobe devnet</a>.
|
||||
config.group.link.paths = https://www.adobe.com/support/flashplayer/debug_downloads.html http://www.adobe.com/devnet/flex/flex-sdk-download.html
|
||||
|
||||
config.name.playerLocation = 1) Ruta de Flash Player projector
|
||||
config.description.playerLocation = Ubicaci\u00f3n del ejecutable aut\u00f3nomo de Flash Player. Utilizado para la acci\u00f3n Correr.
|
||||
|
||||
@@ -379,9 +379,10 @@ config.description.lastSessionFileTitles = Comprend les titres des fichiers ouve
|
||||
|
||||
config.group.name.paths = Chemins
|
||||
config.group.description.paths = Location des fichiers demand\u00e9s
|
||||
config.group.tip.paths = Vous pouvez t\u00e9l\u00e9charger ces fichiers depuis le site web d'Adobe
|
||||
config.group.link.paths = https://www.adobe.com/support/flashplayer/debug_downloads.html
|
||||
config.group.linkText.paths = [visiter]
|
||||
#config.group.tip.paths = Vous pouvez t\u00e9l\u00e9charger ces fichiers depuis le site web d'Adobe
|
||||
#TODO: translate again:
|
||||
config.group.tip.paths = Download projector and Playerglobal on <a href="%link1%">adobe webpage</a>. Flex SDK can be downloaded on <a href="%link2%">adobe devnet</a>.
|
||||
config.group.link.paths = https://www.adobe.com/support/flashplayer/debug_downloads.html http://www.adobe.com/devnet/flex/flex-sdk-download.html
|
||||
|
||||
config.name.playerLocation = 1) Chemin du lecteur Flash
|
||||
config.description.playerLocation = Location du lecteur autonome de fichier ex\u00e9cutable Flash. Used for Run action.
|
||||
|
||||
@@ -379,9 +379,10 @@ config.description.lastSessionFileTitles = Tartalmazza az utols\u00f3 munkamenet
|
||||
|
||||
config.group.name.paths = \u00datvonalak
|
||||
config.group.description.paths = A sz\u00fcks\u00e9ges f\u00e1jlok el\u00e9rhet\u0151s\u00e9gei
|
||||
config.group.tip.paths = Ezeket a f\u00e1jlokat az Adobe honlapj\u00e1r\u00f3l t\u00f6ltheti le
|
||||
config.group.link.paths = https://www.adobe.com/support/flashplayer/debug_downloads.html
|
||||
config.group.linkText.paths = [visit]
|
||||
#config.group.tip.paths = Ezeket a f\u00e1jlokat az Adobe honlapj\u00e1r\u00f3l t\u00f6ltheti le
|
||||
#TODO: translate again:
|
||||
config.group.tip.paths = Download projector and Playerglobal on <a href="%link1%">adobe webpage</a>. Flex SDK can be downloaded on <a href="%link2%">adobe devnet</a>.
|
||||
config.group.link.paths = https://www.adobe.com/support/flashplayer/debug_downloads.html http://www.adobe.com/devnet/flex/flex-sdk-download.html
|
||||
|
||||
config.name.playerLocation = 1) Flash Player projector \u00fatvonal
|
||||
config.description.playerLocation = Standalone flash player helye. A Futtat\u00e1shoz sz\u00fcks\u00e9ges.
|
||||
|
||||
@@ -379,9 +379,10 @@ config.description.lastSessionFileTitles = Contiene i titoli dei file aperti nel
|
||||
|
||||
config.group.name.paths = Percorsi
|
||||
config.group.description.paths = Ubicazione dei file richiesti
|
||||
config.group.tip.paths = \ufffd possibile ottenere questi file dal sito Adobe
|
||||
config.group.link.paths = https://www.adobe.com/support/flashplayer/debug_downloads.html
|
||||
config.group.linkText.paths = [apri]
|
||||
#config.group.tip.paths = possibile ottenere questi file dal sito Adobe
|
||||
#TODO: translate again:
|
||||
config.group.tip.paths = Download projector and Playerglobal on <a href="%link1%">adobe webpage</a>. Flex SDK can be downloaded on <a href="%link2%">adobe devnet</a>.
|
||||
config.group.link.paths = https://www.adobe.com/support/flashplayer/debug_downloads.html http://www.adobe.com/devnet/flex/flex-sdk-download.html
|
||||
|
||||
config.name.playerLocation = 1) Percorso Flash Player
|
||||
config.description.playerLocation = Posizione eseguibile Flash Player. Utilizzato per l'azione Esegui.
|
||||
|
||||
@@ -44,6 +44,7 @@ scripts.pcode = P-code
|
||||
scripts.pcode_hex = P-code with Hex
|
||||
scripts.hex = Hex
|
||||
scripts.constants = Constants
|
||||
scripts.as_method_stubs = ActionScript method stubs
|
||||
|
||||
binaryData = Binary data
|
||||
binaryData.raw = Raw
|
||||
|
||||
@@ -735,4 +735,4 @@ generic.editor.amf3.help = AMF3 value syntax:\n\
|
||||
%reference_sample%\n\
|
||||
\ * Keys in Dictionary entries can be any type\n
|
||||
contextmenu.showInResources = Show in Resources
|
||||
|
||||
message.flexpath.notset = Flex SDK not found. Please configure its path in Advanced Settings / Paths (4).
|
||||
|
||||
@@ -438,13 +438,11 @@ public class Win32ProcessTools extends ProcessTools {
|
||||
bufSize = maxsize - pos;
|
||||
}
|
||||
} while (bufSize > 0);
|
||||
} else {
|
||||
if (hasGuard(mbi)) {
|
||||
if (unsetGuard(hOtherProcess, mbi)) {
|
||||
guardedPages.add(pg);
|
||||
pg--;
|
||||
continue;
|
||||
}
|
||||
} else if (hasGuard(mbi)) {
|
||||
if (unsetGuard(hOtherProcess, mbi)) {
|
||||
guardedPages.add(pg);
|
||||
pg--;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
actualPos += mbi.regionSize.longValue();
|
||||
|
||||
@@ -966,12 +966,9 @@ public interface User32 extends StdCallLibrary, WinUser {
|
||||
* process is idle.
|
||||
*
|
||||
* @return The following table shows the possible return values for this
|
||||
* function.
|
||||
* Return code: Description
|
||||
* 0: The wait was satisfied successfully.
|
||||
* WAIT_TIMEOUT: The wait was terminated because the time-out interval
|
||||
* elapsed.
|
||||
* WAIT_FAILED: An error occurred.
|
||||
* function. Return code: Description 0: The wait was satisfied
|
||||
* successfully. WAIT_TIMEOUT: The wait was terminated because the time-out
|
||||
* interval elapsed. WAIT_FAILED: An error occurred.
|
||||
*/
|
||||
DWORD WaitForInputIdle(HANDLE hProcess, DWORD dwMilliseconds);
|
||||
|
||||
@@ -1099,8 +1096,7 @@ public interface User32 extends StdCallLibrary, WinUser {
|
||||
* If the function fails, the return value is zero. To get extended error
|
||||
* information, call {@link Kernel32#GetLastError}.
|
||||
* {@link WinUser#WM_HOTKEY} messages generated by the hot key
|
||||
* {@link WinUser#WM_HOTKEY} message.
|
||||
* A combination of the following values
|
||||
* {@link WinUser#WM_HOTKEY} message. A combination of the following values
|
||||
* <ul>
|
||||
* <li>{@link WinUser#MOD_ALT} Either ALT key must be held down.</li>
|
||||
* <li>{@link WinUser#MOD_CONTROL} Either CTRL key must be held down.</li>
|
||||
@@ -1317,11 +1313,10 @@ public interface User32 extends StdCallLibrary, WinUser {
|
||||
*
|
||||
* This function typically fails for one of the following reasons:
|
||||
*
|
||||
* - an invalid parameter value
|
||||
* - the system class was registered by a different module
|
||||
* - The WH_CBT hook is installed and returns a failure code
|
||||
* - if one of the controls in the dialog template is not registered, or its
|
||||
* window window procedure fails WM_CREATE or WM_NCCREATE
|
||||
* - an invalid parameter value - the system class was registered by a
|
||||
* different module - The WH_CBT hook is installed and returns a failure
|
||||
* code - if one of the controls in the dialog template is not registered,
|
||||
* or its window window procedure fails WM_CREATE or WM_NCCREATE
|
||||
*/
|
||||
public HWND CreateWindowEx(int dwExStyle, WString lpClassName,
|
||||
String lpWindowName, int dwStyle, int x, int y, int nWidth,
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user