diff --git a/CommandLineArgumentParser.java b/CommandLineArgumentParser.java
deleted file mode 100644
index 0cc93c8e9..000000000
--- a/CommandLineArgumentParser.java
+++ /dev/null
@@ -1,4161 +0,0 @@
-/*
- * Copyright (C) 2010-2021 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.console;
-
-import com.jpexs.decompiler.flash.AbortRetryIgnoreHandler;
-import com.jpexs.decompiler.flash.ApplicationInfo;
-import com.jpexs.decompiler.flash.EventListener;
-import com.jpexs.decompiler.flash.IdentifiersDeobfuscation;
-import com.jpexs.decompiler.flash.ReadOnlyTagList;
-import com.jpexs.decompiler.flash.SWF;
-import com.jpexs.decompiler.flash.SWFBundle;
-import com.jpexs.decompiler.flash.SWFCompression;
-import com.jpexs.decompiler.flash.SWFSourceInfo;
-import com.jpexs.decompiler.flash.SearchMode;
-import com.jpexs.decompiler.flash.SwfOpenException;
-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.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.TextExporter;
-import com.jpexs.decompiler.flash.exporters.amf.amf3.Amf3Exporter;
-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.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.TextExportMode;
-import com.jpexs.decompiler.flash.exporters.script.LinkReportExporter;
-import com.jpexs.decompiler.flash.exporters.settings.BinaryDataExportSettings;
-import com.jpexs.decompiler.flash.exporters.settings.ButtonExportSettings;
-import com.jpexs.decompiler.flash.exporters.settings.FontExportSettings;
-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.TextExportSettings;
-import com.jpexs.decompiler.flash.exporters.swf.SwfToSwcExporter;
-import com.jpexs.decompiler.flash.exporters.swf.SwfXmlExporter;
-import com.jpexs.decompiler.flash.flexsdk.MxmlcAs3ScriptReplacer;
-import com.jpexs.decompiler.flash.gui.AppStrings;
-import com.jpexs.decompiler.flash.gui.Main;
-import com.jpexs.decompiler.flash.gui.SearchInMemory;
-import com.jpexs.decompiler.flash.gui.SearchInMemoryListener;
-import com.jpexs.decompiler.flash.gui.SwfInMemory;
-import com.jpexs.decompiler.flash.gui.helpers.CheckResources;
-import com.jpexs.decompiler.flash.helpers.FileTextWriter;
-import com.jpexs.decompiler.flash.helpers.SWFDecompilerPlugin;
-import com.jpexs.decompiler.flash.importers.AS2ScriptImporter;
-import com.jpexs.decompiler.flash.importers.AS3ScriptImporter;
-import com.jpexs.decompiler.flash.importers.As3ScriptReplaceException;
-import com.jpexs.decompiler.flash.importers.As3ScriptReplaceExceptionItem;
-import com.jpexs.decompiler.flash.importers.As3ScriptReplacerFactory;
-import com.jpexs.decompiler.flash.importers.As3ScriptReplacerInterface;
-import com.jpexs.decompiler.flash.importers.BinaryDataImporter;
-import com.jpexs.decompiler.flash.importers.FFDecAs3ScriptReplacer;
-import com.jpexs.decompiler.flash.importers.FontImporter;
-import com.jpexs.decompiler.flash.importers.ImageImporter;
-import com.jpexs.decompiler.flash.importers.MorphShapeImporter;
-import com.jpexs.decompiler.flash.importers.ShapeImporter;
-import com.jpexs.decompiler.flash.importers.SwfXmlImporter;
-import com.jpexs.decompiler.flash.importers.TextImporter;
-import com.jpexs.decompiler.flash.importers.amf.amf3.Amf3Importer;
-import com.jpexs.decompiler.flash.importers.amf.amf3.Amf3ParseException;
-import com.jpexs.decompiler.flash.importers.svg.SvgImporter;
-import com.jpexs.decompiler.flash.tags.ABCContainerTag;
-import com.jpexs.decompiler.flash.tags.DefineBinaryDataTag;
-import com.jpexs.decompiler.flash.tags.DefineBitsJPEG2Tag;
-import com.jpexs.decompiler.flash.tags.DefineBitsJPEG3Tag;
-import com.jpexs.decompiler.flash.tags.DefineBitsJPEG4Tag;
-import com.jpexs.decompiler.flash.tags.DefineSpriteTag;
-import com.jpexs.decompiler.flash.tags.FileAttributesTag;
-import com.jpexs.decompiler.flash.tags.JPEGTablesTag;
-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.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.ShapeTag;
-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.timeline.Timelined;
-import com.jpexs.decompiler.flash.treeitems.SWFList;
-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.stat.StatisticData;
-import com.jpexs.helpers.stat.Statistics;
-import com.jpexs.helpers.streams.SeekableInputStream;
-import com.jpexs.helpers.utf8.Utf8Helper;
-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.PDFJob;
-import java.awt.Color;
-import java.awt.Graphics;
-import java.awt.image.BufferedImage;
-import java.awt.print.PageFormat;
-import java.awt.print.Paper;
-import java.io.BufferedInputStream;
-import java.io.BufferedOutputStream;
-import java.io.BufferedWriter;
-import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
-import java.io.File;
-import java.io.FileInputStream;
-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.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.concurrent.atomic.AtomicInteger;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-import java.io.FileWriter;
-import java.io.OutputStreamWriter;
-import java.io.Writer;
-import java.nio.charset.StandardCharsets;
-import java.nio.file.Files;
-import java.nio.file.Paths;
-import java.util.Scanner;
-
-/**
- *
- * @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(" 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(" 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(" 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(" 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("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("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, DefineSound 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");
- }
-
- 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 chatacter 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 chatacter 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("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: controlflow/3/max, traps/2, 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");
- }
-
- printCmdLineUsageExamples(out, filter);
- }
-
- private static void printCmdLineUsageExamples(PrintStream out, String filter) {
- out.println();
- out.println("Examples:");
-
- final String PREFIX = "java -jar ffdec.jar ";
-
- 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 (!exampleFound) {
- out.println("Sorry, no example found for command " + filter + ", Let us know in issue tracker when you need it.");
- }
-
- out.println();
- out.println("Instead of \"java -jar ffdec.jar\" you can use ffdec.bat on Windows, ffdec.sh on Linux/MacOs");
- }
-
- /**
- * 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;
- boolean cliMode = false;
- Selection selection = new Selection();
- Selection selectionIds = new Selection();
- List selectionClasses = null;
- String nextParam = null, nextParamOriginal = null;
- OUTER:
- while (true) {
- nextParamOriginal = args.pop();
- if (nextParamOriginal != null) {
- nextParam = nextParamOriginal.toLowerCase(Locale.ENGLISH);
- }
- if (nextParam == null) {
- nextParam = "";
- }
- switch (nextParam) {
- case "-cli":
- cliMode = true;
- break;
- case "-selectid":
- selectionIds = parseSelect(args);
- break;
- case "-select":
- selection = parseSelect(args);
- break;
- case "-selectclass":
- selectionClasses = parseSelectClass(args);
- break;
- case "-zoom":
- zoom = parseZoom(args);
- break;
- case "-format":
- format = parseFormat(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);
- 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("abcmerge")) {
- parseAbcMerge(args);
- } else if (command.equals("swf2swc")) {
- parseSwf2Swc(args);
- } else if (command.equals("linkreport")) {
- parseLinkReport(selectionClasses, args);
- } else if (command.equals("getinstancemetadata")) {
- parseGetInstanceMetadata(args);
- } else if (command.equals("setinstancemetadata")) {
- parseSetInstanceMetadata(args);
- } else if (command.equals("removeinstancemetadata")) {
- parseRemoveInstanceMetadata(args);
- } 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);
- } else if (command.equals("compress")) {
- parseCompress(args);
- } else if (command.equals("decompress")) {
- parseDecompress(args);
- } else if (command.equals("swf2xml")) {
- parseSwf2Xml(args);
- } else if (command.equals("xml2swf")) {
- parseXml2Swf(args);
- } else if (command.equals("extract")) {
- parseExtract(args);
- } else if (command.equals("memorysearch")) {
- parseMemorySearch(args);
- } else if (command.equals("deobfuscate")) {
- parseDeobfuscate(args);
- } else if (command.equals("renameinvalididentifiers")) {
- parseRenameInvalidIdentifiers(args);
- } else if (command.equals("dumpswf")) {
- parseDumpSwf(args);
- } else if (command.equals("dumpas2")) {
- parseDumpAS2(args);
- } else if (command.equals("dumpas3")) {
- parseDumpAS3(args);
- } else if (command.equals("enabledebugging")) {
- parseEnableDebugging(args);
- } else if (command.equals("flashpaper2pdf")) {
- parseFlashPaperToPdf(selection, zoom, args);
- } else if (command.equals("replace")) {
- parseReplace(args);
- } else if (command.equals("replacealpha")) {
- parseReplaceAlpha(args);
- } else if (command.equals("replacecharacter")) {
- parseReplaceCharacter(args);
- } else if (command.equals("replacecharacterid")) {
- parseReplaceCharacterId(args);
- } else if (command.equals("convert")) {
- parseConvert(args);
- } else if (command.equals("remove")) {
- parseRemove(args);
- } else if (command.equals("removecharacter")) {
- parseRemoveCharacter(args, false);
- } else if (command.equals("removecharacterwithdependencies")) {
- parseRemoveCharacter(args, true);
- } else if (command.equals("doc")) {
- parseDoc(args);
- } else if (command.equals("importscript")) {
- parseImportScript(args);
- } else if (command.equals("as3compiler")) {
- ActionScript3Parser.compile(null /*?*/, args.pop(), args.pop(), 0, 0);
- } else if (nextParam.equals("--debugtool")) {
- parseDebugTool(args);
- } else if (nextParam.equals("--compareresources")) {
- parseCompareResources(args);
- } else if (nextParam.equals("--resourcedates")) {
- parseResourceDates(args);
- } 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);
- } 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();
- }
-
- 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) item).set(calendarValue);
- } catch (ParseException ex) {
- Logger.getLogger(CommandLineArgumentParser.class.getName()).log(Level.SEVERE, null, ex);
- }
- } else if (type == Integer.class) {
- int intValue = Integer.parseInt(stringValue);
- ((ConfigurationItem) item).set(intValue);
- } else if ((type == Integer.class) || (type == Long.class)) {
- long longValue = Long.parseLong(stringValue);
- ((ConfigurationItem) item).set(longValue);
- } else if (type == Double.class) {
- double doubleValue = Double.parseDouble(stringValue);
- ((ConfigurationItem) item).set(doubleValue);
- } else if (type == Float.class) {
- float floatValue = Float.parseFloat(stringValue);
- ((ConfigurationItem) item).set(floatValue);
- } else if (type == Boolean.class) {
- Boolean boolValue = parseBooleanConfigValue(stringValue);
- if (boolValue != null) {
- System.out.println("Config " + item.getName() + " set to " + boolValue);
- ((ConfigurationItem) item).set(boolValue);
- } else {
- System.out.println("Invalid config value for " + item.getName() + ": " + stringValue);
- }
- } else if (type.isEnum()) {
- Enum enumValue = Enum.valueOf((Class) type, stringValue);
- ConfigurationItem uncheckedItem = (ConfigurationItem) item;
- uncheckedItem.set(enumValue);
- }
- }
- }
-
- private static Boolean parseBooleanConfigValue(String value) {
- if (value == null) {
- return null;
- }
-
- Boolean bValue = null;
- value = value.toLowerCase(Locale.ENGLISH);
- if (value.equals("0") || value.equals("false") || value.equals("no") || value.equals("off")) {
- bValue = false;
- }
-
- if (value.equals("1") || value.equals("true") || value.equals("yes") || value.equals("on")) {
- bValue = true;
- }
-
- return bValue;
- }
-
- private static void parseConfig(Stack args) {
- if (args.isEmpty()) {
- System.err.println("Config values expected");
- badArguments("config");
- }
-
- setConfigurations(args.pop());
- }
-
- private static void parseAbcMerge(Stack args) {
- if (args.size() < 2) {
- badArguments("abcmerge");
- }
- final File outFile = new File(args.pop());
- final File swfFile = new File(args.pop());
- processModifySWF(swfFile, outFile, null, (SWF swf, OutputStream stdout) -> {
- List abcList = swf.getAbcList();
- if (!abcList.isEmpty() && abcList.size() > 1) {
- ABC firstAbc = abcList.get(0).getABC();
- for (int i = 1; i < abcList.size(); i++) {
- firstAbc.mergeABC(abcList.get(i).getABC());
- }
- for (int i = 1; i < abcList.size(); i++) {
- swf.removeTag((Tag) abcList.get(i));
- }
- }
- });
-
- }
-
- private static void parseSwf2Swc(Stack args) {
- if (args.size() < 2) {
- badArguments("swf2swc");
- }
- final File outFile = new File(args.pop());
- final File swfFile = new File(args.pop());
- processReadSWF(swfFile, null, (SWF swf, OutputStream stdout) -> {
- SwfToSwcExporter exporter = new SwfToSwcExporter();
- try {
- exporter.exportSwf(swf, outFile, false);
- } catch (IOException | InterruptedException ex) {
- Logger.getLogger(CommandLineArgumentParser.class.getName()).log(Level.SEVERE, null, ex);
- }
- });
- }
-
- private static void parseLinkReport(List selectionClasses, Stack args) {
- if (args.isEmpty()) {
- badArguments("linkreport");
- }
- File stdOutFile = null;
- File swfFile = null;
- while (!args.isEmpty()) {
- String paramName = args.pop().toLowerCase(Locale.ENGLISH);
- switch (paramName) {
- case "-outfile":
- if (args.empty()) {
- System.err.println("Missing output file");
- badArguments("linkreport");
- }
- stdOutFile = new File(args.pop());
- break;
- default:
- if (!args.isEmpty()) {
- badArguments("linkreport");
- }
- swfFile = new File(paramName);
- }
- }
- if (swfFile == null) {
- System.err.println("No SWF file specified");
- badArguments("getinstancemetadata");
- }
- processReadSWF(swfFile, stdOutFile, (SWF swf, OutputStream stdout) -> {
-
- LinkReportExporter lre = new LinkReportExporter();
-
- List reportPacks;
- try {
- reportPacks = selectionClasses != null ? swf.getScriptPacksByClassNames(selectionClasses) : swf.getAS3Packs();
- } catch (Exception ex) {
- System.err.println("Error while getting packs");
- System.exit(1);
- return;
- }
- try {
- String reportStr = lre.generateReport(swf, reportPacks, null);
- stdout.write(reportStr.getBytes("UTF-8"));
- } catch (InterruptedException ex) {
- System.err.println("Report generation interrupted");
- }
- });
- }
-
- private static void parseGetInstanceMetadata(Stack args) {
- if (args.size() < 3) {
- badArguments("getinstancemetadata");
- }
- Set processedParams = new HashSet<>();
- String format = METADATA_FORMAT_JSLIKE;
- String key = null;
- String instance = null;
- File stdOutFile = null;
- File swfFile = null;
-
- while (!args.empty()) {
- String paramName = args.pop().toLowerCase(Locale.ENGLISH);
- if (processedParams.contains(paramName)) {
- System.err.println("Parameter " + paramName + " can appear only once.");
- }
- switch (paramName) {
- case "-instance":
- if (args.isEmpty()) {
- System.err.println("Missing instance name");
- badArguments("getinstancemetadata");
- }
- instance = args.pop();
- break;
- case "-outputformat":
- if (args.empty()) {
- System.err.println("Missing format value");
- badArguments("getinstancemetadata");
- }
- format = args.pop();
- if (!Arrays.asList(METADATA_FORMAT_RAW, METADATA_FORMAT_JSLIKE).contains(format)) {
- System.err.println("Invalid output format");
- badArguments("getinstancemetadata");
- }
- break;
- case "-key":
- if (args.empty()) {
- System.err.println("Missing key value");
- badArguments("getinstancemetadata");
- }
-
- key = args.pop();
- break;
- case "-datafile":
- if (args.empty()) {
- System.err.println("Missing datafile file");
- badArguments("getinstancemetadata");
- }
- stdOutFile = new File(args.pop());
- break;
- default:
- if (!args.isEmpty()) {
- badArguments("getinstancemetadata");
- }
- swfFile = new File(paramName);
- paramName = null;
- }
- if (paramName != null) {
- processedParams.add(paramName);
- }
- }
- if (instance == null) {
- System.err.println("No instance specified");
- badArguments("getinstancemetadata");
- }
- if (swfFile == null) {
- System.err.println("No SWF file specified");
- badArguments("getinstancemetadata");
- }
-
- final String fInstance = instance;
- final String fKey = key;
- final String fFormat = format;
-
- processReadSWF(swfFile, stdOutFile, new SwfAction() {
- @Override
- public void swfAction(SWF swf, OutputStream stdout) throws IOException {
- if (!processTimelined(swf, stdout)) {
- System.err.println("No instance with name " + fInstance + " found");
- System.exit(0);
- }
- }
-
- private boolean processTimelined(Timelined tim, OutputStream stdout) throws IOException {
- ReadOnlyTagList rtl = tim.getTags();
- for (int i = 0; i < rtl.size(); i++) {
- Tag t = rtl.get(i);
- if (t instanceof Timelined) {
- if (processTimelined((Timelined) t, stdout)) {
- return true;
- }
- }
- if (t instanceof PlaceObjectTypeTag) {
- PlaceObjectTypeTag pt = (PlaceObjectTypeTag) t;
- String instanceName = pt.getInstanceName();
- if (fInstance.equals(instanceName)) {
- Amf3Value oldValue = pt.getAmfData();
- if (oldValue == null) {
- System.err.println("No metadata for instance " + instanceName + " found");
- System.exit(1); //TODO? Different exit code
- }
- Object actualValue = oldValue.getValue();
-
- Object displayVal = actualValue;
- if (fKey != null) {
- if (actualValue instanceof ObjectType) {
- ObjectType ot = (ObjectType) actualValue;
- if (ot.containsDynamicMember(fKey)) {
- displayVal = ot.getDynamicMember(fKey);
- } else {
- System.err.println("No value with key " + fKey + " exists");
- System.err.println("Available keys: " + String.join(",", ot.dynamicMembersKeySet()));
- System.exit(1);
- }
- } else {
- System.err.println("Metadata present, but not as Object type, cannot get key " + fKey);
- System.exit(1);
- }
- }
-
- switch (fFormat) {
- case METADATA_FORMAT_JSLIKE:
- stdout.write(Utf8Helper.getBytes(Amf3Exporter.amfToString(displayVal, " ", System.lineSeparator()) + System.lineSeparator()));
- break;
- case METADATA_FORMAT_RAW:
- Amf3OutputStream aos = new Amf3OutputStream(stdout);
- try {
- aos.writeValue(displayVal);
- } catch (NoSerializerExistsException ex) {
- //should not happen
- }
- break;
- }
- return true;
- }
- }
- }
- return false;
- }
- });
- System.exit(0);
- }
-
- private static void parseSetInstanceMetadata(Stack args) {
- if (args.size() < 3) {
- badArguments("setinstancemetadata");
- }
- Set processedParams = new HashSet<>();
- String format = METADATA_FORMAT_JSLIKE;
- String key = null;
- String instance = null;
- File outFile = null;
- File swfFile = null;
- String value = null;
- File valueFile = null;
-
- while (!args.empty()) {
- String paramName = args.pop().toLowerCase(Locale.ENGLISH);
- if (processedParams.contains(paramName)) {
- System.err.println("Parameter " + paramName + " can appear only once.");
- }
- switch (paramName) {
- case "-instance":
- if (args.isEmpty()) {
- System.err.println("Missing instance name");
- badArguments("setinstancemetadata");
- }
- instance = args.pop();
- break;
- case "-inputformat":
- if (args.empty()) {
- System.err.println("Missing format value");
- badArguments("setinstancemetadata");
- }
- format = args.pop();
- if (!Arrays.asList(METADATA_FORMAT_RAW, METADATA_FORMAT_JSLIKE).contains(format)) {
- System.err.println("Invalid output format");
- badArguments("setinstancemetadata");
- }
- break;
- case "-key":
- if (args.empty()) {
- System.err.println("Missing key value");
- badArguments("setinstancemetadata");
- }
-
- key = args.pop();
- break;
- case "-value":
- if (args.empty()) {
- System.err.println("Missing value");
- badArguments("setinstancemetadata");
- }
-
- value = args.pop();
- break;
- case "-outfile":
- if (args.empty()) {
- System.err.println("Missing outFile");
- badArguments("setinstancemetadata");
- }
- outFile = new File(args.pop());
- break;
-
- case "-datafile":
- if (args.empty()) {
- System.err.println("Missing datafile file");
- badArguments("setinstancemetadata");
- }
- valueFile = new File(args.pop());
- break;
- default:
- if (!args.isEmpty()) {
- badArguments("setinstancemetadata");
- }
- swfFile = new File(paramName);
- paramName = null;
- }
- if (paramName != null) {
- processedParams.add(paramName);
- }
- }
- if (instance == null) {
- System.err.println("No instance specified");
- badArguments("getinstancemetadata");
- }
- if (swfFile == null) {
- System.err.println("No SWF file specified");
- badArguments("getinstancemetadata");
- }
- if (outFile == null) {
- outFile = swfFile;
- }
-
- byte[] valueBytes = new byte[]{};
- if (valueFile != null) {
- try {
- valueBytes = Helper.readFileEx(valueFile.getAbsolutePath());
- } catch (IOException ex) {
- System.err.println("Cannot read value: " + ex.getMessage());
- System.exit(1);
- return;
- }
- } else if (value != null) {
- valueBytes = Utf8Helper.getBytes(value);
- }
-
- if (valueBytes.length == 0) {
- valueBytes = Helper.readStream(System.in);
- }
-
- if (valueBytes.length < 1) {
- System.err.println("No value to set specified");
- System.exit(1);
- }
-
- Object amfValue = null;
- try {
- switch (format) {
- case METADATA_FORMAT_JSLIKE:
- Amf3Importer importer = new Amf3Importer();
- amfValue = importer.stringToAmf(value);
- break;
- case METADATA_FORMAT_RAW:
- Amf3InputStream ais = new Amf3InputStream(new MemoryInputStream(valueBytes));
- amfValue = ais.readValue("val");
- break;
- }
- } catch (IOException | Amf3ParseException | NoSerializerExistsException ex) {
- System.err.println("Error parsing input value: " + ex.getMessage());
- System.exit(1);
- return;
- }
-
- final String fInstance = instance;
- final String fKey = key;
- final Object fAmfValue = amfValue;
-
- processModifySWF(swfFile, outFile, null, new SwfAction() {
- @Override
- public void swfAction(SWF swf, OutputStream stdout) throws IOException {
- if (!processTimelined(swf, stdout)) {
- System.err.println("No instance with name " + fInstance + " found");
- System.exit(0);
- }
- }
-
- private boolean processTimelined(Timelined tim, OutputStream stdout) throws IOException {
- ReadOnlyTagList rtl = tim.getTags();
- for (int i = 0; i < rtl.size(); i++) {
- Tag t = rtl.get(i);
- if (t instanceof Timelined) {
- if (processTimelined((Timelined) t, stdout)) {
- return true;
- }
- }
- if (t instanceof PlaceObjectTypeTag) {
- PlaceObjectTypeTag pt = (PlaceObjectTypeTag) t;
- String instanceName = pt.getInstanceName();
- if (fInstance.equals(instanceName)) {
-
- Amf3Value oldValue = pt.getAmfData();
- if (oldValue != null && oldValue.getValue() == null) {
- oldValue = null;
- }
- if (oldValue != null && fKey != null) { //it has AMFData and we are going to set key
- Object actualValue = oldValue.getValue();
- if (actualValue instanceof ObjectType) { //add it to ObjectType
- ObjectType ot = (ObjectType) actualValue;
- ot.putDynamicMember(fKey, fAmfValue);
- t.setModified(true);
- oldValue.setValue(ot);
- System.out.println("Key " + fKey + " added");
- System.out.println("New instance data for " + instanceName + ":");
- System.out.println(Amf3Exporter.amfToString(ot, " ", System.lineSeparator()));
- return true;
- }
- }
-
- PlaceObject4Tag pt4;
- if (pt instanceof PlaceObject4Tag) {
- pt4 = (PlaceObject4Tag) pt;
- } else {
- pt4 = new PlaceObject4Tag(
- pt.getSwf(), pt.flagMove(), pt.getDepth(), pt.getClassName(), pt.getCharacterId(), pt.getMatrix(), pt.getColorTransform() == null ? null : new CXFORMWITHALPHA(pt.getColorTransform()), pt.getRatio(),
- pt.getInstanceName(), pt.getClipDepth(), pt.getFilters(), pt.getBlendMode(), pt.getBitmapCache(), pt.getVisible(), pt.getBackgroundColor(), pt.getClipActions(), pt.getAmfData(), pt.hasImage());
- tim.replaceTag(i, pt4);
- }
-
- Object newValue;
- if (fKey != null) {
- ObjectType ot = new ObjectType(new Traits("", true, new ArrayList<>()));
- ot.put(fKey, fAmfValue);
- newValue = ot;
- } else {
- newValue = fAmfValue;
- }
- pt4.amfData = new Amf3Value(newValue);
- pt4.setModified(true);
-
- System.out.println("New instance data for " + instanceName + ":");
- System.out.println(Amf3Exporter.amfToString(newValue, " ", System.lineSeparator()));
-
- return true;
- }
- }
- }
- return false;
- }
- });
- System.exit(0);
- }
-
- private static void parseRemoveInstanceMetadata(Stack args) {
- if (args.size() < 2) {
- badArguments("removeinstancemetadata");
- }
-
- Set processedParams = new HashSet<>();
- String key = null;
- String instance = null;
- File swfFile = null;
- File outFile = null;
- while (!args.empty()) {
- String paramName = args.pop().toLowerCase(Locale.ENGLISH);
- if (processedParams.contains(paramName)) {
- System.err.println("Parameter " + paramName + " can appear only once.");
- }
- switch (paramName) {
- case "-instance":
- if (args.isEmpty()) {
- System.err.println("Missing instance name");
- badArguments("removeinstancemetadata");
- }
- instance = args.pop();
- break;
- case "-key":
- if (args.empty()) {
- System.err.println("Missing key value");
- badArguments("removeinstancemetadata");
- }
-
- key = args.pop();
- break;
- case "-outfile":
- if (args.empty()) {
- System.err.println("Missing outFile");
- badArguments("removeinstancemetadata");
- }
- outFile = new File(args.pop());
- break;
- default:
- if (!args.isEmpty()) {
- badArguments("removeinstancemetadata");
- }
- swfFile = new File(paramName);
- paramName = null;
- }
- if (paramName != null) {
- processedParams.add(paramName);
- }
- }
- if (instance == null) {
- System.err.println("No instance specified");
- badArguments("removeinstancemetadata");
- }
- if (swfFile == null) {
- System.err.println("No SWF file specified");
- badArguments("removeinstancemetadata");
- }
- if (outFile == null) {
- outFile = swfFile;
- }
-
- final String fInstance = instance;
- final String fKey = key;
-
- processModifySWF(swfFile, outFile, null, new SwfAction() {
- @Override
- public void swfAction(SWF swf, OutputStream stdout) throws IOException {
- if (!processTimelined(swf, stdout)) {
- System.err.println("No instance with name " + fInstance + " found");
- System.exit(0);
- }
- }
-
- private boolean processTimelined(Timelined tim, OutputStream stdout) throws IOException {
- ReadOnlyTagList rtl = tim.getTags();
- for (int i = 0; i < rtl.size(); i++) {
- Tag t = rtl.get(i);
- if (t instanceof Timelined) {
- if (processTimelined((Timelined) t, stdout)) {
- return true;
- }
- }
- if (t instanceof PlaceObject4Tag) {
- PlaceObject4Tag pt4 = (PlaceObject4Tag) t;
- String instanceName = pt4.getInstanceName();
- if (fInstance.equals(instanceName)) {
- Amf3Value oldValue = pt4.getAmfData();
- if (oldValue == null) {
- System.err.println("No metadata for instance " + instanceName + " found");
- System.exit(1); //TODO? Different exit code
- }
- Object actualValue = oldValue.getValue();
-
- if (fKey != null) {
- if (actualValue instanceof ObjectType) {
- ObjectType ot = (ObjectType) actualValue;
- if (ot.containsDynamicMember(fKey)) {
- ot.remove(fKey);
- oldValue.setValue(ot);
- System.out.println("Key " + fKey + " removed");
- System.out.println("New instance data for " + instanceName + ":");
- System.out.println(Amf3Exporter.amfToString(ot, " ", System.lineSeparator()));
- pt4.setModified(true);
- return true;
- } else {
- System.err.println("No value with key " + fKey + " exists");
- System.err.println("Available keys: " + String.join(",", ot.dynamicMembersKeySet()));
- System.exit(1);
- }
- } else {
- System.err.println("Metadata present, but not as Object type, cannot remove key " + fKey);
- System.exit(1);
- }
- } else {
- pt4.amfData = null;
- pt4.setModified(true);
- System.out.println("Whole metadata removed for instance " + instanceName);
- }
-
- return true;
- }
- }
- }
- return false;
- }
- });
- System.exit(0);
-
- }
-
- private static class Range {
-
- public Integer min;
-
- public Integer max;
-
- public Range(Integer min, Integer max) {
- this.min = min;
- this.max = max;
- }
-
- public boolean contains(int index) {
- int minimum = min == null ? Integer.MIN_VALUE : min;
- int maximum = max == null ? Integer.MAX_VALUE : max;
-
- return index >= minimum && index <= maximum;
- }
- }
-
- private static class Selection {
-
- public List ranges;
-
- public Selection() {
- this.ranges = new ArrayList<>();
- this.ranges.add(new Range(null, null));
- }
-
- public Selection(List ranges) {
- this.ranges = ranges;
- }
-
- public boolean contains(int index) {
- for (Range r : ranges) {
- if (r.contains(index)) {
- return true;
- }
- }
- return false;
- }
- }
-
- private static Selection parseSelect(Stack args) {
- List ret = new ArrayList<>();
- if (args.isEmpty()) {
- System.err.println("range parameter expected");
- badArguments("select");
- }
- String range = args.pop();
- String[] ranges;
- if (range.contains(",")) {
- ranges = range.split(",");
- } else {
- ranges = new String[]{range};
- }
- for (String r : ranges) {
- Integer min = null;
- Integer max = null;
- if (r.contains("-")) {
- String[] ps = r.split("\\-");
- if (ps.length != 2) {
- System.err.println("invalid range");
- badArguments("select");
- }
- try {
- if (!"".equals(ps[0])) {
- min = Integer.parseInt(ps[0]);
- }
- if (!"".equals(ps[1])) {
- max = Integer.parseInt(ps[1]);
- }
- } catch (NumberFormatException nfe) {
- System.err.println("invalid range");
- badArguments("select");
- }
- } else {
- try {
- min = Integer.parseInt(r);
- max = min;
- } catch (NumberFormatException nfe) {
- System.err.println("invalid range");
- badArguments("select");
- }
- }
- ret.add(new Range(min, max));
- }
- return new Selection(ret);
- }
-
- private static double parseZoom(Stack args) {
- if (args.isEmpty()) {
- System.err.println("zoom parameter expected");
- badArguments("zoom");
- }
- try {
- return Double.parseDouble(args.pop());
- } catch (NumberFormatException nfe) {
- System.err.println("invalid zoom");
- badArguments("zoom");
- }
- return 1;
- }
-
- private static AbortRetryIgnoreHandler parseOnError(Stack args) {
- int errorMode = AbortRetryIgnoreHandler.UNDEFINED;
- int retryCount = 0;
-
- if (args.isEmpty()) {
- System.err.println("onerror parameter expected");
- badArguments("onerror");
- }
- String errorModeParameter = args.pop();
- switch (errorModeParameter) {
- case "abort":
- errorMode = AbortRetryIgnoreHandler.ABORT;
- break;
- case "retry":
- errorMode = AbortRetryIgnoreHandler.RETRY;
- if (args.isEmpty()) {
- System.err.println("onerror retry count parameter expected");
- badArguments("onerror");
- }
-
- try {
- retryCount = Integer.parseInt(args.pop());
- } catch (NumberFormatException nex) {
- System.err.println("Bad retry count number");
- }
- break;
- case "ignore":
- errorMode = AbortRetryIgnoreHandler.IGNORE;
- break;
- }
-
- return new ConsoleAbortRetryIgnoreHandler(errorMode, retryCount);
- }
-
- private static void parseTimeout(Stack args) {
- if (args.isEmpty()) {
- System.err.println("timeout parameter expected");
- badArguments("timeout");
- }
- try {
- int timeout = Integer.parseInt(args.pop());
- Configuration.decompilationTimeoutSingleMethod.set(timeout);
- } catch (NumberFormatException nex) {
- System.err.println("Bad timeout value");
- }
- }
-
- private static void parseExportTimeout(Stack args) {
- if (args.isEmpty()) {
- System.err.println("timeout parameter expected");
- badArguments("exporttimeout");
- }
- try {
- int timeout = Integer.parseInt(args.pop());
- Configuration.exportTimeout.set(timeout);
- } catch (NumberFormatException nex) {
- System.err.println("Bad timeout value");
- }
- }
-
- private static void parseExportFileTimeout(Stack args) {
- if (args.isEmpty()) {
- System.err.println("timeout parameter expected");
- badArguments("exportfiletimeout");
- }
- try {
- int timeout = Integer.parseInt(args.pop());
- Configuration.decompilationTimeoutFile.set(timeout);
- } catch (NumberFormatException nex) {
- System.err.println("Bad timeout value");
- }
- }
-
- private static void parseStat(Stack args) {
- showStat = true;
- Configuration.showStat = showStat;
- }
-
- private static void parseStdOut(Stack args) {
- if (args.isEmpty()) {
- System.err.println("stdOut parameter expected");
- badArguments("stdout");
- }
-
- stdOut = args.pop();
- }
-
- private static void parseStdErr(Stack args) {
- if (args.isEmpty()) {
- System.err.println("stdErr parameter expected");
- badArguments("stderr");
- }
-
- stdErr = args.pop();
- }
-
- private static void parseAffinity(Stack args) {
- if (Platform.isWindows()) {
- if (args.isEmpty()) {
- System.err.println("affinity parameter expected");
- badArguments("affinity");
- }
- try {
- int affinityMask = Integer.parseInt(args.pop());
- Kernel32.INSTANCE.SetProcessAffinityMask(Kernel32.INSTANCE.GetCurrentProcess(), affinityMask);
- } catch (NumberFormatException nex) {
- System.err.println("Bad affinityMask value");
- }
- } else {
- System.err.println("Process affinity setting is only available on Windows platform.");
- }
- }
-
- private static void parsePriority(Stack args) {
- if (Platform.isWindows()) {
- if (args.isEmpty()) {
- System.err.println("priority parameter expected");
- badArguments("priority");
- }
- String priority = args.pop();
- int priorityClass = 0;
- switch (priority) {
- case "low":
- priorityClass = Kernel32.IDLE_PRIORITY_CLASS;
- break;
- case "belownormal":
- priorityClass = Kernel32.BELOW_NORMAL_PRIORITY_CLASS;
- break;
- case "normal":
- priorityClass = Kernel32.NORMAL_PRIORITY_CLASS;
- break;
- case "abovenormal":
- priorityClass = Kernel32.ABOVE_NORMAL_PRIORITY_CLASS;
- break;
- case "high":
- priorityClass = Kernel32.HIGH_PRIORITY_CLASS;
- break;
- case "realtime":
- priorityClass = Kernel32.REALTIME_PRIORITY_CLASS;
- break;
- default:
- System.err.println("Bad affinityMask value");
- }
- if (priorityClass != 0) {
- Kernel32.INSTANCE.SetPriorityClass(Kernel32.INSTANCE.GetCurrentProcess(), priorityClass);
- }
- } else {
- System.err.println("Process priority setting is only available on Windows platform.");
- }
- }
-
- private static void parseDebugTool(Stack args) {
- String cmd = args.pop().toLowerCase(Locale.ENGLISH);
- switch (cmd) {
- case "findtag": {
- String folder = args.pop();
- String tagIdOrName = args.pop();
- int tagId;
- try {
- tagId = Integer.parseInt(tagIdOrName);
- } catch (NumberFormatException e) {
- tagId = Tag.getKnownClassesByName().get(tagIdOrName).getId();
- }
-
- PrintStream oldOut = System.out;
- PrintStream oldErr = System.err;
- PrintStream nullStream = new PrintStream(new OutputStream() {
- @Override
- public void write(int b) {
- }
- });
- System.setOut(nullStream);
- System.setErr(nullStream);
- Main.initLogging(Configuration._debugMode.get());
-
- File[] files = new File(folder).listFiles(getSwfFilter());
- for (File file : files) {
- SWFSourceInfo sourceInfo = new SWFSourceInfo(null, file.getAbsolutePath(), file.getName());
- try {
- SWF swf = new SWF(new FileInputStream(file), sourceInfo.getFile(), sourceInfo.getFileTitle(), Configuration.parallelSpeedUp.get());
- swf.swfList = new SWFList();
- swf.swfList.sourceInfo = sourceInfo;
- boolean found = false;
- for (Tag tag : swf.getTags()) {
- if (tag.getId() == tagId) {
- found = true;
- break;
- }
- }
-
- if (found) {
- oldOut.println("Tag found in file: " + file.getAbsolutePath());
- }
- } catch (IOException | InterruptedException ex) {
- logger.log(Level.SEVERE, null, ex);
- }
- }
-
- System.setOut(oldOut);
- System.setErr(oldErr);
- Main.initLogging(Configuration._debugMode.get());
- break;
- }
- case "finderrorheader": {
- String folder = args.pop();
-
- PrintStream oldOut = System.out;
- PrintStream oldErr = System.err;
- PrintStream nullStream = new PrintStream(new OutputStream() {
- @Override
- public void write(int b) {
- }
- });
- System.setOut(nullStream);
- System.setErr(nullStream);
- Main.initLogging(Configuration._debugMode.get());
-
- File[] files = new File(folder).listFiles(getSwfFilter());
- for (File file : files) {
- SWFSourceInfo sourceInfo = new SWFSourceInfo(null, file.getAbsolutePath(), file.getName());
- try {
- SWF swf = new SWF(new FileInputStream(file), sourceInfo.getFile(), sourceInfo.getFileTitle(), Configuration.parallelSpeedUp.get());
- swf.swfList = new SWFList();
- swf.swfList.sourceInfo = sourceInfo;
- boolean found = false;
- for (Tag tag : swf.getTags()) {
- if (tag instanceof JPEGTablesTag) {
- JPEGTablesTag jtt = (JPEGTablesTag) tag;
- if (ImageTag.hasErrorHeader(jtt.jpegData)) {
- found = true;
- break;
- }
- } else if (tag instanceof DefineBitsJPEG2Tag) {
- DefineBitsJPEG2Tag jpeg = (DefineBitsJPEG2Tag) tag;
- if (ImageTag.hasErrorHeader(jpeg.imageData)) {
- found = true;
- break;
- }
- } else if (tag instanceof DefineBitsJPEG3Tag) {
- DefineBitsJPEG3Tag jpeg = (DefineBitsJPEG3Tag) tag;
- if (ImageTag.hasErrorHeader(jpeg.imageData)) {
- found = true;
- break;
- }
- }
- }
-
- if (found) {
- oldOut.println("Tag found in file: " + file.getAbsolutePath());
- }
- } catch (IOException | InterruptedException ex) {
- logger.log(Level.SEVERE, null, ex);
- }
- }
-
- System.setOut(oldOut);
- System.setErr(oldErr);
- Main.initLogging(Configuration._debugMode.get());
- break;
- }
- }
- }
-
- private static void parseCompareResources(Stack args) {
- String revision = args.pop().toLowerCase(Locale.ENGLISH);
- String revision2 = null;
- if (!args.isEmpty()) {
- revision2 = args.pop();
- }
-
- CheckResources.compareResources(System.out, revision, revision2);
- }
-
- private static void parseResourceDates(Stack args) {
- CheckResources.checkTranslationDate(System.out);
- }
-
- private static void parseProxy(Stack args) {
- int port = 55555;
- String portStr = args.peek();
- if (portStr != null && portStr.startsWith("-P")) {
- args.pop();
- try {
- port = Integer.parseInt(portStr.substring(2));
- } catch (NumberFormatException nex) {
- System.err.println("Bad port number");
- }
- }
- Main.startProxy(port);
- }
-
- private static List parseSelectClass(Stack args) {
- if (args.size() < 1) {
- badArguments("selectclass");
- }
- List ret = new ArrayList<>();
- String classesStr = args.pop();
- String classes[];
- if (classesStr.contains(",")) {
- classes = classesStr.split(",");
- } else {
- classes = new String[]{classesStr};
- }
- ret.addAll(Arrays.asList(classes));
- return ret;
-
- }
-
- private static void parseExport(List selectionClasses, Selection selection, Selection selectionIds, Stack args, AbortRetryIgnoreHandler handler, Level traceLevel, Map formats, double zoom) {
- if (args.size() < 3) {
- badArguments("export");
- }
- String[] validExportItems = new String[]{
- "script",
- "script_as2",
- "script_as3",
- "image",
- "shape",
- "morphshape",
- "movie",
- "font",
- "frame",
- "sprite",
- "button",
- "sound",
- "binarydata",
- "text",
- "all",
- "fla",
- "xfl"
- };
-
- String[] removedExportFormats = new String[]{
- "as", "pcode", "hex", "pcodehex", "all_as", "all_pcode", "all_pcodehex", "all_hex", "textplain"
- };
-
- if (handler == null) {
- handler = new ConsoleAbortRetryIgnoreHandler(AbortRetryIgnoreHandler.UNDEFINED, 0);
- }
-
- String exportFormatString = args.pop().toLowerCase(Locale.ENGLISH);
- List exportFormats = Arrays.asList(exportFormatString.split(","));
- long startTime = System.currentTimeMillis();
-
- File outDirBase = new File(args.pop());
- File inFileOrFolder = new File(args.pop());
- if (!inFileOrFolder.exists()) {
- System.err.println("Input SWF file does not exist!");
- badArguments("export");
- }
-
- if (!args.isEmpty() && args.peek().equals("-selectas3class")) {
- System.err.println("Error: -selectas3class parameter was REMOVED. Please use -selectclass instead. See --help for usage.");
- System.exit(1);
- }
-
- printHeader();
- boolean exportOK = true;
-
- List as3classes = new ArrayList<>();
- if (selectionClasses != null) {
- as3classes.addAll(selectionClasses);
- }
-
- Map stat = new HashMap<>();
-
- try {
- File[] inFiles;
- boolean singleFile = true;
- if (inFileOrFolder.isDirectory()) {
- singleFile = false;
- inFiles = inFileOrFolder.listFiles(getSwfFilter());
- } else {
- inFiles = new File[]{inFileOrFolder};
- }
-
- for (File inFile : inFiles) {
- String inFileName = Path.getFileNameWithoutExtension(inFile);
- if (stdOut != null) {
- String outFilePath = stdOut.replace("{swfFile}", inFileName);
- Path.createDirectorySafe(new File(outFilePath).getParentFile());
- System.setOut(new PrintStream(new FileOutputStream(outFilePath, true)));
- }
-
- if (stdErr != null) {
- String errFilePath = stdErr.replace("{swfFile}", inFileName);
- Path.createDirectorySafe(new File(errFilePath).getParentFile());
- System.setErr(new PrintStream(new FileOutputStream(errFilePath, true)));
- Main.initLogging(Configuration._debugMode.get());
- }
-
- long startTimeSwf = 0;
- if (!singleFile) {
- startTimeSwf = System.currentTimeMillis();
- System.out.println("Start exporting " + inFile.getName());
- }
-
- SWFSourceInfo sourceInfo = new SWFSourceInfo(null, inFile.getAbsolutePath(), inFile.getName());
- SWF swf;
- try {
- swf = new SWF(new FileInputStream(inFile), sourceInfo.getFile(), sourceInfo.getFileTitle(), Configuration.parallelSpeedUp.get());
- } catch (FileNotFoundException | SwfOpenException ex) {
- // FileNotFoundException when anti virus software blocks to open the file
- logger.log(Level.SEVERE, "Failed to open swf: " + inFile.getName(), ex);
- continue;
- }
-
- swf.swfList = new SWFList();
- swf.swfList.sourceInfo = sourceInfo;
- String outDir = outDirBase.getAbsolutePath();
- if (!singleFile) {
- outDir = Path.combine(outDir, inFile.getName());
- }
-
- List extags = new ArrayList<>();
- for (Tag t : swf.getTags()) {
- if (t instanceof CharacterIdTag) {
- CharacterIdTag c = (CharacterIdTag) t;
- if (selectionIds.contains(c.getCharacterId())) {
- extags.add(t);
- }
- } else if (selectionIds.contains(0)) {
- extags.add(t);
- }
- }
-
- final Level level = traceLevel;
- swf.addEventListener(new EventListener() {
- @Override
- public void handleExportingEvent(String type, int index, int count, Object data) {
- if (level.intValue() <= Level.FINE.intValue()) {
- String text = "Exporting ";
- if (type != null && type.length() > 0) {
- text += type + " ";
- }
- System.out.println(text + index + "/" + count + " " + data);
- }
- }
-
- @Override
- public void handleExportedEvent(String type, int index, int count, Object data) {
- String text = "Exported ";
- if (type != null && type.length() > 0) {
- text += type + " ";
- }
- System.out.println(text + index + "/" + count + " " + data);
- }
-
- @Override
- public void handleEvent(String event, Object data) {
- }
- });
-
- // First check all the specified export formats
- for (String exportFormat : exportFormats) {
- if (Arrays.asList(removedExportFormats).contains(exportFormat)) {
- System.err.println("Error: Export format : " + exportFormat + " was REMOVED. Run application with --help parameter to see available formats.");
- System.exit(1);
- } else if (!Arrays.asList(validExportItems).contains(exportFormat)) {
- System.err.println("Invalid export item:" + exportFormat);
- badArguments("export");
- }
- }
-
- // Here the exportFormats array should contain only validitems
- commandLineMode = true;
- boolean exportAll = exportFormats.contains("all");
- boolean multipleExportTypes = exportAll || exportFormats.size() > 1;
- EventListener evl = swf.getExportEventListener();
-
- if (exportAll || exportFormats.contains("image")) {
- System.out.println("Exporting images...");
- new ImageExporter().exportImages(handler, outDir + (multipleExportTypes ? File.separator + ImageExportSettings.EXPORT_FOLDER_NAME : ""), new ReadOnlyTagList(extags), new ImageExportSettings(enumFromStr(formats.get("image"), ImageExportMode.class)), evl);
- }
-
- if (exportAll || exportFormats.contains("shape")) {
- System.out.println("Exporting shapes...");
- new ShapeExporter().exportShapes(handler, outDir + (multipleExportTypes ? File.separator + ShapeExportSettings.EXPORT_FOLDER_NAME : ""), swf, new ReadOnlyTagList(extags), new ShapeExportSettings(enumFromStr(formats.get("shape"), ShapeExportMode.class), zoom), evl, zoom);
- }
-
- if (exportAll || exportFormats.contains("morphshape")) {
- System.out.println("Exporting morphshapes...");
- new MorphShapeExporter().exportMorphShapes(handler, outDir + (multipleExportTypes ? File.separator + MorphShapeExportSettings.EXPORT_FOLDER_NAME : ""), new ReadOnlyTagList(extags), new MorphShapeExportSettings(enumFromStr(formats.get("morphshape"), MorphShapeExportMode.class), zoom), evl);
- }
-
- if (exportAll || exportFormats.contains("movie")) {
- System.out.println("Exporting movies...");
- new MovieExporter().exportMovies(handler, outDir + (multipleExportTypes ? File.separator + MovieExportSettings.EXPORT_FOLDER_NAME : ""), new ReadOnlyTagList(extags), new MovieExportSettings(enumFromStr(formats.get("movie"), MovieExportMode.class)), evl);
- }
-
- if (exportAll || exportFormats.contains("font")) {
- System.out.println("Exporting fonts...");
- new FontExporter().exportFonts(handler, outDir + (multipleExportTypes ? File.separator + FontExportSettings.EXPORT_FOLDER_NAME : ""), new ReadOnlyTagList(extags), new FontExportSettings(enumFromStr(formats.get("font"), FontExportMode.class)), evl);
- }
-
- if (exportAll || exportFormats.contains("sound")) {
- System.out.println("Exporting sounds...");
- new SoundExporter().exportSounds(handler, outDir + (multipleExportTypes ? File.separator + SoundExportSettings.EXPORT_FOLDER_NAME : ""), new ReadOnlyTagList(extags), new SoundExportSettings(enumFromStr(formats.get("sound"), SoundExportMode.class)), evl);
- }
-
- if (exportAll || exportFormats.contains("binarydata")) {
- System.out.println("Exporting binaryData...");
- new BinaryDataExporter().exportBinaryData(handler, outDir + (multipleExportTypes ? File.separator + BinaryDataExportSettings.EXPORT_FOLDER_NAME : ""), new ReadOnlyTagList(extags), new BinaryDataExportSettings(enumFromStr(formats.get("binarydata"), BinaryDataExportMode.class)), evl);
- }
-
- if (exportAll || exportFormats.contains("text")) {
- System.out.println("Exporting texts...");
- Boolean singleTextFile = parseBooleanConfigValue(formats.get("singletext"));
- if (singleTextFile == null) {
- singleTextFile = Configuration.textExportSingleFile.get();
- }
- new TextExporter().exportTexts(handler, outDir + (multipleExportTypes ? File.separator + TextExportSettings.EXPORT_FOLDER_NAME : ""), new ReadOnlyTagList(extags), new TextExportSettings(enumFromStr(formats.get("text"), TextExportMode.class), singleTextFile, zoom), evl);
- }
-
- FrameExporter frameExporter = new FrameExporter();
-
- if (exportAll || exportFormats.contains("frame")) {
- System.out.println("Exporting frames...");
- List frames = new ArrayList<>();
- for (int i = 0; i < swf.frameCount; i++) {
- if (selection.contains(i + 1)) {
- frames.add(i);
- }
- }
- FrameExportSettings fes = new FrameExportSettings(enumFromStr(formats.get("frame"), FrameExportMode.class), zoom);
- frameExporter.exportFrames(handler, outDir + (multipleExportTypes ? File.separator + FrameExportSettings.EXPORT_FOLDER_NAME : ""), swf, 0, frames, fes, evl);
- }
-
- if (exportAll || exportFormats.contains("sprite")) {
- System.out.println("Exporting sprite...");
- SpriteExportSettings ses = new SpriteExportSettings(enumFromStr(formats.get("sprite"), SpriteExportMode.class), zoom);
- for (Tag t : extags) {
- if (t instanceof DefineSpriteTag) {
- frameExporter.exportSpriteFrames(handler, outDir + (multipleExportTypes ? File.separator + SpriteExportSettings.EXPORT_FOLDER_NAME : ""), swf, ((DefineSpriteTag) t).getCharacterId(), null, ses, evl);
- }
- }
- }
-
- if (exportAll || exportFormats.contains("button")) {
- System.out.println("Exporting buttons...");
- ButtonExportSettings bes = new ButtonExportSettings(enumFromStr(formats.get("button"), ButtonExportMode.class), zoom);
- for (Tag t : extags) {
- if (t instanceof ButtonTag) {
- frameExporter.exportButtonFrames(handler, outDir + (multipleExportTypes ? File.separator + ButtonExportSettings.EXPORT_FOLDER_NAME : ""), swf, ((ButtonTag) t).getCharacterId(), null, bes, evl);
- }
- }
- }
-
- boolean parallel = Configuration.parallelSpeedUp.get();
- Boolean singleScriptFile = parseBooleanConfigValue(formats.get("singlescript"));
- if (singleScriptFile == null) {
- singleScriptFile = Configuration.scriptExportSingleFile.get();
- }
-
- if (parallel && singleScriptFile) {
- logger.log(Level.WARNING, AppStrings.translate("export.script.singleFilePallelModeWarning"));
- singleScriptFile = false;
- }
-
- ScriptExportSettings scriptExportSettings = new ScriptExportSettings(enumFromStr(formats.get("script"), ScriptExportMode.class), singleScriptFile, false);
- boolean exportAllScript = exportAll || exportFormats.contains("script");
- boolean exportAs2Script = exportAllScript || exportFormats.contains("script_as2");
- boolean exportAs3Script = exportAllScript || exportFormats.contains("script_as3");
- if (exportAs2Script || exportAs3Script) {
- System.out.println("Exporting scripts...");
-
- String scriptsFolder = Path.combine(outDir, ScriptExportSettings.EXPORT_FOLDER_NAME);
- Path.createDirectorySafe(new File(scriptsFolder));
- String singleFileName = Path.combine(scriptsFolder, swf.getShortFileName() + scriptExportSettings.getFileExtension());
- try (FileTextWriter writer = scriptExportSettings.singleFile ? new FileTextWriter(Configuration.getCodeFormatting(), new FileOutputStream(singleFileName)) : null) {
- scriptExportSettings.singleFileWriter = writer;
- List as3packs = as3classes.isEmpty() ? null : swf.getScriptPacksByClassNames(as3classes);
- exportOK = swf.exportActionScript(handler, scriptsFolder, as3classes.isEmpty() ? null : as3packs, scriptExportSettings, parallel, evl, exportAs2Script, exportAs3Script) != null && exportOK;
- }
-
- if (showStat) {
- Statistics.print();
- Statistics.addToMap(stat);
- Statistics.clear();
- }
- }
-
- if (exportFormats.contains("fla")) {
- System.out.println("Exporting FLA...");
- exportFla(true, outDir, inFile, swf, multipleExportTypes, formats, handler);
- }
-
- if (exportFormats.contains("xfl")) {
- System.out.println("Exporting XFL...");
- exportFla(false, outDir, inFile, swf, multipleExportTypes, formats, handler);
- }
-
- if (!singleFile) {
- long stopTimeSwf = System.currentTimeMillis();
- long time = stopTimeSwf - startTimeSwf;
- System.out.println("Export finished: " + inFile.getName() + " Export time: " + Helper.formatTimeSec(time));
- }
-
- swf.clearAllCache();
- CancellableWorker.cancelBackgroundThreads();
- }
- } catch (OutOfMemoryError | Exception ex) {
- System.err.print("FAIL: Exporting Failed on Exception - ");
- logger.log(Level.SEVERE, null, ex);
- System.exit(1);
- }
-
- if (showStat) {
- Statistics.print(stat);
- }
-
- long stopTime = System.currentTimeMillis();
- long time = stopTime - startTime;
- System.out.println("Export finished. Total export time: " + Helper.formatTimeSec(time));
- System.out.println(exportOK ? "OK" : "FAIL");
- System.exit(exportOK ? 0 : 1);
- }
-
- private static void exportFla(boolean compressed, String outDir, File inFile, SWF swf, boolean multipleExportTypes, Map formats, AbortRetryIgnoreHandler handler) throws IOException, InterruptedException {
- String exportFormat = compressed ? "fla" : "xfl";
- String format = formats.get(exportFormat);
- boolean exportScript = true;
- if (format != null && format.endsWith("_noscript")) {
- format = format.substring(0, format.length() - 9);
- exportScript = false;
- }
-
- FLAVersion flaVersion = FLAVersion.fromString(format);
- if (flaVersion == null) {
- flaVersion = FLAVersion.CS6; //Defaults to CS6
- }
-
- String outFile = outDir;
- if (multipleExportTypes) {
- outFile = Path.combine(outFile, exportFormat);
- };
-
- String outFileName = inFile.getName().toLowerCase(Locale.ENGLISH).endsWith(".swf") ? inFile.getName().substring(0, inFile.getName().length() - 3) + exportFormat : inFile.getName();
- outFile = Path.combine(outFile, outFileName);
- XFLExportSettings settings = new XFLExportSettings();
- settings.compressed = compressed;
- settings.exportScript = exportScript;
-
- try {
- if (Configuration.setFFDecVersionInExportedFont.get()) {
- swf.exportXfl(handler, outFile, inFile.getName(), ApplicationInfo.APPLICATION_NAME, ApplicationInfo.applicationVerName, ApplicationInfo.version, Configuration.parallelSpeedUp.get(), flaVersion, settings);
- } else {
- swf.exportXfl(handler, outFile, inFile.getName(), ApplicationInfo.APPLICATION_NAME, ApplicationInfo.APPLICATION_NAME, "1.0.0", Configuration.parallelSpeedUp.get(), flaVersion, settings);
- }
- } catch (Exception ex) {
- logger.log(Level.SEVERE, "Error during XFL/FLA export", ex);
- }
- }
-
- private static void parseDeobfuscate(Stack args) {
- if (args.size() < 3) {
- badArguments("deobfuscate");
- }
- String mode = args.pop();
- DeobfuscationLevel lev;
- switch (mode) {
- case "controlflow":
- case "max":
- case "3":
- lev = DeobfuscationLevel.LEVEL_RESTORE_CONTROL_FLOW;
- break;
- case "traps":
- case "2":
- lev = DeobfuscationLevel.LEVEL_REMOVE_TRAPS;
- break;
- case "deadcode":
- case "1":
- lev = DeobfuscationLevel.LEVEL_REMOVE_DEAD_CODE;
- break;
- default:
- System.err.println("Invalid level, must be one of: controlflow,traps,deadcode or 1,2,3/max");
- System.exit(1);
- return;
- }
- File inFile = new File(args.pop());
- File outFile = new File(args.pop());
- File tmpFile = null;
- if (inFile.equals(outFile)) {
- try {
- tmpFile = File.createTempFile("ffdec_deobf_", ".swf");
- outFile = tmpFile;
- } catch (IOException ex) {
- System.err.println("Unable to create temp file");
- System.exit(1);
- }
- }
- try (FileInputStream is = new FileInputStream(inFile);
- FileOutputStream fos = new FileOutputStream(outFile)) {
- SWF swf = new SWF(is, Configuration.parallelSpeedUp.get());
- if (!swf.isAS3()) {
- System.out.println("Warning: The file is not AS3. Only AS3 deobfuscation from commandline is available.");
- System.exit(0);
- }
- swf.deobfuscate(lev);
- swf.saveTo(fos);
- if (tmpFile != null) {
- inFile.delete();
- tmpFile.renameTo(inFile);
- tmpFile = null;
- System.out.println(inFile + " overwritten.");
- }
- System.out.println("OK");
- } catch (FileNotFoundException ex) {
- System.err.println("File not found.");
- System.exit(1);
- } catch (InterruptedException ex) {
- logger.log(Level.SEVERE, null, ex);
- System.exit(1);
- } catch (IOException ex) {
- logger.log(Level.SEVERE, "Error", ex);
- System.exit(1);
- } finally {
- if (tmpFile != null && tmpFile.exists()) {
- tmpFile.delete();
- }
- }
- }
-
- private static void parseCompress(Stack args) {
- if (args.size() < 2) {
- badArguments("compress");
- }
-
- boolean result = false;
- try {
- SWFCompression compression = SWFCompression.ZLIB;
- String compressionString = !args.isEmpty() ? args.pop() : null;
- if (compressionString != null) {
- switch (compressionString.toLowerCase(Locale.ENGLISH)) {
- case "zlib":
- compression = SWFCompression.ZLIB;
- break;
- case "lzma":
- compression = SWFCompression.LZMA;
- break;
- default:
- System.out.println("Unsupported compression method: " + compressionString);
- System.exit(0);
- break;
- }
- }
-
- try (InputStream fis = new BufferedInputStream(new FileInputStream(args.pop()));
- OutputStream fos = new BufferedOutputStream(new FileOutputStream(args.pop()))) {
- result = SWF.compress(fis, fos, compression);
- System.out.println(result ? "OK" : "FAIL");
- } catch (FileNotFoundException ex) {
- System.err.println("File not found.");
- System.exit(1);
- }
- } catch (IOException ex) {
- logger.log(Level.SEVERE, null, ex);
- }
-
- System.exit(result ? 0 : 1);
- }
-
- private static void parseDecompress(Stack args) {
- if (args.size() < 2) {
- badArguments("decompress");
- }
-
- boolean result = false;
- try {
- try (InputStream fis = new BufferedInputStream(new FileInputStream(args.pop()));
- OutputStream fos = new BufferedOutputStream(new FileOutputStream(args.pop()))) {
- result = SWF.decompress(fis, fos);
- System.out.println(result ? "OK" : "FAIL");
- } catch (FileNotFoundException ex) {
- System.err.println("File not found.");
- System.exit(1);
- }
- } catch (IOException ex) {
- logger.log(Level.SEVERE, null, ex);
- }
-
- System.exit(result ? 0 : 1);
- }
-
- private static void parseSwf2Xml(Stack args) {
- if (args.size() < 2) {
- badArguments("swf2xml");
- }
-
- try {
- try (FileInputStream is = new FileInputStream(args.pop())) {
- SWF swf = new SWF(is, Configuration.parallelSpeedUp.get());
- new SwfXmlExporter().exportXml(swf, new File(args.pop()));
- } catch (FileNotFoundException ex) {
- System.err.println("File not found.");
- System.exit(1);
- } catch (InterruptedException ex) {
- logger.log(Level.SEVERE, null, ex);
- }
- } catch (IOException ex) {
- logger.log(Level.SEVERE, null, ex);
- }
-
- System.exit(0);
- }
-
- private static void parseXml2Swf(Stack args) {
- if (args.size() < 2) {
- badArguments("xml2swf");
- }
-
- try {
- File inFile = new File(args.pop());
- SWF swf = new SWF();
- new SwfXmlImporter().importSwf(swf, inFile);
- try (OutputStream fos = new BufferedOutputStream(new FileOutputStream(new File(args.pop())))) {
- swf.saveTo(fos);
- }
- } catch (IOException ex) {
- logger.log(Level.SEVERE, null, ex);
- }
-
- System.exit(0);
- }
-
- private static void parseExtract(Stack args) {
- if (args.size() < 1) {
- badArguments("extract");
- }
-
- String fileName = args.pop();
- SearchMode mode = SearchMode.ALL;
-
- boolean noCheck = false;
- String output = null;
-
- if (args.size() > 0 && args.peek().toLowerCase(Locale.ENGLISH).equals("-o")) {
- args.pop();
- if (args.size() < 1) {
- badArguments("extract");
- }
- output = args.pop();
- }
-
- if (args.size() > 0 && args.peek().toLowerCase(Locale.ENGLISH).equals("nocheck")) {
- noCheck = true;
- args.pop();
- }
-
- if (args.size() > 0) {
- String modeStr = args.pop().toLowerCase(Locale.ENGLISH);
- switch (modeStr) {
- case "biggest":
- mode = SearchMode.BIGGEST;
- break;
- case "smallest":
- mode = SearchMode.SMALLEST;
- break;
- case "first":
- mode = SearchMode.FIRST;
- break;
- case "last":
- mode = SearchMode.LAST;
- break;
- }
- }
-
- try {
- SWFSourceInfo sourceInfo = new SWFSourceInfo(null, fileName, null);
- if (!sourceInfo.isBundle()) {
- System.err.println("Error: should be a bundle. (ZIP or non SWF binary file)");
- System.exit(1);
- }
- SWFBundle bundle = sourceInfo.getBundle(noCheck, mode);
- List> streamsToExtract = new ArrayList<>();
- for (Map.Entry streamEntry : bundle.getAll().entrySet()) {
- InputStream stream = streamEntry.getValue();
- stream.reset();
- streamsToExtract.add(streamEntry);
- }
-
- for (Map.Entry streamEntry : streamsToExtract) {
- InputStream stream = streamEntry.getValue();
- stream.reset();
- String fileNameOut;
- if (mode != SearchMode.ALL) {
- if (output == null) {
- fileNameOut = Path.getFileNameWithoutExtension(new File(fileName)) + ".swf";
- } else {
- fileNameOut = output;
- }
- } else {
- fileNameOut = streamEntry.getKey() + ".swf";
- if (output != null) {
- fileNameOut = Path.combine(output, fileNameOut);
- }
- }
-
- try (OutputStream fos = new BufferedOutputStream(new FileOutputStream(fileNameOut))) {
- byte[] swfData = new byte[stream.available()];
- int cnt = stream.read(swfData);
- fos.write(swfData, 0, cnt);
- }
- }
- } catch (IOException ex) {
- logger.log(Level.SEVERE, null, ex);
- }
-
- System.exit(0);
- }
-
- private static void parseMemorySearch(Stack args) {
- if (args.size() < 1) {
- badArguments("memorysearch");
- }
-
- if (Platform.isWindows()) {
- AtomicInteger cnt = new AtomicInteger();
- List procs = new ArrayList<>();
- List