mirror of
https://github.com/Yuyi-Oak/BlueArchiveToolkit.git
synced 2026-07-22 09:15:15 +08:00
chore: establish development baseline
This commit is contained in:
@@ -0,0 +1,167 @@
|
||||
//! 游戏客户端领域对象
|
||||
|
||||
use std::path::PathBuf;
|
||||
|
||||
/// 游戏区域
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, serde::Serialize, serde::Deserialize)]
|
||||
pub enum GameRegion {
|
||||
/// 日本服
|
||||
Japan,
|
||||
/// 国际服
|
||||
Global,
|
||||
/// 韩国服
|
||||
Korea,
|
||||
/// 国服
|
||||
China,
|
||||
}
|
||||
|
||||
impl GameRegion {
|
||||
/// 获取区域代码
|
||||
pub fn code(&self) -> &'static str {
|
||||
match self {
|
||||
Self::Japan => "JP",
|
||||
Self::Global => "GLOBAL",
|
||||
Self::Korea => "KR",
|
||||
Self::China => "CN",
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// 客户端状态
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
|
||||
pub enum ClientStatus {
|
||||
/// 原始状态(未修改)
|
||||
Pristine,
|
||||
/// 已应用翻译
|
||||
Translated,
|
||||
/// 损坏(需要修复)
|
||||
Corrupted,
|
||||
/// 未知状态
|
||||
Unknown,
|
||||
}
|
||||
|
||||
/// 游戏客户端
|
||||
///
|
||||
/// 代表用户本地安装的 Blue Archive 游戏客户端
|
||||
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
|
||||
pub struct GameClient {
|
||||
/// 安装路径
|
||||
pub install_path: PathBuf,
|
||||
|
||||
/// 游戏区域
|
||||
pub region: GameRegion,
|
||||
|
||||
/// 当前状态
|
||||
pub status: ClientStatus,
|
||||
}
|
||||
|
||||
impl GameClient {
|
||||
/// 创建新的游戏客户端实例
|
||||
///
|
||||
/// # 参数
|
||||
/// - `install_path`: 游戏安装目录
|
||||
/// - `region`: 游戏区域
|
||||
pub fn new(install_path: PathBuf, region: GameRegion) -> Self {
|
||||
Self {
|
||||
install_path,
|
||||
region,
|
||||
status: ClientStatus::Unknown,
|
||||
}
|
||||
}
|
||||
|
||||
/// 发现本地安装的客户端
|
||||
///
|
||||
/// # 返回
|
||||
/// - 成功:返回找到的所有客户端
|
||||
/// - 失败:返回错误
|
||||
///
|
||||
/// # 注意
|
||||
/// 此功能将在 Phase 3 实现
|
||||
pub fn discover() -> crate::Result<Vec<GameClient>> {
|
||||
Err(crate::Error::NotImplemented(
|
||||
"客户端发现功能将在 Phase 3 实现".to_string()
|
||||
))
|
||||
}
|
||||
|
||||
/// 验证客户端完整性
|
||||
///
|
||||
/// # 返回
|
||||
/// - true: 客户端完整
|
||||
/// - false: 客户端损坏
|
||||
///
|
||||
/// # 注意
|
||||
/// 此功能将在 Phase 3 实现
|
||||
pub fn verify_integrity(&self) -> crate::Result<bool> {
|
||||
Err(crate::Error::NotImplemented(
|
||||
"完整性验证将在 Phase 3 实现".to_string()
|
||||
))
|
||||
}
|
||||
|
||||
/// 获取 StreamingAssets 目录路径
|
||||
pub fn streaming_assets_path(&self) -> PathBuf {
|
||||
self.install_path
|
||||
.join("BlueArchive_Data")
|
||||
.join("StreamingAssets")
|
||||
}
|
||||
|
||||
/// 获取 AssetBundles 目录路径
|
||||
pub fn asset_bundles_path(&self) -> PathBuf {
|
||||
self.streaming_assets_path().join("AssetBundles")
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_game_region_code() {
|
||||
assert_eq!(GameRegion::Japan.code(), "JP");
|
||||
assert_eq!(GameRegion::Global.code(), "GLOBAL");
|
||||
assert_eq!(GameRegion::Korea.code(), "KR");
|
||||
assert_eq!(GameRegion::China.code(), "CN");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_new_game_client() {
|
||||
let path = PathBuf::from("/test/path");
|
||||
let client = GameClient::new(path.clone(), GameRegion::Japan);
|
||||
|
||||
assert_eq!(client.install_path, path);
|
||||
assert_eq!(client.region, GameRegion::Japan);
|
||||
assert_eq!(client.status, ClientStatus::Unknown);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_streaming_assets_path() {
|
||||
let client = GameClient::new(
|
||||
PathBuf::from("/game/BlueArchive_JP"),
|
||||
GameRegion::Japan
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
client.streaming_assets_path(),
|
||||
PathBuf::from("/game/BlueArchive_JP/BlueArchive_Data/StreamingAssets")
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_asset_bundles_path() {
|
||||
let client = GameClient::new(
|
||||
PathBuf::from("/game/BlueArchive_JP"),
|
||||
GameRegion::Japan
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
client.asset_bundles_path(),
|
||||
PathBuf::from("/game/BlueArchive_JP/BlueArchive_Data/StreamingAssets/AssetBundles")
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_discover_not_implemented() {
|
||||
let result = GameClient::discover();
|
||||
assert!(result.is_err());
|
||||
assert!(matches!(result.unwrap_err(), crate::Error::NotImplemented(_)));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
//! 游戏版本领域对象
|
||||
|
||||
use std::fmt;
|
||||
|
||||
/// Unity 版本
|
||||
#[derive(Debug, Clone, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
|
||||
pub struct UnityVersion {
|
||||
/// 主版本号
|
||||
pub year: u32,
|
||||
/// 次版本号
|
||||
pub stream: u32,
|
||||
/// 补丁版本号
|
||||
pub patch: u32,
|
||||
/// 修订版本(如 f2, b1)
|
||||
pub revision: String,
|
||||
}
|
||||
|
||||
impl UnityVersion {
|
||||
/// 创建新的 Unity 版本
|
||||
pub fn new(year: u32, stream: u32, patch: u32, revision: String) -> Self {
|
||||
Self { year, stream, patch, revision }
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for UnityVersion {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
write!(f, "{}.{}.{}{}", self.year, self.stream, self.patch, self.revision)
|
||||
}
|
||||
}
|
||||
|
||||
/// 游戏版本
|
||||
#[derive(Debug, Clone, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
|
||||
pub struct GameVersion {
|
||||
/// 主版本号
|
||||
pub major: u32,
|
||||
/// 次版本号
|
||||
pub minor: u32,
|
||||
/// 补丁版本号
|
||||
pub patch: u32,
|
||||
/// Unity 版本
|
||||
pub unity_version: UnityVersion,
|
||||
}
|
||||
|
||||
impl GameVersion {
|
||||
/// 创建新的游戏版本
|
||||
pub fn new(major: u32, minor: u32, patch: u32, unity_version: UnityVersion) -> Self {
|
||||
Self { major, minor, patch, unity_version }
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for GameVersion {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
write!(f, "{}.{}.{}", self.major, self.minor, self.patch)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_unity_version_display() {
|
||||
let version = UnityVersion::new(2021, 3, 56, "f2".to_string());
|
||||
assert_eq!(version.to_string(), "2021.3.56f2");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_game_version_display() {
|
||||
let unity = UnityVersion::new(2021, 3, 56, "f2".to_string());
|
||||
let version = GameVersion::new(1, 70, 0, unity);
|
||||
assert_eq!(version.to_string(), "1.70.0");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
//! 领域对象模块
|
||||
|
||||
pub mod game_client;
|
||||
pub mod game_version;
|
||||
pub mod resource;
|
||||
pub mod translation;
|
||||
|
||||
pub use game_client::{ClientStatus, GameClient, GameRegion};
|
||||
pub use game_version::{GameVersion, UnityVersion};
|
||||
pub use resource::{Resource, ResourceEntry, ResourceType};
|
||||
pub use translation::{ExtractedText, SourceText, TextContext, TextMetadata, TextSource, TranslatedText, TranslationStatus};
|
||||
@@ -0,0 +1,58 @@
|
||||
//! 资源领域对象
|
||||
|
||||
use std::path::PathBuf;
|
||||
|
||||
/// 资源类型
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
|
||||
pub enum ResourceType {
|
||||
/// AssetBundle
|
||||
AssetBundle,
|
||||
/// Manifest
|
||||
Manifest,
|
||||
/// TableBundle
|
||||
TableBundle,
|
||||
/// 其他
|
||||
Other,
|
||||
}
|
||||
|
||||
/// 资源条目
|
||||
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
|
||||
pub struct ResourceEntry {
|
||||
/// 资源路径
|
||||
pub path: String,
|
||||
/// 资源 Hash
|
||||
pub hash: String,
|
||||
/// 资源大小
|
||||
pub size: u64,
|
||||
/// 资源类型
|
||||
pub resource_type: ResourceType,
|
||||
}
|
||||
|
||||
/// 资源
|
||||
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
|
||||
pub struct Resource {
|
||||
/// 资源 ID
|
||||
pub id: String,
|
||||
/// 本地路径
|
||||
pub local_path: PathBuf,
|
||||
/// 资源条目
|
||||
pub entry: ResourceEntry,
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_resource_entry() {
|
||||
let entry = ResourceEntry {
|
||||
path: "test.bundle".to_string(),
|
||||
hash: "abc123".to_string(),
|
||||
size: 1024,
|
||||
resource_type: ResourceType::AssetBundle,
|
||||
};
|
||||
|
||||
assert_eq!(entry.path, "test.bundle");
|
||||
assert_eq!(entry.size, 1024);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,102 @@
|
||||
//! 翻译领域对象
|
||||
|
||||
use std::collections::HashMap;
|
||||
|
||||
/// 文本来源
|
||||
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
|
||||
pub struct TextSource {
|
||||
/// AssetBundle 名称
|
||||
pub asset_bundle: String,
|
||||
/// Asset 路径
|
||||
pub asset_path: String,
|
||||
/// 对象类型
|
||||
pub object_type: String,
|
||||
/// 字段路径
|
||||
pub field_path: Vec<String>,
|
||||
}
|
||||
|
||||
/// 文本上下文
|
||||
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
|
||||
pub struct TextContext {
|
||||
/// 场景
|
||||
pub scene: Option<String>,
|
||||
/// 角色
|
||||
pub character: Option<String>,
|
||||
/// 额外信息
|
||||
pub extra: HashMap<String, String>,
|
||||
}
|
||||
|
||||
/// 文本元数据
|
||||
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
|
||||
pub struct TextMetadata {
|
||||
/// 标签
|
||||
pub tags: Vec<String>,
|
||||
/// 优先级
|
||||
pub priority: u8,
|
||||
/// 备注
|
||||
pub notes: Option<String>,
|
||||
}
|
||||
|
||||
/// 提取的源文本
|
||||
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
|
||||
pub struct ExtractedText {
|
||||
/// 文本 ID
|
||||
pub id: String,
|
||||
/// 来源
|
||||
pub source: TextSource,
|
||||
/// 上下文
|
||||
pub context: TextContext,
|
||||
/// 内容
|
||||
pub content: String,
|
||||
/// 元数据
|
||||
pub metadata: TextMetadata,
|
||||
}
|
||||
|
||||
/// 源文本
|
||||
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
|
||||
pub struct SourceText {
|
||||
/// 文本 ID
|
||||
pub id: String,
|
||||
/// 内容
|
||||
pub content: String,
|
||||
}
|
||||
|
||||
/// 翻译状态
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
|
||||
pub enum TranslationStatus {
|
||||
/// 待翻译
|
||||
Pending,
|
||||
/// 已翻译
|
||||
Translated,
|
||||
/// 已审核
|
||||
Reviewed,
|
||||
}
|
||||
|
||||
/// 翻译后的文本
|
||||
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
|
||||
pub struct TranslatedText {
|
||||
/// 源文本 ID
|
||||
pub source_id: String,
|
||||
/// 翻译内容
|
||||
pub translation: String,
|
||||
/// 提供商
|
||||
pub provider: String,
|
||||
/// 置信度
|
||||
pub confidence: f32,
|
||||
/// 状态
|
||||
pub status: TranslationStatus,
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_source_text() {
|
||||
let text = SourceText {
|
||||
id: "test_001".to_string(),
|
||||
content: "Hello".to_string(),
|
||||
};
|
||||
assert_eq!(text.id, "test_001");
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user