mirror of
https://github.com/lifegpc/msg-tool.git
synced 2026-06-06 12:58:45 +08:00
增强脚本解析功能,支持多种脚本类型识别和处理
This commit is contained in:
48
src/main.rs
48
src/main.rs
@@ -99,15 +99,59 @@ pub fn parse_script(
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
let mut exts_builder = Vec::new();
|
||||
for builder in scripts::BUILDER.iter() {
|
||||
let exts = builder.extensions();
|
||||
for ext in exts {
|
||||
if filename.to_lowercase().ends_with(ext) {
|
||||
let encoding = get_encoding(arg, builder);
|
||||
return Ok((builder.build_script(filename, encoding, config)?, builder));
|
||||
exts_builder.push(builder);
|
||||
}
|
||||
}
|
||||
}
|
||||
let exts_builder = if exts_builder.is_empty() {
|
||||
scripts::BUILDER.iter().collect::<Vec<_>>()
|
||||
} else {
|
||||
exts_builder
|
||||
};
|
||||
if exts_builder.len() == 1 {
|
||||
let builder = exts_builder.first().unwrap();
|
||||
let encoding = get_encoding(arg, builder);
|
||||
return Ok((builder.build_script(filename, encoding, config)?, builder));
|
||||
}
|
||||
let mut buf = [0u8; 1024];
|
||||
let mut size = 0;
|
||||
if filename != "-" {
|
||||
let mut f = std::fs::File::open(filename)?;
|
||||
size = std::io::Read::read(&mut f, &mut buf)?;
|
||||
}
|
||||
let mut scores = Vec::new();
|
||||
for builder in exts_builder.iter() {
|
||||
if let Some(score) = builder.is_this_format(filename, &buf, size) {
|
||||
scores.push((score, builder));
|
||||
}
|
||||
}
|
||||
if scores.is_empty() {
|
||||
return Err(anyhow::anyhow!("Unsupported script type"));
|
||||
}
|
||||
let max_score = scores.iter().map(|s| s.0).max().unwrap();
|
||||
let mut best_builders = Vec::new();
|
||||
for (score, builder) in scores.iter() {
|
||||
if *score == max_score {
|
||||
best_builders.push(builder);
|
||||
}
|
||||
}
|
||||
if best_builders.len() == 1 {
|
||||
let builder = best_builders.first().unwrap();
|
||||
let encoding = get_encoding(arg, builder);
|
||||
return Ok((builder.build_script(filename, encoding, config)?, builder));
|
||||
}
|
||||
if best_builders.len() > 1 {
|
||||
eprintln!(
|
||||
"Multiple script types found for {}: {:?}",
|
||||
filename, best_builders
|
||||
);
|
||||
return Err(anyhow::anyhow!("Multiple script types found"));
|
||||
}
|
||||
Err(anyhow::anyhow!("Unsupported script type"))
|
||||
}
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
use crate::types::*;
|
||||
use anyhow::Result;
|
||||
|
||||
pub trait ScriptBuilder {
|
||||
pub trait ScriptBuilder: std::fmt::Debug {
|
||||
fn default_encoding(&self) -> Encoding;
|
||||
|
||||
fn default_patched_encoding(&self) -> Encoding {
|
||||
@@ -17,6 +17,10 @@ pub trait ScriptBuilder {
|
||||
|
||||
fn extensions(&self) -> &'static [&'static str];
|
||||
|
||||
fn is_this_format(&self, _filename: &str, _buf: &[u8], _buf_len: usize) -> Option<u8> {
|
||||
None
|
||||
}
|
||||
|
||||
fn script_type(&self) -> &'static ScriptType;
|
||||
}
|
||||
|
||||
|
||||
@@ -4,6 +4,7 @@ use crate::types::*;
|
||||
use crate::utils::encoding::{decode_to_string, encode_string};
|
||||
use anyhow::Result;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct BGIScriptBuilder {}
|
||||
|
||||
impl BGIScriptBuilder {
|
||||
@@ -37,6 +38,13 @@ impl ScriptBuilder for BGIScriptBuilder {
|
||||
fn script_type(&self) -> &'static ScriptType {
|
||||
&ScriptType::BGI
|
||||
}
|
||||
|
||||
fn is_this_format(&self, _filename: &str, buf: &[u8], buf_len: usize) -> Option<u8> {
|
||||
if buf_len > 28 && buf.starts_with(b"BurikoCompiledScriptVer1.00\0") {
|
||||
return Some(255);
|
||||
}
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
pub struct BGIScript {
|
||||
|
||||
@@ -4,6 +4,7 @@ use crate::types::*;
|
||||
use crate::utils::encoding::{decode_to_string, encode_string};
|
||||
use anyhow::Result;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct CircusMesScriptBuilder {}
|
||||
|
||||
impl CircusMesScriptBuilder {
|
||||
|
||||
1
src/scripts/escude/mod.rs
Normal file
1
src/scripts/escude/mod.rs
Normal file
@@ -0,0 +1 @@
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
pub mod base;
|
||||
pub mod bgi;
|
||||
pub mod circus;
|
||||
pub mod escude;
|
||||
|
||||
pub use base::{Script, ScriptBuilder};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user