Files
BlueArchiveToolkit/docs/archive/ARCHITECTURE_REVIEW.md

1904 lines
44 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# BlueArchive Toolkit 架构审查报告
**审查日期**2026-06-27
**审查阶段**Architecture Refactoring Sprint
**审查目标**:评估当前架构是否适合十年以上长期维护
---
## 执行摘要
经过对整个项目的全面分析,我发现当前架构存在**多个严重的架构缺陷**,这些问题如果不立即解决,将在未来 1-3 年内导致项目陷入技术债务泥潭,需要大规模重构。
**核心问题**:当前架构**过度关注技术实现细节**,而**严重忽视了业务领域建模**和**与 Blue Archive 客户端的集成方式**。
**关键发现**
-**缺少游戏客户端集成层设计**Critical
-**缺少 Unity 版本适配抽象层**Critical
-**缺少 Manifest 格式适配层**High
-**模块职责边界不清晰**High
-**工作流自动化设计缺失**High
- ⚠️ **过早的技术选型固化**Medium
---
## 第一部分:项目现状分析
### 1.1 已完成工作
**基础设施**
- Monorepo 目录结构
- Rust workspace (4 个 crates)
- Go module 初始化
- Docker 配置(支持远程数据库)
- Makefile 构建系统
- 基础文档
**部分实现的模块**
- CAS 存储接口定义
- Hash 计算模块
- Storage trait 实现
- AssetBundle、Patch、FFI 框架搭建
### 1.2 关键缺失
**业务领域模型**
- 没有 Game Client 抽象
- 没有 Version 概念
- 没有 Asset 生命周期管理
- 没有 Translation Workflow 设计
**集成方式设计**
- 如何注入客户端?
- 如何更新客户端资源?
- 如何处理官方更新?
**可扩展性设计**
- Unity 版本升级如何处理?
- Manifest 格式变化如何适配?
- 新的资源类型如何扩展?
---
## 第二部分:架构问题深度分析
### 问题 1:缺少游戏客户端集成层设计 ⚠️ **CRITICAL**
#### 当前状况
整个项目**没有明确定义如何与 Blue Archive 客户端集成**。
#### 问题描述
- 文档中只提到"资源同步"、"AssetBundle 解析"、"Patch 生成"
- **但没有说明这些功能最终如何作用于游戏客户端**
- 没有定义"客户端"的抽象概念
#### 为什么这是 Critical
这是整个项目的**核心业务逻辑**!如果不先设计清楚这一层,后续所有模块都可能需要推倒重来。
#### 未来后果
- **1 年内**:发现现有设计无法适配实际客户端需求,需要大量重构
- **3 年内**:积累大量临时方案和 workaround,代码质量急剧下降
- **5 年内**:维护成本过高,项目陷入停滞
---
### 问题 2:缺少 Unity 版本适配抽象层 ⚠️ **CRITICAL**
#### 当前状况
AssetBundle 解析器直接依赖特定的 Unity 版本实现。
#### 问题描述
```rust
// 当前设计(crates/bat-assetbundle/
pub trait AssetParser {
fn parse(&self, bundle: &AssetBundle) -> Result<Vec<Asset>>;
}
```
这个设计假设 AssetBundle 格式是稳定的,但实际上:
- Unity 不同版本的 AssetBundle 格式**完全不同**
- 官方随时可能升级 Unity 版本
- 需要同时支持多个 Unity 版本
#### 正确设计应该是
```rust
// 需要的设计
pub trait UnityVersionAdapter {
fn version(&self) -> UnityVersion;
fn can_handle(&self, bundle: &RawBundle) -> bool;
fn parse(&self, bundle: &RawBundle) -> Result<GenericAssetBundle>;
}
pub struct AssetBundleParser {
adapters: Vec<Box<dyn UnityVersionAdapter>>,
}
```
#### 为什么这是 Critical
官方升级 Unity 版本是**必然会发生**的事情,如果现在不设计好,到时候整个 AssetBundle 模块都要重写。
---
### 问题 3:缺少 Manifest 格式适配层 ⚠️ **HIGH**
#### 当前状况
架构文档中提到"Manifest Parser",但没有设计适配层。
#### 问题描述
- Blue Archive 的 Manifest 格式可能随时变化
- 不同区域(日服、国际服)的 Manifest 格式可能不同
- 需要支持旧版本的 Manifest 以便回溯历史
#### 正确设计
```rust
pub trait ManifestAdapter {
fn format_version(&self) -> &str;
fn can_parse(&self, raw_data: &[u8]) -> bool;
fn parse(&self, raw_data: &[u8]) -> Result<GenericManifest>;
}
pub struct ManifestParser {
adapters: HashMap<String, Box<dyn ManifestAdapter>>,
}
```
#### 未来后果
- **1 年内**:官方修改 Manifest 格式,整个同步系统瘫痪
- **3 年内**:为了支持多个版本,代码中充斥着 if-else 判断
---
### 问题 4:模块职责边界不清晰 ⚠️ **HIGH**
#### 当前问题
**CAS 存储引擎职责过重**
```rust
// 当前设计混合了多个职责
pub trait Storage {
async fn put(&self, data: &[u8]) -> Result<Hash>; // 存储
async fn get(&self, hash: &Hash) -> Result<Vec<u8>>; // 读取
async fn stats(&self) -> Result<StorageStats>; // 统计
}
// 引用计数独立管理
pub struct RefCounter {
// 使用独立的 SQLite
}
```
**问题**
1. Storage 和 RefCounter 是两个独立的组件,但它们的数据必须保持一致
2. 如果 put() 成功但 incr() 失败,会导致数据不一致
3. 没有事务保证
**正确设计**
```rust
pub trait CasRepository {
// 统一的仓储接口,内部保证事务一致性
async fn store(&self, data: &[u8]) -> Result<ObjectId>;
async fn get(&self, id: &ObjectId) -> Result<Vec<u8>>;
async fn add_reference(&self, id: &ObjectId) -> Result<()>;
async fn remove_reference(&self, id: &ObjectId) -> Result<bool>; // 返回是否应该删除
}
```
---
### 问题 5:工作流自动化设计缺失 ⚠️ **HIGH**
#### 当前状况
项目规划了各个技术模块,但**没有设计完整的业务工作流**。
#### 缺失的工作流
**官方更新后的自动化流程**
1. 版本检测 → 如何实现?
2. Manifest 获取 → 从哪里获取?
3. 资源同步 → 如何判断哪些需要下载?
4. 自动解析 → 如何识别文本资源?
5. 自动识别新增文本 → 如何 diff?
6. 自动翻译 → 如何调度?
7. 人工审核 → 工作流如何设计?
8. Patch 生成 → 如何保证一致性?
9. 自动发布 → 发布到哪里?
**当前架构中这些都是空白!**
#### 正确设计需要
```
workflow/
├── version_detector/ # 版本检测服务
├── sync_coordinator/ # 同步协调器
├── text_extractor/ # 文本提取器
├── diff_analyzer/ # 差异分析器
├── translation_pipeline/ # 翻译管道
├── review_queue/ # 审核队列
├── patch_generator/ # Patch 生成器
└── release_manager/ # 发布管理器
```
---
## 第三部分:Blue Archive 客户端集成方案分析
### 3.1 可能的集成方案
#### 方案 A:客户端资源替换(推荐)⭐
**原理**
1. 工具下载官方资源到本地
2. 解析 AssetBundle,提取文本
3. 翻译后重新打包 AssetBundle
4. 替换客户端的资源文件
**优点**
- ✅ 不修改游戏可执行文件,安全性高
- ✅ 支持增量更新
- ✅ 易于回滚
- ✅ 可以离线工作
**缺点**
- ⚠️ 需要深入理解 Unity AssetBundle 格式
- ⚠️ Unity 版本升级需要适配
**维护成本**:中等
**更新成本**:低
**兼容性**:高
**架构要求**
```
Client Integration Layer:
├── AssetBundleReplacer # 资源替换器
├── IntegrityVerifier # 完整性验证
└── RollbackManager # 回滚管理
```
---
#### 方案 B:代理服务器模式
**原理**
1. 在客户端和游戏服务器之间插入代理
2. 拦截资源下载请求
3. 返回翻译后的资源
**优点**
- ✅ 不需要修改客户端文件
- ✅ 动态更新翻译
**缺点**
- ❌ 需要用户配置代理
- ❌ 可能影响游戏性能
- ❌ 需要持续运行服务
- ❌ 官方可能检测并封禁
**维护成本**:高
**更新成本**:低
**兼容性**:中
**不推荐**:维护成本高,用户体验差
---
#### 方案 C:内存补丁模式
**原理**
1. Hook 游戏进程
2. 在内存中替换文本
**优点**
- ✅ 不修改文件
**缺点**
- ❌ 技术复杂度极高
- ❌ 容易被反作弊系统检测
- ❌ 每次游戏更新都可能失效
- ❌ 不同平台需要不同实现
**维护成本**:极高
**更新成本**:极高
**兼容性**:低
**不推荐**:风险高,维护成本不可持续
---
### 3.2 推荐方案:方案 A(客户端资源替换)
#### 实施步骤
**Step 1:资源定位**
```
ClientResourceLocator:
- 识别客户端安装路径
- 定位 AssetBundle 文件位置
- 建立资源索引
```
**Step 2:资源备份**
```
BackupManager:
- 首次运行时备份原始资源
- 支持多版本备份
- 快速恢复机制
```
**Step 3:资源替换**
```
ResourceReplacer:
- 验证资源完整性
- 原子替换(要么全部成功,要么全部回滚)
- 更新资源索引
```
**Step 4:启动验证**
```
LaunchVerifier:
- 游戏启动前检查资源完整性
- 自动修复损坏的资源
- 生成诊断报告
```
---
## 第四部分:自动化流程设计
### 4.1 完整的官方更新适配流程
```mermaid
graph TD
A[官方发布新版本] --> B[版本检测服务]
B --> C{是否有新版本?}
C -->|是| D[下载新 Manifest]
C -->|否| Z[等待]
D --> E[Manifest 差异分析]
E --> F[识别变更的资源]
F --> G[资源同步下载]
G --> H[存入 CAS]
H --> I[AssetBundle 解析]
I --> J[文本提取]
J --> K[文本差异分析]
K --> L{有新增文本?}
L -->|是| M[查询翻译记忆库]
L -->|否| Y[完成]
M --> N{记忆库命中?}
N -->|全部命中| S[应用翻译]
N -->|部分未命中| O[AI 翻译]
O --> P[术语库替换]
P --> Q[加入审核队列]
Q --> R[人工审核]
R --> S[应用翻译]
S --> T[重新打包 AssetBundle]
T --> U[生成 Patch]
U --> V[完整性测试]
V --> W[发布到仓库]
W --> X[通知用户]
X --> Y[完成]
```
### 4.2 关键服务设计
#### 4.2.1 版本检测服务
```rust
pub struct VersionDetector {
region: GameRegion, // JP, Global, CN, etc.
check_interval: Duration,
}
impl VersionDetector {
/// 检测是否有新版本
pub async fn check_for_updates(&self) -> Result<Option<GameVersion>> {
// 1. 获取官方 API 最新版本号
// 2. 与本地记录对比
// 3. 返回版本信息
}
/// 下载新版本的 Manifest
pub async fn fetch_manifest(&self, version: &GameVersion) -> Result<RawManifest> {
// 从 CDN 下载 Manifest
}
}
```
#### 4.2.2 差异分析器
```rust
pub struct DiffAnalyzer {
cas: Arc<CasRepository>,
}
impl DiffAnalyzer {
/// 分析两个版本之间的资源差异
pub async fn analyze_manifest_diff(
&self,
old_version: &Manifest,
new_version: &Manifest,
) -> Result<ManifestDiff> {
// 返回:新增、修改、删除的资源列表
}
/// 分析文本差异
pub async fn analyze_text_diff(
&self,
old_texts: &[ExtractedText],
new_texts: &[ExtractedText],
) -> Result<TextDiff> {
// 返回:新增、修改、删除的文本
}
}
```
#### 4.2.3 翻译管道
```rust
pub struct TranslationPipeline {
memory: Arc<TranslationMemory>,
glossary: Arc<Glossary>,
providers: Vec<Box<dyn TranslationProvider>>,
}
impl TranslationPipeline {
/// 处理待翻译文本
pub async fn process(&self, texts: Vec<SourceText>) -> Result<Vec<TranslationResult>> {
// 1. 查询翻译记忆库
// 2. 未命中的发送给 AI
// 3. 应用术语库
// 4. 返回结果
}
}
```
#### 4.2.4 审核队列
```rust
pub struct ReviewQueue {
db: Pool<Postgres>,
}
impl ReviewQueue {
/// 添加待审核项
pub async fn enqueue(&self, item: ReviewItem) -> Result<QueueId>;
/// 获取待审核项
pub async fn fetch_pending(&self, limit: usize) -> Result<Vec<ReviewItem>>;
/// 提交审核结果
pub async fn submit_review(&self, id: QueueId, result: ReviewResult) -> Result<()>;
}
```
### 4.3 自动化程度设计
**完全自动化**(无需人工干预):
- ✅ 版本检测
- ✅ Manifest 下载
- ✅ 资源同步
- ✅ AssetBundle 解析
- ✅ 文本提取
- ✅ 差异分析
- ✅ 翻译记忆库查询
- ✅ AI 翻译
- ✅ 术语应用
**半自动化**(需要人工审核):
- ⚠️ 新增术语的添加
- ⚠️ AI 翻译质量审核
- ⚠️ 关键剧情翻译确认
**手动操作**(首次或特殊情况):
- 🔧 术语库初始化
- 🔧 翻译风格指南制定
- 🔧 异常情况处理
**目标**:90% 的更新可以在 1 小时内自动完成,仅 10% 需要人工审核。
---
## 第五部分:适配 Unity/Manifest 变化的架构设计
### 5.1 核心设计原则
**原则 1:版本即插件**
- 每个 Unity 版本对应一个 Adapter 插件
- 新版本 = 新增插件,不修改已有代码
**原则 2:格式即 Driver**
- 每种 Manifest 格式对应一个 Driver
- 自动检测格式,加载对应 Driver
**原则 3:解耦核心与适配**
- 核心业务逻辑不依赖具体版本
- 通过抽象接口与适配层通信
### 5.2 Unity 版本适配架构
```
adapters/
├── unity/
│ ├── adapter_trait.rs # Unity Adapter 接口定义
│ ├── version_2019_4/ # Unity 2019.4 适配器
│ │ ├── assetbundle_parser.rs
│ │ └── serialization.rs
│ ├── version_2021_3/ # Unity 2021.3 适配器
│ │ ├── assetbundle_parser.rs
│ │ └── serialization.rs
│ └── version_2022_3/ # Unity 2022.3 适配器
│ ├── assetbundle_parser.rs
│ └── serialization.rs
└── registry.rs # 适配器注册表
```
**接口设计**
```rust
pub trait UnityAdapter: Send + Sync {
/// 适配器名称(例如 "Unity-2019.4"
fn name(&self) -> &str;
/// 支持的 Unity 版本范围
fn supported_versions(&self) -> VersionRange;
/// 检测是否可以处理这个 AssetBundle
fn can_handle(&self, bundle: &RawAssetBundle) -> bool;
/// 解析 AssetBundle
fn parse(&self, bundle: &RawAssetBundle) -> Result<ParsedAssetBundle>;
/// 序列化回 AssetBundle
fn serialize(&self, parsed: &ParsedAssetBundle) -> Result<Vec<u8>>;
}
pub struct UnityAdapterRegistry {
adapters: Vec<Box<dyn UnityAdapter>>,
}
impl UnityAdapterRegistry {
/// 自动选择合适的适配器
pub fn select_adapter(&self, bundle: &RawAssetBundle) -> Result<&dyn UnityAdapter> {
for adapter in &self.adapters {
if adapter.can_handle(bundle) {
return Ok(adapter.as_ref());
}
}
Err(Error::NoSuitableAdapter)
}
}
```
**新增 Unity 版本的步骤**
1. 创建新目录:`adapters/unity/version_XXXX_X/`
2. 实现 `UnityAdapter` trait
3.`registry.rs` 中注册
4. **无需修改核心代码!**
---
### 5.3 Manifest 格式适配架构
```
adapters/
├── manifest/
│ ├── driver_trait.rs # Manifest Driver 接口
│ ├── format_v1/ # 第一代格式
│ │ └── parser.rs
│ ├── format_v2/ # 第二代格式
│ │ └── parser.rs
│ ├── format_v3/ # 第三代格式(假设未来会有)
│ │ └── parser.rs
│ └── registry.rs
```
**接口设计**
```rust
pub trait ManifestDriver: Send + Sync {
/// Driver 名称
fn name(&self) -> &str;
/// 格式版本标识
fn format_version(&self) -> &str;
/// 检测是否可以解析这个 Manifest
fn can_parse(&self, raw_data: &[u8]) -> bool;
/// 解析 Manifest
fn parse(&self, raw_data: &[u8]) -> Result<GenericManifest>;
}
/// 通用 Manifest 结构(所有格式都转换到这个结构)
pub struct GenericManifest {
pub version: String,
pub resources: Vec<ResourceEntry>,
pub metadata: HashMap<String, String>,
}
pub struct ResourceEntry {
pub path: String,
pub hash: String,
pub size: u64,
pub url: String,
}
```
**新增格式的步骤**
1. 创建新目录:`adapters/manifest/format_vX/`
2. 实现 `ManifestDriver` trait
3. 注册到 Registry
4. **无需修改核心代码!**
---
## 第六部分:必须立即重构的模块
### 6.1 Critical 级别(必须在继续开发前完成)
#### 🔴 C1: 建立业务领域模型
**当前状态**:只有技术组件,没有业务抽象
**必须重构的原因**:所有后续开发都依赖清晰的领域模型
**不改的后果**:项目会变成一堆技术组件的堆砌,无法形成完整系统
**需要的领域模型**
```rust
// 核心领域对象
pub struct GameClient {
region: GameRegion,
version: GameVersion,
install_path: PathBuf,
resources: ResourceIndex,
}
pub struct GameVersion {
major: u32,
minor: u32,
patch: u32,
revision: String,
unity_version: UnityVersion,
}
pub struct ResourceIndex {
manifest: Manifest,
asset_bundles: HashMap<String, AssetBundleInfo>,
}
pub struct TranslationProject {
source_version: GameVersion,
target_language: Language,
translations: TranslationSet,
status: ProjectStatus,
}
```
---
#### 🔴 C2: 设计客户端集成层
**当前状态**:完全缺失
**必须重构的原因**:这是项目的核心价值所在
**不改的后果**:做出来的工具无法实际使用
**需要的集成层**
```rust
pub trait ClientIntegration {
/// 发现客户端安装
fn discover_installation(&self) -> Result<Vec<GameClient>>;
/// 备份原始资源
fn backup_resources(&self, client: &GameClient) -> Result<BackupId>;
/// 应用翻译
fn apply_translation(&self, client: &GameClient, patch: &Patch) -> Result<()>;
/// 验证完整性
fn verify_integrity(&self, client: &GameClient) -> Result<IntegrityReport>;
/// 回滚到原始状态
fn rollback(&self, client: &GameClient, backup_id: BackupId) -> Result<()>;
}
```
---
#### 🔴 C3: 建立 Adapter 架构
**当前状态**:直接依赖具体实现
**必须重构的原因**:未来版本变化时需要全部重写
**不改的后果**:每次官方更新都需要大规模重构
**需要重构的模块**
1. `bat-assetbundle` → 改为基于 Adapter 的架构
2. Manifest 解析 → 改为基于 Driver 的架构
3. 所有版本相关的代码 → 改为插件化
---
### 6.2 High 级别(第一个迭代必须完成)
#### 🟠 H1: 重新设计 CAS 存储
**当前问题**Storage 和 RefCounter 分离,没有事务保证
**重构方案**
```rust
// 统一的 CAS Repository
pub struct CasRepository {
storage: Box<dyn ObjectStorage>,
metadata: Pool<Sqlite>,
}
impl CasRepository {
/// 存储对象(原子操作)
pub async fn store(&self, data: &[u8]) -> Result<ObjectId> {
let mut tx = self.metadata.begin().await?;
// 1. 计算 Hash
let hash = compute_hash(data);
// 2. 检查是否存在
if self.object_exists(&hash, &mut tx).await? {
// 3a. 增加引用计数
self.increment_ref(&hash, &mut tx).await?;
} else {
// 3b. 存储数据
self.storage.put(&hash, data).await?;
// 4. 记录元数据
self.insert_metadata(&hash, data.len(), &mut tx).await?;
}
tx.commit().await?;
Ok(ObjectId::from(hash))
}
}
```
---
#### 🟠 H2: 建立工作流引擎
**当前问题**:没有工作流设计
**重构方案**
```rust
pub struct WorkflowEngine {
steps: Vec<Box<dyn WorkflowStep>>,
context: WorkflowContext,
}
pub trait WorkflowStep: Send + Sync {
fn name(&self) -> &str;
async fn execute(&self, ctx: &mut WorkflowContext) -> Result<StepResult>;
async fn rollback(&self, ctx: &mut WorkflowContext) -> Result<()>;
}
// 标准工作流:官方更新适配
pub struct OfficialUpdateWorkflow {
steps: [
VersionDetectionStep,
ManifestDownloadStep,
ResourceSyncStep,
TextExtractionStep,
DiffAnalysisStep,
TranslationStep,
ReviewStep,
PatchGenerationStep,
PublishStep,
],
}
```
---
#### 🟠 H3: 定义标准数据格式
**当前问题**:没有定义中间数据格式
**需要的标准格式**
```rust
/// 提取的文本(标准格式)
pub struct ExtractedText {
pub id: TextId, // 唯一标识
pub source: TextSource, // 来源(哪个资源文件)
pub context: TextContext, // 上下文信息
pub content: String, // 文本内容
pub metadata: TextMetadata, // 元数据
}
pub struct TextSource {
pub asset_bundle: String,
pub asset_path: String,
pub object_type: String,
pub field_path: Vec<String>,
}
/// 翻译后的文本
pub struct TranslatedText {
pub source_id: TextId,
pub target_language: Language,
pub translation: String,
pub provider: String,
pub confidence: f32,
pub reviewed: bool,
}
```
---
### 6.3 Medium 级别(可以逐步优化)
#### 🟡 M1: FFI 层设计
**当前问题**:只有占位代码
**建议**
- 先完成 Rust 端的核心功能
- 然后设计稳定的 C ABI
- 最后实现 Go 绑定
**不急迫的原因**:可以先用纯 Rust 实现原型,验证设计后再做 FFI
---
#### 🟡 M2: 性能优化
**当前问题**:没有性能测试和优化
**建议**
- 先保证功能正确性
- 再用 Benchmark 找瓶颈
- 最后针对性优化
**不急迫的原因**:过早优化是万恶之源
---
### 6.4 Low 级别(未来可选)
#### 🟢 L1: Web 后台
**建议**:核心 CLI 工具稳定后再做
#### 🟢 L2: API Server
**建议**:先做单机版,需求明确后再做服务端
---
## 第七部分:当前目录结构评估与重构建议
### 7.1 当前目录结构问题
**问题 1:缺少领域层**
```
当前:
crates/
├── bat-cas-engine/ # 技术组件
├── bat-assetbundle/ # 技术组件
├── bat-patch/ # 技术组件
└── bat-ffi/ # 技术组件
缺少:
- 没有业务领域模型
- 没有应用服务层
- 没有集成层
```
**问题 2:模块划分不清晰**
```
internal/ # Go 私有包
├── downloader/ # 这是基础设施
├── manifest/ # 这是领域对象
├── storage/ # 这是基础设施
├── config/ # 这是基础设施
└── extractor/ # 这是应用服务
混在一起,职责不清!
```
**问题 3:适配层缺失**
```
应该有但没有:
adapters/
├── unity/ # Unity 版本适配器
├── manifest/ # Manifest 格式适配器
└── client/ # 客户端平台适配器
```
---
### 7.2 推荐的新目录结构
```
BlueArchiveToolkit/
├── core/ # 核心领域层(Rust)
│ ├── domain/ # 领域模型
│ │ ├── game_client.rs
│ │ ├── game_version.rs
│ │ ├── resource.rs
│ │ ├── translation.rs
│ │ └── mod.rs
│ ├── repositories/ # 仓储接口
│ │ ├── cas_repository.rs
│ │ ├── translation_repository.rs
│ │ └── mod.rs
│ └── services/ # 领域服务
│ ├── version_service.rs
│ ├── translation_service.rs
│ └── mod.rs
├── adapters/ # 适配器层(Rust)
│ ├── unity/ # Unity 版本适配
│ │ ├── adapter_trait.rs
│ │ ├── unity_2019_4/
│ │ ├── unity_2021_3/
│ │ └── registry.rs
│ ├── manifest/ # Manifest 格式适配
│ │ ├── driver_trait.rs
│ │ ├── format_v1/
│ │ ├── format_v2/
│ │ └── registry.rs
│ └── client/ # 客户端平台适配
│ ├── windows.rs
│ ├── android.rs
│ └── ios.rs
├── infrastructure/ # 基础设施层(Rust)
│ ├── cas/ # CAS 存储实现
│ │ ├── repository_impl.rs
│ │ ├── file_storage.rs
│ │ └── s3_storage.rs
│ ├── downloader/ # 下载器
│ ├── parser/ # 底层解析器
│ └── crypto/ # 加密工具
├── application/ # 应用服务层(Go)
│ ├── workflows/ # 工作流
│ │ ├── official_update.go
│ │ ├── manual_translation.go
│ │ └── patch_generation.go
│ ├── commands/ # 命令处理器
│ │ ├── sync.go
│ │ ├── extract.go
│ │ ├── translate.go
│ │ └── patch.go
│ └── queries/ # 查询处理器
│ ├── version_query.go
│ └── translation_query.go
├── api/ # API 层(Go
│ ├── http/ # HTTP API
│ ├── grpc/ # gRPC API(可选)
│ └── cli/ # CLI 入口
│ └── main.go
├── web/ # 前端(Vue 3
│ ├── admin/
│ └── shared/
├── shared/ # 共享代码
│ ├── types/ # 类型定义
│ ├── errors/ # 错误定义
│ └── utils/ # 工具函数
├── migrations/ # 数据库迁移
├── docs/ # 文档
├── scripts/ # 脚本
└── deployments/ # 部署配置
```
---
### 7.3 新目录结构的优势
**1. 清晰的分层架构**
- 核心领域层:业务逻辑,不依赖外部
- 适配器层:隔离变化,易于扩展
- 基础设施层:技术实现,可替换
- 应用服务层:编排业务流程
- API 层:对外接口
**2. 依赖关系清晰**
```
API → Application → Core ← Adapters ← Infrastructure
Domain (最核心,不依赖任何外部)
```
**3. 易于测试**
- 核心层:纯业务逻辑,易于单元测试
- 适配器层:Mock 接口,易于集成测试
- 应用层:Mock 依赖,易于端到端测试
**4. 易于扩展**
- 新增 Unity 版本:添加新适配器
- 新增 Manifest 格式:添加新 Driver
- 新增翻译 Provider:实现接口即可
---
## 第八部分:技术风险评估
### 8.1 高风险(发生概率高 + 影响大)
#### ⚠️ R1: Unity 版本升级导致 AssetBundle 格式变化
**发生概率**:**90%**(官方必然会升级)
**影响程度**:**极高**(整个解析系统失效)
**维护成本**:**当前设计:极高 / 新设计:低**
**缓解措施**
- ✅ 立即实施 Adapter 架构
- ✅ 为每个 Unity 版本建立独立适配器
- ✅ 建立自动化测试套件
---
#### ⚠️ R2: Manifest 格式变化
**发生概率****70%**
**影响程度****高**(资源同步失败)
**维护成本**:**当前设计:高 / 新设计:低**
**缓解措施**
- ✅ 实施 Driver 架构
- ✅ 支持多版本 Manifest 并存
- ✅ 建立格式自动检测机制
---
#### ⚠️ R3: 官方增加反破解机制
**发生概率****50%**
**影响程度****极高**(工具完全失效)
**维护成本****极高**
**缓解措施**
- ⚠️ 采用最小侵入性的方案(资源替换)
- ⚠️ 不修改游戏可执行文件
- ⚠️ 不使用 Hook 技术
- ⚠️ 提供快速回滚机制
---
### 8.2 中风险
#### ⚠️ R4: 新增的资源类型无法解析
**发生概率****60%**
**影响程度****中**(部分内容无法翻译)
**维护成本**:**当前设计:中 / 新设计:低**
**缓解措施**
- ✅ 插件化的解析器架构
- ✅ 支持动态加载新解析器
---
#### ⚠️ R5: AI API 限流或成本过高
**发生概率****40%**
**影响程度****中**(翻译速度下降)
**维护成本****低**
**缓解措施**
- ✅ 支持多个 Provider
- ✅ 实现请求队列和限流
- ✅ 最大化利用翻译记忆库
---
### 8.3 低风险
#### 🟢 R6: 数据库性能瓶颈
**发生概率****20%**
**影响程度****低**(响应变慢)
**维护成本****低**
**缓解措施**
- 索引优化
- 查询优化
- 必要时分库分表
---
## 第九部分:其他关键问题
### 9.1 没有考虑的问题
#### 问题 1:多区域支持
**当前状况**:架构假设只有一个游戏版本
**实际情况**
- 日服(JP
- 国际服(Global
- 韩服(KR
- 国服(CN- 可能有特殊审查要求
每个区域的:
- Manifest 地址不同
- 资源 CDN 不同
- 更新时间不同
- 可能有独占内容
**需要的设计**
```rust
pub enum GameRegion {
Japan,
Global,
Korea,
China,
}
pub struct RegionConfig {
manifest_url: String,
cdn_urls: Vec<String>,
api_endpoints: Vec<String>,
special_handling: Option<RegionHandler>,
}
```
---
#### 问题 2:增量更新策略
**当前状况**:没有明确的增量更新策略
**问题**
- 用户不应该每次都下载全部资源
- 需要智能判断哪些需要更新
- 需要支持差异化更新
**需要的设计**
```rust
pub struct UpdateStrategy {
/// 计算需要更新的资源
fn calculate_delta(
&self,
local: &ResourceIndex,
remote: &Manifest,
) -> Vec<ResourceUpdate>;
/// 优先级排序(先下载重要的)
fn prioritize(&self, updates: Vec<ResourceUpdate>) -> Vec<ResourceUpdate>;
}
```
---
#### 问题 3:错误恢复机制
**当前状况**:没有设计错误恢复
**问题**
- 下载中断如何恢复?
- 翻译失败如何重试?
- Patch 应用失败如何回滚?
**需要的设计**
```rust
pub trait Recoverable {
/// 保存检查点
fn save_checkpoint(&self) -> Result<CheckpointId>;
/// 从检查点恢复
fn restore_from_checkpoint(&self, id: CheckpointId) -> Result<()>;
/// 清理检查点
fn cleanup_checkpoint(&self, id: CheckpointId) -> Result<()>;
}
```
---
#### 问题 4:版本兼容性矩阵
**当前状况**:没有定义兼容性规则
**问题**
- 工具版本 1.0 能否处理游戏版本 2.0 的资源?
- 旧的翻译能否应用到新版本?
- 如何处理不兼容的情况?
**需要的设计**
```rust
pub struct CompatibilityMatrix {
/// 检查工具版本是否支持游戏版本
fn is_compatible(
&self,
tool_version: &Version,
game_version: &GameVersion,
) -> CompatibilityResult;
/// 获取升级路径
fn get_upgrade_path(
&self,
from: &Version,
to: &Version,
) -> Vec<Version>;
}
```
---
#### 问题 5:用户数据迁移
**当前状况**:没有考虑数据迁移
**问题**
- 工具升级时如何迁移用户数据?
- 如何保证数据完整性?
- 如何支持降级?
**需要的设计**
```rust
pub trait Migratable {
fn current_version(&self) -> Version;
fn migrate_from(&self, version: Version) -> Result<()>;
fn can_downgrade_to(&self, version: Version) -> bool;
}
```
---
#### 问题 6:并发控制
**当前状况**CAS 存储有并发问题
**问题**
- 多个进程同时访问 CAS 怎么办?
- 如何防止数据竞争?
- 如何保证原子性?
**需要的设计**
```rust
pub struct ConcurrencyControl {
lock_manager: LockManager,
}
impl ConcurrencyControl {
/// 获取排他锁
async fn acquire_exclusive(&self, resource: &str) -> Result<Lock>;
/// 获取共享锁
async fn acquire_shared(&self, resource: &str) -> Result<Lock>;
}
```
---
#### 问题 7:监控和可观测性
**当前状况**:没有监控设计
**问题**
- 如何知道系统运行状况?
- 如何追踪问题?
- 如何收集性能数据?
**需要的设计**
```rust
pub struct Telemetry {
metrics: MetricsCollector,
traces: TraceCollector,
logs: LogCollector,
}
// 关键指标
- 下载速度
- 翻译质量
- API 响应时间
- 错误率
- 资源使用情况
```
---
#### 问题 8:安全性
**当前状况**:没有安全设计
**问题**
- 如何防止恶意 Patch
- 如何验证资源完整性?
- 如何保护用户隐私?
**需要的设计**
```rust
pub struct SecurityValidator {
/// 验证 Patch 签名
fn verify_patch_signature(&self, patch: &Patch) -> Result<bool>;
/// 检查资源完整性
fn check_integrity(&self, resource: &Resource) -> Result<bool>;
/// 加密敏感数据
fn encrypt_sensitive_data(&self, data: &[u8]) -> Result<Vec<u8>>;
}
```
---
#### 问题 9:测试策略
**当前状况**:只有少量单元测试
**问题**
- 如何保证代码质量?
- 如何测试适配器?
- 如何测试工作流?
**需要的测试层次**
```
1. 单元测试(Unit Tests
- 每个模块独立测试
- Mock 所有依赖
2. 集成测试(Integration Tests
- 测试模块间交互
- 使用真实数据库(测试环境)
3. 端到端测试(E2E Tests
- 测试完整工作流
- 使用真实游戏资源(脱敏)
4. 性能测试(Performance Tests
- Benchmark 关键路径
- 压力测试
5. 兼容性测试(Compatibility Tests
- 测试不同 Unity 版本
- 测试不同 Manifest 格式
```
---
#### 问题 10:文档策略
**当前状况**:文档偏技术,缺少用户视角
**问题**
- 用户如何使用工具?
- 开发者如何贡献代码?
- 如何编写插件?
**需要的文档**
```
docs/
├── user-guide/ # 用户指南
│ ├── installation.md
│ ├── first-translation.md
│ └── troubleshooting.md
├── developer-guide/ # 开发者指南
│ ├── architecture.md
│ ├── contributing.md
│ └── code-style.md
├── plugin-guide/ # 插件开发指南
│ ├── unity-adapter.md
│ ├── manifest-driver.md
│ └── translation-provider.md
└── api-reference/ # API 参考
├── rust-api.md
└── go-api.md
```
---
## 第十部分:完整重构方案
### 10.1 重构优先级和时间线
#### Phase 0:立即暂停(已完成 ✅)
- 停止继续实现技术细节
- 完成架构审查
#### Phase 1:核心架构重构(2-3 周)
**Week 1:领域建模**
- [ ] 定义核心领域对象(GameClient, GameVersion, Resource, Translation
- [ ] 设计仓储接口(Repository Interfaces
- [ ] 实现领域服务(Domain Services
- [ ] 编写领域层测试
**Week 2:适配器架构**
- [ ] 设计 Unity Adapter 接口
- [ ] 实现第一个 Unity 适配器(当前使用的版本)
- [ ] 设计 Manifest Driver 接口
- [ ] 实现第一个 Manifest Driver
- [ ] 设计客户端集成接口
**Week 3:基础设施重构**
- [ ] 重构 CAS 为统一的 Repository
- [ ] 实现事务支持
- [ ] 重新组织目录结构
- [ ] 迁移现有代码到新架构
**产出物**
- 清晰的领域模型
- 可扩展的适配器架构
- 重构后的代码库
---
#### Phase 2:工作流实现(2-3 周)
**Week 4-5:核心工作流**
- [ ] 实现版本检测服务
- [ ] 实现资源同步工作流
- [ ] 实现文本提取工作流
- [ ] 实现差异分析器
**Week 6:翻译工作流**
- [ ] 实现翻译记忆库
- [ ] 实现术语库
- [ ] 实现翻译管道
- [ ] 实现审核队列
**产出物**
- 完整的自动化工作流
- 可测试的业务流程
---
#### Phase 3:客户端集成(2 周)
**Week 7-8:集成层实现**
- [ ] 实现客户端发现
- [ ] 实现资源备份
- [ ] 实现资源替换
- [ ] 实现完整性验证
- [ ] 实现回滚机制
**产出物**
- 可用的客户端集成
- 端到端测试通过
---
#### Phase 4:打磨和优化(2 周)
**Week 9-10**
- [ ] 性能优化
- [ ] 错误处理完善
- [ ] 日志和监控
- [ ] 文档完善
- [ ] 用户指南
**产出物**
- 可发布的 Alpha 版本
---
### 10.2 新架构的模块依赖图
```mermaid
graph TB
subgraph "API Layer"
CLI[CLI]
HTTP[HTTP API]
end
subgraph "Application Layer"
WF[Workflows]
CMD[Commands]
end
subgraph "Domain Layer"
DOM[Domain Models]
SVC[Domain Services]
REPO[Repository Interfaces]
end
subgraph "Adapter Layer"
UNITY[Unity Adapters]
MANIFEST[Manifest Drivers]
CLIENT[Client Adapters]
end
subgraph "Infrastructure Layer"
CAS[CAS Repository]
DL[Downloader]
DB[Database]
end
CLI --> WF
HTTP --> WF
WF --> CMD
CMD --> SVC
SVC --> DOM
SVC --> REPO
REPO --> CAS
REPO --> DB
SVC --> UNITY
SVC --> MANIFEST
CMD --> CLIENT
CLIENT --> CAS
style DOM fill:#90EE90
style UNITY fill:#FFB6C1
style MANIFEST fill:#FFB6C1
style CLIENT fill:#FFB6C1
```
---
### 10.3 关键设计决策
#### 决策 1Rust 为核心,Go 为应用层
**理由**
- Rust:性能关键路径(解析、Patch、CAS)
- Go:业务编排、HTTP API、CLI
- 优势互补
**权衡**
- ✅ 发挥各语言优势
- ⚠️ FFI 有一定复杂度
- ✅ 但隔离清晰,便于测试
---
#### 决策 2:采用资源替换而非内存 Hook
**理由**
- 维护成本低
- 兼容性好
- 安全性高
- 易于回滚
**权衡**
- ✅ 长期维护成本低
- ⚠️ 需要深入理解 AssetBundle
- ✅ 但这是一次性成本
---
#### 决策 3:插件化架构
**理由**
- Unity 版本必然升级
- Manifest 格式可能变化
- 需要支持扩展
**权衡**
- ✅ 长期可维护
- ⚠️ 初期开发成本略高
- ✅ 但避免未来大规模重构
---
#### 决策 4:工作流引擎
**理由**
- 业务流程复杂
- 需要错误恢复
- 需要可观测性
**权衡**
- ✅ 流程清晰
- ✅ 易于扩展
- ⚠️ 需要学习成本
---
### 10.4 技术债务清单
#### 必须立即偿还
- ❌ 缺少领域模型
- ❌ 缺少适配器架构
- ❌ CAS 缺少事务
- ❌ 缺少客户端集成
#### 第一个版本前偿还
- ⚠️ 工作流设计
- ⚠️ 错误恢复机制
- ⚠️ 监控和日志
#### 可以延后
- 🟢 性能优化
- 🟢 Web 后台
- 🟢 API Server
---
## 第十一部分:行动计划
### 11.1 立即行动(本周)
**任务 1:确认架构方向**
- [ ] 审查本文档
- [ ] 确认重构范围
- [ ] 确认时间线
**任务 2:准备重构**
- [ ] 备份当前代码
- [ ] 创建 refactor 分支
- [ ] 准备测试环境
**任务 3:开始领域建模**
- [ ] 定义核心领域对象
- [ ] 编写领域层代码
- [ ] 编写单元测试
---
### 11.2 第一周目标
**交付物**
- ✅ 完整的领域模型(Rust
- ✅ 核心接口定义
- ✅ 通过测试的领域层
**验收标准**
- 代码编译通过
- 所有单元测试通过
- 文档更新
---
### 11.3 第一个月目标
**交付物**
- ✅ 重构后的架构
- ✅ 适配器框架
- ✅ 核心工作流
**里程碑**
- M1:领域层完成(Week 1
- M2:适配器层完成(Week 2
- M3:基础设施完成(Week 3
- M4:工作流完成(Week 5
---
### 11.4 三个月目标
**交付物**
- ✅ 可用的 Alpha 版本
- ✅ 完整文档
- ✅ 测试覆盖 > 80%
**里程碑**
- M5:客户端集成完成(Week 8)
- M6:端到端测试通过(Week 9)
- M7Alpha 版本发布(Week 10
---
## 第十二部分:总结与建议
### 12.1 核心结论
1. **当前架构不可持续**
- 缺少业务领域建模
- 缺少适配层设计
- 缺少客户端集成
- 无法应对未来变化
2. **必须立即重构** ⚠️
- 继续开发会积累技术债
- 未来重构成本呈指数增长
- 现在重构成本最低
3. **重构方向明确**
- 领域驱动设计
- 适配器+插件架构
- 工作流引擎
- 清晰的分层
---
### 12.2 关键建议
#### 建议 1:先做对,再做快
不要为了快速实现功能而妥协架构质量。好的架构会让后续开发更快。
#### 建议 2:接受重构成本
当前已写的代码中,约 30-40% 需要重构或重写。这是必要的投资。
#### 建议 3:边重构边测试
每重构一个模块,立即编写测试。不要等到最后。
#### 建议 4:文档同步更新
代码重构的同时更新文档,保持一致性。
#### 建议 5:小步快跑
按周交付,每周都有可验证的成果。
---
### 12.3 成功标准
**技术标准**
- ✅ 编译通过,无警告
- ✅ 测试覆盖率 > 80%
- ✅ 所有 Critical 问题解决
- ✅ 架构文档完整
**业务标准**
- ✅ 能够完成一次完整的官方更新适配
- ✅ 翻译质量达标
- ✅ 用户可以正常使用
**可维护性标准**
- ✅ 新增 Unity 版本只需要添加适配器
- ✅ 新增 Manifest 格式只需要添加 Driver
- ✅ 代码易读、易测试、易扩展
---
### 12.4 风险与应对
**风险 1:重构时间超出预期**
**应对**
- 采用迭代方式
- 先完成核心,再完善细节
- 保持可运行状态
**风险 2:需求理解偏差**
**应对**
- 尽早实现端到端原型
- 及时验证假设
- 快速迭代
**风险 3:技术难点卡住**
**应对**
- 预留缓冲时间
- 及时寻求帮助
- 准备备选方案
---
## 附录:代码示例
### A1. 核心领域对象示例
```rust
// core/domain/game_client.rs
use std::path::PathBuf;
use crate::domain::{GameVersion, ResourceIndex, GameRegion};
/// 游戏客户端
///
/// 代表用户本地安装的 Blue Archive 游戏客户端
pub struct GameClient {
/// 客户端 ID
id: ClientId,
/// 安装路径
install_path: PathBuf,
/// 当前版本
version: GameVersion,
/// 区域
region: GameRegion,
/// 资源索引
resources: ResourceIndex,
/// 客户端状态
status: ClientStatus,
}
impl GameClient {
/// 发现本地安装的客户端
pub fn discover() -> Result<Vec<GameClient>> {
todo!()
}
/// 验证客户端完整性
pub fn verify_integrity(&self) -> Result<IntegrityReport> {
todo!()
}
/// 获取当前版本
pub fn current_version(&self) -> &GameVersion {
&self.version
}
/// 检查是否有可用更新
pub async fn check_for_updates(&self) -> Result<Option<GameVersion>> {
todo!()
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum ClientStatus {
/// 原始状态(未修改)
Pristine,
/// 已应用翻译
Translated,
/// 损坏(需要修复)
Corrupted,
/// 未知状态
Unknown,
}
```
### A2. Unity 适配器示例
```rust
// adapters/unity/unity_2021_3/assetbundle_parser.rs
use crate::adapters::unity::UnityAdapter;
use crate::core::domain::AssetBundle;
pub struct Unity2021_3Adapter {
// 配置
}
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 {
// 检查文件头部的版本信息
bundle.version().major == 2021
&& bundle.version().minor == 3
}
fn parse(&self, bundle: &RawAssetBundle) -> Result<ParsedAssetBundle> {
// Unity 2021.3 特定的解析逻辑
todo!()
}
fn serialize(&self, parsed: &ParsedAssetBundle) -> Result<Vec<u8>> {
// Unity 2021.3 特定的序列化逻辑
todo!()
}
}
```
---
## 结语
这份架构审查报告指出了当前项目的核心问题:**过度关注技术实现,而忽视了业务领域建模和可扩展性设计**。
如果不立即重构,项目将在 1-3 年内陷入技术债务泥潭,最终可能需要推倒重来。
好的消息是:问题已经被识别,解决方案也很明确。现在重构的成本是最低的,收益是最大的。
**建议立即启动重构,按照本文档规划的路线图执行。**
---
**文档版本**v1.0
**创建日期**2026-06-27
**作者**Claude (Chief Architect)
**状态**:待审核