1use clap::ValueEnum;
3use serde::{Deserialize, Serialize};
4use std::collections::HashMap;
5
6#[derive(Copy, Clone, Serialize, Deserialize, Debug)]
7#[serde(untagged, rename_all = "camelCase")]
8pub enum Encoding {
10 Auto,
12 Utf8,
14 Cp932,
16 Gb2312,
18 #[cfg(windows)]
20 CodePage(u32),
21}
22
23impl Default for Encoding {
24 fn default() -> Self {
25 Encoding::Utf8
26 }
27}
28
29impl Encoding {
30 pub fn is_jis(&self) -> bool {
32 match self {
33 Self::Cp932 => true,
34 #[cfg(windows)]
35 Self::CodePage(code_page) => *code_page == 932,
36 _ => false,
37 }
38 }
39
40 pub fn is_utf8(&self) -> bool {
42 match self {
43 Self::Utf8 => true,
44 #[cfg(windows)]
45 Self::CodePage(code_page) => *code_page == 65001,
46 _ => false,
47 }
48 }
49}
50
51#[derive(Clone, Copy, Debug, ValueEnum, PartialEq, Eq, PartialOrd, Ord)]
52pub enum TextEncoding {
54 Default,
56 Auto,
58 Utf8,
60 #[value(alias("jis"))]
61 Cp932,
63 #[value(alias("gbk"))]
64 Gb2312,
66}
67
68#[derive(Clone, Copy, Debug, ValueEnum, PartialEq, Eq, PartialOrd, Ord)]
69pub enum OutputScriptType {
71 M3t,
73 Json,
75 Yaml,
77 Custom,
79}
80
81impl OutputScriptType {
82 pub fn is_custom(&self) -> bool {
84 matches!(self, OutputScriptType::Custom)
85 }
86}
87
88impl AsRef<str> for OutputScriptType {
89 fn as_ref(&self) -> &str {
91 match self {
92 OutputScriptType::M3t => "m3t",
93 OutputScriptType::Json => "json",
94 OutputScriptType::Yaml => "yaml",
95 OutputScriptType::Custom => "",
96 }
97 }
98}
99
100#[cfg(feature = "circus")]
101#[derive(Clone, Copy, Debug, ValueEnum, PartialEq, Eq, PartialOrd, Ord)]
102pub enum CircusMesType {
104 Ffexa,
106 Ffexs,
108 Ef,
110 Dcos,
112 Ktlep,
114 Dcws,
116 Dcsv,
118 Dcpc,
120 Dcmems,
122 Dcdx,
124 Dcas,
126 Dcbs,
128 Dc2fl,
130 Dc2bs,
132 Dc2dm,
134 Dc2fy,
136 Dc2cckko,
138 Dc2ccotm,
140 Dc2sc,
142 Dc2ty,
144 Dc2pc,
146 Dc3rx,
148 Dc3pp,
150 Dc3wy,
152 Dc3dd,
154 Dc4,
156 Dc4ph,
158 Ds,
160 Dsif,
162 Tmpl,
164 Nightshade,
166}
167
168#[cfg(feature = "circus")]
169impl AsRef<str> for CircusMesType {
170 fn as_ref(&self) -> &str {
172 match self {
173 CircusMesType::Ffexa => "ffexa",
174 CircusMesType::Ffexs => "ffexs",
175 CircusMesType::Ef => "ef",
176 CircusMesType::Dcos => "dcos",
177 CircusMesType::Ktlep => "ktlep",
178 CircusMesType::Dcws => "dcws",
179 CircusMesType::Dcsv => "dcsv",
180 CircusMesType::Dcpc => "dcpc",
181 CircusMesType::Dcmems => "dcmems",
182 CircusMesType::Dcdx => "dcdx",
183 CircusMesType::Dcas => "dcas",
184 CircusMesType::Dcbs => "dcbs",
185 CircusMesType::Dc2fl => "dc2fl",
186 CircusMesType::Dc2bs => "dc2bs",
187 CircusMesType::Dc2dm => "dc2dm",
188 CircusMesType::Dc2fy => "dc2fy",
189 CircusMesType::Dc2cckko => "dc2cckko",
190 CircusMesType::Dc2ccotm => "dc2ccotm",
191 CircusMesType::Dc2sc => "dc2sc",
192 CircusMesType::Dc2ty => "dc2ty",
193 CircusMesType::Dc2pc => "dc2pc",
194 CircusMesType::Dc3rx => "dc3rx",
195 CircusMesType::Dc3pp => "dc3pp",
196 CircusMesType::Dc3wy => "dc3wy",
197 CircusMesType::Dc3dd => "dc3dd",
198 CircusMesType::Dc4 => "dc4",
199 CircusMesType::Dc4ph => "dc4ph",
200 CircusMesType::Ds => "ds",
201 CircusMesType::Dsif => "dsif",
202 CircusMesType::Tmpl => "tmpl",
203 CircusMesType::Nightshade => "nightshade",
204 }
205 }
206}
207
208#[derive(Debug, Clone, Default)]
210pub struct ExtraConfig {
211 #[cfg(feature = "circus")]
212 pub circus_mes_type: Option<CircusMesType>,
214 #[cfg(feature = "escude-arc")]
215 pub escude_fake_compress: bool,
217 #[cfg(feature = "escude")]
218 pub escude_enum_scr: Option<String>,
220 #[cfg(feature = "bgi")]
221 pub bgi_import_duplicate: bool,
224 #[cfg(feature = "bgi")]
225 pub bgi_disable_append: bool,
228 #[cfg(feature = "image")]
229 pub image_type: Option<ImageOutputType>,
231 #[cfg(all(feature = "bgi-arc", feature = "bgi-img"))]
232 pub bgi_is_sysgrp_arc: Option<bool>,
234 #[cfg(feature = "bgi-img")]
235 pub bgi_img_scramble: Option<bool>,
238 #[cfg(feature = "cat-system-arc")]
239 pub cat_system_int_encrypt_password: Option<String>,
241 #[cfg(feature = "cat-system-img")]
242 pub cat_system_image_canvas: bool,
244 #[cfg(feature = "kirikiri")]
245 pub kirikiri_language_index: Option<usize>,
247 #[cfg(feature = "kirikiri")]
248 pub kirikiri_export_comumode: bool,
251 #[cfg(feature = "kirikiri")]
252 pub kirikiri_comumode_json: Option<std::sync::Arc<HashMap<String, String>>>,
254 #[cfg(feature = "kirikiri")]
255 pub kirikiri_remove_empty_lines: bool,
257 #[cfg(feature = "kirikiri")]
258 pub kirikiri_name_commands: std::sync::Arc<std::collections::HashSet<String>>,
260 #[cfg(feature = "kirikiri")]
261 pub kirikiri_message_commands: std::sync::Arc<std::collections::HashSet<String>>,
263 #[cfg(feature = "bgi-arc")]
264 pub bgi_compress_file: bool,
266 #[cfg(feature = "bgi-arc")]
267 pub bgi_compress_min_len: usize,
269 #[cfg(feature = "emote-img")]
270 pub emote_pimg_overlay: Option<bool>,
272 #[cfg(feature = "artemis-arc")]
273 pub artemis_arc_disable_xor: bool,
275 #[cfg(feature = "artemis")]
276 pub artemis_indent: Option<usize>,
279 #[cfg(feature = "artemis")]
280 pub artemis_no_indent: bool,
282 #[cfg(feature = "artemis")]
283 pub artemis_max_line_width: usize,
285 #[cfg(feature = "artemis")]
286 pub artemis_ast_lang: Option<String>,
289 #[cfg(feature = "cat-system")]
290 pub cat_system_cstl_lang: Option<String>,
293 #[cfg(feature = "flate2")]
294 pub zlib_compression_level: u32,
296 #[cfg(feature = "image")]
297 pub png_compression_level: PngCompressionLevel,
299 #[cfg(feature = "circus-img")]
300 pub circus_crx_keep_original_bpp: bool,
302 #[cfg(feature = "circus-img")]
303 pub circus_crx_zstd: bool,
305 #[cfg(feature = "zstd")]
306 pub zstd_compression_level: i32,
308 #[cfg(feature = "circus-img")]
309 pub circus_crx_mode: crate::scripts::circus::image::crx::CircusCrxMode,
311 #[cfg(feature = "ex-hibit")]
312 pub ex_hibit_rld_xor_key: Option<u32>,
315 #[cfg(feature = "ex-hibit")]
316 pub ex_hibit_rld_def_xor_key: Option<u32>,
318 #[cfg(feature = "ex-hibit")]
319 pub ex_hibit_rld_keys: Option<Box<[u32; 0x100]>>,
321 #[cfg(feature = "ex-hibit")]
322 pub ex_hibit_rld_def_keys: Option<Box<[u32; 0x100]>>,
324 #[cfg(feature = "mozjpeg")]
325 pub jpeg_quality: u8,
327 #[cfg(feature = "webp")]
328 pub webp_lossless: bool,
330 #[cfg(feature = "webp")]
331 pub webp_quality: u8,
333 #[cfg(feature = "circus-img")]
334 pub circus_crx_canvas: bool,
336 pub custom_yaml: bool,
338 #[cfg(feature = "entis-gls")]
339 pub entis_gls_srcxml_lang: Option<String>,
342 #[cfg(feature = "will-plus")]
343 pub will_plus_ws2_no_disasm: bool,
347 #[cfg(feature = "artemis")]
348 pub artemis_txt_blacklist_names: std::sync::Arc<std::collections::HashSet<String>>,
351 #[cfg(feature = "artemis")]
352 pub artemis_txt_lang: Option<String>,
355}
356
357#[derive(Clone, Copy, Debug, ValueEnum, PartialEq, Eq, PartialOrd, Ord)]
358pub enum ScriptType {
360 #[cfg(feature = "artemis")]
361 Artemis,
363 #[cfg(feature = "artemis")]
364 ArtemisAsb,
366 #[cfg(feature = "artemis")]
367 ArtemisTxt,
369 #[cfg(feature = "artemis-arc")]
370 #[value(alias("pfs"))]
371 ArtemisArc,
373 #[cfg(feature = "bgi")]
374 #[value(alias("ethornell"))]
375 BGI,
377 #[cfg(feature = "bgi")]
378 #[value(alias("ethornell-bsi"))]
379 BGIBsi,
381 #[cfg(feature = "bgi")]
382 #[value(alias("ethornell-bp"))]
383 BGIBp,
385 #[cfg(feature = "bgi-arc")]
386 #[value(alias = "ethornell-arc-v1")]
387 BGIArcV1,
389 #[cfg(feature = "bgi-arc")]
390 #[value(alias = "ethornell-arc-v2", alias = "bgi-arc", alias = "ethornell-arc")]
391 BGIArcV2,
393 #[cfg(feature = "bgi-arc")]
394 #[value(alias("ethornell-dsc"))]
395 BGIDsc,
397 #[cfg(feature = "bgi-audio")]
398 #[value(alias("ethornell-audio"))]
399 BGIAudio,
401 #[cfg(feature = "bgi-img")]
402 #[value(alias("ethornell-img"))]
403 BGIImg,
405 #[cfg(feature = "bgi-img")]
406 #[value(alias("ethornell-cbg"))]
407 BGICbg,
409 #[cfg(feature = "cat-system")]
410 CatSystem,
412 #[cfg(feature = "cat-system")]
413 CatSystemCstl,
415 #[cfg(feature = "cat-system-arc")]
416 CatSystemInt,
418 #[cfg(feature = "cat-system-img")]
419 CatSystemHg3,
421 #[cfg(feature = "circus")]
422 Circus,
424 #[cfg(feature = "circus-arc")]
425 CircusCrm,
427 #[cfg(feature = "circus-arc")]
428 CircusDat,
430 #[cfg(feature = "circus-arc")]
431 CircusPck,
433 #[cfg(feature = "circus-audio")]
434 CircusPcm,
436 #[cfg(feature = "circus-img")]
437 CircusCrx,
439 #[cfg(feature = "circus-img")]
440 CircusCrxd,
442 #[cfg(feature = "emote-img")]
443 #[value(alias("pimg"))]
444 EmotePimg,
446 #[cfg(feature = "emote-img")]
447 #[value(alias("dref"))]
448 EmoteDref,
450 #[cfg(feature = "entis-gls")]
451 EntisGls,
453 #[cfg(feature = "escude-arc")]
454 EscudeArc,
456 #[cfg(feature = "escude")]
457 Escude,
459 #[cfg(feature = "escude")]
460 EscudeList,
462 #[cfg(feature = "ex-hibit")]
463 ExHibit,
465 #[cfg(feature = "hexen-haus")]
466 HexenHaus,
468 #[cfg(feature = "kirikiri")]
469 #[value(alias("kr-scn"))]
470 KirikiriScn,
472 #[cfg(feature = "kirikiri")]
473 #[value(alias("kr-simple-crypt"))]
474 KirikiriSimpleCrypt,
476 #[cfg(feature = "kirikiri")]
477 #[value(alias = "kr", alias = "kr-ks", alias = "kirikiri-ks")]
478 Kirikiri,
480 #[cfg(feature = "kirikiri-img")]
481 #[value(alias("kr-tlg"))]
482 KirikiriTlg,
484 #[cfg(feature = "kirikiri")]
485 #[value(alias("kr-mdf"))]
486 KirikiriMdf,
488 #[cfg(feature = "softpal")]
489 Softpal,
491 #[cfg(feature = "will-plus")]
492 #[value(alias("adv-hd-ws2"))]
493 WillPlusWs2,
495 #[cfg(feature = "yaneurao-itufuru")]
496 #[value(alias("itufuru"))]
497 YaneuraoItufuru,
499 #[cfg(feature = "yaneurao-itufuru")]
500 #[value(alias("itufuru-arc"))]
501 YaneuraoItufuruArc,
503}
504
505#[derive(Clone, Debug, Serialize, Deserialize)]
506pub struct Message {
508 #[serde(skip_serializing_if = "Option::is_none")]
509 pub name: Option<String>,
511 pub message: String,
513}
514
515impl Message {
516 pub fn new(message: String, name: Option<String>) -> Self {
518 Message { message, name }
519 }
520}
521
522pub enum ScriptResult {
524 Ok,
526 Ignored,
529}
530
531#[derive(Clone, Copy, Debug, ValueEnum, PartialEq, Eq, PartialOrd, Ord)]
532pub enum FormatType {
534 Fixed,
536 None,
538}
539
540pub enum FormatOptions {
542 Fixed {
544 length: usize,
546 keep_original: bool,
548 },
549 None,
551}
552
553#[derive(Debug, Serialize, Deserialize)]
554pub struct NameTableCell {
556 #[serde(rename = "JP_Name")]
557 pub jp_name: String,
559 #[serde(rename = "CN_Name")]
560 pub cn_name: String,
562 #[serde(rename = "Count")]
563 pub count: usize,
565}
566
567#[derive(Debug, Serialize, Deserialize)]
568pub struct ReplacementTable {
570 #[serde(flatten)]
571 pub map: HashMap<String, String>,
573}
574
575#[cfg(feature = "image")]
576#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord)]
577pub enum ImageColorType {
579 Grayscale,
581 Rgb,
583 Rgba,
585 Bgr,
587 Bgra,
589}
590
591#[cfg(feature = "image")]
592impl ImageColorType {
593 pub fn bpp(&self, depth: u8) -> u16 {
595 match self {
596 ImageColorType::Grayscale => depth as u16,
597 ImageColorType::Rgb => depth as u16 * 3,
598 ImageColorType::Rgba => depth as u16 * 4,
599 ImageColorType::Bgr => depth as u16 * 3,
600 ImageColorType::Bgra => depth as u16 * 4,
601 }
602 }
603}
604
605#[cfg(feature = "image")]
606#[derive(Clone, Copy, Debug, ValueEnum, PartialEq, Eq, PartialOrd, Ord)]
607pub enum ImageOutputType {
609 Png,
611 #[cfg(feature = "image-jpg")]
612 Jpg,
614 #[cfg(feature = "image-webp")]
615 Webp,
617}
618
619#[cfg(feature = "image")]
620impl TryFrom<&str> for ImageOutputType {
621 type Error = anyhow::Error;
622
623 fn try_from(value: &str) -> Result<Self, Self::Error> {
626 match value.to_ascii_lowercase().as_str() {
627 "png" => Ok(ImageOutputType::Png),
628 #[cfg(feature = "image-jpg")]
629 "jpg" => Ok(ImageOutputType::Jpg),
630 #[cfg(feature = "image-jpg")]
631 "jpeg" => Ok(ImageOutputType::Jpg),
632 #[cfg(feature = "image-webp")]
633 "webp" => Ok(ImageOutputType::Webp),
634 _ => Err(anyhow::anyhow!("Unsupported image output type: {}", value)),
635 }
636 }
637}
638
639#[cfg(feature = "image")]
640impl TryFrom<&std::path::Path> for ImageOutputType {
641 type Error = anyhow::Error;
642
643 fn try_from(value: &std::path::Path) -> Result<Self, Self::Error> {
644 if let Some(ext) = value.extension() {
645 Self::try_from(ext.to_string_lossy().as_ref())
646 } else {
647 Err(anyhow::anyhow!("No extension found in path"))
648 }
649 }
650}
651
652#[cfg(feature = "image")]
653impl AsRef<str> for ImageOutputType {
654 fn as_ref(&self) -> &str {
656 match self {
657 ImageOutputType::Png => "png",
658 #[cfg(feature = "image-jpg")]
659 ImageOutputType::Jpg => "jpg",
660 #[cfg(feature = "image-webp")]
661 ImageOutputType::Webp => "webp",
662 }
663 }
664}
665
666#[cfg(feature = "image")]
667#[derive(Clone, Debug)]
668pub struct ImageData {
670 pub width: u32,
672 pub height: u32,
674 pub color_type: ImageColorType,
676 pub depth: u8,
678 pub data: Vec<u8>,
680}
681
682#[cfg(feature = "image")]
683#[derive(Clone, Debug)]
684pub struct ImageDataWithName {
686 pub name: String,
688 pub data: ImageData,
690}
691
692#[derive(Clone, Copy, Debug, ValueEnum, PartialEq, Eq, PartialOrd, Ord)]
693pub enum BomType {
695 None,
697 Utf8,
699 Utf16LE,
701 Utf16BE,
703}
704
705impl BomType {
706 pub fn as_bytes(&self) -> &'static [u8] {
708 match self {
709 BomType::None => &[],
710 BomType::Utf8 => b"\xEF\xBB\xBF",
711 BomType::Utf16LE => b"\xFF\xFE",
712 BomType::Utf16BE => b"\xFE\xFF",
713 }
714 }
715}
716
717#[cfg(feature = "image")]
718#[derive(Clone, Copy, Debug, ValueEnum, PartialEq, Eq, PartialOrd, Ord)]
719pub enum PngCompressionLevel {
721 #[value(alias = "d")]
722 Default,
724 #[value(alias = "f")]
725 Fast,
727 #[value(alias = "b")]
728 Best,
734}
735
736#[cfg(feature = "image")]
737impl Default for PngCompressionLevel {
738 fn default() -> Self {
739 PngCompressionLevel::Default
740 }
741}
742
743#[cfg(feature = "image")]
744impl PngCompressionLevel {
745 pub fn to_compression(&self) -> png::Compression {
747 match self {
748 PngCompressionLevel::Default => png::Compression::Default,
749 PngCompressionLevel::Fast => png::Compression::Fast,
750 PngCompressionLevel::Best => png::Compression::Best,
751 }
752 }
753}