mirror of
https://github.com/Yuyi-Oak/BlueArchiveToolkit.git
synced 2026-07-22 05:55:15 +08:00
refactor: address quality findings
This commit is contained in:
@@ -16,6 +16,59 @@ impl AddressablesCatalogDriver {
|
||||
pub fn new() -> Self {
|
||||
Self
|
||||
}
|
||||
|
||||
fn parse_json(raw_data: &[u8]) -> Result<Value, String> {
|
||||
let text = std::str::from_utf8(raw_data).map_err(|e| format!("Invalid UTF-8: {}", e))?;
|
||||
serde_json::from_str(text).map_err(|e| format!("Invalid JSON: {}", e))
|
||||
}
|
||||
|
||||
fn locator_id(json: &Value) -> Option<String> {
|
||||
json.get("m_LocatorId")
|
||||
.and_then(|value| value.as_str())
|
||||
.map(ToOwned::to_owned)
|
||||
}
|
||||
|
||||
fn cdn_prefixes(json: &Value) -> Vec<String> {
|
||||
json.get("m_InternalIdPrefixes")
|
||||
.and_then(|value| value.as_array())
|
||||
.into_iter()
|
||||
.flatten()
|
||||
.filter_map(|value| value.as_str())
|
||||
.map(ToOwned::to_owned)
|
||||
.collect()
|
||||
}
|
||||
|
||||
fn resource_type_for_path(path: &str) -> ResourceType {
|
||||
if path.ends_with(".bundle") {
|
||||
ResourceType::AssetBundle
|
||||
} else if path.contains("catalog") {
|
||||
ResourceType::Manifest
|
||||
} else {
|
||||
ResourceType::Other
|
||||
}
|
||||
}
|
||||
|
||||
fn resources(json: &Value) -> Vec<ResourceEntry> {
|
||||
json.get("m_InternalIds")
|
||||
.and_then(|value| value.as_array())
|
||||
.into_iter()
|
||||
.flatten()
|
||||
.enumerate()
|
||||
.filter_map(|(index, value)| {
|
||||
let path = value.as_str()?;
|
||||
if path.is_empty() {
|
||||
return None;
|
||||
}
|
||||
|
||||
Some(ResourceEntry {
|
||||
path: path.to_string(),
|
||||
hash: format!("addressable_{}", index),
|
||||
size: 0,
|
||||
resource_type: Self::resource_type_for_path(path),
|
||||
})
|
||||
})
|
||||
.collect()
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for AddressablesCatalogDriver {
|
||||
@@ -64,69 +117,21 @@ impl ManifestDriver for AddressablesCatalogDriver {
|
||||
}
|
||||
|
||||
async fn parse(&self, raw_data: &[u8]) -> Result<GenericManifest, String> {
|
||||
// 解析 JSON
|
||||
let text = std::str::from_utf8(raw_data).map_err(|e| format!("Invalid UTF-8: {}", e))?;
|
||||
|
||||
let json: Value = serde_json::from_str(text).map_err(|e| format!("Invalid JSON: {}", e))?;
|
||||
|
||||
// 提取元数据
|
||||
let locator_id = json
|
||||
.get("m_LocatorId")
|
||||
.and_then(|v| v.as_str())
|
||||
.map(|s| s.to_string());
|
||||
|
||||
// 提取 CDN 前缀
|
||||
let mut cdn_prefixes = Vec::new();
|
||||
if let Some(prefixes) = json.get("m_InternalIdPrefixes").and_then(|v| v.as_array()) {
|
||||
for prefix in prefixes {
|
||||
if let Some(s) = prefix.as_str() {
|
||||
cdn_prefixes.push(s.to_string());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 提取资源列表(基础版本 - 仅从 m_InternalIds 提取)
|
||||
let mut resources = Vec::new();
|
||||
if let Some(internal_ids) = json.get("m_InternalIds").and_then(|v| v.as_array()) {
|
||||
for (index, id) in internal_ids.iter().enumerate() {
|
||||
if let Some(path) = id.as_str() {
|
||||
// 跳过空路径
|
||||
if path.is_empty() {
|
||||
continue;
|
||||
}
|
||||
|
||||
// 判断资源类型
|
||||
let resource_type = if path.ends_with(".bundle") {
|
||||
ResourceType::AssetBundle
|
||||
} else if path.contains("catalog") {
|
||||
ResourceType::Manifest
|
||||
} else {
|
||||
ResourceType::Other
|
||||
};
|
||||
|
||||
resources.push(ResourceEntry {
|
||||
path: path.to_string(),
|
||||
hash: format!("addressable_{}", index), // 临时 Hash
|
||||
size: 0, // 大小未知
|
||||
resource_type,
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
let json = Self::parse_json(raw_data)?;
|
||||
|
||||
// TODO: 解析 m_KeyDataString、m_EntryDataString 等压缩字段
|
||||
// 这些字段使用了自定义压缩格式,需要实现解压缩算法
|
||||
// 参考:Unity Addressables 源代码
|
||||
|
||||
let metadata = ManifestMetadata {
|
||||
locator_id,
|
||||
cdn_prefixes,
|
||||
locator_id: Self::locator_id(&json),
|
||||
cdn_prefixes: Self::cdn_prefixes(&json),
|
||||
extra: HashMap::new(),
|
||||
};
|
||||
|
||||
Ok(GenericManifest {
|
||||
format: ManifestFormat::AddressablesCatalog,
|
||||
resources,
|
||||
resources: Self::resources(&json),
|
||||
metadata,
|
||||
})
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user