mirror of
https://git.huckle.dev/Huckles-Minecraft-Archive/jpexs-decompiler.git
synced 2026-05-28 11:26:10 +00:00
Added: FLA/FlashDevelop/IDEA export - A link to all classes (sound, font, images) is added so no class is missed during compilation
This commit is contained in:
@@ -133,7 +133,7 @@ public class DecompilerPool {
|
||||
}
|
||||
boolean parallel = Configuration.parallelSpeedUp.get();
|
||||
HighlightedTextWriter writer = new HighlightedTextWriter(Configuration.getCodeFormatting(), true);
|
||||
pack.toSource(abcIndex, writer, script == null ? null : script.traits.traits, new ConvertData(), ScriptExportMode.AS, parallel, false);
|
||||
pack.toSource(abcIndex, writer, script == null ? null : script.traits.traits, new ConvertData(), ScriptExportMode.AS, parallel, false, false);
|
||||
|
||||
writer.finishHilights();
|
||||
HighlightedText result = new HighlightedText(writer);
|
||||
|
||||
@@ -297,9 +297,11 @@ public class ScriptPack extends AS3ClassTreeItem {
|
||||
* @param convertData Convert data
|
||||
* @param exportMode Export mode
|
||||
* @param parallel Parallel
|
||||
* @param exportAllClasses Export all classes - reference it in document
|
||||
* class
|
||||
* @throws InterruptedException On interrupt
|
||||
*/
|
||||
private void appendTo(AbcIndexing abcIndex, GraphTextWriter writer, List<Trait> traits, ConvertData convertData, ScriptExportMode exportMode, boolean parallel) throws InterruptedException {
|
||||
private void appendTo(AbcIndexing abcIndex, GraphTextWriter writer, List<Trait> traits, ConvertData convertData, ScriptExportMode exportMode, boolean parallel, boolean exportAllClasses) throws InterruptedException {
|
||||
boolean first = true;
|
||||
//script initializer
|
||||
int script_init = abc.script_info.get(scriptIndex).init_index;
|
||||
@@ -307,21 +309,21 @@ public class ScriptPack extends AS3ClassTreeItem {
|
||||
|
||||
if (!isSimple && traitIndices.isEmpty()) {
|
||||
for (Trait t : abc.script_info.get(scriptIndex).traits.traits) {
|
||||
|
||||
|
||||
if (t instanceof TraitSlotConst) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
String fullName = t.getName(abc).getNameWithNamespace(abc.constants, false).toPrintableString(true);
|
||||
writer.appendNoHilight("include \"" + fullName.replace(".", "/") + ".as\";").newLine();
|
||||
}
|
||||
writer.newLine();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
for (int t : traitIndices) {
|
||||
|
||||
|
||||
Trait trait = traits.get(t);
|
||||
|
||||
|
||||
if (trait instanceof TraitSlotConst) {
|
||||
continue;
|
||||
}
|
||||
@@ -342,7 +344,7 @@ public class ScriptPack extends AS3ClassTreeItem {
|
||||
}
|
||||
first = false;
|
||||
}
|
||||
|
||||
|
||||
List<DottedChain> fullyQualifiedNames = new ArrayList<>();
|
||||
if (!first) {
|
||||
writer.newLine();
|
||||
@@ -354,16 +356,15 @@ public class ScriptPack extends AS3ClassTreeItem {
|
||||
Trait.writeImports(null, script_init, abcIndex, scriptIndex, -1, true, abc, writer, ignorePackage, fullyQualifiedNames);
|
||||
first = true;
|
||||
|
||||
|
||||
//Slot const last
|
||||
for (int t : traitIndices) {
|
||||
|
||||
|
||||
Trait trait = traits.get(t);
|
||||
|
||||
|
||||
if (!(trait instanceof TraitSlotConst)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
if (convertData.assignedValues.containsKey((TraitSlotConst) trait)) {
|
||||
continue;
|
||||
}
|
||||
@@ -384,19 +385,19 @@ public class ScriptPack extends AS3ClassTreeItem {
|
||||
}
|
||||
first = false;
|
||||
}
|
||||
|
||||
|
||||
if (bodyIndex != -1 && (isSimple || traitIndices.isEmpty())) {
|
||||
//Note: There must be trait/method highlight even if the initializer is empty to TraitList in GUI to work correctly
|
||||
writer.startTrait(GraphTextWriter.TRAIT_SCRIPT_INITIALIZER);
|
||||
writer.startMethod(script_init, null);
|
||||
if (exportMode != ScriptExportMode.AS_METHOD_STUBS) {
|
||||
if (!scriptInitializerIsEmpty) {
|
||||
if (!scriptInitializerIsEmpty) {
|
||||
List<MethodBody> callStack = new ArrayList<>();
|
||||
callStack.add(abc.bodies.get(bodyIndex));
|
||||
if (!first) {
|
||||
writer.newLine();
|
||||
writer.newLine();
|
||||
}
|
||||
abc.bodies.get(bodyIndex).toString(callStack, abcIndex, path + "/.scriptinitializer", exportMode, abc, null, writer, fullyQualifiedNames, new HashSet<>());
|
||||
abc.bodies.get(bodyIndex).toString(callStack, abcIndex, path + "/.scriptinitializer", exportMode, abc, null, writer, fullyQualifiedNames, new HashSet<>());
|
||||
} else {
|
||||
writer.append("");
|
||||
}
|
||||
@@ -408,6 +409,16 @@ public class ScriptPack extends AS3ClassTreeItem {
|
||||
first = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (exportAllClasses) {
|
||||
String documentClass = abc.getSwf().getDocumentClass();
|
||||
if (documentClass != null) {
|
||||
if (path.toRawString().equals(documentClass)) {
|
||||
writer.append("//Include all classes in the build").append("\r\n");
|
||||
writer.append("function __ffdec_include_classes() { FFDecIncludeClasses; }");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -420,9 +431,10 @@ public class ScriptPack extends AS3ClassTreeItem {
|
||||
* @param exportMode Export mode
|
||||
* @param parallel Parallel
|
||||
* @param ignoreFrameScripts Whether to ignore frame scripts
|
||||
* @param exportAllClasses Export all classes
|
||||
* @throws InterruptedException On interrupt
|
||||
*/
|
||||
public void toSource(AbcIndexing abcIndex, GraphTextWriter writer, final List<Trait> traits, final ConvertData convertData, final ScriptExportMode exportMode, final boolean parallel, boolean ignoreFrameScripts) throws InterruptedException {
|
||||
public void toSource(AbcIndexing abcIndex, GraphTextWriter writer, final List<Trait> traits, final ConvertData convertData, final ScriptExportMode exportMode, final boolean parallel, boolean ignoreFrameScripts, boolean exportAllClasses) throws InterruptedException {
|
||||
writer.suspendMeasure();
|
||||
int timeout = Configuration.decompilationTimeoutFile.get();
|
||||
try {
|
||||
@@ -460,7 +472,7 @@ public class ScriptPack extends AS3ClassTreeItem {
|
||||
}
|
||||
writer.continueMeasure();
|
||||
|
||||
appendTo(abcIndex, writer, traits, convertData, exportMode, parallel);
|
||||
appendTo(abcIndex, writer, traits, convertData, exportMode, parallel, exportAllClasses);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -492,7 +504,7 @@ public class ScriptPack extends AS3ClassTreeItem {
|
||||
convertData.exportEmbed = exportSettings.exportEmbed;
|
||||
convertData.exportEmbedFlaMode = exportSettings.exportEmbedFlaMode;
|
||||
convertData.assetsDir = exportSettings.assetsDir;
|
||||
toSource(abcIndex, writer2, abc.script_info.get(scriptIndex).traits.traits, convertData, exportSettings.mode, parallel, exportSettings.ignoreFrameScripts);
|
||||
toSource(abcIndex, writer2, abc.script_info.get(scriptIndex).traits.traits, convertData, exportSettings.mode, parallel, exportSettings.ignoreFrameScripts, exportSettings.includeAllClasses);
|
||||
} catch (FileNotFoundException ex) {
|
||||
logger.log(Level.SEVERE, "The file path is probably too long", ex);
|
||||
}
|
||||
|
||||
@@ -1019,6 +1019,10 @@ public final class Configuration {
|
||||
@ConfigurationDefaultBoolean(true)
|
||||
@ConfigurationCategory("script")
|
||||
public static ConfigurationItem<Boolean> warningAddFunction = null;
|
||||
|
||||
@ConfigurationDefaultBoolean(true)
|
||||
@ConfigurationCategory("export")
|
||||
public static ConfigurationItem<Boolean> linkAllClasses = null;
|
||||
|
||||
private enum OSId {
|
||||
WINDOWS, OSX, UNIX
|
||||
|
||||
@@ -81,6 +81,7 @@ import com.jpexs.decompiler.flash.tags.base.FontTag;
|
||||
import com.jpexs.decompiler.flash.tags.base.ImageTag;
|
||||
import com.jpexs.decompiler.flash.tags.base.PlaceObjectTypeTag;
|
||||
import com.jpexs.decompiler.flash.tags.base.RemoveTag;
|
||||
import com.jpexs.decompiler.flash.tags.base.SoundTag;
|
||||
import com.jpexs.decompiler.graph.DottedChain;
|
||||
import com.jpexs.decompiler.graph.GraphTargetItem;
|
||||
import com.jpexs.decompiler.graph.ScopeStack;
|
||||
@@ -92,6 +93,7 @@ import com.jpexs.helpers.XmlPrettyFormat;
|
||||
import com.jpexs.helpers.utf8.Utf8Helper;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
@@ -381,6 +383,7 @@ public class AS3ScriptExporter {
|
||||
|
||||
/**
|
||||
* Export ActionScript 3 scripts.
|
||||
*
|
||||
* @param swf SWF
|
||||
* @param handler AbortRetryIgnoreHandler
|
||||
* @param outdir Output directory
|
||||
@@ -405,6 +408,56 @@ public class AS3ScriptExporter {
|
||||
int cnt = 1;
|
||||
List<ExportPackTask> tasks = new ArrayList<>();
|
||||
Set<String> files = new HashSet<>();
|
||||
String documentClass = swf.getDocumentClass();
|
||||
StringBuffer includeClassesBuilder = new StringBuffer();
|
||||
String documentPkg = DottedChain.parseNoSuffix(documentClass).getWithoutLast().toPrintableString(true);
|
||||
|
||||
StringBuilder importsBuilder = new StringBuilder();
|
||||
|
||||
for (ScriptPack item : packs) {
|
||||
if (!item.isSimple && Configuration.ignoreCLikePackages.get()) {
|
||||
continue;
|
||||
}
|
||||
if (ignoredClasses.contains(item.getClassPath().toRawString())) {
|
||||
continue;
|
||||
}
|
||||
if (flexClass != null && item.getClassPath().toRawString().equals(flexClass)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
String rawClassName = item.getClassPath().toRawString();
|
||||
CharacterTag character = swf.getCharacterByClass(rawClassName);
|
||||
|
||||
//For some reasons Sprites do not work...
|
||||
boolean allowedType = (character instanceof SoundTag)
|
||||
|| (character instanceof ImageTag)
|
||||
|| (character instanceof FontTag);
|
||||
|
||||
if (allowedType) {
|
||||
if (!item.getClassPath().packageStr.isTopLevel()) {
|
||||
importsBuilder.append(" import ").append(item.getClassPath().toString()).append(";\r\n");
|
||||
}
|
||||
includeClassesBuilder.append(" ").append(item.getClassPath().toString()).append(";\r\n");
|
||||
}
|
||||
}
|
||||
|
||||
if (documentClass != null && !includeClassesBuilder.isEmpty()) {
|
||||
StringBuilder prep = new StringBuilder();
|
||||
prep.append(" /**\r\n");
|
||||
prep.append(" * This class contains references to all decompiled sound/image/font classes.\r\n");
|
||||
prep.append(" * It is needed for compilation otherwise some classes will be missed.\r\n");
|
||||
prep.append(" */\r\n");
|
||||
prep.append(" public class FFDecIncludeClasses\r\n");
|
||||
prep.append(" {\r\n");
|
||||
includeClassesBuilder.insert(0, prep);
|
||||
}
|
||||
|
||||
//If no sound/image classes found, then do not include FFDecIncludeClasses at all
|
||||
if (includeClassesBuilder.isEmpty()) {
|
||||
exportSettings = exportSettings.clone();
|
||||
exportSettings.includeAllClasses = false;
|
||||
}
|
||||
|
||||
for (ScriptPack item : packs) {
|
||||
if (!item.isSimple && Configuration.ignoreCLikePackages.get()) {
|
||||
continue;
|
||||
@@ -446,6 +499,35 @@ public class AS3ScriptExporter {
|
||||
tasks.add(new ExportPackTask(swf.getAbcIndex(), handler, cnt++, packs.size(), item.getClassPath(), item, file, exportSettings, parallel, evl));
|
||||
}
|
||||
|
||||
if (!includeClassesBuilder.isEmpty()) {
|
||||
includeClassesBuilder.append(" }\r\n");
|
||||
includeClassesBuilder.append("}\r\n");
|
||||
|
||||
StringBuilder prepend = new StringBuilder();
|
||||
prepend.append("package ").append(documentPkg).append("\r\n");
|
||||
prepend.append("{\r\n");
|
||||
prepend.append(importsBuilder.toString());
|
||||
prepend.append("\r\n");
|
||||
|
||||
includeClassesBuilder.insert(0, prepend.toString());
|
||||
|
||||
if (exportSettings.includeAllClasses) {
|
||||
java.nio.file.Path outPath = new File(outdir).toPath();
|
||||
if (!documentPkg.isEmpty()) {
|
||||
outPath = outPath.resolve(documentPkg);
|
||||
}
|
||||
File ffdecIncludeFilePath = outPath.resolve("FFDecIncludeClasses.as").toFile();
|
||||
|
||||
try (FileOutputStream fos = new FileOutputStream(ffdecIncludeFilePath)) {
|
||||
fos.write(Utf8Helper.getBytes(includeClassesBuilder.toString()));
|
||||
} catch (FileNotFoundException ex) {
|
||||
Logger.getLogger(AS3ScriptExporter.class.getName()).log(Level.SEVERE, null, ex);
|
||||
} catch (IOException ex) {
|
||||
Logger.getLogger(AS3ScriptExporter.class.getName()).log(Level.SEVERE, null, ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!parallel || tasks.size() < 2) {
|
||||
try {
|
||||
CancellableWorker.call(new Callable<Void>() {
|
||||
|
||||
@@ -18,6 +18,8 @@ package com.jpexs.decompiler.flash.exporters.settings;
|
||||
|
||||
import com.jpexs.decompiler.flash.exporters.modes.ScriptExportMode;
|
||||
import com.jpexs.decompiler.flash.helpers.FileTextWriter;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
/**
|
||||
* Script export settings.
|
||||
@@ -71,6 +73,11 @@ public class ScriptExportSettings {
|
||||
*/
|
||||
public String assetsDir;
|
||||
|
||||
/**
|
||||
* Modify main class to reference all classes
|
||||
*/
|
||||
public boolean includeAllClasses = true;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
* @param mode Mode
|
||||
@@ -88,7 +95,7 @@ public class ScriptExportSettings {
|
||||
boolean exportEmbedFlaMode,
|
||||
boolean resampleWav
|
||||
) {
|
||||
this(mode, singleFile, ignoreFrameScripts, exportEmbed, exportEmbedFlaMode, resampleWav, "/_assets/");
|
||||
this(mode, singleFile, ignoreFrameScripts, exportEmbed, exportEmbedFlaMode, resampleWav, "/_assets/", false);
|
||||
}
|
||||
|
||||
public ScriptExportSettings(
|
||||
@@ -98,7 +105,8 @@ public class ScriptExportSettings {
|
||||
boolean exportEmbed,
|
||||
boolean exportEmbedFlaMode,
|
||||
boolean resampleWav,
|
||||
String assetsDir
|
||||
String assetsDir,
|
||||
boolean includeAllClasses
|
||||
) {
|
||||
this.mode = mode;
|
||||
this.singleFile = singleFile;
|
||||
@@ -107,6 +115,7 @@ public class ScriptExportSettings {
|
||||
this.exportEmbedFlaMode = exportEmbedFlaMode;
|
||||
this.resampleWav = resampleWav;
|
||||
this.assetsDir = assetsDir;
|
||||
this.includeAllClasses = includeAllClasses;
|
||||
}
|
||||
|
||||
public String getFileExtension() {
|
||||
@@ -127,4 +136,14 @@ public class ScriptExportSettings {
|
||||
throw new Error("Unsupported script export mode: " + mode);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public ScriptExportSettings clone() {
|
||||
try {
|
||||
return (ScriptExportSettings) super.clone();
|
||||
} catch (CloneNotSupportedException ex) {
|
||||
//ignored
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -343,7 +343,7 @@ public class SwfFlashDevelopExporter {
|
||||
}
|
||||
|
||||
boolean parallel = Configuration.parallelSpeedUp.get();
|
||||
ScriptExportSettings scriptExportSettings = new ScriptExportSettings(ScriptExportMode.AS, false, false, true, false, false);
|
||||
ScriptExportSettings scriptExportSettings = new ScriptExportSettings(ScriptExportMode.AS, false, false, true, false, false, "/_assets/", Configuration.linkAllClasses.get());
|
||||
swf.exportActionScript(handler, outFile.toPath().getParent().resolve(srcPath).toFile().getAbsolutePath(), scriptExportSettings, parallel, eventListener);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -316,7 +316,7 @@ public class SwfIntelliJIdeaExporter {
|
||||
}
|
||||
|
||||
boolean parallel = Configuration.parallelSpeedUp.get();
|
||||
ScriptExportSettings scriptExportSettings = new ScriptExportSettings(ScriptExportMode.AS, false, false, true, false, false);
|
||||
ScriptExportSettings scriptExportSettings = new ScriptExportSettings(ScriptExportMode.AS, false, false, true, false, false, "/_assets/", Configuration.linkAllClasses.get());
|
||||
swf.exportActionScript(handler, new File(outDir, "src").getAbsolutePath(), scriptExportSettings, parallel, eventListener);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1463,16 +1463,16 @@ public class XFLConverter {
|
||||
return date.getTime() / 1000;
|
||||
}
|
||||
|
||||
private void convertLibrary(Set<CharacterTag> charactersExportedInFirstFrame, Map<CharacterTag, String> characterImportLinkageURL, Set<CharacterTag> characters, Reference<Integer> lastImportedId, Map<CharacterTag, String> characterNameMap, SWF swf, Map<CharacterTag, String> characterVariables, Map<CharacterTag, String> characterClasses, Map<CharacterTag, ScriptPack> characterScriptPacks, List<CharacterTag> nonLibraryShapes, String backgroundColor, ReadOnlyTagList tags, HashMap<String, byte[]> files, HashMap<String, byte[]> datfiles, FLAVersion flaVersion, XFLXmlWriter writer, Map<PlaceObjectTypeTag, MultiLevelClip> placeToMaskedSymbol, List<Integer> multiUsageMorphShapes, StatusStack statusStack) throws XMLStreamException {
|
||||
private void convertLibrary(Reference<Integer> lastItemIdNumber, Set<CharacterTag> charactersExportedInFirstFrame, Map<CharacterTag, String> characterImportLinkageURL, Set<CharacterTag> characters, Reference<Integer> lastImportedId, Map<CharacterTag, String> characterNameMap, SWF swf, Map<CharacterTag, String> characterVariables, Map<CharacterTag, String> characterClasses, Map<CharacterTag, ScriptPack> characterScriptPacks, List<CharacterTag> nonLibraryShapes, String backgroundColor, ReadOnlyTagList tags, HashMap<String, byte[]> files, HashMap<String, byte[]> datfiles, FLAVersion flaVersion, XFLXmlWriter writer, Map<PlaceObjectTypeTag, MultiLevelClip> placeToMaskedSymbol, List<Integer> multiUsageMorphShapes, StatusStack statusStack) throws XMLStreamException {
|
||||
statusStack.pushStatus("media");
|
||||
convertMedia(charactersExportedInFirstFrame, lastImportedId, characterNameMap, characterImportLinkageURL, characters, swf, characterVariables, characterClasses, tags, files, datfiles, writer, statusStack);
|
||||
convertMedia(lastItemIdNumber, charactersExportedInFirstFrame, lastImportedId, characterNameMap, characterImportLinkageURL, characters, swf, characterVariables, characterClasses, tags, files, datfiles, writer, statusStack);
|
||||
statusStack.popStatus();
|
||||
statusStack.pushStatus("symbols");
|
||||
convertSymbols(charactersExportedInFirstFrame, characterImportLinkageURL, characters, lastImportedId, characterNameMap, swf, characterVariables, characterClasses, characterScriptPacks, nonLibraryShapes, backgroundColor, tags, files, flaVersion, writer, placeToMaskedSymbol, multiUsageMorphShapes, statusStack);
|
||||
convertSymbols(lastItemIdNumber, charactersExportedInFirstFrame, characterImportLinkageURL, characters, lastImportedId, characterNameMap, swf, characterVariables, characterClasses, characterScriptPacks, nonLibraryShapes, backgroundColor, tags, files, flaVersion, writer, placeToMaskedSymbol, multiUsageMorphShapes, statusStack);
|
||||
statusStack.popStatus();
|
||||
}
|
||||
|
||||
private void convertSymbols(Set<CharacterTag> charactersExportedInFirstFrame, Map<CharacterTag, String> characterImportLinkageURL, Set<CharacterTag> characters, Reference<Integer> lastImportedId, Map<CharacterTag, String> characterNameMap, SWF swf, Map<CharacterTag, String> characterVariables, Map<CharacterTag, String> characterClasses, Map<CharacterTag, ScriptPack> characterScriptPacks, List<CharacterTag> nonLibraryShapes, String backgroundColor, ReadOnlyTagList tags, HashMap<String, byte[]> files, FLAVersion flaVersion, XFLXmlWriter writer, Map<PlaceObjectTypeTag, MultiLevelClip> placeToMaskedSymbol, List<Integer> multiUsageMorphShapes, StatusStack statusStack) throws XMLStreamException {
|
||||
private void convertSymbols(Reference<Integer> lastItemIdNumber, Set<CharacterTag> charactersExportedInFirstFrame, Map<CharacterTag, String> characterImportLinkageURL, Set<CharacterTag> characters, Reference<Integer> lastImportedId, Map<CharacterTag, String> characterNameMap, SWF swf, Map<CharacterTag, String> characterVariables, Map<CharacterTag, String> characterClasses, Map<CharacterTag, ScriptPack> characterScriptPacks, List<CharacterTag> nonLibraryShapes, String backgroundColor, ReadOnlyTagList tags, HashMap<String, byte[]> files, FLAVersion flaVersion, XFLXmlWriter writer, Map<PlaceObjectTypeTag, MultiLevelClip> placeToMaskedSymbol, List<Integer> multiUsageMorphShapes, StatusStack statusStack) throws XMLStreamException {
|
||||
//boolean hasSymbol = false;
|
||||
Reference<Integer> nextClipId = new Reference<>(-1);
|
||||
writer.writeStartElement("symbols");
|
||||
@@ -1486,10 +1486,12 @@ public class XFLConverter {
|
||||
statusStack.pushStatus(symbol.toString());
|
||||
XFLXmlWriter symbolStr = new XFLXmlWriter();
|
||||
|
||||
String itemId = generateItemId(lastItemIdNumber);
|
||||
symbolStr.writeStartElement("DOMSymbolItem", new String[]{
|
||||
"xmlns:xsi", "http://www.w3.org/2001/XMLSchema-instance",
|
||||
"xmlns", "http://ns.adobe.com/xfl/2008/",
|
||||
"name", getSymbolName(lastImportedId, characterNameMap, swf, symbol),
|
||||
"itemID", itemId,
|
||||
"lastModified", Long.toString(getTimestamp(swf))}); //TODO:itemID
|
||||
if (characterImportLinkageURL.containsKey(symbol)) {
|
||||
symbolStr.writeAttribute("linkageImportForRS", "true");
|
||||
@@ -1705,7 +1707,7 @@ public class XFLConverter {
|
||||
}
|
||||
final ScriptPack spriteScriptPack = characterScriptPacks.containsKey(sprite) ? characterScriptPacks.get(sprite) : null;
|
||||
|
||||
extractMultilevelClips(lastImportedId, characterNameMap, sprite.getTags(), writer, swf, nextClipId, nonLibraryShapes, backgroundColor, flaVersion, files, placeToMaskedSymbol, multiUsageMorphShapes, statusStack);
|
||||
extractMultilevelClips(lastItemIdNumber, lastImportedId, characterNameMap, sprite.getTags(), writer, swf, nextClipId, nonLibraryShapes, backgroundColor, flaVersion, files, placeToMaskedSymbol, multiUsageMorphShapes, statusStack);
|
||||
|
||||
convertTimelines(lastImportedId, characterNameMap, swf, swf.getAbcIndex(), sprite, characterVariables.get(sprite), nonLibraryShapes, tags, sprite.getTags(), getSymbolName(lastImportedId, characterNameMap, swf, symbol), flaVersion, files, symbolStr, spriteScriptPack, placeToMaskedSymbol, multiUsageMorphShapes, statusStack);
|
||||
|
||||
@@ -1732,6 +1734,7 @@ public class XFLConverter {
|
||||
|
||||
// write symbLink
|
||||
writer.writeStartElement("Include", new String[]{"href", symbolFile});
|
||||
writer.writeAttribute("itemID", itemId);
|
||||
if (itemIcon != null) {
|
||||
writer.writeAttribute("itemIcon", itemIcon);
|
||||
}
|
||||
@@ -1747,11 +1750,11 @@ public class XFLConverter {
|
||||
}
|
||||
|
||||
statusStack.pushStatus("extracting multilevel clips");
|
||||
extractMultilevelClips(lastImportedId, characterNameMap, swf.getTags(), writer, swf, nextClipId, nonLibraryShapes, backgroundColor, flaVersion, files, placeToMaskedSymbol, multiUsageMorphShapes, statusStack);
|
||||
extractMultilevelClips(lastItemIdNumber, lastImportedId, characterNameMap, swf.getTags(), writer, swf, nextClipId, nonLibraryShapes, backgroundColor, flaVersion, files, placeToMaskedSymbol, multiUsageMorphShapes, statusStack);
|
||||
statusStack.popStatus();
|
||||
|
||||
statusStack.pushStatus("converting multiusage morphshapes");
|
||||
extractMultiUsageMorphShapes(lastImportedId, characterNameMap, writer, swf, nonLibraryShapes, flaVersion, files, multiUsageMorphShapes, statusStack);
|
||||
extractMultiUsageMorphShapes(lastItemIdNumber, lastImportedId, characterNameMap, writer, swf, nonLibraryShapes, flaVersion, files, multiUsageMorphShapes, statusStack);
|
||||
statusStack.popStatus();
|
||||
/*if (hasSymbol) {
|
||||
|
||||
@@ -1759,7 +1762,7 @@ public class XFLConverter {
|
||||
writer.writeEndElement();
|
||||
}
|
||||
|
||||
private void convertSoundMedia(Map<CharacterTag, String> characterImportLinkageURL, SWF swf, ReadOnlyTagList tags, SoundTag symbol, XFLXmlWriter writer, HashMap<String, byte[]> files, HashMap<String, byte[]> datfiles) throws XMLStreamException {
|
||||
private void convertSoundMedia(Reference<Integer> lastItemIdNumber, Map<CharacterTag, String> characterImportLinkageURL, SWF swf, ReadOnlyTagList tags, SoundTag symbol, XFLXmlWriter writer, HashMap<String, byte[]> files, HashMap<String, byte[]> datfiles) throws XMLStreamException {
|
||||
int soundFormat = 0;
|
||||
int soundRate = 0;
|
||||
boolean soundType = false;
|
||||
@@ -1929,6 +1932,7 @@ public class XFLConverter {
|
||||
files.put(symbolFile, data);
|
||||
writer.writeStartElement("DOMSoundItem", new String[]{
|
||||
"name", symbolFile,
|
||||
"itemID", generateItemId(lastItemIdNumber),
|
||||
"sourceLastImported", Long.toString(getTimestamp(swf)),
|
||||
"externalFileSize", Integer.toString(data.length)});
|
||||
if ((symbol instanceof CharacterTag) && characterImportLinkageURL.containsKey((CharacterTag) symbol)) {
|
||||
@@ -1945,7 +1949,7 @@ public class XFLConverter {
|
||||
writer.writeAttribute("sampleCount", soundSampleCount);
|
||||
}
|
||||
|
||||
private void convertMedia(Set<CharacterTag> charactersExportedInFirstFrame, Reference<Integer> lastImportedId, Map<CharacterTag, String> characterNameMap, Map<CharacterTag, String> characterImportLinkageURL, Set<CharacterTag> characters, SWF swf, Map<CharacterTag, String> characterVariables, Map<CharacterTag, String> characterClasses, ReadOnlyTagList tags, HashMap<String, byte[]> files, HashMap<String, byte[]> datfiles, XFLXmlWriter writer, StatusStack statusStack) throws XMLStreamException {
|
||||
private void convertMedia(Reference<Integer> lastItemIdNumber, Set<CharacterTag> charactersExportedInFirstFrame, Reference<Integer> lastImportedId, Map<CharacterTag, String> characterNameMap, Map<CharacterTag, String> characterImportLinkageURL, Set<CharacterTag> characters, SWF swf, Map<CharacterTag, String> characterVariables, Map<CharacterTag, String> characterClasses, ReadOnlyTagList tags, HashMap<String, byte[]> files, HashMap<String, byte[]> datfiles, XFLXmlWriter writer, StatusStack statusStack) throws XMLStreamException {
|
||||
boolean hasMedia = false;
|
||||
for (CharacterTag symbol : characters) {
|
||||
if (symbol instanceof ImageTag
|
||||
@@ -2003,8 +2007,9 @@ public class XFLConverter {
|
||||
ImageFormat format = imageTag.getImageFormat();
|
||||
String symbolFile = getSymbolName(lastImportedId, characterNameMap, swf, symbol, "Bitmap") + imageTag.getImageFormat().getExtension();
|
||||
files.put(symbolFile, imageBytes);
|
||||
writer.writeStartElement("DOMBitmapItem", new String[]{
|
||||
writer.writeStartElement("DOMBitmapItem", new String[]{
|
||||
"name", symbolFile,
|
||||
"itemID", generateItemId(lastItemIdNumber),
|
||||
"sourceLastImported", Long.toString(getTimestamp(swf)),
|
||||
"externalFileSize", Integer.toString(imageBytes.length)});
|
||||
|
||||
@@ -2061,7 +2066,7 @@ public class XFLConverter {
|
||||
statusStack.popStatus();
|
||||
} else if (symbol instanceof DefineSoundTag) {
|
||||
statusStack.pushStatus(symbol.toString());
|
||||
convertSoundMedia(characterImportLinkageURL, swf, tags, (DefineSoundTag) symbol, writer, files, datfiles);
|
||||
convertSoundMedia(lastItemIdNumber, characterImportLinkageURL, swf, tags, (DefineSoundTag) symbol, writer, files, datfiles);
|
||||
|
||||
if (characterImportLinkageURL.containsKey(symbol)) {
|
||||
writer.writeAttribute("linkageImportForRS", "true");
|
||||
@@ -2148,6 +2153,7 @@ public class XFLConverter {
|
||||
files.put(symbolFile, data);
|
||||
writer.writeStartElement("DOMVideoItem", new String[]{
|
||||
"name", symbolFile,
|
||||
"itemID", generateItemId(lastItemIdNumber),
|
||||
"sourceLastImported", Long.toString(getTimestamp(swf)),
|
||||
"externalFileSize", Integer.toString(data.length)});
|
||||
if (characterImportLinkageURL.containsKey(symbol)) {
|
||||
@@ -2188,7 +2194,7 @@ public class XFLConverter {
|
||||
SoundStreamHeadTypeTag head = (SoundStreamHeadTypeTag) t;
|
||||
for (SoundStreamFrameRange range : head.getRanges()) {
|
||||
statusStack.pushStatus(range.toString());
|
||||
convertSoundMedia(characterImportLinkageURL, swf, tags, range, writer, files, datfiles);
|
||||
convertSoundMedia(lastItemIdNumber, characterImportLinkageURL, swf, tags, range, writer, files, datfiles);
|
||||
writer.writeEndElement();
|
||||
statusStack.popStatus();
|
||||
}
|
||||
@@ -2200,7 +2206,7 @@ public class XFLConverter {
|
||||
SoundStreamHeadTypeTag head = (SoundStreamHeadTypeTag) st;
|
||||
for (SoundStreamFrameRange range : head.getRanges()) {
|
||||
statusStack.pushStatus(range.toString());
|
||||
convertSoundMedia(characterImportLinkageURL, swf, sprite.getTags(), range, writer, files, datfiles);
|
||||
convertSoundMedia(lastItemIdNumber, characterImportLinkageURL, swf, sprite.getTags(), range, writer, files, datfiles);
|
||||
writer.writeEndElement();
|
||||
statusStack.popStatus();
|
||||
}
|
||||
@@ -2675,7 +2681,7 @@ public class XFLConverter {
|
||||
}
|
||||
}
|
||||
|
||||
private static void convertFonts(Set<CharacterTag> charactersExportedInFirstFrame, Reference<Integer> lastImportedId, Map<CharacterTag, String> characterNameMap, SWF swf, Set<CharacterTag> characters, Map<CharacterTag, String> characterClasses, XFLXmlWriter writer, StatusStack statusStack) throws XMLStreamException {
|
||||
private static void convertFonts(Reference<Integer> lastItemIdNumber, Set<CharacterTag> charactersExportedInFirstFrame, Reference<Integer> lastImportedId, Map<CharacterTag, String> characterNameMap, SWF swf, Set<CharacterTag> characters, Map<CharacterTag, String> characterClasses, XFLXmlWriter writer, StatusStack statusStack) throws XMLStreamException {
|
||||
boolean hasFont = false;
|
||||
int fontCounter = 0;
|
||||
for (CharacterTag t : characters) {
|
||||
@@ -2758,6 +2764,7 @@ public class XFLConverter {
|
||||
fontCounter++;
|
||||
writer.writeStartElement("DOMFontItem", new String[]{
|
||||
"name", getSymbolName(lastImportedId, characterNameMap, swf, font, "Font"),
|
||||
"itemID", generateItemId(lastItemIdNumber),
|
||||
"font", fontName,
|
||||
"size", "0",
|
||||
"id", Integer.toString(fontCounter),
|
||||
@@ -3159,7 +3166,9 @@ public class XFLConverter {
|
||||
}
|
||||
|
||||
private void addExtractedClip(
|
||||
Reference<Integer> lastImportedId, Map<CharacterTag, String> characterNameMap,
|
||||
Reference<Integer> lastItemIdNumber,
|
||||
Reference<Integer> lastImportedId,
|
||||
Map<CharacterTag, String> characterNameMap,
|
||||
ReadOnlyTagList timelineTags,
|
||||
XFLXmlWriter writer,
|
||||
SWF swf,
|
||||
@@ -3174,7 +3183,7 @@ public class XFLConverter {
|
||||
) throws XMLStreamException {
|
||||
XFLXmlWriter symbolStr = new XFLXmlWriter();
|
||||
|
||||
extractMultilevelClips(lastImportedId, characterNameMap, timelineTags, writer, swf, nextClipId, nonLibraryShapes, backgroundColor, flaVersion, files, placeToMaskedSymbol, multiUsageMorphShapes, statusStack);
|
||||
extractMultilevelClips(lastItemIdNumber, lastImportedId, characterNameMap, timelineTags, writer, swf, nextClipId, nonLibraryShapes, backgroundColor, flaVersion, files, placeToMaskedSymbol, multiUsageMorphShapes, statusStack);
|
||||
|
||||
if (nextClipId.getVal() < 0) {
|
||||
nextClipId.setVal(swf.getNextCharacterId());
|
||||
@@ -3183,11 +3192,12 @@ public class XFLConverter {
|
||||
}
|
||||
|
||||
int objectId = nextClipId.getVal();
|
||||
|
||||
String itemId = generateItemId(lastItemIdNumber);
|
||||
symbolStr.writeStartElement("DOMSymbolItem", new String[]{
|
||||
"xmlns:xsi", "http://www.w3.org/2001/XMLSchema-instance",
|
||||
"xmlns", "http://ns.adobe.com/xfl/2008/",
|
||||
"name", getMaskedSymbolName(objectId),
|
||||
"itemID", itemId,
|
||||
"lastModified", Long.toString(getTimestamp(swf))});
|
||||
symbolStr.writeAttribute("symbolType", "graphic");
|
||||
|
||||
@@ -3199,6 +3209,7 @@ public class XFLConverter {
|
||||
files.put(symbolFile, Utf8Helper.getBytes(symbolStr2));
|
||||
|
||||
writer.writeStartElement("Include", new String[]{"href", symbolFile});
|
||||
writer.writeAttribute("itemID", itemId);
|
||||
writer.writeAttribute("itemIcon", "1");
|
||||
writer.writeAttribute("loadImmediate", false);
|
||||
if (flaVersion.ordinal() >= FLAVersion.CS5_5.ordinal()) {
|
||||
@@ -3263,7 +3274,9 @@ public class XFLConverter {
|
||||
}
|
||||
|
||||
private void extractMultiUsageMorphShapes(
|
||||
Reference<Integer> lastImportedId, Map<CharacterTag, String> characterNameMap,
|
||||
Reference<Integer> lastItemIdNumber,
|
||||
Reference<Integer> lastImportedId,
|
||||
Map<CharacterTag, String> characterNameMap,
|
||||
XFLXmlWriter writer,
|
||||
SWF swf,
|
||||
List<CharacterTag> nonLibraryShapes,
|
||||
@@ -3276,11 +3289,13 @@ public class XFLConverter {
|
||||
for (int objectId : multiUsageMorphShapes) {
|
||||
statusStack.pushStatus(swf.getCharacter(objectId).toString());
|
||||
|
||||
String itemId = generateItemId(lastItemIdNumber);
|
||||
XFLXmlWriter symbolStr = new XFLXmlWriter();
|
||||
symbolStr.writeStartElement("DOMSymbolItem", new String[]{
|
||||
"xmlns:xsi", "http://www.w3.org/2001/XMLSchema-instance",
|
||||
"xmlns", "http://ns.adobe.com/xfl/2008/",
|
||||
"name", getSymbolName(lastImportedId, characterNameMap, swf, swf.getCharacter(objectId)),
|
||||
"itemID", itemId,
|
||||
"lastModified", Long.toString(getTimestamp(swf))});
|
||||
symbolStr.writeAttribute("symbolType", "graphic");
|
||||
|
||||
@@ -3308,6 +3323,7 @@ public class XFLConverter {
|
||||
files.put(symbolFile, Utf8Helper.getBytes(symbolStr2));
|
||||
|
||||
writer.writeStartElement("Include", new String[]{"href", symbolFile});
|
||||
writer.writeAttribute("itemID", itemId);
|
||||
writer.writeAttribute("itemIcon", "1");
|
||||
writer.writeAttribute("loadImmediate", false);
|
||||
if (flaVersion.ordinal() >= FLAVersion.CS5_5.ordinal()) {
|
||||
@@ -3320,7 +3336,9 @@ public class XFLConverter {
|
||||
}
|
||||
|
||||
private void extractMultilevelClips(
|
||||
Reference<Integer> lastImportedId, Map<CharacterTag, String> characterNameMap,
|
||||
Reference<Integer> lastItemIdNumber,
|
||||
Reference<Integer> lastImportedId,
|
||||
Map<CharacterTag, String> characterNameMap,
|
||||
ReadOnlyTagList timelineTags,
|
||||
XFLXmlWriter writer,
|
||||
SWF swf,
|
||||
@@ -3520,7 +3538,7 @@ public class XFLConverter {
|
||||
//set timelined?
|
||||
delegatedTimeline.add(showFrame);
|
||||
}
|
||||
addExtractedClip(lastImportedId, characterNameMap, new ReadOnlyTagList(delegatedTimeline), writer, swf, nextClipId, nonLibraryShapes, backgroundColor, flaVersion, files, placeToMaskedSymbol, multiUsageMorphShapes, statusStack);
|
||||
addExtractedClip(lastItemIdNumber, lastImportedId, characterNameMap, new ReadOnlyTagList(delegatedTimeline), writer, swf, nextClipId, nonLibraryShapes, backgroundColor, flaVersion, files, placeToMaskedSymbol, multiUsageMorphShapes, statusStack);
|
||||
placeToMaskedSymbol.put(secondPlace, new MultiLevelClip(secondPlace, nextClipId.getVal(), numFrames));
|
||||
}
|
||||
}
|
||||
@@ -4670,6 +4688,7 @@ public class XFLConverter {
|
||||
|
||||
Set<CharacterTag> charactersExportedInFirstFrame = new LinkedIdentityHashSet<>();
|
||||
Map<CharacterTag, String> characterImportLinkageURL = new IdentityHashMap<>();
|
||||
Reference<Integer> lastItemIdNumber = new Reference<>(0);
|
||||
int frame = 1;
|
||||
for (Tag tag : swf.getTags()) {
|
||||
if (tag instanceof ImportTag) {
|
||||
@@ -4717,9 +4736,9 @@ public class XFLConverter {
|
||||
}
|
||||
}
|
||||
}
|
||||
convertFonts(charactersExportedInFirstFrame, lastImportedId, characterNameMap, swf, characters, characterClasses, domDocument, statusStack);
|
||||
convertFonts(lastItemIdNumber, charactersExportedInFirstFrame, lastImportedId, characterNameMap, swf, characters, characterClasses, domDocument, statusStack);
|
||||
|
||||
convertLibrary(charactersExportedInFirstFrame, characterImportLinkageURL, characters, lastImportedId, characterNameMap, swf, characterVariables, characterClasses, characterScriptPacks, nonLibraryShapes, backgroundColor, swf.getTags(), files, datfiles, flaVersion, domDocument, placeToMaskedSymbol, multiUsageMorphShapes, statusStack);
|
||||
convertLibrary(lastItemIdNumber, charactersExportedInFirstFrame, characterImportLinkageURL, characters, lastImportedId, characterNameMap, swf, characterVariables, characterClasses, characterScriptPacks, nonLibraryShapes, backgroundColor, swf.getTags(), files, datfiles, flaVersion, domDocument, placeToMaskedSymbol, multiUsageMorphShapes, statusStack);
|
||||
|
||||
//domDocument.writeStartElement("timelines");
|
||||
ScriptPack documentScriptPack = null;
|
||||
@@ -5203,7 +5222,7 @@ public class XFLConverter {
|
||||
}
|
||||
if (useAS3 && settings.exportScript) {
|
||||
try {
|
||||
ScriptExportSettings scriptExportSettings = new ScriptExportSettings(ScriptExportMode.AS, false, true, false, true, true);
|
||||
ScriptExportSettings scriptExportSettings = new ScriptExportSettings(ScriptExportMode.AS, false, true, false, true, true, "/_assets/", Configuration.linkAllClasses.get());
|
||||
swf.exportActionScript(handler, scriptsDir.getAbsolutePath(), scriptExportSettings, parallel, null);
|
||||
} catch (Exception ex) {
|
||||
logger.log(Level.SEVERE, "Error during ActionScript3 export", ex);
|
||||
@@ -5365,7 +5384,14 @@ public class XFLConverter {
|
||||
private static double twipToPixel(double tw) {
|
||||
return tw / SWF.unitDivisor;
|
||||
}
|
||||
|
||||
|
||||
private static String generateItemId(Reference<Integer> lastItemIdNumber) {
|
||||
lastItemIdNumber.setVal(lastItemIdNumber.getVal() + 1);
|
||||
String epochHex = String.format("%1$08x", Math.round(System.currentTimeMillis() / 1000));
|
||||
String numberHex = String.format("%1$08x", lastItemIdNumber.getVal());
|
||||
return epochHex + "-" + numberHex;
|
||||
}
|
||||
|
||||
private static class HTMLTextParser extends DefaultHandler {
|
||||
|
||||
public XFLXmlWriter result = new XFLXmlWriter();
|
||||
|
||||
Reference in New Issue
Block a user