mirror of
https://github.com/lifegpc/msg-tool.git
synced 2026-06-22 03:44:28 +08:00
Add document
This commit is contained in:
@@ -1,3 +1,4 @@
|
||||
//! Kirikiri DPAK-referenced Image File (.dref)
|
||||
use crate::ext::io::*;
|
||||
use crate::ext::psb::*;
|
||||
use crate::scripts::base::*;
|
||||
@@ -12,9 +13,11 @@ use std::path::{Path, PathBuf};
|
||||
use url::Url;
|
||||
|
||||
#[derive(Debug)]
|
||||
/// Kirikiri DREF Script Builder
|
||||
pub struct DrefBuilder {}
|
||||
|
||||
impl DrefBuilder {
|
||||
/// Creates a new instance of `DrefBuilder`
|
||||
pub fn new() -> Self {
|
||||
Self {}
|
||||
}
|
||||
@@ -174,6 +177,7 @@ impl DpakLoader {
|
||||
}
|
||||
}
|
||||
|
||||
/// Kirikiri DREF Script
|
||||
pub struct Dref {
|
||||
urls: Vec<Url>,
|
||||
dir: PathBuf,
|
||||
@@ -190,6 +194,13 @@ impl std::fmt::Debug for Dref {
|
||||
}
|
||||
|
||||
impl Dref {
|
||||
/// Create a new dref script
|
||||
///
|
||||
/// * `buf` - The buffer containing the dref script data
|
||||
/// * `encoding` - The encoding of the script
|
||||
/// * `filename` - The name of the file
|
||||
/// * `config` - Extra configuration options
|
||||
/// * `archive` - Optional archive containing additional resources
|
||||
pub fn new(
|
||||
buf: Vec<u8>,
|
||||
encoding: Encoding,
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
//! Kirikiri Images
|
||||
pub mod dref;
|
||||
pub mod pimg;
|
||||
pub mod tlg;
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
//! Kirikiri Multiple Image File (.pimg)
|
||||
use crate::ext::io::*;
|
||||
use crate::ext::psb::*;
|
||||
use crate::scripts::base::*;
|
||||
@@ -12,9 +13,11 @@ use std::io::{Read, Seek};
|
||||
use std::path::Path;
|
||||
|
||||
#[derive(Debug)]
|
||||
/// Kirikiri PImg Script Builder
|
||||
pub struct PImgBuilder {}
|
||||
|
||||
impl PImgBuilder {
|
||||
/// Creates a new instance of `PImgBuilder`
|
||||
pub const fn new() -> Self {
|
||||
Self {}
|
||||
}
|
||||
@@ -94,12 +97,18 @@ impl ScriptBuilder for PImgBuilder {
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
/// Kirikiri PImg Script
|
||||
pub struct PImg {
|
||||
psb: VirtualPsbFixed,
|
||||
overlay: Option<bool>,
|
||||
}
|
||||
|
||||
impl PImg {
|
||||
/// Create a new PImg script
|
||||
///
|
||||
/// * `reader` - The reader containing the PImg script data
|
||||
/// * `filename` - The name of the file
|
||||
/// * `config` - Extra configuration options
|
||||
pub fn new<R: Read + Seek>(reader: R, filename: &str, config: &ExtraConfig) -> Result<Self> {
|
||||
let mut psb = PsbReader::open_psb(reader)
|
||||
.map_err(|e| anyhow::anyhow!("Failed to open PSB from {}: {:?}", filename, e))?;
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
//! Kirikiri TLG Image File (.tlg)
|
||||
use crate::ext::io::*;
|
||||
use crate::scripts::base::*;
|
||||
use crate::types::*;
|
||||
@@ -6,9 +7,11 @@ use libtlg_rs::*;
|
||||
use std::io::{Read, Seek};
|
||||
|
||||
#[derive(Debug)]
|
||||
/// Kirikiri TLG Script Builder
|
||||
pub struct TlgImageBuilder {}
|
||||
|
||||
impl TlgImageBuilder {
|
||||
/// Creates a new instance of `TlgImageBuilder`
|
||||
pub const fn new() -> Self {
|
||||
TlgImageBuilder {}
|
||||
}
|
||||
@@ -54,11 +57,16 @@ impl ScriptBuilder for TlgImageBuilder {
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
/// Kirikiri TLG Script
|
||||
pub struct TlgImage {
|
||||
data: Tlg,
|
||||
}
|
||||
|
||||
impl TlgImage {
|
||||
/// Create a new TLG script
|
||||
///
|
||||
/// * `data` - The reader containing the TLG script data
|
||||
/// * `config` - Extra configuration options
|
||||
pub fn new<T: Read + Seek>(data: T, _config: &ExtraConfig) -> Result<Self> {
|
||||
let tlg = load_tlg(data)?;
|
||||
Ok(TlgImage { data: tlg })
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
//! Kirikiri Script File (.ks)
|
||||
use crate::ext::fancy_regex::*;
|
||||
use crate::scripts::base::*;
|
||||
use crate::types::*;
|
||||
@@ -11,9 +12,11 @@ use std::ops::{Deref, DerefMut, Index, IndexMut};
|
||||
use std::sync::Arc;
|
||||
|
||||
#[derive(Debug)]
|
||||
/// Kirikiri Script Builder
|
||||
pub struct KsBuilder {}
|
||||
|
||||
impl KsBuilder {
|
||||
/// Creates a new instance of `KsBuilder`
|
||||
pub fn new() -> Self {
|
||||
Self {}
|
||||
}
|
||||
@@ -45,12 +48,15 @@ impl ScriptBuilder for KsBuilder {
|
||||
}
|
||||
}
|
||||
|
||||
trait Node {
|
||||
/// Kirikiri Script Node Trait
|
||||
pub trait Node {
|
||||
/// Serializes the node to ks format
|
||||
fn serialize(&self) -> String;
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
struct CommentNode(String);
|
||||
/// Comment Node
|
||||
pub struct CommentNode(pub String);
|
||||
|
||||
impl Node for CommentNode {
|
||||
fn serialize(&self) -> String {
|
||||
@@ -59,9 +65,12 @@ impl Node for CommentNode {
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
struct LabelNode {
|
||||
name: String,
|
||||
page: Option<String>,
|
||||
/// Label Node
|
||||
pub struct LabelNode {
|
||||
/// The name of the label
|
||||
pub name: String,
|
||||
/// The page of the label
|
||||
pub page: Option<String>,
|
||||
}
|
||||
|
||||
impl Node for LabelNode {
|
||||
@@ -75,7 +84,8 @@ impl Node for LabelNode {
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
struct TextNode(String);
|
||||
/// Text Node
|
||||
pub struct TextNode(pub String);
|
||||
|
||||
impl Node for TextNode {
|
||||
fn serialize(&self) -> String {
|
||||
@@ -85,7 +95,8 @@ impl Node for TextNode {
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
struct EmptyLineNode;
|
||||
/// Empty Line Node
|
||||
pub struct EmptyLineNode;
|
||||
|
||||
impl Node for EmptyLineNode {
|
||||
fn serialize(&self) -> String {
|
||||
@@ -94,15 +105,21 @@ impl Node for EmptyLineNode {
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
enum TagAttr {
|
||||
/// Represents a tag attribute's value
|
||||
pub enum TagAttr {
|
||||
/// true if no value is specified
|
||||
True,
|
||||
/// String value of the attribute
|
||||
Str(String),
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
struct TagNode {
|
||||
name: String,
|
||||
attributes: Vec<(String, TagAttr)>,
|
||||
/// Tag Node
|
||||
pub struct TagNode {
|
||||
/// The name of the tag
|
||||
pub name: String,
|
||||
/// The attributes of the tag
|
||||
pub attributes: Vec<(String, TagAttr)>,
|
||||
}
|
||||
|
||||
impl TagNode {
|
||||
@@ -140,6 +157,7 @@ impl TagNode {
|
||||
parts.join(" ")
|
||||
}
|
||||
|
||||
/// Sets an attribute for the tag, replacing it if it already exists.
|
||||
pub fn set_attr(&mut self, key: &str, value: String) {
|
||||
if let Some(attr) = self.attributes.iter_mut().find(|(k, _)| k == key) {
|
||||
attr.1 = TagAttr::Str(value);
|
||||
@@ -170,8 +188,10 @@ impl Node for TagNode {
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
struct CommandNode {
|
||||
inner: TagNode,
|
||||
/// Command Node
|
||||
pub struct CommandNode {
|
||||
/// Same as TagNode, but used for commands
|
||||
pub inner: TagNode,
|
||||
}
|
||||
|
||||
impl Deref for CommandNode {
|
||||
@@ -209,7 +229,8 @@ impl Node for CommandNode {
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
struct ScriptBlockNode(String);
|
||||
/// Script Block Node
|
||||
pub struct ScriptBlockNode(pub String);
|
||||
|
||||
impl Node for ScriptBlockNode {
|
||||
fn serialize(&self) -> String {
|
||||
@@ -218,8 +239,11 @@ impl Node for ScriptBlockNode {
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
enum ParsedLineNode {
|
||||
/// Parsed Line Node
|
||||
pub enum ParsedLineNode {
|
||||
/// Text node containing plain text
|
||||
Text(TextNode),
|
||||
/// Tag node
|
||||
Tag(TagNode),
|
||||
}
|
||||
|
||||
@@ -252,7 +276,8 @@ impl Node for ParsedLineNode {
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
struct ParsedLine(Vec<ParsedLineNode>);
|
||||
/// Parsed Line
|
||||
pub struct ParsedLine(pub Vec<ParsedLineNode>);
|
||||
|
||||
impl ParsedLine {
|
||||
fn to_xml(&self) -> String {
|
||||
@@ -289,20 +314,29 @@ impl Node for ParsedLine {
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
enum ParsedScriptNode {
|
||||
/// Parsed Script Node
|
||||
pub enum ParsedScriptNode {
|
||||
/// Comment node
|
||||
Comment(CommentNode),
|
||||
/// Label node
|
||||
Label(LabelNode),
|
||||
/// Command node
|
||||
Command(CommandNode),
|
||||
/// Script block node
|
||||
ScriptBlock(ScriptBlockNode),
|
||||
/// Line
|
||||
Line(ParsedLine),
|
||||
/// Empty line node
|
||||
EmptyLine(EmptyLineNode),
|
||||
}
|
||||
|
||||
impl ParsedScriptNode {
|
||||
/// Returns true if the node is empty line node
|
||||
pub fn is_empty(&self) -> bool {
|
||||
matches!(self, ParsedScriptNode::EmptyLine(_))
|
||||
}
|
||||
|
||||
/// Sets an attribute for the command node, replacing it if it already exists.
|
||||
pub fn set_attr(&mut self, key: &str, value: String) {
|
||||
if let ParsedScriptNode::Command(command) = self {
|
||||
command.set_attr(key, value);
|
||||
@@ -324,7 +358,8 @@ impl Node for ParsedScriptNode {
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
struct ParsedScript(Vec<ParsedScriptNode>);
|
||||
/// Parsed ks script
|
||||
pub struct ParsedScript(pub Vec<ParsedScriptNode>);
|
||||
|
||||
impl Deref for ParsedScript {
|
||||
type Target = Vec<ParsedScriptNode>;
|
||||
@@ -374,11 +409,15 @@ lazy_static::lazy_static! {
|
||||
static ref ATTR_RE: Regex = Regex::new("([a-zA-Z0-9_]+)(?:=(\"[^\"]*\"|'[^']*'|[^\\s\\]]+))?").unwrap();
|
||||
}
|
||||
|
||||
struct Parser {
|
||||
/// Parser for Kirikiri Script (.ks)
|
||||
pub struct Parser {
|
||||
lines: Vec<String>,
|
||||
}
|
||||
|
||||
impl Parser {
|
||||
/// Creates a new parser for the given script
|
||||
///
|
||||
/// * `script` - The script to parse
|
||||
pub fn new(script: &str) -> Self {
|
||||
let lines = script.lines().map(|s| s.to_string()).collect();
|
||||
Self { lines }
|
||||
@@ -422,7 +461,10 @@ impl Parser {
|
||||
})
|
||||
}
|
||||
|
||||
fn parse(&self, preserve_empty_lines: bool) -> Result<ParsedScript> {
|
||||
/// Parses the script and returns a `ParsedScript`
|
||||
///
|
||||
/// * `preserve_empty_lines` - If true, empty lines will be preserved in the parsed script
|
||||
pub fn parse(&self, preserve_empty_lines: bool) -> Result<ParsedScript> {
|
||||
let mut parsed_scripts = Vec::new();
|
||||
let mut in_script_block = false;
|
||||
let mut script_buffer = Vec::new();
|
||||
@@ -657,6 +699,7 @@ impl XMLTextParser {
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
/// Kirikiri Script
|
||||
pub struct KsScript {
|
||||
bom: BomType,
|
||||
tree: ParsedScript,
|
||||
@@ -666,6 +709,11 @@ pub struct KsScript {
|
||||
}
|
||||
|
||||
impl KsScript {
|
||||
/// Creates a new `KsScript` from the given reader and encoding
|
||||
///
|
||||
/// * `reader` - The reader containing the script data
|
||||
/// * `encoding` - The encoding of the script
|
||||
/// * `config` - Extra configuration options
|
||||
pub fn new(reader: Vec<u8>, encoding: Encoding, config: &ExtraConfig) -> Result<Self> {
|
||||
let (text, bom) = decode_with_bom_detect(encoding, &reader, true)?;
|
||||
let parser = Parser::new(&text);
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
//! Kirikiri Zlib-Compressed File
|
||||
use crate::ext::io::*;
|
||||
use crate::scripts::base::*;
|
||||
use crate::types::*;
|
||||
@@ -5,9 +6,11 @@ use anyhow::Result;
|
||||
use std::io::Read;
|
||||
|
||||
#[derive(Debug)]
|
||||
/// Kirikiri MDF Script Builder
|
||||
pub struct MdfBuilder {}
|
||||
|
||||
impl MdfBuilder {
|
||||
/// Creates a new instance of `MdfBuilder`
|
||||
pub fn new() -> Self {
|
||||
Self {}
|
||||
}
|
||||
@@ -48,12 +51,17 @@ impl ScriptBuilder for MdfBuilder {
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
/// Kirikiri MDF Script
|
||||
pub struct Mdf {
|
||||
data: MemReader,
|
||||
ext: String,
|
||||
}
|
||||
|
||||
impl Mdf {
|
||||
/// Creates a new `Mdf` script from the given buffer and filename
|
||||
///
|
||||
/// * `buf` - The buffer containing the MDF data
|
||||
/// * `filename` - The name of the file (used for extension detection)
|
||||
pub fn new(buf: Vec<u8>, filename: &str) -> Result<Self> {
|
||||
let mut data = MemReader::new(buf);
|
||||
let mut header = [0u8; 4];
|
||||
@@ -71,7 +79,7 @@ impl Mdf {
|
||||
})
|
||||
}
|
||||
|
||||
pub fn unpack(mut data: MemReaderRef) -> Result<Vec<u8>> {
|
||||
pub(crate) fn unpack(mut data: MemReaderRef) -> Result<Vec<u8>> {
|
||||
let size = data.read_u32()?;
|
||||
let mut decoder = flate2::read::ZlibDecoder::new(data);
|
||||
let mut result = Vec::new();
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
//! Kirikiri Scripts
|
||||
#[cfg(feature = "kirikiri-img")]
|
||||
pub mod image;
|
||||
pub mod ks;
|
||||
@@ -7,6 +8,7 @@ pub mod simple_crypt;
|
||||
use std::collections::HashMap;
|
||||
use std::sync::Arc;
|
||||
|
||||
/// Read a Kirikiri Comu JSON file. (For CIRCUS games)
|
||||
pub fn read_kirikiri_comu_json(path: &str) -> anyhow::Result<Arc<HashMap<String, String>>> {
|
||||
let mut reader = std::fs::File::open(path)?;
|
||||
let data = serde_json::from_reader(&mut reader)?;
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
//! Kirikiri Scene File (.scn)
|
||||
use super::mdf::Mdf;
|
||||
use crate::ext::io::*;
|
||||
use crate::ext::psb::*;
|
||||
@@ -12,9 +13,11 @@ use std::path::Path;
|
||||
use std::sync::Arc;
|
||||
|
||||
#[derive(Debug)]
|
||||
/// Kirikiri Scene Script Builder
|
||||
pub struct ScnScriptBuilder {}
|
||||
|
||||
impl ScnScriptBuilder {
|
||||
/// Creates a new instance of `ScnScriptBuilder`
|
||||
pub fn new() -> Self {
|
||||
Self {}
|
||||
}
|
||||
@@ -102,6 +105,7 @@ impl ScriptBuilder for ScnScriptBuilder {
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
/// Kirikiri Scene Script
|
||||
pub struct ScnScript {
|
||||
psb: VirtualPsbFixed,
|
||||
language_index: usize,
|
||||
@@ -111,6 +115,11 @@ pub struct ScnScript {
|
||||
}
|
||||
|
||||
impl ScnScript {
|
||||
/// Creates a new `ScnScript` from the given reader and filename
|
||||
///
|
||||
/// * `reader` - The reader containing the PSB or MDF data
|
||||
/// * `filename` - The name of the file (used for error reporting and extension detection)
|
||||
/// * `config` - Extra configuration options
|
||||
pub fn new<R: Read + Seek>(
|
||||
mut reader: R,
|
||||
filename: &str,
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
//! Kirikiri Simple Crypt Text File
|
||||
use crate::ext::io::*;
|
||||
use crate::scripts::base::*;
|
||||
use crate::types::*;
|
||||
@@ -6,9 +7,11 @@ use overf::wrapping;
|
||||
use std::io::Read;
|
||||
|
||||
#[derive(Debug)]
|
||||
/// Kirikiri Simple Crypt Script Builder
|
||||
pub struct SimpleCryptBuilder {}
|
||||
|
||||
impl SimpleCryptBuilder {
|
||||
/// Creates a new instance of `SimpleCryptBuilder`
|
||||
pub fn new() -> Self {
|
||||
Self {}
|
||||
}
|
||||
@@ -55,6 +58,7 @@ impl ScriptBuilder for SimpleCryptBuilder {
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
/// Kirikiri Simple Crypt Script
|
||||
pub struct SimpleCrypt {
|
||||
/// Crypt mode
|
||||
crypt: u8,
|
||||
@@ -63,6 +67,10 @@ pub struct SimpleCrypt {
|
||||
}
|
||||
|
||||
impl SimpleCrypt {
|
||||
/// Creates a new `SimpleCrypt` script from the given buffer and filename
|
||||
///
|
||||
/// * `buf` - The buffer containing the SimpleCrypt data
|
||||
/// * `filename` - The name of the file
|
||||
pub fn new(buf: Vec<u8>, filename: &str) -> Result<Self> {
|
||||
let mut reader = MemReader::new(buf);
|
||||
let mut header = [0u8; 5];
|
||||
@@ -86,7 +94,7 @@ impl SimpleCrypt {
|
||||
})
|
||||
}
|
||||
|
||||
pub fn unpack(crypt: u8, data: MemReaderRef) -> Result<Vec<u8>> {
|
||||
pub(crate) fn unpack(crypt: u8, data: MemReaderRef) -> Result<Vec<u8>> {
|
||||
match crypt {
|
||||
0 => Self::unpack_mode0(data),
|
||||
1 => Self::unpack_mode1(data),
|
||||
|
||||
Reference in New Issue
Block a user