增强脚本解析功能,支持多种脚本类型识别和处理

This commit is contained in:
2025-06-02 15:41:20 +08:00
parent 70066d3f86
commit 24192050dc
6 changed files with 62 additions and 3 deletions

View File

@@ -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"))
}

View File

@@ -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;
}

View File

@@ -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 {

View File

@@ -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 {

View File

@@ -0,0 +1 @@

View File

@@ -1,6 +1,7 @@
pub mod base;
pub mod bgi;
pub mod circus;
pub mod escude;
pub use base::{Script, ScriptBuilder};