mirror of
https://github.com/Yuyi-Oak/BlueArchiveToolkit.git
synced 2026-07-23 07:55:15 +08:00
chore: establish development baseline
This commit is contained in:
@@ -0,0 +1,158 @@
|
||||
//! Unity 2021.3 Adapter
|
||||
//!
|
||||
//! 支持 Unity 2021.3.x 版本的 AssetBundle
|
||||
|
||||
use super::adapter::{ParsedAssetBundle, RawAssetBundle, UnityAdapter, VersionRange};
|
||||
use async_trait::async_trait;
|
||||
|
||||
/// Unity 2021.3 Adapter
|
||||
pub struct Unity2021_3Adapter;
|
||||
|
||||
impl Unity2021_3Adapter {
|
||||
/// 创建新的适配器实例
|
||||
pub fn new() -> Self {
|
||||
Self
|
||||
}
|
||||
|
||||
/// 检测 Unity 版本(从文件头)
|
||||
fn detect_unity_version(data: &[u8]) -> Option<String> {
|
||||
// UnityFS 文件头结构:
|
||||
// 0x00-0x06: "UnityFS\0"
|
||||
// 0x08-0x0B: format version
|
||||
// 0x0C-...: Unity version string
|
||||
|
||||
if data.len() < 20 {
|
||||
return None;
|
||||
}
|
||||
|
||||
// 检查签名
|
||||
if &data[0..7] != b"UnityFS" {
|
||||
return None;
|
||||
}
|
||||
|
||||
// 读取 Unity 版本字符串
|
||||
// 版本字符串从偏移 0x14 开始(可能因格式版本不同而变化)
|
||||
if let Some(version_start) = data.windows(7).position(|w| w.starts_with(b"2021.3.")) {
|
||||
// 读取版本字符串直到 null 或非 ASCII
|
||||
let version_bytes = &data[version_start..];
|
||||
if let Some(end) = version_bytes.iter().position(|&b| b == 0 || !b.is_ascii()) {
|
||||
if let Ok(version) = std::str::from_utf8(&version_bytes[..end]) {
|
||||
return Some(version.to_string());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for Unity2021_3Adapter {
|
||||
fn default() -> Self {
|
||||
Self::new()
|
||||
}
|
||||
}
|
||||
|
||||
#[async_trait]
|
||||
impl UnityAdapter for Unity2021_3Adapter {
|
||||
fn name(&self) -> &str {
|
||||
"Unity-2021.3"
|
||||
}
|
||||
|
||||
fn supported_versions(&self) -> VersionRange {
|
||||
VersionRange::new("2021.3.0", "2021.3.99")
|
||||
}
|
||||
|
||||
fn can_handle(&self, bundle: &RawAssetBundle) -> bool {
|
||||
// 检测 Unity 版本
|
||||
if let Some(version) = Self::detect_unity_version(&bundle.data) {
|
||||
self.supported_versions().contains(&version)
|
||||
} else {
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
async fn parse(&self, _bundle: &RawAssetBundle) -> Result<ParsedAssetBundle, String> {
|
||||
// TODO: Phase 2 实现
|
||||
// 需要:
|
||||
// 1. 解析 UnityFS 文件头
|
||||
// 2. 解压缩数据块
|
||||
// 3. 解析 TypeTree
|
||||
// 4. 提取 Asset 对象
|
||||
Err("parse() 将在 Phase 2 实现".to_string())
|
||||
}
|
||||
|
||||
async fn serialize(&self, _parsed: &ParsedAssetBundle) -> Result<Vec<u8>, String> {
|
||||
// TODO: Phase 2 实现
|
||||
// 需要:
|
||||
// 1. 序列化 Asset 对象
|
||||
// 2. 重新构建 TypeTree
|
||||
// 3. 压缩数据块
|
||||
// 4. 写入 UnityFS 文件头
|
||||
Err("serialize() 将在 Phase 2 实现".to_string())
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_adapter_name() {
|
||||
let adapter = Unity2021_3Adapter::new();
|
||||
assert_eq!(adapter.name(), "Unity-2021.3");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_supported_versions() {
|
||||
let adapter = Unity2021_3Adapter::new();
|
||||
let range = adapter.supported_versions();
|
||||
|
||||
assert!(range.contains("2021.3.0"));
|
||||
assert!(range.contains("2021.3.56"));
|
||||
assert!(!range.contains("2021.2.0"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_can_handle_valid_bundle() {
|
||||
let adapter = Unity2021_3Adapter::new();
|
||||
|
||||
// 模拟 UnityFS 文件头
|
||||
let mut data = Vec::new();
|
||||
data.extend_from_slice(b"UnityFS\0");
|
||||
data.extend_from_slice(&[0, 0, 0, 8]); // format version
|
||||
data.extend_from_slice(b"5.x.x\x002021.3.56f2\0");
|
||||
|
||||
let bundle = RawAssetBundle {
|
||||
data,
|
||||
path: Some("test.bundle".to_string()),
|
||||
};
|
||||
|
||||
assert!(adapter.can_handle(&bundle));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_can_handle_invalid_bundle() {
|
||||
let adapter = Unity2021_3Adapter::new();
|
||||
|
||||
let bundle = RawAssetBundle {
|
||||
data: vec![0, 1, 2, 3],
|
||||
path: None,
|
||||
};
|
||||
|
||||
assert!(!adapter.can_handle(&bundle));
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn test_parse_not_implemented() {
|
||||
let adapter = Unity2021_3Adapter::new();
|
||||
|
||||
let bundle = RawAssetBundle {
|
||||
data: vec![],
|
||||
path: None,
|
||||
};
|
||||
|
||||
let result = adapter.parse(&bundle).await;
|
||||
assert!(result.is_err());
|
||||
assert!(result.unwrap_err().contains("Phase 2"));
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user