diff --git a/libsrc/ffdec_cli/build.properties b/libsrc/ffdec_cli/build.properties
index 587a8991a..d7f6b6524 100644
--- a/libsrc/ffdec_cli/build.properties
+++ b/libsrc/ffdec_cli/build.properties
@@ -34,4 +34,6 @@ main.class = com.jpexs.decompiler.flash.cli.CommandlineInterface
app.dir = ../../dist
app.lib.dir = ../../dist/lib
-ffdec_lib.path = lib/ffdec_lib.jar
\ No newline at end of file
+ffdec_lib.path = lib/ffdec_lib.jar
+
+additional.libs = lib/gnujpdf.jar
\ No newline at end of file
diff --git a/libsrc/ffdec_cli/build.xml b/libsrc/ffdec_cli/build.xml
index 0ce93ed56..5f7901bd8 100644
--- a/libsrc/ffdec_cli/build.xml
+++ b/libsrc/ffdec_cli/build.xml
@@ -137,7 +137,7 @@
-
+
diff --git a/libsrc/ffdec_cli/nbproject/project.xml b/libsrc/ffdec_cli/nbproject/project.xml
index 9f85fa8e9..4acbcc702 100644
--- a/libsrc/ffdec_cli/nbproject/project.xml
+++ b/libsrc/ffdec_cli/nbproject/project.xml
@@ -63,11 +63,12 @@ auxiliary.show.customizer.message=
+
src
- lib/jansi-2.4.0.jar;../../lib/ffdec_lib.jar
+ lib/jansi-2.4.0.jar;../../lib/ffdec_lib.jar;../../lib/gnujpdf.jar
build/classes
1.8
diff --git a/libsrc/ffdec_cli/src/com/jpexs/decompiler/flash/cli/commands/Main.java b/libsrc/ffdec_cli/src/com/jpexs/decompiler/flash/cli/commands/Main.java
index e4a41f2fd..5ef7c1cae 100644
--- a/libsrc/ffdec_cli/src/com/jpexs/decompiler/flash/cli/commands/Main.java
+++ b/libsrc/ffdec_cli/src/com/jpexs/decompiler/flash/cli/commands/Main.java
@@ -62,7 +62,8 @@ import picocli.CommandLine.ScopeType;
AbcMerge.class,
Swf2Exe.class,
Header.class,
- Config.class
+ Config.class,
+ Old.class
},
descriptionHeading = "%n@|bold,underline Description|@:%n",
optionListHeading = "%n@|bold,underline Options|@:%n",
diff --git a/libsrc/ffdec_cli/src/com/jpexs/decompiler/flash/cli/commands/Old.java b/libsrc/ffdec_cli/src/com/jpexs/decompiler/flash/cli/commands/Old.java
new file mode 100644
index 000000000..1cb8758ea
--- /dev/null
+++ b/libsrc/ffdec_cli/src/com/jpexs/decompiler/flash/cli/commands/Old.java
@@ -0,0 +1,53 @@
+package com.jpexs.decompiler.flash.cli.commands;
+
+import com.jpexs.decompiler.flash.cli.VersionProvider;
+import com.jpexs.decompiler.flash.cli.legacy.CommandLineArgumentParser;
+import java.io.IOException;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+import picocli.CommandLine;
+import picocli.CommandLine.Command;
+import picocli.CommandLine.Option;
+import picocli.CommandLine.Parameters;
+import picocli.CommandLine.ParentCommand;
+
+
+/**
+ *
+ * @author JPEXS
+ */
+@CommandLine.Command(
+ name = "old",
+ mixinStandardHelpOptions = true,
+ versionProvider = VersionProvider.class,
+ header = "Old legacy commandline interface.",
+ optionListHeading = "%n@|bold,underline Options|@:%n",
+ parameterListHeading = "%n@|bold,underline Parameters|@:%n",
+ synopsisHeading = "@|bold,underline Usage|@:",
+ footerHeading = "%n@|bold,underline Examples|@:%n",
+ footer = {
+ "ffdec-cli old",
+ "ffdec-cli old -export script -format script:pcode outdir/ file.swf"
+ },
+ sortSynopsis = false
+)
+public class Old implements Runnable {
+
+ @Parameters (
+ index = "0",
+ arity = "0..*"
+ )
+ String args[] = new String[]{};
+
+ @Override
+ public void run() {
+ if (args.length == 0) {
+ args = new String[] {"--help"};
+ }
+ try {
+ CommandLineArgumentParser.parseArguments(args);
+ } catch (IOException ex) {
+ Logger.getLogger(Old.class.getName()).log(Level.SEVERE, null, ex);
+ }
+ }
+}
diff --git a/libsrc/ffdec_cli/src/com/jpexs/decompiler/flash/cli/legacy/CommandLineArgumentParser.java b/libsrc/ffdec_cli/src/com/jpexs/decompiler/flash/cli/legacy/CommandLineArgumentParser.java
new file mode 100644
index 000000000..15c05fa88
--- /dev/null
+++ b/libsrc/ffdec_cli/src/com/jpexs/decompiler/flash/cli/legacy/CommandLineArgumentParser.java
@@ -0,0 +1,5104 @@
+/*
+ * Copyright (C) 2010-2023 JPEXS
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+package com.jpexs.decompiler.flash.cli.legacy;
+
+import com.jpexs.decompiler.flash.AbortRetryIgnoreHandler;
+import com.jpexs.decompiler.flash.ApplicationInfo;
+import com.jpexs.decompiler.flash.Bundle;
+import com.jpexs.decompiler.flash.EventListener;
+import com.jpexs.decompiler.flash.IdentifiersDeobfuscation;
+import com.jpexs.decompiler.flash.OpenableSourceInfo;
+import com.jpexs.decompiler.flash.ReadOnlyTagList;
+import com.jpexs.decompiler.flash.SWF;
+import com.jpexs.decompiler.flash.SWFCompression;
+import com.jpexs.decompiler.flash.SearchMode;
+import com.jpexs.decompiler.flash.SwfOpenException;
+import com.jpexs.decompiler.flash.ValueTooLargeException;
+import com.jpexs.decompiler.flash.abc.ABC;
+import com.jpexs.decompiler.flash.abc.RenameType;
+import com.jpexs.decompiler.flash.abc.ScriptPack;
+import com.jpexs.decompiler.flash.abc.avm2.AVM2Code;
+import com.jpexs.decompiler.flash.abc.avm2.deobfuscation.DeobfuscationLevel;
+import com.jpexs.decompiler.flash.abc.avm2.parser.AVM2ParseException;
+import com.jpexs.decompiler.flash.abc.avm2.parser.pcode.ASM3Parser;
+import com.jpexs.decompiler.flash.abc.avm2.parser.pcode.MissingSymbolHandler;
+import com.jpexs.decompiler.flash.abc.avm2.parser.script.ActionScript3Parser;
+import com.jpexs.decompiler.flash.abc.types.Decimal;
+import com.jpexs.decompiler.flash.abc.types.Float4;
+import com.jpexs.decompiler.flash.abc.types.MethodBody;
+import com.jpexs.decompiler.flash.abc.types.traits.Trait;
+import com.jpexs.decompiler.flash.action.parser.ActionParseException;
+import com.jpexs.decompiler.flash.action.parser.pcode.ASMParser;
+import com.jpexs.decompiler.flash.action.parser.script.ActionScript2Parser;
+import com.jpexs.decompiler.flash.amf.amf3.Amf3InputStream;
+import com.jpexs.decompiler.flash.amf.amf3.Amf3OutputStream;
+import com.jpexs.decompiler.flash.amf.amf3.Amf3Value;
+import com.jpexs.decompiler.flash.amf.amf3.NoSerializerExistsException;
+import com.jpexs.decompiler.flash.amf.amf3.Traits;
+import com.jpexs.decompiler.flash.amf.amf3.types.ObjectType;
+import com.jpexs.decompiler.flash.configuration.Configuration;
+import com.jpexs.decompiler.flash.configuration.ConfigurationItem;
+import com.jpexs.decompiler.flash.docs.As3PCodeDocs;
+import com.jpexs.decompiler.flash.exporters.BinaryDataExporter;
+import com.jpexs.decompiler.flash.exporters.DualPdfGraphics2D;
+import com.jpexs.decompiler.flash.exporters.Font4Exporter;
+import com.jpexs.decompiler.flash.exporters.FontExporter;
+import com.jpexs.decompiler.flash.exporters.FrameExporter;
+import com.jpexs.decompiler.flash.exporters.ImageExporter;
+import com.jpexs.decompiler.flash.exporters.MorphShapeExporter;
+import com.jpexs.decompiler.flash.exporters.MovieExporter;
+import com.jpexs.decompiler.flash.exporters.ShapeExporter;
+import com.jpexs.decompiler.flash.exporters.SoundExporter;
+import com.jpexs.decompiler.flash.exporters.SymbolClassExporter;
+import com.jpexs.decompiler.flash.exporters.TextExporter;
+import com.jpexs.decompiler.flash.exporters.amf.amf3.Amf3Exporter;
+import com.jpexs.decompiler.flash.exporters.commonshape.ExportRectangle;
+import com.jpexs.decompiler.flash.exporters.commonshape.Matrix;
+import com.jpexs.decompiler.flash.exporters.modes.BinaryDataExportMode;
+import com.jpexs.decompiler.flash.exporters.modes.ButtonExportMode;
+import com.jpexs.decompiler.flash.exporters.modes.ExeExportMode;
+import com.jpexs.decompiler.flash.exporters.modes.Font4ExportMode;
+import com.jpexs.decompiler.flash.exporters.modes.FontExportMode;
+import com.jpexs.decompiler.flash.exporters.modes.FrameExportMode;
+import com.jpexs.decompiler.flash.exporters.modes.ImageExportMode;
+import com.jpexs.decompiler.flash.exporters.modes.MorphShapeExportMode;
+import com.jpexs.decompiler.flash.exporters.modes.MovieExportMode;
+import com.jpexs.decompiler.flash.exporters.modes.ScriptExportMode;
+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.SymbolClassExportMode;
+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.Font4ExportSettings;
+import com.jpexs.decompiler.flash.exporters.settings.FontExportSettings;
+import com.jpexs.decompiler.flash.exporters.settings.FrameExportSettings;
+import com.jpexs.decompiler.flash.exporters.settings.ImageExportSettings;
+import com.jpexs.decompiler.flash.exporters.settings.MorphShapeExportSettings;
+import com.jpexs.decompiler.flash.exporters.settings.MovieExportSettings;
+import com.jpexs.decompiler.flash.exporters.settings.ScriptExportSettings;
+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.SymbolClassExportSettings;
+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.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;
+import com.jpexs.decompiler.flash.importers.MovieImporter;
+import com.jpexs.decompiler.flash.importers.ScriptImporterProgressListener;
+import com.jpexs.decompiler.flash.importers.ShapeImporter;
+import com.jpexs.decompiler.flash.importers.SoundImporter;
+import com.jpexs.decompiler.flash.importers.SpriteImporter;
+import com.jpexs.decompiler.flash.importers.SwfXmlImporter;
+import com.jpexs.decompiler.flash.importers.SymbolClassImporter;
+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.importers.svg.SvgImporter;
+import com.jpexs.decompiler.flash.tags.ABCContainerTag;
+import com.jpexs.decompiler.flash.tags.DefineBinaryDataTag;
+import com.jpexs.decompiler.flash.tags.DefineSpriteTag;
+import com.jpexs.decompiler.flash.tags.DefineVideoStreamTag;
+import com.jpexs.decompiler.flash.tags.FileAttributesTag;
+import com.jpexs.decompiler.flash.tags.PlaceObject4Tag;
+import com.jpexs.decompiler.flash.tags.ScriptLimitsTag;
+import com.jpexs.decompiler.flash.tags.SetBackgroundColorTag;
+import com.jpexs.decompiler.flash.tags.Tag;
+import com.jpexs.decompiler.flash.tags.base.ASMSource;
+import com.jpexs.decompiler.flash.tags.base.ButtonTag;
+import com.jpexs.decompiler.flash.tags.base.CharacterIdTag;
+import com.jpexs.decompiler.flash.tags.base.CharacterTag;
+import com.jpexs.decompiler.flash.tags.base.FontTag;
+import com.jpexs.decompiler.flash.tags.base.HasSeparateAlphaChannel;
+import com.jpexs.decompiler.flash.tags.base.ImageTag;
+import com.jpexs.decompiler.flash.tags.base.MissingCharacterHandler;
+import com.jpexs.decompiler.flash.tags.base.MorphShapeTag;
+import com.jpexs.decompiler.flash.tags.base.PlaceObjectTypeTag;
+import com.jpexs.decompiler.flash.tags.base.RenderContext;
+import com.jpexs.decompiler.flash.tags.base.ShapeTag;
+import com.jpexs.decompiler.flash.tags.base.SoundImportException;
+import com.jpexs.decompiler.flash.tags.base.SoundStreamHeadTypeTag;
+import com.jpexs.decompiler.flash.tags.base.SoundTag;
+import com.jpexs.decompiler.flash.tags.base.TextImportErrorHandler;
+import com.jpexs.decompiler.flash.tags.base.TextTag;
+import com.jpexs.decompiler.flash.tags.base.UnsupportedSamplingRateException;
+import com.jpexs.decompiler.flash.timeline.Timeline;
+import com.jpexs.decompiler.flash.timeline.Timelined;
+import com.jpexs.decompiler.flash.treeitems.OpenableList;
+import com.jpexs.decompiler.flash.types.CXFORMWITHALPHA;
+import com.jpexs.decompiler.flash.types.RECT;
+import com.jpexs.decompiler.flash.types.sound.SoundFormat;
+import com.jpexs.decompiler.flash.xfl.FLAVersion;
+import com.jpexs.decompiler.flash.xfl.XFLExportSettings;
+import com.jpexs.decompiler.graph.CompilationException;
+import com.jpexs.decompiler.graph.DottedChain;
+import com.jpexs.helpers.CancellableWorker;
+import com.jpexs.helpers.Helper;
+import com.jpexs.helpers.MemoryInputStream;
+import com.jpexs.helpers.Path;
+import com.jpexs.helpers.ProgressListener;
+import com.jpexs.helpers.SerializableImage;
+import com.jpexs.helpers.stat.StatisticData;
+import com.jpexs.helpers.stat.Statistics;
+import com.jpexs.helpers.streams.SeekableInputStream;
+import com.jpexs.helpers.utf8.Utf8Helper;
+import com.jpexs.decompiler.flash.exporters.swf.SwfToExeExporter;
+/*import com.jpexs.process.Process;
+import com.jpexs.process.ProcessTools;
+import com.sun.jna.Platform;
+import com.sun.jna.platform.win32.Kernel32;*/
+import gnu.jpdf.PDFGraphics;
+import gnu.jpdf.PDFJob;
+import java.awt.Font;
+import java.awt.Graphics;
+import java.awt.Graphics2D;
+import java.awt.Point;
+import java.awt.print.PageFormat;
+import java.awt.print.Paper;
+import java.io.BufferedInputStream;
+import java.io.BufferedOutputStream;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.FilenameFilter;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.PrintStream;
+import java.io.PrintWriter;
+import java.io.StringReader;
+import java.io.UnsupportedEncodingException;
+import java.lang.reflect.Field;
+import java.nio.charset.Charset;
+import java.nio.charset.StandardCharsets;
+import java.nio.file.Files;
+import java.nio.file.Paths;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Calendar;
+import java.util.Collections;
+import java.util.Date;
+import java.util.GregorianCalendar;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Set;
+import java.util.Stack;
+import java.util.concurrent.CancellationException;
+import java.util.concurrent.ExecutionException;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ *
+ * @author JPEXS
+ */
+public class CommandLineArgumentParser {
+
+ private static final Logger logger = Logger.getLogger(CommandLineArgumentParser.class.getName());
+
+ private static boolean commandLineMode = false;
+
+ private static boolean showStat = false;
+
+ private static String stdOut = null;
+
+ private static String stdErr = null;
+
+ private static final String METADATA_FORMAT_JSLIKE = "jslike";
+
+ private static final String METADATA_FORMAT_RAW = "raw";
+
+ public static boolean isCommandLineMode() {
+ return commandLineMode;
+ }
+
+ public static void printConfigurationSettings() {
+ Map fields = Configuration.getConfigurationFields();
+ String[] keys = new String[fields.size()];
+ keys = fields.keySet().toArray(keys);
+ Arrays.sort(keys);
+
+ System.out.println("Available keys[current setting]-type:");
+ for (String name : keys) {
+ Field field = fields.get(name);
+ if (ConfigurationItem.isInternal(field)) {
+ continue;
+ }
+
+ ConfigurationItem> item = ConfigurationItem.getItem(field);
+ Object value = item.get();
+ Class> type = ConfigurationItem.getConfigurationFieldType(field);
+ String valueString = objectToString(value, type);
+ String typeString = objectTypeToString(type);
+
+ if (typeString != null) {
+ System.out.println(name + "[" + valueString + "]-" + typeString);
+ }
+ }
+ }
+
+ private static String objectTypeToString(Class> type) {
+ if (type == String.class) {
+ return "string";
+ } else if (type == Calendar.class) {
+ return "date";
+ } else if ((type == Integer.class) || (type == Long.class)) {
+ return "integer";
+ } else if ((type == Double.class) || (type == Float.class)) {
+ return "float";
+ } else if (type == Boolean.class) {
+ return "bool";
+ } else if (type.isEnum()) {
+ return "enum";
+ }
+
+ return null;
+ }
+
+ private static String objectToString(Object obj, Class> type) {
+ if (obj == null) {
+ return "null";
+ }
+
+ if (type == String.class) {
+ //return '"' + obj.toString() + '"';
+ return obj.toString();
+ } else if (type == Calendar.class) {
+ return new SimpleDateFormat("yyyy/MM/dd HH:mm:ss").format(((Calendar) obj).getTime());
+ } else if ((type == Integer.class) || (type == Long.class) || (type == Double.class) || (type == Float.class)) {
+ return obj.toString();
+ } else if (type == Boolean.class) {
+ return ((boolean) (Boolean) obj) ? "true" : "false";
+ } else if (type.isEnum()) {
+ return obj.toString();
+ }
+
+ return null;
+ }
+
+ public static void printCmdLineUsage(String filter, boolean webHelp) {
+ printCmdLineUsage(System.out, webHelp, filter);
+ }
+
+ public static void printCmdLineUsage(PrintStream out, boolean webHelp, String filter) {
+ int cnt = 1;
+ out.println("Commandline arguments:");
+ if (filter == null) {
+ out.println(" " + (cnt++) + ") -help | --help | /?");
+ out.println(" ...shows commandline arguments (this help)");
+ out.println(" " + (cnt++) + ") [ ...]");
+ out.println(" ...opens SWF file(s) with the decompiler GUI");
+ }
+
+ if (filter == null || filter.equals("proxy")) {
+ out.println(" " + (cnt++) + ") -proxy [-P]");
+ out.println(" ...auto start proxy in the tray. Optional parameter -P specifies port for proxy. Defaults to 55555. ");
+ }
+
+ if (filter == null || filter.equals("export")) {
+ out.println(" " + (cnt++) + ") -export ");
+ out.println(" ...export sources to .");
+ out.println(" Exports all files from when it is a folder.");
+ out.println(" Values for parameter:");
+ out.println(" script - Scripts (Default format: ActionScript source)");
+ out.println(" image - Images (Default format: PNG/JPEG)");
+ out.println(" shape - Shapes (Default format: SVG)");
+ out.println(" morphshape - MorphShapes (Default format: SVG)");
+ out.println(" movie - Movies (Default format: FLV without sound)");
+ out.println(" font - Fonts (Default format: TTF)");
+ out.println(" font4 - DefineFont4 (Default format: CFF)");
+ out.println(" frame - Frames (Default format: PNG)");
+ out.println(" sprite - Sprites (Default format: PNG)");
+ out.println(" button - Buttons (Default format: PNG)");
+ out.println(" sound - Sounds (Default format: MP3/WAV/FLV only sound)");
+ out.println(" binaryData - Binary data (Default format: Raw data)");
+ out.println(" symbolClass - Symbol-Class mapping (Default format: CSV)");
+ out.println(" text - Texts (Default format: Plain text)");
+ out.println(" all - Every resource (but not FLA and XFL)");
+ out.println(" fla - Everything to FLA compressed format");
+ out.println(" xfl - Everything to uncompressed FLA format (XFL)");
+ out.println(" You can export multiple types of items by using colon \",\"");
+ out.println(" DO NOT PUT space between comma (,) and next value.");
+ out.println();
+ }
+
+ if (filter == null || filter.equals("format")) {
+ out.println(" " + (cnt++) + ") -format ");
+ out.println(" ...sets output formats for export");
+ out.println(" Values for parameter:");
+ out.println(" script:as - ActionScript source");
+ out.println(" script:pcode - ActionScript P-code");
+ out.println(" script:pcodehex - ActionScript P-code with hex");
+ out.println(" script:hex - ActionScript Hex only");
+ out.println(" shape:svg - SVG format for Shapes");
+ out.println(" shape:png - PNG format for Shapes");
+ out.println(" shape:canvas - HTML5 Canvas format for Shapes");
+ out.println(" shape:bmp - BMP format for Shapes");
+ out.println(" morphshape:svg - SVG format for MorphShapes");
+ out.println(" morphshape:canvas - HTML5 Canvas format for MorphShapes");
+ out.println(" frame:png - PNG format for Frames");
+ out.println(" frame:gif - GIF format for Frames");
+ out.println(" frame:avi - AVI format for Frames");
+ out.println(" frame:svg - SVG format for Frames");
+ out.println(" frame:canvas - HTML5 Canvas format for Frames");
+ out.println(" frame:pdf - PDF format for Frames");
+ out.println(" frame:bmp - BMP format for Frames");
+ out.println(" sprite:png - PNG format for Sprites");
+ out.println(" sprite:gif - GIF format for Sprites");
+ out.println(" sprite:avi - AVI format for Sprites");
+ out.println(" sprite:svg - SVG format for Sprites");
+ out.println(" sprite:canvas - HTML5 Canvas format for Sprites");
+ out.println(" sprite:pdf - PDF format for Sprites");
+ out.println(" sprite:bmp - BMP format for Sprites");
+ out.println(" button:png - PNG format for Buttons");
+ out.println(" button:svg - SVG format for Buttons");
+ out.println(" button:bmp - BMP format for Buttons");
+ out.println(" image:png_gif_jpeg - PNG/GIF/JPEG format for Images");
+ out.println(" image:png - PNG format for Images");
+ out.println(" image:jpeg - JPEG format for Images");
+ out.println(" image:bmp - BMP format for Images");
+ out.println(" image:png_gif_jpeg_alpha - PNG/GIF/JPEG+ALPHA format for Images");
+ out.println(" text:plain - Plain text format for Texts");
+ out.println(" text:formatted - Formatted text format for Texts");
+ out.println(" text:svg - SVG format for Texts");
+ out.println(" sound:mp3_wav_flv - MP3/WAV/FLV format for Sounds");
+ out.println(" sound:mp3_wav - MP3/WAV format for Sounds");
+ out.println(" sound:wav - WAV format for Sounds");
+ out.println(" sound:flv - FLV format for Sounds");
+ out.println(" font:ttf - TTF format for Fonts");
+ out.println(" font:woff - WOFF format for Fonts");
+ out.println(" font4:cff - CFF format for DefineFont4");
+ out.println(" fla: or xfl: - Specify FLA format version");
+ out.println(" - values for : cs5,cs5.5,cs6,cc");
+ out.println(" You can set multiple formats at once using comma (,)");
+ out.println(" DO NOT PUT space between comma (,) and next value.");
+ out.println(" The prefix with colon (:) is neccessary.");
+ }
+
+ if (filter == null || filter.equals("cli")) {
+ out.println(" " + (cnt++) + ") -cli");
+ out.println(" ...Command line mode. Parses the SWFs without opening the GUI");
+ }
+
+ if (filter == null || filter.equals("select")) {
+ out.println(" " + (cnt++) + ") -select ");
+ out.println(" ...selects frames/pages for export");
+ out.println(" Example formats:");
+ out.println(" 1-5");
+ out.println(" 2,3");
+ out.println(" 2-5,7,9-");
+ out.println(" DO NOT PUT space between comma (,) and next ramge.");
+ out.println(" " + (cnt++) + ") -selectid ");
+ out.println(" ...selects characters for export by character id");
+ out.println(" format is same as in -select");
+ }
+
+ if (filter == null || filter.equals("selectclass")) {
+ out.println(" " + (cnt++) + ") -selectclass ");
+ out.println(" ...selects scripts to export by class name (ActionScript 3 ONLY)");
+ out.println(" format:");
+ out.println(" com.example.MyClass");
+ out.println(" com.example.+ (all classes in package \"com.example\")");
+ out.println(" com.++,net.company.MyClass (all classes in package \"com\" and all subpackages, class net.company.MyClass)");
+ out.println(" DO NOT PUT space between comma (,) and next class.");
+ }
+
+ if (filter == null || filter.equals("exportembed")) {
+ out.println(" " + (cnt++) + ") -exportembed");
+ out.println(" ...Allows exporting embedded assets via [Embed tag]");
+ out.println(" Use in combination with -export -format script:as");
+ }
+
+ if (filter == null || filter.equals("dumpswf")) {
+ out.println(" " + (cnt++) + ") -dumpSWF ");
+ out.println(" ...dumps list of SWF tags to console");
+ }
+
+ if (filter == null || filter.equals("dumpas2")) {
+ out.println(" " + (cnt++) + ") -dumpAS2 ");
+ out.println(" ...dumps list of AS1/2 scripts to console");
+ }
+
+ if (filter == null || filter.equals("dumpas3")) {
+ out.println(" " + (cnt++) + ") -dumpAS3 ");
+ out.println(" ...dumps list of AS3 scripts to console");
+ }
+
+ if (filter == null || filter.equals("compress")) {
+ out.println(" " + (cnt++) + ") -compress [(zlib|lzma)]");
+ out.println(" ...Compress SWF and save it to . If is already compressed, it will be re-compressed. Default compression method is ZLIB");
+ }
+
+ if (filter == null || filter.equals("decompress")) {
+ out.println(" " + (cnt++) + ") -decompress ");
+ out.println(" ...Decompress and save it to ");
+ }
+
+ if (filter == null || filter.equals("encrypt")) {
+ out.println(" " + (cnt++) + ") -encrypt ");
+ out.println(" ...Encrypts file with HARMAN Air encryption and saves it to ");
+ }
+
+ if (filter == null || filter.equals("decrypt")) {
+ out.println(" " + (cnt++) + ") -decrypt ");
+ out.println(" ...Decrypts HARMAN Air encrypted file and saves it to ");
+ }
+
+ if (filter == null || filter.equals("swf2xml")) {
+ out.println(" " + (cnt++) + ") -swf2xml ");
+ out.println(" ...Converts the SWF to XML file");
+ }
+
+ if (filter == null || filter.equals("xml2swf")) {
+ out.println(" " + (cnt++) + ") -xml2swf ");
+ out.println(" ...Converts the XML to SWF file");
+ }
+
+ if (filter == null || filter.equals("extract")) {
+ out.println(" " + (cnt++) + ") -extract [-o |] [nocheck] [(all|biggest|smallest|first|last)]");
+ out.println(" ...Extracts SWF files from ZIP or other binary files");
+ out.println(" ...-o parameter should contain a file path when \"biggest\" or \"first\" parameter is specified");
+ out.println(" ...-o parameter should contain a folder path when no extaction mode or \"all\" parameter is specified");
+ }
+
+ if (filter == null || filter.equals("memorysearch")) {
+ out.println(" " + (cnt++) + ") -memorySearch (|) (|)...");
+ out.println(" ...Search SWF files in the memory");
+ }
+
+ if (filter == null || filter.equals("renameinvalididentifiers")) {
+ out.println(" " + (cnt++) + ") -renameInvalidIdentifiers (typeNumber|randomWord) ");
+ out.println(" ...Renames the invalid identifiers in and save it to ");
+ }
+
+ if (filter == null || filter.equals("config")) {
+ out.println(" " + (cnt++) + ") -config key=value[,key2=value2][,key3=value3...] [other parameters]");
+ out.print(" ...Sets configuration values. Use -listconfigs command to list the available configuration settings.");
+ out.println();
+ out.println(" Values are boolean, you can use 0/1, true/false, on/off or yes/no.");
+ out.println(" If no other parameters passed, configuration is saved. Otherwise it is used only once.");
+ out.println(" DO NOT PUT space between comma (,) and next value.");
+ }
+
+ if (filter == null || filter.equals("onerror")) {
+ out.println(" " + (cnt++) + ") -onerror (abort|retryN|ignore)");
+ out.println(" ...error handling mode. \"abort\" stops the exporting, \"retry\" tries the exporting N times, \"ignore\" ignores the current file");
+ }
+
+ if (filter == null || filter.equals("timeout")) {
+ out.println(" " + (cnt++) + ") -timeout ");
+ out.println(" ...decompilation timeout for a single method in AS3 or single action in AS1/2 in seconds");
+ }
+
+ if (filter == null || filter.equals("exporttimeout")) {
+ out.println(" " + (cnt++) + ") -exportTimeout ");
+ out.println(" ...total export timeout in seconds");
+ }
+
+ if (filter == null || filter.equals("exportfiletimeout")) {
+ out.println(" " + (cnt++) + ") -exportFileTimeout ");
+ out.println(" ...export timeout for a single AS3 class in seconds");
+ }
+
+ if (filter == null || filter.equals("stat")) {
+ out.println(" " + (cnt++) + ") -stat");
+ out.println(" ...show export performance statistics");
+ }
+
+ if (filter == null || filter.equals("flashpaper2pdf")) {
+ out.println(" " + (cnt++) + ") -flashpaper2pdf ");
+ out.println(" ...converts FlashPaper SWF file to PDF . Use -zoom parameter to specify image quality.");
+ }
+
+ if (filter == null || filter.equals("zoom")) {
+ out.println(" " + (cnt++) + ") -zoom ");
+ out.println(" ...apply zoom during export");
+ }
+
+ if (filter == null || filter.equals("replace")) {
+ out.println(" " + (cnt++) + ") -replace (|) [nofill] ([][]) [(|) [nofill] ([][])]...");
+ out.println(" ...replaces the data of the specified BinaryData, Image, Shape, Text, Sound tag or Script");
+ out.println(" ...nofill parameter can be specified only for shape replace");
+ out.println(" ... parameter can be specified for Image and Shape tags");
+ out.println(" ...valid formats: lossless, lossless2, jpeg2, jpeg3, jpeg4");
+ out.println(" ... parameter should be specified if and only if the imported entity is an AS3 P-Code");
+ out.println(" ...use -1 as characterId to replace main timeline SoundStreamHead");
+
+ out.println(" " + (cnt++) + ") -replace ");
+ out.println(" ... same as -replace command, but the rest of arguments is read as lines from a text file ");
+
+ }
+
+ if (filter == null || filter.equals("replacealpha")) {
+ out.println(" " + (cnt++) + ") -replaceAlpha [ ]...");
+ out.println(" ...replaces the alpha channel of the specified JPEG3 or JPEG4 tag");
+ }
+
+ if (filter == null || filter.equals("replacecharacter")) {
+ out.println(" " + (cnt++) + ") -replaceCharacter [ ]...");
+ out.println(" ...replaces a character tag with another character tag from the same SWF");
+ }
+
+ if (filter == null || filter.equals("replacecharacterid")) {
+ out.println(" " + (cnt++) + ") -replaceCharacterId ,,,... or");
+ out.println(" " + (cnt++) + ") -replaceCharacterId (pack|sort)");
+ out.println(" ...replaces the character id with ");
+ out.println(" ...pack: removes the spaces between the character ids (1,4,3 => 1,3,2)");
+ out.println(" ...sort: assigns increasing IDs to the character tags + pack (1,4,3 => 1,2,3)");
+ out.println(" DO NOT PUT space between comma (,) and next value.");
+ }
+
+ if (filter == null || filter.equals("remove")) {
+ out.println(" " + (cnt++) + ") -remove []...");
+ out.println(" ...removes a tag from the SWF");
+ }
+
+ if (filter == null || filter.equals("removecharacter")) {
+ out.println(" " + (cnt++) + ") -removeCharacter[WithDependencies] []...");
+ out.println(" ...removes a character tag from the SWF");
+ }
+
+ if (filter == null || filter.equals("importsymbolclass")) {
+ out.println(" " + (cnt++) + ") -importSymbolClass ");
+ out.println(" ...imports Symbol-Class mapping to and saves the result to ");
+ }
+
+ if (filter == null || filter.equals("importmovies")) {
+ out.println(" " + (cnt++) + ") -importMovies ");
+ out.println(" ...imports movies to and saves the result to ");
+ }
+
+ if (filter == null || filter.equals("importsounds")) {
+ out.println(" " + (cnt++) + ") -importSounds ");
+ out.println(" ...imports sounds to and saves the result to ");
+ }
+
+ if (filter == null || filter.equals("importshapes")) {
+ out.println(" " + (cnt++) + ") -importShapes [nofill] ");
+ out.println(" ...imports shapes to and saves the result to ");
+ }
+
+ if (filter == null || filter.equals("importimages")) {
+ out.println(" " + (cnt++) + ") -importImages ");
+ out.println(" ...imports images to and saves the result to ");
+ }
+
+ if (filter == null || filter.equals("importsprites")) {
+ out.println(" " + (cnt++) + ") -importSprites ");
+ out.println(" ...imports sprites to and saves the result to ");
+ }
+
+ if (filter == null || filter.equals("importtext")) {
+ out.println(" " + (cnt++) + ") -importText ");
+ out.println(" ...imports texts to and saves the result to ");
+ }
+
+ if (filter == null || filter.equals("importscript")) {
+ out.println(" " + (cnt++) + ") -importScript ");
+ out.println(" ...imports scripts to and saves the result to ");
+ }
+
+ if (filter == null || filter.equals("deobfuscate")) {
+ out.println(" " + (cnt++) + ") -deobfuscate ");
+ out.println(" ...Deobfuscates AS3 P-code in and saves result to ");
+ out.println(" ... can be one of: traps/2/max, deadcode/1");
+ out.println(" ...WARNING: The deobfuscation result is still probably far enough to be openable by other decompilers.");
+ }
+
+ if (filter == null || filter.equals("enabledebugging")) {
+ out.println(" " + (cnt++) + ") -enabledebugging [-injectas3|-generateswd] [-pcode] ");
+ out.println(" ...Enables debugging for and saves result to ");
+ out.println(" ...-injectas3 (optional) causes debugfile and debugline instructions to be injected into the code to match decompiled/pcode source.");
+ out.println(" ...-generateswd (optional) parameter creates SWD file needed for AS1/2 debugging. for , is generated");
+ out.println(" ...-pcode (optional) parameter specified after -injectas3 or -generateswd causes lines to be handled as lines in P-code => All P-code lines are injected, etc.");
+ out.println(" ...WARNING: Injected/SWD script filenames may be different than from standard compiler");
+ }
+
+ if (filter == null || filter.equals("custom")) {
+ out.println(" " + (cnt++) + ") -custom []...");
+ out.println(" ...Forwards all parameters after the -custom parameter to the plugins");
+ }
+
+ if (filter == null || filter.equals("doc")) {
+ out.println(" " + (cnt++) + ") -doc -type [-out ] [-format ] [-locale ]");
+ out.println(" ...Generate documentation");
+ out.println(" ...-type Selects documentation type");
+ out.println(" ... can be currently only: as3.pcode.instructions for list of ActionScript3 AVM2 instructions");
+ out.println(" ...-out (optional) If specified, output is written to instead of stdout");
+ out.println(" ...-format (optional, html is default) Selects output format");
+ out.println(" ... is currently only html");
+ out.println(" ...-locale (optional) Override default locale");
+ out.println(" ... is localization identifier, en for english for example");
+ out.println(" ... is currently only html");
+ }
+
+ if (filter == null || filter.equals("getinstancemetadata")) {
+ out.println(" " + (cnt++) + ") -getInstanceMetadata -instance [-outputFormat ] [-key ] [-datafile ] ");
+ out.println(" ...reads instance metadata");
+ out.println(" ...-instance : name of instance to fetch metadata from");
+ out.println(" ...-outputFormat (optional): format of output - one of: jslike|raw. Default is jslike.");
+ out.println(" ...- key (optional): name of subkey to display. When present, only value from subkey is shown, whole object value otherwise.");
+ out.println(" ...-datafile (optional): File to write the data to. If ommited, stdout is used.");
+ out.println(" ...: SWF file to read metadata from");
+ }
+
+ if (filter == null || filter.equals("setinstancemetadata")) {
+ out.println(" " + (cnt++) + ") -setInstanceMetadata -instance [-inputFormat ] [-key ] [-value | -datafile ] [-outfile ] ");
+ out.println(" ...adds metadata to instance");
+ out.println(" ...-instance : name of instance to replace data in");
+ out.println(" ...-inputFormat : format of input data - one of: jslike|raw. Default is jslike.");
+ out.println(" ...- key (optional): name of subkey to use. When present, the value is set as object property with the name.");
+ out.println(" Otherwise the value is set directly to the instance without any subkeys.");
+ out.println(" ...-value (optional): value to set.");
+ out.println(" ...-datafile (optional): value to set from file.");
+ out.println(" ...If no -value or -infile parameter present, the value to set is taken from stdin.");
+ out.println(" ...-outfile (optional): Where to save resulting file. If ommited, original SWF file is overwritten.");
+ out.println(" ...: SWF file to search instance in");
+ }
+
+ if (filter == null || filter.equals("removeinstancemetadata")) {
+ out.println(" " + (cnt++) + ") -removeInstanceMetadata -instance [-key ] [-outfile ] ");
+ out.println(" ...removes metadata from instance");
+ out.println(" ...-instance : name of instance to remove data from");
+ out.println(" ...- key (optional): name of subkey to remove. When present, only the value from subkey of the AMF object is removed.");
+ out.println(" Otherwise all metadata are removed from the instance.");
+ out.println(" ...-outfile (optional): Where to save resulting file. If ommited, original SWF file is overwritten.");
+ out.println(" ...: SWF file to search instance in");
+ }
+
+ if (filter == null || filter.equals("linkreport")) {
+ out.println(" " + (cnt++) + ") -linkReport [-outfile ] ");
+ out.println(" ...generates linker report for the swffile");
+ out.println(" ...-outfile (optional): Saves XML report to . When ommited, the report is printed to stdout.");
+ out.println(" ...: SWF file to search instance in");
+ }
+
+ if (filter == null || filter.equals("swf2swc")) {
+ out.println(" " + (cnt++) + ") -swf2swc ");
+ out.println(" ...generates SWC file from SWF");
+ out.println(" ...: Where to save SWC file");
+ out.println(" ...: Input SWF file");
+ }
+
+ if (filter == null || filter.equals("abcmerge")) {
+ out.println(" " + (cnt++) + ") -abcmerge ");
+ out.println(" ...merge all ABC tags in SWF file to one");
+ out.println(" ...: Where to save merged file");
+ out.println(" ...: Input SWF file");
+ }
+
+ if (filter == null || filter.equals("swf2exe")) {
+ out.println(" " + (cnt++) + ") -swf2exe ");
+ out.println(" ...export SWF to executable file");
+ out.println(" ...: wrapper|projector_win||projector_mac|projector_linux");
+ }
+
+ if (filter == null || filter.equals("charset")) {
+ out.println(" " + (cnt++) + ") -charset ");
+ out.println(" ...sets desired character set for reading/writing SWF files with SWF version <= 5");
+ out.println(" (use in combination with other commands)");
+ }
+
+ if (filter == null || filter.equals("air")) {
+ out.println(" " + (cnt++) + ") -air");
+ out.println(" ...use AIR (airglobal.swc) for AS3 compilation instead of playerglobal.swc");
+ out.println(" (use in combination with other commands)");
+ }
+
+ if (filter == null || filter.equals("header")) {
+ out.println(" " + (cnt++) + ") -header -set [-set ...] []");
+ out.println(" ...prints header or sets SWF header values (with -set arguments) in and saves it to ");
+ out.println(" Available keys: version");
+ out.println(" gfx (true/false)");
+ out.println(" displayrect ([x1,y1,x2,y2])");
+ out.println(" width");
+ out.println(" height");
+ out.println(" framecount");
+ out.println(" framerate");
+ out.println(" For width, height and displayrect subvalues you can use suffix px for pixel values. Otherwise its twips.");
+ }
+
+ printCmdLineUsageExamples(out, filter);
+
+ System.out.println("You can use special value \"/dev/stdin\" for input files to read data from standard input (even on Windows)");
+ }
+
+ private static void printCmdLineUsageExamples(PrintStream out, String filter) {
+ out.println();
+ out.println("Examples:");
+
+ final String PREFIX = "ffdec-cli old ";
+
+ boolean exampleFound = false;
+ if (filter == null) {
+ out.println(PREFIX + "myfile.swf");
+ exampleFound = true;
+ }
+
+ if (filter == null || filter.equals("proxy")) {
+ out.println(PREFIX + "-proxy");
+ out.println(PREFIX + "-proxy -P1234");
+ exampleFound = true;
+ }
+
+ if (filter == null || filter.equals("export") || filter.equals("format") || filter.equals("selectclass") || filter.equals("onerror")) {
+ out.println(PREFIX + "-export script \"C:\\decompiled\" myfile.swf");
+ out.println(PREFIX + "-selectclass com.example.MyClass,com.example.SecondClass -export script \"C:\\decompiled\" myfile.swf");
+ out.println(PREFIX + "-format script:pcode -export script \"C:\\decompiled\" myfile.swf");
+ out.println(PREFIX + "-format script:pcode,text:plain -export script,text,image \"C:\\decompiled\" myfile.swf");
+ out.println(PREFIX + "-format fla:cs5.5 -export fla \"C:\\sources\\myfile.fla\" myfile.swf");
+ out.println(PREFIX + "-onerror ignore -export script \"C:\\decompiled\" myfile.swf");
+ out.println(PREFIX + "-onerror retry 5 -export script \"C:\\decompiled\" myfile.swf");
+ exampleFound = true;
+ }
+
+ if (filter == null || filter.equals("cli")) {
+ out.println(PREFIX + "-cli myfile.swf");
+ exampleFound = true;
+ }
+
+ if (filter == null || filter.equals("dumpswf")) {
+ out.println(PREFIX + "-dumpSWF myfile.swf");
+ exampleFound = true;
+ }
+
+ if (filter == null || filter.equals("compress")) {
+ out.println(PREFIX + "-compress myfile.swf myfilecomp.swf");
+ exampleFound = true;
+ }
+
+ if (filter == null || filter.equals("decompress")) {
+ out.println(PREFIX + "-decompress myfile.swf myfiledec.swf");
+ exampleFound = true;
+ }
+
+ if (filter == null || filter.equals("config")) {
+ out.println(PREFIX + "-config autoDeobfuscate=1,parallelSpeedUp=0 -export script \"C:\\decompiled\" myfile.swf");
+ exampleFound = true;
+ }
+
+ if (filter == null || filter.equals("deobfuscate")) {
+ out.println(PREFIX + "-deobfuscate max myas3file_secure.swf myas3file.swf");
+ exampleFound = true;
+ }
+
+ if (filter == null || filter.equals("enabledebugging")) {
+ out.println(PREFIX + "-enabledebugging -injectas3 myas3file.swf myas3file_debug.swf");
+ out.println(PREFIX + "-enabledebugging -generateswd myas2file.swf myas2file_debug.swf");
+ exampleFound = true;
+ }
+
+ if (filter == null || filter.equals("doc")) {
+ out.println(PREFIX + "-doc -type as3.pcode.instructions -format html");
+ out.println(PREFIX + "-doc -type as3.pcode.instructions -format html -locale en -out as3_docs_en.html");
+ exampleFound = true;
+ }
+
+ if (filter == null || filter.equals("getinstancemetadata")) {
+ out.println(PREFIX + "-getInstanceMetadata -instance myobj -key keyone myfile.swf");
+ out.println(PREFIX + "-getInstanceMetadata -instance myobj2 -outputFormat raw -outfile out.amf myfile.swf");
+ exampleFound = true;
+ }
+ if (filter == null || filter.equals("setinstancemetadata")) {
+ out.println(PREFIX + "-setInstanceMetadata -instance myobj -key mykey -value 1234 myfile.swf");
+ out.println(PREFIX + "-setInstanceMetadata -instance myobj -key my -inputFormat raw -datafile value.amf -outfile modified.swf myfile.swf");
+ exampleFound = true;
+ }
+
+ if (filter == null || filter.equals("removeinstancemetadata")) {
+ out.println(PREFIX + "-removeInstanceMetadata -instance myobj -key mykey -outfile result.swf myfile.swf");
+ out.println(PREFIX + "-removeInstanceMetadata -instance myobj myfile.swf");
+ exampleFound = true;
+ }
+
+ if (filter == null || filter.equals("swf2exe")) {
+ out.println(PREFIX + "-swf2exe wrapper result.exe myfile.swf");
+ exampleFound = true;
+ }
+
+ if (filter == null || filter.equals("header")) {
+ out.println(PREFIX + "-header myfile.swf");
+ out.println(PREFIX + "-header -set version 10 -set width 800px -set framerate 23.5 myfile.swf outfile.swf");
+ out.println(PREFIX + "-header -set displayrect [0,0,800px,600px] myfile.swf outfile.swf");
+ out.println(PREFIX + "-header -set gfx true myfile.swf outfile.swf");
+ exampleFound = true;
+ }
+
+ if (!exampleFound) {
+ out.println("Sorry, no example found for command " + filter + ", Let us know in issue tracker when you need it.");
+ }
+
+ out.println();
+ }
+
+ /**
+ * Parses the console arguments
+ *
+ * @param arguments Arguments
+ * @return paths to the file which should be opened or null
+ * @throws java.io.IOException On error
+ */
+ public static String[] parseArguments(String[] arguments) throws IOException {
+ Level traceLevel = Level.WARNING;
+ Stack args = new Stack<>();
+ for (int i = arguments.length - 1; i >= 0; i--) {
+ String arg = arguments[i];
+ if (arg.length() > 0) {
+ args.add(arg);
+ }
+ }
+
+ AbortRetryIgnoreHandler handler = null;
+ Map format = new HashMap<>();
+ double zoom = 1;
+ String charset = Charset.defaultCharset().name();
+ boolean cliMode = false;
+ boolean air = false;
+ boolean exportEmbed = false;
+ Selection selection = new Selection();
+ Selection selectionIds = new Selection();
+ List selectionClasses = null;
+ String nextParam = null;
+ String nextParamOriginal = null;
+ OUTER:
+ while (true) {
+ nextParamOriginal = args.pop();
+ if (nextParamOriginal != null) {
+ nextParam = nextParamOriginal.toLowerCase(Locale.ENGLISH);
+ }
+ if (nextParam == null) {
+ nextParam = "";
+ }
+ switch (nextParam) {
+ case "-air":
+ air = true;
+ break;
+ case "-cli":
+ cliMode = true;
+ break;
+ case "-selectid":
+ selectionIds = parseSelect(args);
+ break;
+ case "-select":
+ selection = parseSelect(args);
+ break;
+ case "-selectclass":
+ selectionClasses = parseSelectClass(args);
+ break;
+ case "-exportembed":
+ exportEmbed = true;
+ break;
+ case "-zoom":
+ zoom = parseZoom(args);
+ break;
+ case "-format":
+ format = parseFormat(args);
+ break;
+ case "-charset":
+ charset = parseCharset(args);
+ break;
+ case "-config":
+ parseConfig(args);
+ if (args.isEmpty()) {
+ Configuration.saveConfig();
+ System.out.println("Configuration saved");
+ return null;
+ }
+ break;
+ case "-onerror":
+ handler = parseOnError(args);
+ break;
+ case "-timeout":
+ parseTimeout(args);
+ break;
+ case "-exporttimeout":
+ parseExportTimeout(args);
+ break;
+ case "-exportfiletimeout":
+ parseExportFileTimeout(args);
+ break;
+ case "-stat":
+ parseStat(args);
+ break;
+ case "-info":
+ parseInfo(args, charset);
+ System.exit(0);
+ break;
+ case "-stdout":
+ parseStdOut(args);
+ break;
+ case "-stderr":
+ parseStdErr(args);
+ break;
+ /*case "-affinity":
+ parseAffinity(args);
+ break;
+ case "-priority":
+ parsePriority(args);
+ break;*/
+ case "-verbose":
+ traceLevel = Level.FINE;
+ break;
+ case "-debug":
+ for (int i = 0; i < arguments.length; i++) {
+ System.out.println(i + ".:" + arguments[i]);
+ }
+ Configuration._debugMode.set(true);
+ break;
+ default:
+ break OUTER;
+ }
+ if (args.isEmpty()) {
+ return null;
+ }
+ }
+
+ String command = "";
+ if (nextParam == null) {
+ nextParam = "";
+ }
+ if (nextParam.startsWith("-")) {
+ command = nextParam.substring(1);
+ }
+
+ if (command.equals("header")) {
+ parseHeader(args);
+ System.exit(0);
+ } /*else if (command.equals("translator")) {
+ Translator.main(new String[]{});
+ } */
+ else if (command.equals("swf2exe")) {
+ parseSwf2Exe(args, charset);
+ System.exit(0);
+ } else if (command.equals("abcmerge")) {
+ parseAbcMerge(args, charset);
+ System.exit(0);
+ } else if (command.equals("swf2swc")) {
+ parseSwf2Swc(args, charset);
+ System.exit(0);
+ } else if (command.equals("linkreport")) {
+ parseLinkReport(selectionClasses, args, charset);
+ System.exit(0);
+ } else if (command.equals("getinstancemetadata")) {
+ parseGetInstanceMetadata(args, charset);
+ System.exit(0);
+ } else if (command.equals("setinstancemetadata")) {
+ parseSetInstanceMetadata(args, charset);
+ System.exit(0);
+ } else if (command.equals("removeinstancemetadata")) {
+ parseRemoveInstanceMetadata(args, charset);
+ System.exit(0);
+ } /*else if (command.equals("removefromcontextmenu")) {
+ if (!args.isEmpty()) {
+ badArguments(command);
+ }
+ ContextMenuTools.addToContextMenu(false, true);
+ System.exit(0);
+ } else if (command.equals("addtocontextmenu")) {
+ if (!args.isEmpty()) {
+ badArguments(command);
+ }
+ ContextMenuTools.addToContextMenu(true, true);
+ System.exit(0);
+ } else if (command.equals("proxy")) {
+ parseProxy(args);
+ } */ else if (command.equals("export")) {
+ parseExport(selectionClasses, selection, selectionIds, args, handler, traceLevel, format, zoom, charset, exportEmbed);
+ System.exit(0);
+ } else if (command.equals("compress")) {
+ parseCompress(args);
+ System.exit(0);
+ } else if (command.equals("decompress")) {
+ parseDecompress(args);
+ System.exit(0);
+ } else if (command.equals("encrypt")) {
+ parseDecrypt(args);
+ System.exit(0);
+ } else if (command.equals("decrypt")) {
+ parseDecrypt(args);
+ System.exit(0);
+ } else if (command.equals("swf2xml")) {
+ parseSwf2Xml(args, charset);
+ System.exit(0);
+ } else if (command.equals("xml2swf")) {
+ parseXml2Swf(args, charset);
+ System.exit(0);
+ } else if (command.equals("extract")) {
+ parseExtract(args);
+ System.exit(0);
+ } /*else if (command.equals("memorysearch")) {
+ parseMemorySearch(args);
+ System.exit(0);
+ } */ else if (command.equals("deobfuscate")) {
+ parseDeobfuscate(args, charset);
+ System.exit(0);
+ } else if (command.equals("renameinvalididentifiers")) {
+ parseRenameInvalidIdentifiers(args);
+ System.exit(0);
+ } /*else if (command.equals("dumpswf")) {
+ parseDumpSwf(args);
+ System.exit(0);
+ } */ else if (command.equals("dumpas2")) {
+ parseDumpAS2(args, charset);
+ System.exit(0);
+ } else if (command.equals("dumpas3")) {
+ parseDumpAS3(args, charset);
+ System.exit(0);
+ } else if (command.equals("enabledebugging")) {
+ parseEnableDebugging(args, charset);
+ System.exit(0);
+ } else if (command.equals("flashpaper2pdf")) {
+ parseFlashPaperToPdf(selection, zoom, args, charset);
+ System.exit(0);
+ } else if (command.equals("replace")) {
+ parseReplace(args, charset, air);
+ System.exit(0);
+ } else if (command.equals("replacealpha")) {
+ parseReplaceAlpha(args, charset);
+ System.exit(0);
+ } else if (command.equals("replacecharacter")) {
+ parseReplaceCharacter(args, charset);
+ System.exit(0);
+ } else if (command.equals("replacecharacterid")) {
+ parseReplaceCharacterId(args, charset);
+ System.exit(0);
+ } else if (command.equals("convert")) {
+ parseConvert(args, charset);
+ System.exit(0);
+ } else if (command.equals("remove")) {
+ parseRemove(args, charset);
+ System.exit(0);
+ } else if (command.equals("removecharacter")) {
+ parseRemoveCharacter(args, false, charset);
+ System.exit(0);
+ } else if (command.equals("removecharacterwithdependencies")) {
+ parseRemoveCharacter(args, true, charset);
+ System.exit(0);
+ } else if (command.equals("doc")) {
+ parseDoc(args);
+ } else if (command.equals("importsymbolclass")) {
+ parseImportSymbolClass(args, charset);
+ System.exit(0);
+ } else if (command.equals("importmovies")) {
+ parseImportMovies(args, charset);
+ System.exit(0);
+ } else if (command.equals("importsounds")) {
+ parseImportSounds(args, charset);
+ System.exit(0);
+ } else if (command.equals("importshapes")) {
+ parseImportShapes(args, charset);
+ System.exit(0);
+ } else if (command.equals("importimages")) {
+ parseImportImages(args, charset);
+ System.exit(0);
+ } else if (command.equals("importsprites")) {
+ parseImportSprites(args, charset);
+ System.exit(0);
+ } else if (command.equals("importtext")) {
+ parseImportText(args, charset);
+ System.exit(0);
+ } else if (command.equals("importscript")) {
+ parseImportScript(args, charset, air, handler);
+ System.exit(0);
+ } else if (command.equals("as3compiler")) {
+ ActionScript3Parser.compile(null /*?*/, args.pop(), args.pop(), 0, 0);
+ } /*else if (nextParam.equals("--debugtool")) {
+ parseDebugTool(args, charset);
+ } else if (nextParam.equals("--compareresources")) {
+ parseCompareResources(args);
+ System.exit(0);
+ } else if (nextParam.equals("--resourcedates")) {
+ parseResourceDates(args);
+ System.exit(0);
+ } */else if (nextParam.equals("-listconfigs")) {
+ printHeader();
+ printConfigurationSettings();
+ System.exit(0);
+ } else if (nextParam.equals("-help") || nextParam.equals("--help") || nextParam.equals("/?") || nextParam.equals("\\_") /* /? translates as this on windows */) {
+ printHeader();
+ printCmdLineUsage(null, false);
+ System.exit(0);
+ } else if (nextParam.equals("--webhelp")) { //for generating commandline usage on webpages
+ ByteArrayOutputStream whbaos = new ByteArrayOutputStream();
+ printCmdLineUsage(new PrintStream(whbaos, true), true, null);
+ String wh = new String(whbaos.toByteArray());
+ wh = wh.replace("<", "<").replace(">", ">");
+ System.out.println(wh);
+ System.exit(0);
+ } else {
+ args.push(nextParamOriginal); // file names should be the original one
+ List fileNames = new ArrayList<>();
+ boolean allParamIsAFile = true;
+ while (!args.isEmpty()) {
+ String arg = args.pop();
+ if (arg.equals("-custom")) {
+ parseCustom(args);
+ break;
+ }
+
+ fileNames.add(arg);
+ File file = new File(arg);
+ if (!file.exists() || !file.isFile()) {
+ allParamIsAFile = false;
+ }
+ }
+
+ if (allParamIsAFile) {
+ String[] fileNamesArray = fileNames.toArray(new String[fileNames.size()]);
+ if (cliMode) {
+ //loadFiles(fileNamesArray);
+ return null;
+ } else {
+ return fileNamesArray;
+ }
+ } else {
+ badArguments();
+ }
+ }
+
+ return null;
+ }
+
+ public static void printHeader() {
+ System.out.println(ApplicationInfo.applicationVerName);
+ for (int i = 0; i < ApplicationInfo.applicationVerName.length(); i++) {
+ System.out.print("-");
+ }
+ System.out.println();
+
+ System.err.println("WARNING: You are using outdated CLI interface. Please use other commands than 'ffde-cli old'.");
+ }
+
+ public static void badArguments() {
+ badArguments(null);
+ }
+
+ public static void badArguments(String command) {
+ System.err.println("Error: Bad Commandline Arguments!");
+ printCmdLineUsage(command, false);
+ System.exit(1);
+ }
+
+ @SuppressWarnings("unchecked")
+ private static void setConfigurations(String cfgStr) {
+ String[] cfgs;
+ if (cfgStr.contains(",")) {
+ cfgs = cfgStr.split(",");
+ } else {
+ cfgs = new String[]{cfgStr};
+ }
+
+ Map fields = Configuration.getConfigurationFields(true);
+ for (String c : cfgs) {
+ String[] cp = c.split("=");
+ if (cp.length == 1) {
+ cp = new String[]{cp[0], "1"};
+ }
+
+ Field field = fields.get(cp[0].toLowerCase(Locale.ENGLISH));
+ ConfigurationItem> item = ConfigurationItem.getItem(field);
+ String stringValue = cp[1];
+ Class> type = ConfigurationItem.getConfigurationFieldType(field);
+
+ if (type == String.class) {
+ System.out.println("Config " + item.getName() + " set to " + stringValue);
+ ((ConfigurationItem) item).set(stringValue);
+ } else if (type == Calendar.class) {
+ SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
+ Date dateValue;
+ try {
+ dateValue = dateFormat.parse(stringValue);
+ GregorianCalendar calendarValue = new GregorianCalendar();
+ calendarValue.setTime(dateValue);
+ ((ConfigurationItem