Add import support for escude list

This commit is contained in:
2025-06-03 19:08:00 +08:00
parent cfd78f0c37
commit 833be4fce0
4 changed files with 76 additions and 7 deletions

View File

@@ -1,11 +1,15 @@
use crate::types::*;
use anyhow::Result;
use std::io::{Read, Seek};
use std::io::{Read, Seek, Write};
pub trait ReadSeek: Read + Seek + std::fmt::Debug {}
pub trait WriteSeek: Write + Seek {}
impl<T: Read + Seek + std::fmt::Debug> ReadSeek for T {}
impl<T: Write + Seek> WriteSeek for T {}
pub trait ScriptBuilder: std::fmt::Debug {
fn default_encoding(&self) -> Encoding;
@@ -114,6 +118,29 @@ pub trait Script: std::fmt::Debug {
))
}
fn custom_import(
&self,
_custom_filename: &str,
_file: Box<dyn WriteSeek>,
_encoding: Encoding,
_output_encoding: Encoding,
) -> Result<()> {
Err(anyhow::anyhow!(
"This script type does not support custom import."
))
}
fn custom_import_filename(
&self,
custom_filename: &str,
filename: &str,
encoding: Encoding,
output_encoding: Encoding,
) -> Result<()> {
let f = std::fs::File::create(filename)?;
self.custom_import(custom_filename, Box::new(f), encoding, output_encoding)
}
fn is_archive(&self) -> bool {
false
}

View File

@@ -1,8 +1,8 @@
use crate::ext::io::*;
use crate::scripts::base::*;
use crate::types::*;
use crate::utils::encoding::encode_string;
use crate::utils::struct_pack::*;
use crate::{ext::io::*, utils::encoding::decode_to_string};
use anyhow::Result;
use msg_tool_macro::*;
use serde::{Deserialize, Serialize};
@@ -283,6 +283,38 @@ impl Script for EscudeBinList {
writer.flush()?;
Ok(())
}
fn custom_import(
&self,
custom_filename: &str,
mut writer: Box<dyn WriteSeek>,
encoding: Encoding,
output_encoding: Encoding,
) -> Result<()> {
let input = crate::utils::files::read_file(custom_filename)?;
let s = decode_to_string(output_encoding, &input)?;
let entries: Vec<ListEntry> = serde_json::from_str(&s)
.map_err(|e| anyhow::anyhow!("Failed to read Escude list from JSON: {}", e))?;
writer.write_all(b"LIST")?;
writer.write_u32(0)?; // Placeholder for size
let mut total_size = 0;
for entry in entries {
let cur_pos = writer.stream_position()?;
writer.write_u32(entry.id)?;
writer.write_u32(0)?; // Placeholder for size
entry.data.pack(&mut writer, false, encoding)?;
let end_pos = writer.stream_position()?;
let size = (end_pos - cur_pos - 8) as u32; // 8 bytes for id and size
writer.seek(std::io::SeekFrom::Start(cur_pos + 4))?; // Seek to size position
writer.write_u32(size)?;
writer.seek(std::io::SeekFrom::Start(end_pos))?; // Seek to end
total_size += size + 8;
}
writer.seek(std::io::SeekFrom::Start(4))?; // Seek back to size position
writer.write_u32(total_size)?;
writer.flush()?;
Ok(())
}
}
#[derive(Debug, Serialize, Deserialize, StructPack, StructUnpack)]