Export command WIP

This commit is contained in:
Jindra Petřík
2024-01-07 23:55:35 +01:00
parent e0f1d22de9
commit 54bfd1f6fb
11 changed files with 521 additions and 72 deletions

View File

@@ -31,6 +31,7 @@ public class NewCommandLine {
args = new String[] {"--cli", "help", "export"};
//args = new String[] {"--help"};
//args = new String[] {"--cli", "export", "script:as,image:png", "C:/out/", "C:/in/myfile.swf"};
int exitCode = new CommandLine(new Main()).execute(args);

View File

@@ -15,10 +15,21 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.jpexs.decompiler.flash.console.commands;
import com.jpexs.decompiler.flash.console.commands.types.ConfigConverter;
import com.jpexs.decompiler.flash.console.commands.types.ExportObject;
import com.jpexs.decompiler.flash.console.commands.types.ExportObjectFormat;
import com.jpexs.decompiler.flash.console.commands.types.ExportObjectFormatConverter;
import com.jpexs.decompiler.flash.console.commands.types.Selection;
import com.jpexs.decompiler.flash.console.commands.types.SelectionConverter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import picocli.CommandLine;
import picocli.CommandLine.Command;
import picocli.CommandLine.Option;
import picocli.CommandLine.Parameters;
import picocli.CommandLine.ParentCommand;
/**
*
@@ -27,84 +38,119 @@ import picocli.CommandLine.Parameters;
@Command(name = "export",
header = "Export sources to directory"
)
public class Export {
public class Export implements Runnable {
@ParentCommand
private Main parent;
@Option(names = "--frame",
paramLabel = "<frameRanges>",
converter = SelectionConverter.class,
description = {
"Selected frame(s) to export.",
"Sample values: 1-5 or 2,4 or 2-5,7,9-"
}
)
private Selection frames = new Selection();
@Option(names = "--character-id",
paramLabel = "<characterIdRanges>",
converter = SelectionConverter.class,
description = {
"Selected character id(s) to export.",
"Sample values: 27 or 2-5 or 12,24 or 2-5,10,9-"
}
)
private Selection characterIds = new Selection();
@Option(names = "--class",
paramLabel = "<class>",
split = ",",
description = {
"Selected scripts to export by classname (ActionScript 3 ONLY).",
"Sample values:",
"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)",
})
private List<String> classes = new ArrayList<>();
@Option(names = "--embed",
description = {
"Enables exporting embedded assets via [Embed tag].",
"For script:as exports."
}
)
private boolean useEmbed = false;
@Parameters(index = "0",
split = ",",
paramLabel = "<type>",
description = {"Types to export:",
"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)"}
)
private String[] types;
@Option(names = "--format", split = ",", paramLabel = "<type:format>", description = {
"Sets output format for export:",
"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:<flaversion> or xfl:<flaversion> - Specify FLA format version",
" - values for <flaversion>: cs5,cs5.5,cs6,cc",
})
private String[] formats;
converter = ExportObjectFormatConverter.class,
paramLabel = "<type[:format]>",
description = {"What objects to export. Available formats:",
"script:as (default)",
"script:pcode",
"script:pcodehex",
"script:hex",
"shape:svg (default)",
"shape:png",
"shape:canvas",
"shape:bmp",
"morphshape:svg (default)",
"morphshape:canvas",
"frame:png (default)",
"frame:gif",
"frame:avi",
"frame:svg",
"frame:canvas",
"frame:pdf",
"frame:bmp",
"sprite:png (default)",
"sprite:gif",
"sprite:avi",
"sprite:svg",
"sprite:canvas",
"sprite:pdf",
"sprite:bmp",
"button:png (default)",
"button:svg",
"button:bmp",
"image:png_gif_jpeg (default)",
"image:png",
"image:jpeg",
"image:bmp",
"image:png_gif_jpeg_alpha",
"text:plain (default)",
"text:formatted",
"text:svg",
"sound:mp3_wav_flv (default)",
"sound:mp3_wav",
"sound:wav",
"sound:flv",
"font:ttf (default)",
"font:woff",
"font4:cff (default)",
"fla:cs5",
"fla:cs5.5",
"fla:cs6",
"fla:cc",
"xfl:cs5",
"xfl:cs5.5",
"xfl:cs6",
"xfl:cc",
})
private List<ExportObjectFormat> objects;
@Parameters(index = "1", description = "Target directory")
private String outDirectory;
@Parameters(index = "2", description = "Input file or directory")
private String inFileOrDirectory;
@Override
public void run() {
System.out.println("exporting...ok");
}
}

View File

@@ -16,13 +16,17 @@
*/
package com.jpexs.decompiler.flash.console.commands;
import com.jpexs.decompiler.flash.ApplicationInfo;
import com.jpexs.decompiler.flash.console.commands.types.ConfigConverter;
import java.io.File;
import java.util.HashMap;
import java.util.Map;
import picocli.CommandLine;
import picocli.CommandLine.Command;
import picocli.CommandLine.IVersionProvider;
import picocli.CommandLine.Option;
import picocli.CommandLine.Parameters;
import picocli.CommandLine.HelpCommand;
import picocli.CommandLine.ScopeType;
/**
*
@@ -40,6 +44,17 @@ import picocli.CommandLine.HelpCommand;
)
public class Main implements Runnable {
@Option(names = "--config",
paramLabel = "<key>=<value>[,<key>=<value>...]",
converter = ConfigConverter.class,
description = {
"Sets configuration values for this session.",
"Use command 'config' to list available configuration settings. "
},
scope = ScopeType.INHERIT
)
private Map<String, String> configs = new HashMap<>();
@Parameters(paramLabel = "FILE", description = "one or more files to open in GUI")
private File[] files;

View File

@@ -0,0 +1,51 @@
/*
* 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 <http://www.gnu.org/licenses/>.
*/
package com.jpexs.decompiler.flash.console.commands.types;
import com.jpexs.decompiler.flash.configuration.Configuration;
import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.Map;
import picocli.CommandLine;
/**
*
* @author JPEXS
*/
public class ConfigConverter implements CommandLine.ITypeConverter<Map<String,String>>{
@Override
public Map<String, String> convert(String value) throws Exception {
String[] cfgs;
if (value.contains(",")) {
cfgs = value.split(",");
} else {
cfgs = new String[]{value};
}
Map<String, String> ret = new HashMap<>();
for (String c : cfgs) {
String[] cp = c.split("=");
if (cp.length == 1) {
cp = new String[]{cp[0], "1"};
}
ret.put(cp[0], cp[1]);
}
return ret;
}
}

View File

@@ -0,0 +1,84 @@
/*
* 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 <http://www.gnu.org/licenses/>.
*/
package com.jpexs.decompiler.flash.console.commands.types;
import com.jpexs.decompiler.flash.exporters.modes.BinaryDataExportMode;
import com.jpexs.decompiler.flash.exporters.modes.ButtonExportMode;
import com.jpexs.decompiler.flash.exporters.modes.Font4ExportMode;
import com.jpexs.decompiler.flash.exporters.modes.FontExportMode;
import com.jpexs.decompiler.flash.exporters.modes.FrameExportMode;
import com.jpexs.decompiler.flash.exporters.modes.ImageExportMode;
import com.jpexs.decompiler.flash.exporters.modes.MorphShapeExportMode;
import com.jpexs.decompiler.flash.exporters.modes.MovieExportMode;
import com.jpexs.decompiler.flash.exporters.modes.ScriptExportMode;
import com.jpexs.decompiler.flash.exporters.modes.ShapeExportMode;
import com.jpexs.decompiler.flash.exporters.modes.SoundExportMode;
import com.jpexs.decompiler.flash.exporters.modes.SpriteExportMode;
import com.jpexs.decompiler.flash.exporters.modes.SymbolClassExportMode;
import com.jpexs.decompiler.flash.exporters.modes.TextExportMode;
import com.jpexs.decompiler.flash.types.sound.SoundExportFormat;
import com.jpexs.decompiler.flash.xfl.FLAVersion;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
/**
*
* @author JPEXS
*/
public enum ExportObject {
SCRIPT(ScriptExportMode.class),
IMAGE(ImageExportMode.class),
SHAPE(ShapeExportMode.class),
MORPHSHAPE(MorphShapeExportMode.class),
MOVIE(MovieExportMode.class),
FONT(FontExportMode.class),
FONT4(Font4ExportMode.class),
FRAME(FrameExportMode.class),
SPRITE(SpriteExportMode.class),
BUTTON(ButtonExportMode.class),
SOUND(SoundExportMode.class),
BINARYDATA(BinaryDataExportMode.class),
SYMBOLCLASS(SymbolClassExportMode.class),
TEXT(TextExportMode.class),
ALL(null),
FLA(FLAVersion.class),
XFL(FLAVersion.class);
private Class formatsEnum;
ExportObject(Class formatsEnum) {
this.formatsEnum = formatsEnum;
}
public List<Object> getAllowedFormats() {
if (formatsEnum == null) {
return new ArrayList<>();
}
return Arrays.asList(formatsEnum.getEnumConstants());
}
public List<String> getAllowedFormatsAsStr() {
if (formatsEnum == null) {
return new ArrayList<>();
}
List<String> ret = new ArrayList<>();
for (Object o : formatsEnum.getEnumConstants()) {
ret.add(o.toString().toLowerCase());
}
return ret;
}
}

View File

@@ -0,0 +1,31 @@
/*
* 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 <http://www.gnu.org/licenses/>.
*/
package com.jpexs.decompiler.flash.console.commands.types;
/**
*
* @author JPEXS
*/
public class ExportObjectFormat {
public ExportObject object;
public String format;
public ExportObjectFormat(ExportObject type, String format) {
this.object = type;
this.format = format;
}
}

View File

@@ -0,0 +1,60 @@
/*
* 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 <http://www.gnu.org/licenses/>.
*/
package com.jpexs.decompiler.flash.console.commands.types;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import picocli.CommandLine;
/**
*
* @author JPEXS
*/
public class ExportObjectFormatConverter implements CommandLine.ITypeConverter<ExportObjectFormat>{
@Override
public ExportObjectFormat convert(String value) throws Exception {
Pattern pat = Pattern.compile("^(?<type>[a-z0-9]+)(:(?<format>[a-z0-9]+))?$");
Matcher mat = pat.matcher(value);
if (!mat.matches()) {
throw new CommandLine.TypeConversionException("Invalid value: must be 'type:format' or 'type' but was '" + value + "'");
}
String typeStr = mat.group("type");
String formatStr = mat.group("format");
ExportObject type = null;
try {
type = ExportObject.valueOf(typeStr.toUpperCase());
} catch (IllegalArgumentException ex) {
List<String> ts = new ArrayList<>();
for (ExportObject t : ExportObject.values()) {
ts.add("'" + ts.toString().toLowerCase() + "'");
}
throw new CommandLine.TypeConversionException("Invalid type: must be one of " + String.join(", ", ts) + " but was '" + typeStr+ "'");
}
List<String> allowedFormats = type.getAllowedFormatsAsStr();
if (!allowedFormats.isEmpty() && formatStr != null) {
if (!allowedFormats.contains(formatStr)) {
throw new CommandLine.TypeConversionException("Invalid format: for type '" + type + "' must format be one of '" + String.join("', '", allowedFormats) + "' but was " + formatStr);
}
}
return new ExportObjectFormat(type, formatStr);
}
}

View File

@@ -0,0 +1,40 @@
/*
* 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 <http://www.gnu.org/licenses/>.
*/
package com.jpexs.decompiler.flash.console.commands.types;
/**
*
* @author JPEXS
*/
public 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;
}
}

View File

@@ -0,0 +1,47 @@
/*
* 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 <http://www.gnu.org/licenses/>.
*/
package com.jpexs.decompiler.flash.console.commands.types;
import java.util.ArrayList;
import java.util.List;
/**
*
* @author JPEXS
*/
public class Selection {
public List<Range> ranges;
public Selection() {
this.ranges = new ArrayList<>();
this.ranges.add(new Range(null, null));
}
public Selection(List<Range> ranges) {
this.ranges = ranges;
}
public boolean contains(int index) {
for (Range r : ranges) {
if (r.contains(index)) {
return true;
}
}
return false;
}
}

View File

@@ -0,0 +1,71 @@
/*
* 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 <http://www.gnu.org/licenses/>.
*/
package com.jpexs.decompiler.flash.console.commands.types;
import com.jpexs.decompiler.flash.console.CommandLineArgumentParser;
import static com.jpexs.decompiler.flash.console.CommandLineArgumentParser.badArguments;
import java.util.ArrayList;
import java.util.List;
import picocli.CommandLine;
/**
*
* @author JPEXS
*/
public class SelectionConverter implements CommandLine.ITypeConverter<Selection>{
@Override
public Selection convert(String value) throws Exception {
List<Range> ret = new ArrayList<>();
String[] ranges;
if (value.contains(",")) {
ranges = value.split(",");
} else {
ranges = new String[]{value};
}
for (String r : ranges) {
Integer min = null;
Integer max = null;
if (r.contains("-")) {
String[] ps = r.split("\\-");
if (ps.length != 2) {
throw new CommandLine.TypeConversionException("Invalid range: " + r);
}
try {
if (!"".equals(ps[0])) {
min = Integer.parseInt(ps[0]);
}
if (!"".equals(ps[1])) {
max = Integer.parseInt(ps[1]);
}
} catch (NumberFormatException nfe) {
throw new CommandLine.TypeConversionException("Invalid range: " + r);
}
} else {
try {
min = Integer.parseInt(r);
max = min;
} catch (NumberFormatException nfe) {
throw new CommandLine.TypeConversionException("Invalid range: " + r);
}
}
ret.add(new Range(min, max));
}
return new Selection(ret);
}
}

View File

@@ -11089,6 +11089,7 @@ public class CommandLine {
final String name;
int position;
@SuppressWarnings("deprecation") //JPEXS
public MethodParam(Method method, int paramIndex) {
this.method = method;
this.paramIndex = paramIndex;
@@ -15871,7 +15872,9 @@ public class CommandLine {
} else {
text = text.concat("[").concat(name).concat(param).concat("]");
if (option.isMultiValue()) { // add ellipsis to show option is repeatable
text = text.concat("...");
if (option.splitRegex().isEmpty() && option.converters().length == 0) { //JPEXS
text = text.concat("...");
}
}
}
}