From 81a62402ef6f8900ff092366121a9b7a4263ba52 Mon Sep 17 00:00:00 2001
From: Natsuu <natsukawa247@outlook.com>
Date: Fri, 27 Feb 2026 17:18:25 +0800
Subject: Restructure docs into manual/development and add implementation docs
 (#94)
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

## Summary by Sourcery

Restructure documentation into separate manual and development sections,
introduce detailed internal implementation docs for auth/Java/mod
loaders, and update site navigation, landing page links, and MDX tooling
(Mermaid, card styling) to match the new structure and tech stack.

Enhancements:
- Enable Mermaid rendering support in the docs app and add a reusable
Mermaid React component.
- Refine Docs page rendering by customizing Card styling and removing
redundant in-page titles/descriptions rendered by the layout.
- Align docs source configuration and routing comments with the new
manual-based default paths.

Documentation:
- Split user-facing docs under a new manual section and move contributor
content into a dedicated development section for both English and
Chinese.
- Add comprehensive internal implementation documentation covering
authentication, Java management, mod loader/version merging, event bus,
and architecture patterns in both English and Chinese.
- Update existing feature docs (mod loaders, Java, authentication) and
getting-started/troubleshooting pages to be more conceptual, pointing to
implementation docs for technical details.
- Refresh architecture docs to reflect the React/Zustand frontend stack
and add Mermaid-based architecture diagrams.
- Adjust navigation labels, home-page CTAs, and doc links to target the
new manual/development structure and routes.

---------

Co-authored-by: 简律纯 <i@jyunko.cn>
---
 .../docs/content/zh/development/implementation.mdx | 351 +++++++++++++++++++++
 1 file changed, 351 insertions(+)
 create mode 100644 packages/docs/content/zh/development/implementation.mdx

(limited to 'packages/docs/content/zh/development/implementation.mdx')

diff --git a/packages/docs/content/zh/development/implementation.mdx b/packages/docs/content/zh/development/implementation.mdx
new file mode 100644
index 0000000..d7586aa
--- /dev/null
+++ b/packages/docs/content/zh/development/implementation.mdx
@@ -0,0 +1,351 @@
+---
+title: 内部实现
+description: DropOut 核心功能的详细实现和技术规范
+---
+
+# 内部实现
+
+本页详细介绍了启动器各个核心模块的技术实现细节、数据结构和处理流程。
+
+## 1. 身份验证系统 (Authentication)
+
+身份验证链包含多个异步步骤，任何一步失败都会中断整个流程。DropOut 采用 Microsoft Device Code Flow 实现免重定向的安全登录。
+
+### 1.1 详细流程
+1.  **设备代码请求**: 
+    - 调用 `https://login.microsoftonline.com/consumers/oauth2/v2.0/devicecode`
+    - 获取用户验证码及验证 URL。
+2.  **令牌交换**: 轮询 `/oauth2/v2.0/token` 获取主访问令牌 (Access Token) 和刷新令牌 (Refresh Token)。
+3.  **Xbox Live 认证**: 获取 `Token` 和 `uhs` (User Hash)。
+4.  **XSTS 授权**: 重定向至 `rp://api.minecraftservices.com/`。
+5.  **Minecraft 登录**: 使用 `XBL3.0 x=<uhs>;<xsts_token>` 格式令牌换取最终的游戏 Access Token。
+
+### 1.2 账户存储与安全
+账户数据持久化在 `accounts.json` 中，包含账户类型及加密后的令牌信息：
+```json
+{
+  "active_account_uuid": "...",
+  "accounts": [
+    {
+      "type": "Microsoft",
+      "username": "...",
+      "uuid": "...",
+      "access_token": "...",
+      "refresh_token": "...",
+      "expires_at": 1234567890
+    },
+    { "type": "Offline", "username": "Player", "uuid": "..." }
+  ]
+}
+```
+**离线 UUID**: 使用基于用户名的确定性 UUID v3，确保本地存档和配置的一致性。
+
+```rust
+// core/auth.rs 实现详情
+pub fn generate_offline_uuid(username: &str) -> String {
+    let namespace = Uuid::NAMESPACE_OID;
+    Uuid::new_v3(&namespace, username.as_bytes()).to_string()
+}
+```
+
+### 1.3 身份验证相关接口
+| 命令 / 事件 | 类型 | 说明 |
+| :--- | :--- | :--- |
+| `start_microsoft_login` | Invoke | 启动设备流并返回验证码 |
+| `complete_microsoft_login` | Invoke | 轮询并完成全套身份验证链 |
+| `login_offline` | Invoke | 创建并切换至离线账户 |
+| `auth-progress` | Event | 实时上报认证进度（如 "Xbox Live Auth..."） |
+
+---
+
+## 2. Java 运行环境管理 (Java Runtime)
+
+### 2.1 目录与元数据
+Java 目录 (Catalog) 缓存了来自 Adoptium 的可用版本及其平台特定链接。
+-   **存储**: `java_catalog.json` 记录了各个版本的 SHA256 校验和及文件大小。
+
+```json
+// java_catalog.json 结构示例
+{
+  "releases": [
+    {
+      "major_version": 17,
+      "image_type": "jdk",
+      "version": "17.0.9+9",
+      "download_url": "...",
+      "checksum": "...",
+      "file_size": 123456789
+    }
+  ],
+  "cached_at": 1700000000
+}
+```
+
+-   **检测**: 通过对候选路径执行 `java -version` 命令，解析其 `stderr` 输出中的版本字符串和 64-Bit 标识。
+
+```rust
+// core/java.rs 检测逻辑
+fn check_java_installation(path: &PathBuf) -> Option<JavaInstallation> {
+    let mut cmd = Command::new(path);
+    cmd.arg("-version");
+    // 解析 stderr 输出中的 "version" 关键字信息
+}
+```
+
+### 2.2 自动安装逻辑
+1.  **下载**: 支持断点续传，大型文件通过分片并行下载。
+2.  **解压**: 针对不同操作系统处理压缩包（macOS 处理 .tar.gz 内部的 .app 结构，Windows 处理 .zip）。
+3.  **验证**: 下载后强制进行哈希校验，确保运行时环境的完整性。
+
+### 2.3 Java 管理相关接口
+| 命令 / 事件 | 类型 | 说明 |
+| :--- | :--- | :--- |
+| `detect_java` | Invoke | 扫描系统已安装的 Java 环境 |
+| `download_adoptium_java` | Invoke | 启动异步下载并自动解压配置 |
+| `cancel_java_download` | Invoke | 通过原子标志位取消当前的下载任务 |
+| `java-download-progress` | Event | 报告文件大小、速度、百分比和 ETA |
+
+---
+
+## 3. 游戏启动逻辑与 JVM 优化
+
+### 3.1 内存分配方案
+-   **Xmx & Xms**: 建议将初始内存与最大内存设为一致。
+-   **策略**: 启动器会自动根据系统总内存和 Java 架构提示用户最优分配，且启动器生成的参数具有最高优先级。
+
+### 3.2 G1GC 优化策略
+针对 1.17+ 版本及高负载模组环境，DropOut 默认注入精简的 G1GC 参数链：
+```bash
+-XX:+UseG1GC -XX:+ParallelRefProcEnabled -XX:MaxGCPauseMillis=200 
+-XX:+UnlockExperimentalVMOptions -XX:+DisableExplicitGC 
+```
+
+---
+
+## 4. 模组加载机制 (Mod Loaders)
+
+### 4.1 版本合并 (Inheritance)
+模组加载器通过 `inheritsFrom` 字段链接原版 Minecraft 版本 JSON。
+
+```json
+// 典型的 Fabric 版本配置 (部分)
+{
+  "id": "fabric-loader-0.15.0-1.20.4",
+  "inheritsFrom": "1.20.4",
+  "mainClass": "net.fabricmc.loader.impl.launch.knot.KnotClient",
+  "libraries": [
+    {
+      "name": "net.fabricmc:fabric-loader:0.15.0",
+      "url": "https://maven.fabricmc.net/"
+    }
+  ]
+}
+```
+
+启动阶段执行以下合并：
+1.  **库优先级**: 加载器自身的库（如 Fabric Loader）排在原版库之前。
+2.  **主类覆盖**: `mainClass` 始终取自子级定义（即模组加载器的入口，如 Fabric 的 `KnotClient`）。
+3.  **参数链**: 合并 `jvm` 和 `game` 参数数组，自动剔除不适用的系统规则。
+
+```rust
+// core/version_merge.rs 合并核心实现
+pub fn merge_versions(child: GameVersion, parent: GameVersion) -> GameVersion {
+    let mut merged_libraries = child.libraries;
+    merged_libraries.extend(parent.libraries);
+    // 合并参数逻辑并返回新的 GameVersion 实例
+}
+```
+
+### 4.2 库路径解析 (Maven)
+启动器实现了完整的 Maven 路径转换逻辑：
+`group:artifact:version` → `group_path/artifact/version/artifact-version.jar`
+
+```rust
+// core/maven.rs 坐标转换路径逻辑
+pub fn to_path(&self) -> String {
+    let group_path = self.group.replace('.', "/");
+    format!("{}/{}/{}/{}-{}.{}", 
+        group_path, self.artifact, self.version, 
+        self.artifact, self.version, self.extension
+    )
+}
+```
+
+### 4.3 模组安装接口
+启动器根据不同加载器的特性采用差异化安装策略。
+
+#### Forge 安装逻辑
+对于 Forge，DropOut 会下载官方 Installer 并通过子进程调用 Java 运行标准安装程序，确保这一过程与官方流程完全一致（包括字节码补丁生成）。
+
+```rust
+// core/forge.rs 调用官方安装器 (简化示例)
+Command::new(java_path)
+    .args(&[
+        "-jar", 
+        installer_path.to_str().unwrap(), 
+        "--installClient", 
+        game_dir.to_str().unwrap()
+    ])
+    .output()?;
+```
+
+| 命令 / 事件 | 类型 | 说明 |
+| :--- | :--- | :--- |
+| `install_fabric` | Invoke | 下载 Fabric 库并生成继承 JSON |
+| `install_forge` | Invoke | 运行 Forge Installer 并执行字节码打桩 |
+| `mod-loader-progress` | Event | 报告安装阶段（如 "processing", "complete"） |
+
+---
+
+## 5. 通讯与监控系统
+
+### 5.1 事件总线 (Event Bus)
+后端通过 Tauri 的 `Window` 实例向上层发送异步脉冲。
+
+```rust
+// 后端 emit_log! 宏简化日志外发
+macro_rules! emit_log {
+    ($window:expr, $msg:expr) => {
+        let _ = $window.emit("launcher-log", $msg);
+        println!("[Launcher] {}", $msg);
+    };
+}
+```
+
+-   **`launcher-log`**: 通用的控制台输出流，用于全局操作轨迹记录。
+-   **`game-stdout` / `game-stderr`**: 捕获游戏子进程的标准输出与错误，通过独立线程实时回传前端。
+
+```typescript
+// 前端监听示例 (Svelte 5)
+import { listen } from "@tauri-apps/api/event";
+
+const unlisten = await listen("launcher-log", (event) => {
+    logStore.addLine(event.payload);
+});
+```
+
+-   **`version-installed`**: 异步任务完成后通知 UI 更新版本列表状态。
+
+### 5.2 启动日志脱敏
+为防止敏感信息泄露至第三方日志平台，启动器在记录启动指令前会对令牌进行遮蔽。
+
+```rust
+// 基于 main.rs 的参数遮蔽逻辑 (部分)
+let masked_args: Vec<String> = args.iter().enumerate().map(|(i, arg)| {
+    if i > 0 && (args[i-1] == "--accessToken" || args[i-1] == "--uuid") {
+        "***".to_string()
+    } else {
+        arg.clone()
+    }
+}).collect();
+```
+
+---
+
+## 6. 架构与开发规范
+
+### 6.1 核心架构模式
+
+#### 后端命令模式 (Tauri)
+所有后端功能均封装为异步 Command，并通过 `State` 注入全局状态。
+
+1. **定义命令**:
+```rust
+#[tauri::command]
+async fn start_game(
+    window: Window,
+    auth_state: State<'_, AccountState>,
+    config_state: State<'_, ConfigState>
+) -> Result<String, String> {
+    emit_log!(window, "Starting game launch...");
+    // 业务逻辑...
+    Ok("Success".into())
+}
+```
+
+2. **注册命令 (main.rs)**:
+```rust
+tauri::Builder::default()
+    .invoke_handler(tauri::generate_handler![start_game, ...])
+```
+
+3. **前端调用**:
+```typescript
+import { invoke } from "@tauri-apps/api/core";
+// 参数名需与 Rust 函数参数保持蛇形/驼峰对应
+const result = await invoke("start_game", { versionId: "1.20.4" });
+```
+
+#### 错误处理模式
+所有 Tauri 命令统一返回 `Result<T, String>`，其中 Err 类型固定为 String，以便前端直接展示错误信息。
+
+```rust
+// 统一使用 map_err 将错误转换为 String
+.await
+.map_err(|e| e.to_string())?;
+
+// 前端捕获
+try {
+    await invoke("...")
+} catch (e) {
+    // e 即为 Rust 返回的错误字符串
+    console.error(e); 
+}
+```
+
+#### 前端状态管理 (Svelte 5 Runes)
+前端全线采用 Svelte 5 的 `Runes` 系统 (`$state`, `$effect`) 替代旧版的 `writable` stores。
+
+```typescript
+// ui/src/stores/auth.svelte.ts
+export class AuthState {
+  // 使用 $state 定义响应式数据
+  currentAccount = $state<Account | null>(null);
+  isLoginModalOpen = $state(false);
+
+  constructor() {
+    // 初始化逻辑
+  }
+}
+
+// 导出单例用于全局访问
+export const authState = new AuthState();
+```
+
+#### 前端视图路由 (Manual Routing)
+DropOut 不使用常规的 URL 路由，而是通过全局状态管理当前激活的视图组件。
+
+```typescript
+// ui/src/stores/ui.svelte.ts
+export class UIState {
+    activeView = $state("home"); // "home" | "versions" | "settings"
+    
+    setView(view: string) {
+        this.activeView = view;
+    }
+}
+```
+
+```svelte
+<!-- App.svelte -->
+<script>
+    import { uiState } from "./stores/ui.svelte";
+</script>
+
+{#if uiState.activeView === "home"}
+    <HomeView />
+{:else if uiState.activeView === "settings"}
+    <SettingsView />
+{/if}
+```
+
+### 6.2 开发最佳实践
+1.  **静默刷新**: 在调用 `start_game` 前检查 `expires_at`，若过期则调用 `refresh_full_auth`。
+2.  **UA 伪装**: 微软认证 WAF 会拦截空 UA 请求，务必在 `reqwest` 客户端中模拟真实 UA。
+3.  **日志脱敏**: 启动日志中需屏蔽 `--accessToken` 和 `--uuid` 等敏感参数值。
+
+### 6.3 未来路线图 (Roadmap)
+-   **账户多端同步**: 探索 OS 级加密存储方案以替代现有明文 `accounts.json`。
+-   **自动依赖解析**: 安装模组时自动解析并下载 Modrinth/CurseForge 上的前置库。
+-   **智能冲突检测**: 启动前扫描 `mods/` 文件夹，识别潜在的类冲突或版本不匹配。
+-   **配置文件共享**: 支持一键导出/导入完整的实例配置包（Modpack）。
-- 
cgit v1.2.3-70-g09d2

