From 00b886b7b71893e08684ada659920f5bfbe382c4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jindra=20Pet=C5=99=C3=ADk?= Date: Mon, 22 Jan 2024 15:29:00 +0100 Subject: [PATCH] Better commandline help WIP. Fixed #2182 Add FFDec to context menu --- .../console/CommandLineArgumentParser.java | 15 +- .../flash/console/CommandLineHelp.java | 175 ++++++++ .../jpexs/decompiler/flash/console/help.txt | 373 ++++++++++++++++++ 3 files changed, 555 insertions(+), 8 deletions(-) create mode 100644 src/com/jpexs/decompiler/flash/console/CommandLineHelp.java create mode 100644 src/com/jpexs/decompiler/flash/console/help.txt diff --git a/src/com/jpexs/decompiler/flash/console/CommandLineArgumentParser.java b/src/com/jpexs/decompiler/flash/console/CommandLineArgumentParser.java index 18740bed1..ad5836258 100644 --- a/src/com/jpexs/decompiler/flash/console/CommandLineArgumentParser.java +++ b/src/com/jpexs/decompiler/flash/console/CommandLineArgumentParser.java @@ -334,7 +334,7 @@ public class CommandLineArgumentParser { } public static void printCmdLineUsage(PrintStream out, boolean webHelp, String filter) { - int cnt = 1; + AnsiConsole.systemInstall(); out.println("@|underline,bold Usage|@: @|bold |@ [PRE-OPTIONS] [COMMAND]"); out.println(); out.println("@|underline,bold Executable|@:"); @@ -855,6 +855,8 @@ public class CommandLineArgumentParser { printCmdLineUsageExamples(out, filter); System.out.println("You can use special value \"/dev/stdin\" for input files to read data from standard input (even on Windows)"); + + AnsiConsole.systemUninstall(); } private static void printCmdLineUsageExamples(PrintStream out, String filter) { @@ -973,13 +975,8 @@ public class CommandLineArgumentParser { * @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 { - AnsiConsole.systemInstall(); - try { - return parseArgumentsInternal(arguments); - } finally { - AnsiConsole.systemUninstall(); - } + public static String[] parseArguments(String[] arguments) throws IOException { + return parseArgumentsInternal(arguments); } private static PrintStream ansiSystemOut() { @@ -1320,7 +1317,9 @@ public class CommandLineArgumentParser { } public static void printHeader() { + AnsiConsole.systemInstall(); ansiPrintln(ApplicationInfo.cliApplicationVerName); + AnsiConsole.systemUninstall(); for (int i = 0; i < ApplicationInfo.applicationVerName.length(); i++) { System.out.print("-"); } diff --git a/src/com/jpexs/decompiler/flash/console/CommandLineHelp.java b/src/com/jpexs/decompiler/flash/console/CommandLineHelp.java new file mode 100644 index 000000000..e33724769 --- /dev/null +++ b/src/com/jpexs/decompiler/flash/console/CommandLineHelp.java @@ -0,0 +1,175 @@ +/* + * Copyright (C) 2024 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.helpers.utf8.Utf8Helper; +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.UnsupportedEncodingException; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.logging.Level; +import java.util.logging.Logger; + +/** + * + * @author JPEXS + */ +public class CommandLineHelp { + private static Map> commands = new LinkedHashMap<>(); + private static Map preOptions = new LinkedHashMap<>(); + + private static class Command { + String name; + String customSynopsis; + String arguments; + String header; + String description; + + public Command(String name, String customSynopsis, String arguments, String header, String description) { + this.name = name; + this.customSynopsis = customSynopsis; + this.arguments = arguments; + this.header = header; + this.description = description; + } + + @Override + public String toString() { + if (customSynopsis != null) { + return customSynopsis + "\r\n" + indent(header) + "\r\n" + indent(description); + } else { + return name + " " + arguments + "\r\n" + indent(header) + "\r\n" + indent(description); + } + } + } + + private static String indent(String text) { + String indent = " "; + return indent + rtrim(text.replace("\r\n", "\r\n" + indent)); + } + + private static String rtrim(String text) { + return text.replaceAll("\\s+$",""); + } + + private static class Option { + String name; + String arguments; + String appliesTo; + String description; + + public Option(String name, String arguments, String appliesTo, String description) { + this.name = name; + this.arguments = arguments; + this.appliesTo = appliesTo; + this.description = description; + } + } + + private static void parse() { + InputStream is = CommandLineHelp.class.getClassLoader().getResourceAsStream("com/jpexs/decompiler/flash/console/help.txt"); + try(BufferedReader br = new BufferedReader(new InputStreamReader(is, Utf8Helper.charset))) { + String s; + boolean commandsSection = false; + boolean optionsSection = false; + boolean headerSection = false; + String itemName = null; + String arguments = null; + String customSynopsis = null; + StringBuffer descriptionBuffer = new StringBuffer(); + String header = null; + while ((s = br.readLine()) != null) { + s = rtrim(s); + if (s.startsWith("Commands:")) { + commandsSection = true; + continue; + } + if (s.startsWith("Pre-options:")) { + optionsSection = true; + commandsSection = false; + continue; + } + + if (commandsSection) { + if (s.isEmpty()) { + if (itemName != null) { + if (!commands.containsKey(itemName)) { + commands.put(itemName, new ArrayList<>()); + } + commands.get(itemName).add(new Command(itemName, customSynopsis, arguments, header, descriptionBuffer.toString())); + } + } else if (s.startsWith("<")) { + itemName = "main"; + arguments = null; + customSynopsis = s; + descriptionBuffer.setLength(0); + headerSection = true; + header = null; + } else if (s.startsWith("-help")) { + itemName = "-help"; + arguments = null; + customSynopsis = s; + descriptionBuffer.setLength(0); + headerSection = true; + header = null; + } else if (s.startsWith("-")) { + if (s.contains(" ")) { + itemName = s.substring(0, s.indexOf(" ")); + arguments = s.substring(s.indexOf(" ") + 1); + } else { + itemName = s; + arguments = ""; + } + customSynopsis = null; + descriptionBuffer.setLength(0); + headerSection = true; + header = null; + } else if (s.startsWith(" ")) { + if (headerSection) { + headerSection = false; + header = s.substring(4); + } else { + descriptionBuffer.append(s.substring(4)).append("\r\n"); + } + } + } + + if (optionsSection) { + //TODO... + } + } + } catch (IOException ex) { + Logger.getLogger(CommandLineHelp.class.getName()).log(Level.SEVERE, null, ex); + } + } + + public static void main(String[] args) { + parse(); + for (String name : commands.keySet()) { + List list = commands.get(name); + for (Command c : list) { + System.out.println(c); + } + } + } +} diff --git a/src/com/jpexs/decompiler/flash/console/help.txt b/src/com/jpexs/decompiler/flash/console/help.txt new file mode 100644 index 000000000..4c8205264 --- /dev/null +++ b/src/com/jpexs/decompiler/flash/console/help.txt @@ -0,0 +1,373 @@ +Usage: [PRE-OPTIONS] [COMMAND] + +Executable: + Linux: ffdec or ffdec.sh + Mac OS: ffdec.sh + Windows: ffdec-cli.exe or ffdec.bat + Java: java -jar ffdec.jar + +Commands: +-help | --help | /? + Show commandline arguments (this help). + + [ ...] + Open SWF file(s) with the decompiler GUI. + +-proxy [-P] + Auto start proxy in the tray. + Start proxy in the system tray. Optional parameter -P specifies port for proxy. Defaults to 55555. + +-export + Export sources. + Export sources to . + Exports all files from when it is a folder. + Values for parameter: + script - Scripts (Default format: ActionScript source) + image - Images (Default format: PNG/JPEG) + shape - Shapes (Default format: SVG) + morphshape - MorphShapes (Default format: SVG) + movie - Movies (Default format: FLV without sound) + font - Fonts (Default format: TTF) + font4 - DefineFont4 (Default format: CFF) + frame - Frames (Default format: PNG) + sprite - Sprites (Default format: PNG) + button - Buttons (Default format: PNG) + sound - Sounds (Default format: MP3/WAV/FLV only sound) + binaryData - Binary data (Default format: Raw data) + symbolClass - Symbol-Class mapping (Default format: CSV) + text - Texts (Default format: Plain text) + all - Every resource (but not FLA and XFL) + fla - Everything to FLA compressed format + xfl - Everything to uncompressed FLA format (XFL) + You can export multiple types of items by using colon ",". + DO NOT PUT space between comma (,) and next value. + +-dumpSWF + Dump list of SWF tags to console. + +-dumpAS2 + Dump list of AS1/2 scripts to console. + +-dumpAS3 + Dump list of AS3 scripts to console. + +-compress [(zlib|lzma)] + Compress SWF file. + Compress SWF and save it to . If is already compressed, it will be re-compressed. Default compression method is ZLIB + +-decompress + Decompress SWF file. + Decompress and save it to + +-encrypt + Encrypt SWF file with HARMAN Air encryption. + Encrypt file with HARMAN Air encryption and saves it to + +-decrypt + Decrypt HARMAN Air encrypted file. + Decrypt HARMAN Air encrypted file and saves it to + +-swf2xml + Convert SWF to XML. + Convert the SWF to XML file + +-xml2swf + Convert XML to SWF. + Convert the XML to SWF file + +-extract [-o |] [nocheck] [(all|biggest|smallest|first|last)] + Extract SWF files from ZIP or other binary files. + -o parameter should contain a file path when "biggest" or "first" parameter is specified + -o parameter should contain a folder path when no extaction mode or "all" parameter is specified + +-memorySearch (|) (|)... + Search SWF files in the memory. + +-renameInvalidIdentifiers (typeNumber|randomWord) + Rename invalid identifiers. + Rename the invalid identifiers in and save it to + +-flashpaper2pdf + Convert FlashPaper SWF file to PDF. + Convert FlashPaper SWF file to PDF . Use -zoom parameter to specify image quality. + +-replace (|) [nofill] ([][]) [(|) [nofill] ([][])]... + Replace data. + Replaces the data of the specified BinaryData, Image, Shape, Text, Sound tag or Script + nofill parameter can be specified only for shape replace + parameter can be specified for Image and Shape tags + valid formats: lossless, lossless2, jpeg2, jpeg3, jpeg4 + parameter should be specified if and only if the imported entity is an AS3 P-Code + use -1 as characterId to replace main timeline SoundStreamHead +-replace + Replace data using argsfile. + Same as -replace command, but the rest of arguments is read as lines from a text file + +-replaceAlpha [ ]... + Replace the alpha channel of the specified JPEG3/4 tag. + +-replaceCharacter [ ]... + Replace a character tag with another from the same SWF. + +-replaceCharacterId ,,,... + Replace character ids. + Replace the character id with . +-replaceCharacterId (pack|sort) + Replace character ids bulk operation. + pack: removes the spaces between the character ids (1,4,3 => 1,3,2) + sort: assigns increasing IDs to the character tags + pack (1,4,3 => 1,2,3) + DO NOT PUT space between comma (,) and next value. + +-remove []... + Remove a tag from the SWF. + Remove tags based in index from main SWF timeline. + +-removeCharacter[WithDependencies] []... + Remove a character tag from the SWF + +-importSymbolClass + Import Symbol-Class mapping. + Import Symbol-Class mapping to and saves the result to . + +-importMovies + Bulk import movies. + Import movies to and saves the result to . + +-importSounds + Bulk import sounds. + Import sounds to and saves the result to . + +-importShapes [nofill] + Bulk import shapes. + Import shapes to and saves the result to . + +-importImages + Bulk import images. + Import images to and saves the result to . + +-importSprites + Bulk import sprites. + Import sprites to and saves the result to . + +-importText + Bulk import texts. + Import texts to and saves the result to , + +-importScript + Bulk import scripts. + Import scripts to and saves the result to . + +-deobfuscate + Deobfuscate AS3 P-code. + Deobfuscate AS3 P-code in and saves result to . + can be one of: traps/2/max, deadcode/1 + +-enabledebugging [-injectas3|-generateswd] [-pcode] + Enable debugging in SWF file. + Enable debugging for and saves result to . + -injectas3 (optional) causes debugfile and debugline instructions to be injected into the code to match decompiled/pcode source. + -generateswd (optional) parameter creates SWD file needed for AS1/2 debugging. for , is generated + -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. + WARNING: Injected/SWD script filenames may be different than from standard compiler + +-doc -type [-out ] [-format ] [-locale ] + Generate documentation. + -type Selects documentation type + can be currently only: as3.pcode.instructions for list of ActionScript3 AVM2 instructions + -out (optional) If specified, output is written to instead of stdout + -format (optional, html is default) Selects output format + is currently only html + -locale (optional) Override default locale + is localization identifier, en for english for example + is currently only html + +-getInstanceMetadata -instance [-outputFormat ] [-key ] [-datafile ] + Read instance metadata. + -instance : name of instance to fetch metadata from + -outputFormat (optional): format of output - one of: jslike|raw. Default is jslike. + - key (optional): name of subkey to display. When present, only value from subkey is shown, whole object value otherwise. + -datafile (optional): File to write the data to. If ommited, stdout is used. + : SWF file to read metadata from + +-setInstanceMetadata -instance [-inputFormat ] [-key ] [-value | -datafile ] [-outfile ] + Add metadata to instance. + -instance : name of instance to replace data in + -inputFormat : format of input data - one of: jslike|raw. Default is jslike. + - key (optional): name of subkey to use. When present, the value is set as object property with the name. + Otherwise the value is set directly to the instance without any subkeys. + -value (optional): value to set. + -datafile (optional): value to set from file. + If no -value or -infile parameter present, the value to set is taken from stdin. + -outfile (optional): Where to save resulting file. If ommited, original SWF file is overwritten. + : SWF file to search instance in + +-removeInstanceMetadata -instance [-key ] [-outfile ] + Remove metadata from instance. + -instance : name of instance to remove data from + -key (optional): name of subkey to remove. + When present, only the value from subkey of the AMF object is removed. + Otherwise all metadata are removed from the instance. + -outfile (optional): Where to save resulting file. If ommited, original SWF file is overwritten. + : SWF file to search instance in + +-linkReport [-outfile ] + Generate linker report for the swffile. + -outfile (optional): Saves XML report to . When ommited, the report is printed to stdout. + : SWF file to search instance in + +-swf2swc + Generate SWC file from SWF. + : Where to save SWC file + : Input SWF file + +-abcmerge + Merge all ABC tags in SWF file to one. + : Where to save merged file + : Input SWF file + +-swf2exe + Export SWF to executable file. + : wrapper|projector_win||projector_mac|projector_linux + +-header -set [-set ...] [] + Print or set SWF header values. + Print header or sets SWF header values (with -set arguments) in and saves it to + Available keys: version + gfx (true/false) + displayrect ([x1,y1,x2,y2]) + width + height + framecount + framerate + For width, height and displayrect subvalues you can use suffix px for pixel values. Otherwise its twips. + + +Pre-options: +-format + Applies to: -export COMMAND + Set output formats for export. + Values for parameter: + script:as - ActionScript source + script:pcode - ActionScript P-code + script:pcodehex - ActionScript P-code with hex + script:hex - ActionScript Hex only + shape:svg - SVG format for Shapes + shape:png - PNG format for Shapes + shape:canvas - HTML5 Canvas format for Shapes + shape:bmp - BMP format for Shapes + morphshape:svg - SVG format for MorphShapes + morphshape:canvas - HTML5 Canvas format for MorphShapes + frame:png - PNG format for Frames + frame:gif - GIF format for Frames + frame:avi - AVI format for Frames + frame:svg - SVG format for Frames + frame:canvas - HTML5 Canvas format for Frames + frame:pdf - PDF format for Frames + frame:bmp - BMP format for Frames + sprite:png - PNG format for Sprites + sprite:gif - GIF format for Sprites + sprite:avi - AVI format for Sprites + sprite:svg - SVG format for Sprites + sprite:canvas - HTML5 Canvas format for Sprites + sprite:pdf - PDF format for Sprites + sprite:bmp - BMP format for Sprites + button:png - PNG format for Buttons + button:svg - SVG format for Buttons + button:bmp - BMP format for Buttons + image:png_gif_jpeg - PNG/GIF/JPEG format for Images + image:png - PNG format for Images + image:jpeg - JPEG format for Images + image:bmp - BMP format for Images + image:png_gif_jpeg_alpha - PNG/GIF/JPEG+ALPHA format for Images + text:plain - Plain text format for Texts + text:formatted - Formatted text format for Texts + text:svg - SVG format for Texts + sound:mp3_wav_flv - MP3/WAV/FLV format for Sounds + sound:mp3_wav - MP3/WAV format for Sounds + sound:wav - WAV format for Sounds + sound:flv - FLV format for Sounds + font:ttf - TTF format for Fonts + font:woff - WOFF format for Fonts + font4:cff - CFF format for DefineFont4 + fla: or xfl: - Specify FLA format version + - values for : cs5,cs5.5,cs6,cc + You can set multiple formats at once using comma (,) + DO NOT PUT space between comma (,) and next value. + The prefix with colon (:) is neccessary. + +-cli + Applies to: MAIN COMMAND + Command line mode. Parse the SWFs without opening the GUI. + +-select + Applies to: -export COMMAND + Select frames/pages for export. + Example formats: + 1-5 + 2,3 + 2-5,7,9- + DO NOT PUT space between comma (,) and next ramge. + +-selectid + Select characters for export by character id. + format is same as in -select + +-selectclass + Applies to: -export COMMAND + Select scripts to export by class name (AS 3 ONLY). + format: + com.example.MyClass + com.example.+ (all classes in package "com.example") + com.++,net.company.MyClass (all classes in package "com" and all subpackages, class net.company.MyClass) + DO NOT PUT space between comma (,) and next class. + +-exportembed + Applies to: -export COMMAND + Allow exporting embedded assets via [Embed tag]. + +-config key=value[,key2=value2][,key3=value3...] [other parameters] + Applies to: everything configurable + Set configuration values. + Use -listconfigs command to list the available configuration settings. + Values are boolean, you can use 0/1, true/false, on/off or yes/no. + If no other parameters passed, configuration is saved. Otherwise it is used only once. + DO NOT PUT space between comma (,) and next value. + +-onerror (abort|retry |ignore) + Applies to: -export, -import COMMANDs + Error handling mode. + "abort" stops the exporting + "retry" tries the exporting N times + "ignore" ignores the current file + +-timeout + Applies to: -export COMMAND + Decompilation timeout for a single method in AS3 or single action in AS1/2 in seconds. + +-exportTimeout + Applies to: -export COMMAND + Total export timeout in seconds. + +-exportFileTimeout + Applies to: -export COMMAND + Export timeout for a single AS3 class in seconds. + +-stat + Applies to: -export COMMAND + Show export performance statistics. + +-zoom + Applies to: -export, -flashpaper2pdf COMMANDs + Apply zoom during export. + +-custom []... + Applies to: MAIN COMMAND + Forward all parameters after the -custom parameter to the plugins. + +-charset + Applies to: every SWF reading COMMAND + Set desired character set for reading/writing SWF files with SWF version <= 5. + +-air + Applies to: -replace, -import COMMANDs + Use AIR ("airglobal.swc") for AS3 compilation instead of "playerglobal.swc". \ No newline at end of file