mirror of
https://github.com/lifegpc/msg-tool.git
synced 2026-06-20 02:44:29 +08:00
Add library and documents
This commit is contained in:
@@ -1 +1,2 @@
|
||||
//! Artemis Engine Archive
|
||||
pub mod pfs;
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
//! Artemis Engine PFS Archive (pf6 and pf8)
|
||||
use crate::ext::io::*;
|
||||
use crate::scripts::base::*;
|
||||
use crate::types::*;
|
||||
@@ -10,9 +11,11 @@ use std::io::{Read, Seek, SeekFrom, Write};
|
||||
use std::sync::{Arc, Mutex};
|
||||
|
||||
#[derive(Debug)]
|
||||
/// The builder for Artemis PFS archive scripts.
|
||||
pub struct ArtemisArcBuilder {}
|
||||
|
||||
impl ArtemisArcBuilder {
|
||||
/// Creates a new instance of `ArtemisArcBuilder`.
|
||||
pub fn new() -> Self {
|
||||
ArtemisArcBuilder {}
|
||||
}
|
||||
@@ -125,6 +128,7 @@ struct PfsEntryHeader {
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
/// The Artemis PFS archive script.
|
||||
pub struct ArtemisArc<T: Read + Seek + std::fmt::Debug> {
|
||||
reader: Arc<Mutex<T>>,
|
||||
entries: Vec<PfsEntryHeader>,
|
||||
@@ -133,6 +137,12 @@ pub struct ArtemisArc<T: Read + Seek + std::fmt::Debug> {
|
||||
}
|
||||
|
||||
impl<T: Read + Seek + std::fmt::Debug> ArtemisArc<T> {
|
||||
/// Creates a new Artemis PFS archive script.
|
||||
///
|
||||
/// * `reader` - The reader for the archive.
|
||||
/// * `archive_encoding` - The encoding used for the archive.
|
||||
/// * `config` - Extra configuration options.
|
||||
/// * `filename` - The name of the archive file.
|
||||
pub fn new(
|
||||
mut reader: T,
|
||||
archive_encoding: Encoding,
|
||||
@@ -336,6 +346,7 @@ fn detect_script_type(buf: &[u8], buf_len: usize, filename: &str) -> Option<Scri
|
||||
None
|
||||
}
|
||||
|
||||
/// The Artemis PFS archive writer.
|
||||
pub struct ArtemisArcWriter<T: Write + Seek + Read> {
|
||||
writer: T,
|
||||
headers: HashMap<String, PfsEntryHeader>,
|
||||
@@ -345,6 +356,12 @@ pub struct ArtemisArcWriter<T: Write + Seek + Read> {
|
||||
}
|
||||
|
||||
impl<T: Write + Seek + Read> ArtemisArcWriter<T> {
|
||||
/// Creates a new Artemis PFS archive writer.
|
||||
///
|
||||
/// * `writer` - The writer for the archive.
|
||||
/// * `files` - The list of files to include in the archive.
|
||||
/// * `encoding` - The encoding used for the archive.
|
||||
/// * `config` - Extra configuration options.
|
||||
pub fn new(
|
||||
mut writer: T,
|
||||
files: &[&str],
|
||||
@@ -445,6 +462,7 @@ impl<T: Write + Seek + Read> Archive for ArtemisArcWriter<T> {
|
||||
}
|
||||
}
|
||||
|
||||
/// The Artemis PFS archive file writer.
|
||||
pub struct ArtemisArcFile<'a, T: Write + Seek> {
|
||||
header: &'a mut PfsEntryHeader,
|
||||
writer: &'a mut T,
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
//! Artemis Engine ASB file (.asb)
|
||||
use crate::ext::io::*;
|
||||
use crate::scripts::base::*;
|
||||
use crate::types::*;
|
||||
@@ -11,9 +12,11 @@ use std::ops::Index;
|
||||
use unicode_segmentation::UnicodeSegmentation;
|
||||
|
||||
#[derive(Debug)]
|
||||
/// The builder for Artemis ASB scripts.
|
||||
pub struct ArtemisAsbBuilder {}
|
||||
|
||||
impl ArtemisAsbBuilder {
|
||||
/// Creates a new instance of `ArtemisAsbBuilder`.
|
||||
pub fn new() -> Self {
|
||||
ArtemisAsbBuilder {}
|
||||
}
|
||||
@@ -408,11 +411,17 @@ impl<'a> TextParser<'a> {
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
/// The Artemis ASB script.
|
||||
pub struct Asb {
|
||||
items: Vec<Item>,
|
||||
}
|
||||
|
||||
impl Asb {
|
||||
/// Creates a new Artemis ASB script from the given buffer.
|
||||
///
|
||||
/// * `buf` - The buffer containing the ASB data.
|
||||
/// * `encoding` - The encoding used for the ASB data.
|
||||
/// * `config` - Extra configuration options.
|
||||
pub fn new(buf: Vec<u8>, encoding: Encoding, _config: &ExtraConfig) -> Result<Self> {
|
||||
let mut data = MemReader::new(buf);
|
||||
let mut magic = [0; 5];
|
||||
@@ -654,6 +663,12 @@ impl Script for Asb {
|
||||
}
|
||||
}
|
||||
|
||||
/// Creates a new ASB file.
|
||||
///
|
||||
/// * `custom_filename` - The path ot the input file.
|
||||
/// * `writer` - The writer to write the ASB script.
|
||||
/// * `encoding` - The encoding used for the ASB script.
|
||||
/// * `output_encoding` - The encoding used for the input file.
|
||||
pub fn create_file<'a>(
|
||||
custom_filename: &'a str,
|
||||
mut writer: Box<dyn WriteSeek + 'a>,
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
//! Artemis Engine AST file (.ast)
|
||||
mod dump;
|
||||
mod parser;
|
||||
mod text;
|
||||
@@ -11,9 +12,11 @@ use std::io::Write;
|
||||
use types::*;
|
||||
|
||||
#[derive(Debug)]
|
||||
/// The builder for Artemis AST scripts.
|
||||
pub struct AstScriptBuilder {}
|
||||
|
||||
impl AstScriptBuilder {
|
||||
/// Creates a new instance of `AstScriptBuilder`.
|
||||
pub fn new() -> Self {
|
||||
AstScriptBuilder {}
|
||||
}
|
||||
@@ -55,6 +58,7 @@ impl ScriptBuilder for AstScriptBuilder {
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
/// The Artemis AST script.
|
||||
pub struct AstScript {
|
||||
ast: AstFile,
|
||||
indent: Option<usize>,
|
||||
@@ -64,6 +68,11 @@ pub struct AstScript {
|
||||
}
|
||||
|
||||
impl AstScript {
|
||||
/// Creates a new Artemis AST script from the given buffer.
|
||||
///
|
||||
/// * `buf` - The buffer containing the AST data.
|
||||
/// * `encoding` - The encoding used for the AST data.
|
||||
/// * `config` - Extra configuration options.
|
||||
pub fn new(buf: Vec<u8>, encoding: Encoding, config: &ExtraConfig) -> Result<Self> {
|
||||
let parser = parser::Parser::new(&buf, encoding);
|
||||
let ast = parser.parse()?;
|
||||
@@ -680,6 +689,11 @@ impl Script for AstScript {
|
||||
}
|
||||
}
|
||||
|
||||
/// Checks if the given buffer is in the Artemis AST format.
|
||||
///
|
||||
/// * `filename` - The name of the file.
|
||||
/// * `buf` - The buffer containing the data.
|
||||
/// * `buf_len` - The length of the buffer.
|
||||
pub fn is_this_format(_filename: &str, buf: &[u8], buf_len: usize) -> bool {
|
||||
let parser = parser::Parser::new(&buf[..buf_len], Encoding::Utf8);
|
||||
parser.try_parse_header().is_ok()
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
//! Artemis Engine Scripts
|
||||
#[cfg(feature = "artemis-arc")]
|
||||
pub mod archive;
|
||||
pub mod asb;
|
||||
|
||||
@@ -1,12 +1,16 @@
|
||||
//! Basic traits and types for script.
|
||||
use crate::ext::io::*;
|
||||
use crate::types::*;
|
||||
use anyhow::Result;
|
||||
use std::io::{Read, Seek, Write};
|
||||
|
||||
/// A trait for reading and seeking in a stream.
|
||||
pub trait ReadSeek: Read + Seek + std::fmt::Debug {}
|
||||
|
||||
/// A trait for writing and seeking in a stream.
|
||||
pub trait WriteSeek: Write + Seek {}
|
||||
|
||||
/// A trait for types that can be displayed in debug format and are also support downcasting.
|
||||
pub trait AnyDebug: std::fmt::Debug + std::any::Any {}
|
||||
|
||||
impl<T: Read + Seek + std::fmt::Debug> ReadSeek for T {}
|
||||
@@ -15,17 +19,30 @@ impl<T: Write + Seek> WriteSeek for T {}
|
||||
|
||||
impl<T: std::fmt::Debug + std::any::Any> AnyDebug for T {}
|
||||
|
||||
/// A trait for script builders.
|
||||
pub trait ScriptBuilder: std::fmt::Debug {
|
||||
/// Returns the default encoding for the script.
|
||||
fn default_encoding(&self) -> Encoding;
|
||||
|
||||
/// Returns the default encoding for the archive.
|
||||
/// If None, the default encoding should be used.
|
||||
fn default_archive_encoding(&self) -> Option<Encoding> {
|
||||
None
|
||||
}
|
||||
|
||||
/// Returns the default encoding for script files when patching scripts.
|
||||
fn default_patched_encoding(&self) -> Encoding {
|
||||
self.default_encoding()
|
||||
}
|
||||
|
||||
/// Builds a script from the given buffer.
|
||||
///
|
||||
/// * `buf` - The buffer containing the script data.
|
||||
/// * `filename` - The name of the file from which the script was read.
|
||||
/// * `encoding` - The encoding of the script data.
|
||||
/// * `archive_encoding` - The encoding of the archive, if applicable.
|
||||
/// * `config` - Additional configuration options.
|
||||
/// * `archive` - An optional archive to which the script belongs.
|
||||
fn build_script(
|
||||
&self,
|
||||
buf: Vec<u8>,
|
||||
@@ -36,6 +53,13 @@ pub trait ScriptBuilder: std::fmt::Debug {
|
||||
archive: Option<&Box<dyn Script>>,
|
||||
) -> Result<Box<dyn Script>>;
|
||||
|
||||
/// Builds a script from a file.
|
||||
///
|
||||
/// * `filename` - The name of the file to read.
|
||||
/// * `encoding` - The encoding of the script data.
|
||||
/// * `archive_encoding` - The encoding of the archive, if applicable.
|
||||
/// * `config` - Additional configuration options.
|
||||
/// * `archive` - An optional archive to which the script belongs.
|
||||
fn build_script_from_file(
|
||||
&self,
|
||||
filename: &str,
|
||||
@@ -48,6 +72,14 @@ pub trait ScriptBuilder: std::fmt::Debug {
|
||||
self.build_script(data, filename, encoding, archive_encoding, config, archive)
|
||||
}
|
||||
|
||||
/// Builds a script from a reader.
|
||||
///
|
||||
/// * `reader` - A reader with seek capabilities.
|
||||
/// * `filename` - The name of the file from which the script was read.
|
||||
/// * `encoding` - The encoding of the script data.
|
||||
/// * `archive_encoding` - The encoding of the archive, if applicable.
|
||||
/// * `config` - Additional configuration options.
|
||||
/// * `archive` - An optional archive to which the script belongs.
|
||||
fn build_script_from_reader(
|
||||
&self,
|
||||
mut reader: Box<dyn ReadSeek>,
|
||||
@@ -64,18 +96,34 @@ pub trait ScriptBuilder: std::fmt::Debug {
|
||||
self.build_script(data, filename, encoding, archive_encoding, config, archive)
|
||||
}
|
||||
|
||||
/// Returns the extensions supported by this script builder.
|
||||
fn extensions(&self) -> &'static [&'static str];
|
||||
|
||||
/// Checks if the given filename and buffer match this script format.
|
||||
/// * `filename` - The name of the file to check.
|
||||
/// * `buf` - The buffer containing the script data.
|
||||
/// * `buf_len` - The length of the buffer.
|
||||
///
|
||||
/// Returns a score (0-255) indicating how well the format matches.
|
||||
/// A higher score means a better match.
|
||||
fn is_this_format(&self, _filename: &str, _buf: &[u8], _buf_len: usize) -> Option<u8> {
|
||||
None
|
||||
}
|
||||
|
||||
/// Returns the script type associated with this builder.
|
||||
fn script_type(&self) -> &'static ScriptType;
|
||||
|
||||
/// Returns true if this script is an archive.
|
||||
fn is_archive(&self) -> bool {
|
||||
false
|
||||
}
|
||||
|
||||
/// Creates an archive with the given files.
|
||||
///
|
||||
/// * `filename` - The path of the archive file to create.
|
||||
/// * `files` - A list of files to include in the archive.
|
||||
/// * `encoding` - The encoding to use for the archive.
|
||||
/// * `config` - Additional configuration options.
|
||||
fn create_archive(
|
||||
&self,
|
||||
_filename: &str,
|
||||
@@ -88,10 +136,18 @@ pub trait ScriptBuilder: std::fmt::Debug {
|
||||
))
|
||||
}
|
||||
|
||||
/// Returns true if this script type can create from a file directly.
|
||||
fn can_create_file(&self) -> bool {
|
||||
false
|
||||
}
|
||||
|
||||
/// Creates a new script file.
|
||||
///
|
||||
/// * `filename` - The path to the input file.
|
||||
/// * `writer` - A writer with seek capabilities to write the script data.
|
||||
/// * `encoding` - The encoding to use for the script data.
|
||||
/// * `file_encoding` - The encoding of the file.
|
||||
/// * `config` - Additional configuration options.
|
||||
fn create_file<'a>(
|
||||
&'a self,
|
||||
_filename: &'a str,
|
||||
@@ -105,6 +161,13 @@ pub trait ScriptBuilder: std::fmt::Debug {
|
||||
))
|
||||
}
|
||||
|
||||
/// Creates a new script file with the given filename.
|
||||
///
|
||||
/// * `filename` - The path to the input file.
|
||||
/// * `output_filename` - The path to the output file.
|
||||
/// * `encoding` - The encoding to use for the script data.
|
||||
/// * `file_encoding` - The encoding of the file.
|
||||
/// * `config` - Additional configuration options.
|
||||
fn create_file_filename(
|
||||
&self,
|
||||
filename: &str,
|
||||
@@ -118,16 +181,23 @@ pub trait ScriptBuilder: std::fmt::Debug {
|
||||
self.create_file(filename, Box::new(f), encoding, file_encoding, config)
|
||||
}
|
||||
|
||||
/// Returns true if this script is an image.
|
||||
#[cfg(feature = "image")]
|
||||
fn is_image(&self) -> bool {
|
||||
false
|
||||
}
|
||||
|
||||
/// Returns true if this script type can create from an image file directly.
|
||||
#[cfg(feature = "image")]
|
||||
fn can_create_image_file(&self) -> bool {
|
||||
false
|
||||
}
|
||||
|
||||
/// Creates an image file from the given data.
|
||||
///
|
||||
/// * `data` - The image data to write.
|
||||
/// * `writer` - A writer with seek capabilities to write the image data.
|
||||
/// * `options` - Additional configuration options.
|
||||
#[cfg(feature = "image")]
|
||||
fn create_image_file<'a>(
|
||||
&'a self,
|
||||
@@ -140,6 +210,11 @@ pub trait ScriptBuilder: std::fmt::Debug {
|
||||
))
|
||||
}
|
||||
|
||||
/// Creates an image file from the given data to the specified filename.
|
||||
///
|
||||
/// * `data` - The image data to write.
|
||||
/// * `filename` - The path to the output file.
|
||||
/// * `options` - Additional configuration options.
|
||||
#[cfg(feature = "image")]
|
||||
fn create_image_file_filename(
|
||||
&self,
|
||||
@@ -153,37 +228,49 @@ pub trait ScriptBuilder: std::fmt::Debug {
|
||||
}
|
||||
}
|
||||
|
||||
/// A trait to present the file in an archive.
|
||||
pub trait ArchiveContent: Read {
|
||||
/// Returns the name of the file in the archive.
|
||||
fn name(&self) -> &str;
|
||||
/// Returns true if the file is a script.
|
||||
fn is_script(&self) -> bool {
|
||||
self.script_type().is_some()
|
||||
}
|
||||
/// Returns the script type if the file is a script.
|
||||
fn script_type(&self) -> Option<&ScriptType> {
|
||||
None
|
||||
}
|
||||
/// Returns the data of the file as a vector of bytes.
|
||||
fn data(&mut self) -> Result<Vec<u8>> {
|
||||
let mut data = Vec::new();
|
||||
self.read_to_end(&mut data)?;
|
||||
Ok(data)
|
||||
}
|
||||
/// Returns a reader that supports reading and seeking.
|
||||
fn to_data<'a>(&'a mut self) -> Result<Box<dyn ReadSeek + 'a>> {
|
||||
Ok(Box::new(MemReader::new(self.data()?)))
|
||||
}
|
||||
}
|
||||
|
||||
/// A trait for script types.
|
||||
pub trait Script: std::fmt::Debug + std::any::Any {
|
||||
/// Returns the default output script type for this script.
|
||||
fn default_output_script_type(&self) -> OutputScriptType;
|
||||
|
||||
/// Checks if the given output script type is supported by this script.
|
||||
fn is_output_supported(&self, output: OutputScriptType) -> bool {
|
||||
!matches!(output, OutputScriptType::Custom)
|
||||
}
|
||||
|
||||
/// Returns the output extension for this script when exporting with custom output.
|
||||
fn custom_output_extension<'a>(&'a self) -> &'a str {
|
||||
""
|
||||
}
|
||||
|
||||
/// Returns the default format options for this script.
|
||||
fn default_format_type(&self) -> FormatOptions;
|
||||
|
||||
/// Extract messages from this script.
|
||||
fn extract_messages(&self) -> Result<Vec<Message>> {
|
||||
if !self.is_archive() {
|
||||
return Err(anyhow::anyhow!(
|
||||
@@ -193,6 +280,12 @@ pub trait Script: std::fmt::Debug + std::any::Any {
|
||||
Ok(vec![])
|
||||
}
|
||||
|
||||
/// Import messages into this script.
|
||||
///
|
||||
/// * `messages` - The messages to import.
|
||||
/// * `file` - A writer with seek capabilities to write the patched scripts.
|
||||
/// * `encoding` - The encoding to use for the patched scripts.
|
||||
/// * `replacement` - An optional replacement table for message replacements.
|
||||
fn import_messages<'a>(
|
||||
&'a self,
|
||||
_messages: Vec<Message>,
|
||||
@@ -208,6 +301,12 @@ pub trait Script: std::fmt::Debug + std::any::Any {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Import messages into this script.
|
||||
///
|
||||
/// * `messages` - The messages to import.
|
||||
/// * `filename` - The path of the file to write the patched scripts.
|
||||
/// * `encoding` - The encoding to use for the patched scripts.
|
||||
/// * `replacement` - An optional replacement table for message replacements.
|
||||
fn import_messages_filename(
|
||||
&self,
|
||||
_messages: Vec<Message>,
|
||||
@@ -220,12 +319,22 @@ pub trait Script: std::fmt::Debug + std::any::Any {
|
||||
self.import_messages(_messages, Box::new(f), _encoding, _replacement)
|
||||
}
|
||||
|
||||
/// Exports data from this script.
|
||||
///
|
||||
/// * `filename` - The path of the file to write the exported data.
|
||||
/// * `encoding` - The encoding to use for the exported data.
|
||||
fn custom_export(&self, _filename: &std::path::Path, _encoding: Encoding) -> Result<()> {
|
||||
Err(anyhow::anyhow!(
|
||||
"This script type does not support custom export."
|
||||
))
|
||||
}
|
||||
|
||||
/// Imports data into this script.
|
||||
///
|
||||
/// * `custom_filename` - The path of the file to import.
|
||||
/// * `file` - A writer with seek capabilities to write the patched scripts.
|
||||
/// * `encoding` - The encoding of the patched scripts.
|
||||
/// * `output_encoding` - The encoding to use for the imported file.
|
||||
fn custom_import<'a>(
|
||||
&'a self,
|
||||
_custom_filename: &'a str,
|
||||
@@ -238,6 +347,12 @@ pub trait Script: std::fmt::Debug + std::any::Any {
|
||||
))
|
||||
}
|
||||
|
||||
/// Imports data into this script.
|
||||
///
|
||||
/// * `custom_filename` - The path of the file to import.
|
||||
/// * `filename` - The path of the file to write the patched scripts.
|
||||
/// * `encoding` - The encoding of the patched scripts.
|
||||
/// * `output_encoding` - The encoding to use for the imported file.
|
||||
fn custom_import_filename(
|
||||
&self,
|
||||
custom_filename: &str,
|
||||
@@ -250,10 +365,12 @@ pub trait Script: std::fmt::Debug + std::any::Any {
|
||||
self.custom_import(custom_filename, Box::new(f), encoding, output_encoding)
|
||||
}
|
||||
|
||||
/// Returns true if this script is an archive.
|
||||
fn is_archive(&self) -> bool {
|
||||
false
|
||||
}
|
||||
|
||||
/// Returns an iterator over archive filenames.
|
||||
fn iter_archive_filename<'a>(
|
||||
&'a self,
|
||||
) -> Result<Box<dyn Iterator<Item = Result<String>> + 'a>> {
|
||||
@@ -262,18 +379,24 @@ pub trait Script: std::fmt::Debug + std::any::Any {
|
||||
))
|
||||
}
|
||||
|
||||
/// Returns an iterator over archive offsets.
|
||||
fn iter_archive_offset<'a>(&'a self) -> Result<Box<dyn Iterator<Item = Result<u64>> + 'a>> {
|
||||
Err(anyhow::anyhow!(
|
||||
"This script type does not support iterating over archive offsets."
|
||||
))
|
||||
}
|
||||
|
||||
/// Opens a file in the archive by its index.
|
||||
fn open_file<'a>(&'a self, _index: usize) -> Result<Box<dyn ArchiveContent + 'a>> {
|
||||
Err(anyhow::anyhow!(
|
||||
"This script type does not support opening files."
|
||||
))
|
||||
}
|
||||
|
||||
/// Opens a file in the archive by its name.
|
||||
///
|
||||
/// * `name` - The name of the file to open.
|
||||
/// * `ignore_case` - If true, the name comparison will be case-insensitive.
|
||||
fn open_file_by_name<'a>(
|
||||
&'a self,
|
||||
name: &str,
|
||||
@@ -292,6 +415,7 @@ pub trait Script: std::fmt::Debug + std::any::Any {
|
||||
))
|
||||
}
|
||||
|
||||
/// Opens a file in the archive by its offset.
|
||||
fn open_file_by_offset<'a>(&'a self, offset: u64) -> Result<Box<dyn ArchiveContent + 'a>> {
|
||||
for (i, off) in self.iter_archive_offset()?.enumerate() {
|
||||
if let Ok(off) = off {
|
||||
@@ -312,11 +436,13 @@ pub trait Script: std::fmt::Debug + std::any::Any {
|
||||
}
|
||||
|
||||
#[cfg(feature = "image")]
|
||||
/// Returns true if this script type is an image.
|
||||
fn is_image(&self) -> bool {
|
||||
false
|
||||
}
|
||||
|
||||
#[cfg(feature = "image")]
|
||||
/// Exports the image data from this script.
|
||||
fn export_image(&self) -> Result<ImageData> {
|
||||
Err(anyhow::anyhow!(
|
||||
"This script type does not support to export image."
|
||||
@@ -324,6 +450,10 @@ pub trait Script: std::fmt::Debug + std::any::Any {
|
||||
}
|
||||
|
||||
#[cfg(feature = "image")]
|
||||
/// Imports an image into this script.
|
||||
///
|
||||
/// * `data` - The image data to import.
|
||||
/// * `file` - A writer with seek capabilities to write the patched scripts.
|
||||
fn import_image<'a>(&'a self, _data: ImageData, _file: Box<dyn WriteSeek + 'a>) -> Result<()> {
|
||||
Err(anyhow::anyhow!(
|
||||
"This script type does not support to import image."
|
||||
@@ -331,6 +461,10 @@ pub trait Script: std::fmt::Debug + std::any::Any {
|
||||
}
|
||||
|
||||
#[cfg(feature = "image")]
|
||||
/// Imports an image into this script.
|
||||
///
|
||||
/// * `data` - The image data to import.
|
||||
/// * `filename` - The path of the file to write the patched scripts.
|
||||
fn import_image_filename(&self, data: ImageData, filename: &str) -> Result<()> {
|
||||
let f = std::fs::File::create(filename)?;
|
||||
let f = std::io::BufWriter::new(f);
|
||||
@@ -338,11 +472,13 @@ pub trait Script: std::fmt::Debug + std::any::Any {
|
||||
}
|
||||
|
||||
#[cfg(feature = "image")]
|
||||
/// Returns true if this script is contains multiple images.
|
||||
fn is_multi_image(&self) -> bool {
|
||||
false
|
||||
}
|
||||
|
||||
#[cfg(feature = "image")]
|
||||
/// Exports multiple images from this script.
|
||||
fn export_multi_image<'a>(
|
||||
&'a self,
|
||||
) -> Result<Box<dyn Iterator<Item = Result<ImageDataWithName>> + 'a>> {
|
||||
@@ -352,6 +488,10 @@ pub trait Script: std::fmt::Debug + std::any::Any {
|
||||
}
|
||||
|
||||
#[cfg(feature = "image")]
|
||||
/// Imports multiple images into this script.
|
||||
///
|
||||
/// * `data` - A vector of image data with names to import.
|
||||
/// * `file` - A writer with seek capabilities to write the patched scripts.
|
||||
fn import_multi_image<'a>(
|
||||
&'a self,
|
||||
_data: Vec<ImageDataWithName>,
|
||||
@@ -363,6 +503,10 @@ pub trait Script: std::fmt::Debug + std::any::Any {
|
||||
}
|
||||
|
||||
#[cfg(feature = "image")]
|
||||
/// Imports multiple images into this script.
|
||||
///
|
||||
/// * `data` - A vector of image data with names to import.
|
||||
/// * `filename` - The path of the file to write the patched scripts.
|
||||
fn import_multi_image_filename(
|
||||
&self,
|
||||
data: Vec<ImageDataWithName>,
|
||||
@@ -373,12 +517,16 @@ pub trait Script: std::fmt::Debug + std::any::Any {
|
||||
self.import_multi_image(data, Box::new(f))
|
||||
}
|
||||
|
||||
/// Returns the extra information for this script.
|
||||
fn extra_info<'a>(&'a self) -> Option<Box<dyn AnyDebug + 'a>> {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
/// A trait for creating archives.
|
||||
pub trait Archive {
|
||||
/// Creates a new file in the archive.
|
||||
fn new_file<'a>(&'a mut self, name: &str) -> Result<Box<dyn WriteSeek + 'a>>;
|
||||
/// Writes the header of the archive. (Must be called after writing all files.)
|
||||
fn write_header(&mut self) -> Result<()>;
|
||||
}
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
//! Buriko General Interpreter / Ethornell Scripts
|
||||
#[cfg(feature = "bgi-arc")]
|
||||
pub mod archive;
|
||||
#[cfg(feature = "bgi-audio")]
|
||||
|
||||
@@ -522,44 +522,6 @@ impl Script for RldScript {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn load_xor_key(arg: &crate::args::Arg) -> Result<Option<u32>> {
|
||||
if let Some(key) = &arg.ex_hibit_rld_xor_key {
|
||||
if key.starts_with("0x") {
|
||||
return Ok(Some(u32::from_str_radix(&key[2..], 16)?));
|
||||
} else {
|
||||
return Ok(Some(u32::from_str_radix(key, 16)?));
|
||||
}
|
||||
}
|
||||
if let Some(file) = &arg.ex_hibit_rld_xor_key_file {
|
||||
let key = std::fs::read_to_string(file)?.trim().to_string();
|
||||
if key.starts_with("0x") {
|
||||
return Ok(Some(u32::from_str_radix(&key[2..], 16)?));
|
||||
} else {
|
||||
return Ok(Some(u32::from_str_radix(&key, 16)?));
|
||||
}
|
||||
}
|
||||
Ok(None)
|
||||
}
|
||||
|
||||
pub fn load_def_xor_key(arg: &crate::args::Arg) -> Result<Option<u32>> {
|
||||
if let Some(key) = &arg.ex_hibit_rld_def_xor_key {
|
||||
if key.starts_with("0x") {
|
||||
return Ok(Some(u32::from_str_radix(&key[2..], 16)?));
|
||||
} else {
|
||||
return Ok(Some(u32::from_str_radix(key, 16)?));
|
||||
}
|
||||
}
|
||||
if let Some(file) = &arg.ex_hibit_rld_def_xor_key_file {
|
||||
let key = std::fs::read_to_string(file)?.trim().to_string();
|
||||
if key.starts_with("0x") {
|
||||
return Ok(Some(u32::from_str_radix(&key[2..], 16)?));
|
||||
} else {
|
||||
return Ok(Some(u32::from_str_radix(&key, 16)?));
|
||||
}
|
||||
}
|
||||
Ok(None)
|
||||
}
|
||||
|
||||
pub fn load_keys(path: Option<&String>) -> Result<Option<Box<[u32; 0x100]>>> {
|
||||
if let Some(path) = path {
|
||||
let f = crate::utils::files::read_file(path)?;
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
//! Module for various script formats and builders.
|
||||
#[cfg(feature = "artemis")]
|
||||
pub mod artemis;
|
||||
pub mod base;
|
||||
@@ -23,6 +24,7 @@ pub mod yaneurao;
|
||||
pub use base::{Script, ScriptBuilder};
|
||||
|
||||
lazy_static::lazy_static! {
|
||||
/// A list of all script builders.
|
||||
pub static ref BUILDER: Vec<Box<dyn ScriptBuilder + Sync + Send>> = vec![
|
||||
#[cfg(feature = "circus")]
|
||||
Box::new(circus::script::CircusMesScriptBuilder::new()),
|
||||
@@ -101,8 +103,10 @@ lazy_static::lazy_static! {
|
||||
#[cfg(feature = "bgi-audio")]
|
||||
Box::new(bgi::audio::audio::BgiAudioBuilder::new()),
|
||||
];
|
||||
/// A list of all script extensions.
|
||||
pub static ref ALL_EXTS: Vec<String> =
|
||||
BUILDER.iter().flat_map(|b| b.extensions()).map(|s| s.to_string()).collect();
|
||||
/// A list of all script extensions that are archives.
|
||||
pub static ref ARCHIVE_EXTS: Vec<String> =
|
||||
BUILDER.iter().filter(|b| b.is_archive()).flat_map(|b| b.extensions()).map(|s| s.to_string()).collect();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user