打开/关闭菜单
打开/关闭外观设置菜单
打开/关闭个人菜单
未登录
未登录用户的IP地址会在进行任意编辑后公开展示。

Koring-launcher/about-devmd:修订间差异

来自Lingke支持
创建页面,内容为“# Koring Launcher — 开发文档 ## 技术栈 | 层 | 技术 | |---|---| | Frontend | React 19 + Vite 7 + TypeScript | | UI | Tailwind CSS v4 + shadcn/ui (base-ui) | | 状态管理 | Zustand | | Backend | Rust / Tauri 2 | | Sidecar | Node.js / TypeScript / @xmcl/* | | 配置存储 | YAML (serde_yaml) + Windows Registry | | 包管理 | pnpm | | 目标平台 | ARM64 Windows (`aarch64-pc-windows-msvc`) | ## 快速命令 ```bash pnpm dev # 前…”
 
无编辑摘要
 
第1行: 第1行:
# Koring Launcher — 开发文档
= Koring Launcher — 开发文档 =


## 技术栈
= 技术栈 =
{| class="wikitable"
!层
!技术
|-
|Frontend
|React 19 + Vite 7 + TypeScript
|-
|UI
|Tailwind CSS v4 + shadcn/ui (base-ui)
|-
|状态管理
|Zustand
|-
|Backend
|Rust / Tauri 2
|-
|Sidecar
|Node.js / TypeScript / @xmcl/*
|-
|配置存储
|YAML (serde_yaml) + Windows Registry
|-
|包管理
|pnpm
|-
|目标平台
|ARM64 Windows (<code>aarch64-pc-windows-msvc</code>)
|}


| 层 | 技术 |
== 快速命令 ==
|---|---|
pnpm dev                # 前端 dev server (port 1420)
| Frontend | React 19 + Vite 7 + TypeScript |
pnpm dev:t              # 前端 + Rust dev (需 VS 环境)
| UI | Tailwind CSS v4 + shadcn/ui (base-ui) |
./dev-vs.cmd            # VS ARM64 环境启动 dev
| 状态管理 | Zustand |
pnpm build              # 生产构建 (switch-icon run + tsc + vite build)
| Backend | Rust / Tauri 2 |
pnpm build:beta        # Beta 构建 (switch-icon beta + tsc + vite build --mode beta)
| Sidecar | Node.js / TypeScript / @xmcl/* |
./build-vs.cmd          # Rust 编译 (production, NSIS 打包)
| 配置存储 | YAML (serde_yaml) + Windows Registry |
./build-vs.cmd --mode beta  # Rust 编译 (beta, 跳过打包)
| 包管理 | pnpm |
| 目标平台 | ARM64 Windows (`aarch64-pc-windows-msvc`) |


## 快速命令
== 构建模式 ==
{| class="wikitable"
!模式
!<code>VITE_BUILD_MODE</code>
!图标
!Badge
!说明
|-
|dev
|<code>"dev"</code>
|<code>dev.png</code>
|🟢 DEV
|开发预览版
|-
|beta
|<code>"beta"</code>
|<code>beta.png</code>
|🟡 BETA
|测试版
|-
|run
|<code>"run"</code>
|<code>run.png</code>
|无
|正式版
|}
模式由 <code>src/lib/mode.ts</code> 导出 <code>BUILD_MODE</code>, <code>isDev</code>, <code>isBeta</code>, <code>isRun</code>。


```bash
== 环境变量 (.env.*) ==
pnpm dev                # 前端 dev server (port 1420)
VITE_BUILD_MODE=dev|beta|run
pnpm dev:t              # 前端 + Rust dev (需 VS 环境)
VITE_APP_ICON=/dev.png|/beta.png|/run.png
./dev-vs.cmd            # VS ARM64 环境启动 dev
VITE_START_POP=true|false             # 启动弹窗开关
pnpm build             # 生产构建 (switch-icon run + tsc + vite build)
VITE_START_POP_TITLE="..."            # 弹窗标题
pnpm build:beta        # Beta 构建 (switch-icon beta + tsc + vite build --mode beta)
VITE_START_POP_INFO="..."              # 弹窗内容
./build-vs.cmd          # Rust 编译 (production, NSIS 打包)
VITE_START_POP_BOUTTON="..."          # 弹窗按钮文字
./build-vs.cmd --mode beta  # Rust 编译 (beta, 跳过打包)
----
```


## 构建模式
== 配置存储架构 ==


| 模式 | `VITE_BUILD_MODE` | 图标 | Badge | 说明 |
=== 概览 ===
|---|---|---|---|---|
{| class="wikitable"
| dev | `"dev"` | `dev.png` | 🟢 DEV | 开发预览版 |
!数据类型
| beta | `"beta"` | `beta.png` | 🟡 BETA | 测试版 |
!存储位置
| run | `"run"` | `run.png` | 无 | 正式版 |
!格式
!说明
|-
|用户设置
|程序目录 <code>Koring.yml</code>
|YAML
|所有可配置项
|-
|账户凭证
|Windows Registry <code>HKCU\Software\KoringLauncher</code>
|REG_SZ
|token/xboxProfile
|-
|实例配置
|实例目录 <code>koring-instance.json</code>
|JSON
|per-instance
|-
|任务历史
|localStorage <code>koring-task-history</code>
|JSON
|临时,max 50
|}


模式由 `src/lib/mode.ts` 导出 `BUILD_MODE`, `isDev`, `isBeta`, `isRun`。
=== Koring.yml 结构 ===
version: 1
theme:
  darkMode: auto          # auto | light | dark
  parallax: true
a11y:
  reduceMotion: false
  reduceTransparency: false
  highContrast: false
  contentBlurOpacity: 50  # 0-100
background:
  bgType: image          # image | color
  image: /background.png
  blur: 0                # 0-20
  opacity: 100            # 0-100
game:
  gameDir: .minecraft
  resourceDir: ""
  savesDir: ""
  instancesDir: .minecraft/instances
java:
  javaPath: ""
  memMode: auto          # auto | custom
  memGB: 4                # 1-16
  gc: auto                # auto | zgc | g1
  jvmArgs: ""
advanced:
  afterLaunch: close      # close | minimize | keep
  winMode: default        # default | fullscreen | custom
  customWidth: 854
  customHeight: 480
  gameArgs: ""
  preLaunchCmd: ""
  debugMode: false
download:
  fileSource: mirror      # mirror | official | official-only
  versionSource: mirror
  threads: 16            # 1-64
  speedLimit: 0          # KB/s, 0=不限速
network:
  securityId:
    enabled: false
    authUrl: ""


## 环境变量 (.env.*)
=== 注册表结构 ===
<code>HKCU\Software\KoringLauncher
  └─ auth
        ├─ username      (REG_SZ)
        ├─ uuid          (REG_SZ)
        ├─ accessToken  (REG_SZ)
        ├─ refreshToken  (REG_SZ)
        └─ xboxProfile  (REG_SZ, JSON string)</code>


```env
=== 向上兼容策略 ===
VITE_BUILD_MODE=dev|beta|run
VITE_APP_ICON=/dev.png|/beta.png|/run.png
VITE_START_POP=true|false              # 启动弹窗开关
VITE_START_POP_TITLE="..."            # 弹窗标题
VITE_START_POP_INFO="..."              # 弹窗内容
VITE_START_POP_BOUTTON="..."          # 弹窗按钮文字
```


---
# 版本号 — <code>version</code> 字段,每次结构变更递增
# 默认值填充 — 加载时缺失字段自动补全,不丢数据
# 迁移函数 — <code>migrate_v0_to_v1()</code> 等,按版本链执行
# 未知字段保留 — YAML 解析器保留不认识的字段
# Debounce 写入 — 300ms debounce 避免频繁 IO


## 配置存储架构
=== Rust 实现 ===
新文件:


### 概览
* <code>src-tauri/src/config.rs</code> — <code>AppConfig</code> 结构体、<code>load_config()</code>、<code>save_config()</code>、<code>merge_defaults()</code>、<code>migrate()</code>
* <code>src-tauri/src/registry.rs</code> — <code>read_auth()</code>、<code>write_auth()</code>、<code>delete_auth()</code>


| 数据类型 | 存储位置 | 格式 | 说明 |
Tauri 命令:
|---------|---------|------|------|
| 用户设置 | 程序目录 `Koring.yml` | YAML | 所有可配置项 |
| 账户凭证 | Windows Registry `HKCU\Software\KoringLauncher` | REG_SZ | token/xboxProfile |
| 实例配置 | 实例目录 `koring-instance.json` | JSON | per-instance |
| 任务历史 | localStorage `koring-task-history` | JSON | 临时,max 50 |


### Koring.yml 结构
* <code>get_config</code> → 返回 <code>AppConfig</code> JSON
* <code>save_config(cfg)</code> → 写入 <code>Koring.yml</code>
* <code>get_auth</code> → 从注册表读取 <code>AuthData</code>
* <code>save_auth(auth)</code> → 写入注册表
* <code>delete_auth_cmd</code> → 删除注册表认证数据


```yaml
=== 前端实现 ===
version: 1
新文件:


theme:
* <code>src/api/config.ts</code> — <code>getConfig()</code>、<code>saveConfig()</code> 类型定义
  darkMode: auto          # auto | light | dark
* <code>src/api/auth-registry.ts</code> — <code>getAuth()</code>、<code>saveAuth()</code>、<code>deleteAuth()</code>
  parallax: true
* <code>src/stores/configStore.ts</code> — 统一配置 Zustand store


a11y:
configStore 接口:
  reduceMotion: false
useConfigStore.getState().config        // 完整配置
  reduceTransparency: false
useConfigStore.getState().loaded        // 是否已加载
  highContrast: false
useConfigStore.getState().init()        // 从 Rust 加载
  contentBlurOpacity: 50 # 0-100
useConfigStore.getState().setTheme({...})  // 部分更新 + debounce 写回
useConfigStore.getState().setA11y({...})
  useConfigStore.getState().setBackground({...})
useConfigStore.getState().setGame({...})
useConfigStore.getState().setJava({...})
useConfigStore.getState().setAdvanced({...})
useConfigStore.getState().setDownload({...})
useConfigStore.getState().setNetwork({...})
Store 委托模式: themeStore / a11yStore / backgroundStore / authStore 都是 configStore 的薄包装层:


background:
* 读取时从 <code>configStore.config.*</code> 同步
  bgType: image          # image | color
* 写入时通过各自的 <code>set*()</code> 同时更新本地状态和 configStore
  image: /background.png
* 提供 <code>sync*FromConfig()</code> 函数在 App 启动时同步
  blur: 0                # 0-20
  opacity: 100            # 0-100


game:
App 启动流程:
  gameDir: .minecraft
<code>configStore.init() → syncThemeFromConfig() → syncA11yFromConfig() → syncBackgroundFromConfig() → authStore.initFromRegistry()</code>
  resourceDir: ""
----
  savesDir: ""
  instancesDir: .minecraft/instances


java:
== 项目结构 ==
   javaPath: ""
<code>koring-launcher/
   memMode: auto           # auto | custom
├── src/                        # 前端源码
   memGB: 4                # 1-16
│  ├── App.tsx                # 路由入口 + configStore 初始化
   gc: auto               # auto | zgc | g1
│  ├── index.css              # 全局样式 + CSS 变量 + 动画
  jvmArgs: ""
│  ├── layouts/
│  │  └── RootLayout.tsx      # 三层布局: BackgroundLayer + ContentLayer + SystemLayer
│  ├── components/
│  │  ├── background/
│  │  │  └── BackgroundLayer.tsx    # 全屏背景层 + 视差 + 强内容遮罩
│  │  ├── system/
│  │  │  ├── SystemLayer.tsx        # 系统层容器 (z-[100])
│  │  │  ├── TitleBar.tsx          # 自定义标题栏 (40px, 胶囊菜单/返回按钮)
│  │  │  └── WindowControls.tsx    # 窗口按钮 + DEV/BETA badge + TaskButton
│  │  ├── splash/
│  │  │  └── Splash.tsx            # 启动动画 (独立窗口, HTML+React)
│  │  ├── silk/
│  │  │  └── Silk.tsx              # WebGL 丝绸着色器 (Three.js)
│  │  ├── task/
│  │  │  ├── TaskButton.tsx        # 标题栏任务指示器 (SVG 圆弧动画)
│  │  │  └── TaskCard.tsx          # 单个任务卡片 (进度条+日志)
│  │  ├── ui/                        # shadcn/ui 组件
│  │  │  ├── sheet.tsx, button.tsx, switch.tsx, slider.tsx
│  │  │  ├── progress.tsx, badge.tsx, separator.tsx
  │  │  ├── label.tsx, radio-group.tsx, alert-dialog.tsx
│  │  ├── VersionCard.tsx            # 版本/更新卡片 (Silk 背景+毛玻璃)
│  │  ├── UnderConstruction.tsx      # "装修中" 占位组件
│  │   └── StartupPopup.tsx           # 启动弹窗 (环境变量控制)
│  ├── stores/
│  │  ├── configStore.ts    # 统一配置 store (→ Koring.yml)
│  │  ├── themeStore.ts      # 主题 (委托 configStore)
│  │  ├── a11yStore.ts      # 无障碍 (委托 configStore)
│  │  ├── backgroundStore.ts # 背景 (委托 configStore)
│  │  ├── authStore.ts      # 认证 (→ Registry)
│  │  ├── routeStore.ts      # 路由 (历史栈)
│  │  ├── taskStore.ts      # 任务队列 (localStorage)
│  │  ├── instanceStore.ts  # 实例管理
│  │  ├── installStore.ts    # Minecraft 安装
│  │  ├── launchStore.ts    # 游戏启动
│  │  ├── modsStore.ts      # Mod 搜索
│  │  ├── updateStore.ts    # 应用更新
│  │  └── devStore.ts        # 开发者调试
│  ├── api/
│  │  ├── config.ts          # AppConfig 读写 (→ Tauri invoke)
│  │  ├── auth-registry.ts  # AuthData 读写 (→ Registry)
│  │  ├── instance.ts        # 实例 API
│  │  ├── auth.ts            # 登录 API
│  │  ├── sidecar.ts        # 通用 sidecar IPC
│  │  └── ...
│  ├── hooks/
│  │  └── useTheme.ts        # 同步 darkMode → .dark class
│  ├── lib/
│  │  ├── mode.ts            # BUILD_MODE 常量
│  │  └── utils.ts            # cn() 工具函数
│  ├── types/
│  │  └── task.ts            # Task 类型定义
  └── pages/                  # 页面组件
├── src-tauri/                  # Rust 后端
  ├── Cargo.toml              # 依赖: serde, serde_json, serde_yaml, winreg
│  ├── tauri.conf.json        # 窗口配置 + Bundle + Updater
│  ├── capabilities/default.json  # 权限声明
│  ├── src/
│  │  ├── lib.rs              # 插件注册 + splash/main + 命令注册
│  │  ├── config.rs          # AppConfig 读写 + 迁移 + 默认值
│  │  ├── registry.rs        # Windows Registry 读写
│  │  ├── commands/mod.rs    # Tauri 命令 (→ sidecar + config + auth)
│  │  └── sidecar.rs          # Sidecar 进程管理
│  └── binaries/              # Sidecar 二进制文件
├── sidecar/                    # Node.js Sidecar
│  └── src/
│      ├── handlers/          # 10 个 handler
│      ├── utils/paths.ts      # 路径工具 + InstanceConfig
│      └── protocol/types.ts  # IPC 消息类型
├── splash.html                # 启动动画 HTML 入口
├── build-vs.cmd               # VS 环境编译脚本
└── dev-vs.cmd                  # VS 环境开发脚本</code>
----


advanced:
== 页面路由 ==
  afterLaunch: close      # close | minimize | keep
  winMode: default        # default | fullscreen | custom
  customWidth: 854
  customHeight: 480
  gameArgs: ""
  preLaunchCmd: ""
  debugMode: false


download:
=== 顶层路由 (标题栏可见) ===
  fileSource: mirror      # mirror | official | official-only
{| class="wikitable"
  versionSource: mirror
!Key
  threads: 16            # 1-64
!Label
  speedLimit: 0          # KB/s, 0=不限速
!组件
!说明
|-
|<code>home</code>
|首页
|<code>pages/home/index.tsx</code>
|StartCard 启动组件
|-
|<code>store</code>
|资源
|<code>pages/store/index.tsx</code>
|🚧 装修中
|-
|<code>today</code>
|资讯
|<code>pages/today/index.tsx</code>
|🚧 装修中
|-
|<code>play-link</code>
|联机
|<code>pages/play-link/index.tsx</code>
|🚧 装修中
|-
|<code>setting</code>
|设置
|<code>pages/setting/index.tsx</code>
|侧边栏 + 内容区
|}


network:
=== 隐藏路由 ===
  securityId:
{| class="wikitable"
    enabled: false
!Key
    authUrl: ""
!Label
```
!组件
|-
|<code>task-queue</code>
|任务队列
|<code>pages/task-queue.tsx</code>
|-
|<code>debug</code>
|调试
|<code>pages/debug/index.tsx</code>
|-
|<code>debug-splash</code>
|启动动画调试
|<code>pages/debug/splash-debug.tsx</code>
|-
|<code>debug-display</code>
|显示效果调试
|<code>pages/debug/display-debug.tsx</code>
|-
|<code>debug-version-card</code>
|版本卡片调试
|<code>pages/debug/version-card-debug.tsx</code>
|-
|<code>debug-task</code>
|任务队列调试
|<code>pages/debug/task-debug.tsx</code>
|}


### 注册表结构
=== 路由导航 (历史栈) ===
路由使用动态历史栈替代静态 parentMap。每次 <code>navigate()</code> 压入历史,<code>goBack()</code> 弹出。
----


```
== Zustand Stores ==
HKCU\Software\KoringLauncher
  └─ auth
      ├─ username      (REG_SZ)
      ├─ uuid          (REG_SZ)
      ├─ accessToken  (REG_SZ)
      ├─ refreshToken  (REG_SZ)
      └─ xboxProfile  (REG_SZ, JSON string)
```


### 向上兼容策略
=== configStore (统一配置中心) ===
所有用户设置的单一数据源。读写通过 Tauri invoke 与 <code>Koring.yml</code> 同步。
config: AppConfig      // 完整配置
loaded: boolean        // 是否已从 Rust 加载
init()                  // 从 Rust 加载配置
setTheme(patch)        // 部分更新 + debounce 300ms 写回
setA11y(patch)
setBackground(patch)
setGame(patch)
setJava(patch)
setAdvanced(patch)
setDownload(patch)
setNetwork(patch)


1. **版本号** — `version` 字段,每次结构变更递增
=== themeStore (委托 configStore) ===
2. **默认值填充** — 加载时缺失字段自动补全,不丢数据
darkMode: "auto" | "light" | "dark"
3. **迁移函数** — `migrate_v0_to_v1()` 等,按版本链执行
parallax: boolean
4. **未知字段保留** — YAML 解析器保留不认识的字段
setDarkMode(mode)       // 更新 DOM + configStore
5. **Debounce 写入** — 300ms debounce 避免频繁 IO
setParallax(v)          // configStore
syncThemeFromConfig()  // 启动时从 config 同步


### Rust 实现
=== a11yStore (委托 configStore) ===
reduceMotion, reduceTransparency, highContrast, contentBlurOpacity
syncA11yFromConfig()


**新文件:**
=== backgroundStore (委托 configStore) ===
- `src-tauri/src/config.rs` — `AppConfig` 结构体、`load_config()`、`save_config()`、`merge_defaults()`、`migrate()`
type: "image" | "color", image, blur, opacity
- `src-tauri/src/registry.rs` — `read_auth()`、`write_auth()`、`delete_auth()`
setImage / setColor / setBlur / setOpacity / reset
syncBackgroundFromConfig()


**Tauri 命令:**
=== authStore (委托 Registry) ===
- `get_config` → 返回 `AppConfig` JSON
user: AuthResult | null
- `save_config(cfg)` → 写入 `Koring.yml`
initFromRegistry()     // 从 Windows Registry 加载
- `get_auth` → 从注册表读取 `AuthData`
loginOffline(username)  // 通过 sidecar + 保存到 registry
- `save_auth(auth)` → 写入注册表
logout()               // 清除 registry
- `delete_auth_cmd` → 删除注册表认证数据


### 前端实现
=== routeStore (历史栈导航) ===
 
  current: RouteKey
**新文件:**
history: RouteKey[]    // 导航历史栈
- `src/api/config.ts` — `getConfig()`、`saveConfig()` 类型定义
navigate(key)          // 压入历史
- `src/api/auth-registry.ts` — `getAuth()`、`saveAuth()`、`deleteAuth()`
goBack()                // 弹出历史
- `src/stores/configStore.ts` — 统一配置 Zustand store
 
**configStore 接口:**
```ts
useConfigStore.getState().config        // 完整配置
useConfigStore.getState().loaded        // 是否已加载
useConfigStore.getState().init()        // 从 Rust 加载
useConfigStore.getState().setTheme({...})  // 部分更新 + debounce 写回
useConfigStore.getState().setA11y({...})
useConfigStore.getState().setBackground({...})
useConfigStore.getState().setGame({...})
useConfigStore.getState().setJava({...})
useConfigStore.getState().setAdvanced({...})
useConfigStore.getState().setDownload({...})
useConfigStore.getState().setNetwork({...})
```
 
**Store 委托模式:**
themeStore / a11yStore / backgroundStore / authStore 都是 configStore 的薄包装层:
- 读取时从 `configStore.config.*` 同步
- 写入时通过各自的 `set*()` 同时更新本地状态和 configStore
- 提供 `sync*FromConfig()` 函数在 App 启动时同步
 
**App 启动流程:**
```
configStore.init() → syncThemeFromConfig() → syncA11yFromConfig() → syncBackgroundFromConfig() → authStore.initFromRegistry()
```
 
---
 
## 项目结构
 
```
koring-launcher/
├── src/                        # 前端源码
│  ├── App.tsx                # 路由入口 + configStore 初始化
│  ├── index.css              # 全局样式 + CSS 变量 + 动画
│  ├── layouts/
│  │  └── RootLayout.tsx      # 三层布局: BackgroundLayer + ContentLayer + SystemLayer
│  ├── components/
│  │  ├── background/
│  │  │  └── BackgroundLayer.tsx    # 全屏背景层 + 视差 + 强内容遮罩
│  │  ├── system/
│  │  │  ├── SystemLayer.tsx        # 系统层容器 (z-[100])
│  │  │  ├── TitleBar.tsx          # 自定义标题栏 (40px, 胶囊菜单/返回按钮)
│  │  │  └── WindowControls.tsx    # 窗口按钮 + DEV/BETA badge + TaskButton
│  │  ├── splash/
│  │  │  └── Splash.tsx            # 启动动画 (独立窗口, HTML+React)
│  │  ├── silk/
│  │  │  └── Silk.tsx              # WebGL 丝绸着色器 (Three.js)
│  │  ├── task/
│  │  │  ├── TaskButton.tsx        # 标题栏任务指示器 (SVG 圆弧动画)
│  │  │  └── TaskCard.tsx          # 单个任务卡片 (进度条+日志)
│  │  ├── ui/                        # shadcn/ui 组件
│  │  │  ├── sheet.tsx, button.tsx, switch.tsx, slider.tsx
│  │  │  ├── progress.tsx, badge.tsx, separator.tsx
│  │  │  ├── label.tsx, radio-group.tsx, alert-dialog.tsx
│  │  ├── VersionCard.tsx            # 版本/更新卡片 (Silk 背景+毛玻璃)
│  │  ├── UnderConstruction.tsx      # "装修中" 占位组件
│  │  └── StartupPopup.tsx          # 启动弹窗 (环境变量控制)
│  ├── stores/
│  │  ├── configStore.ts    # 统一配置 store (→ Koring.yml)
│  │  ├── themeStore.ts      # 主题 (委托 configStore)
│  │  ├── a11yStore.ts      # 无障碍 (委托 configStore)
│  │  ├── backgroundStore.ts # 背景 (委托 configStore)
│  │  ├── authStore.ts      # 认证 (→ Registry)
│  │  ├── routeStore.ts      # 路由 (历史栈)
│  │  ├── taskStore.ts      # 任务队列 (localStorage)
│  │  ├── instanceStore.ts  # 实例管理
│  │  ├── installStore.ts    # Minecraft 安装
│  │  ├── launchStore.ts    # 游戏启动
│  │  ├── modsStore.ts      # Mod 搜索
│  │  ├── updateStore.ts    # 应用更新
│  │  └── devStore.ts        # 开发者调试
│  ├── api/
│  │  ├── config.ts          # AppConfig 读写 (→ Tauri invoke)
│  │  ├── auth-registry.ts  # AuthData 读写 (→ Registry)
│  │  ├── instance.ts        # 实例 API
│  │  ├── auth.ts            # 登录 API
│  │  ├── sidecar.ts        # 通用 sidecar IPC
│  │  └── ...
│  ├── hooks/
│  │  └── useTheme.ts        # 同步 darkMode → .dark class
│  ├── lib/
│  │  ├── mode.ts            # BUILD_MODE 常量
│  │  └── utils.ts            # cn() 工具函数
│  ├── types/
│  │  └── task.ts            # Task 类型定义
│  └── pages/                  # 页面组件
├── src-tauri/                  # Rust 后端
│  ├── Cargo.toml              # 依赖: serde, serde_json, serde_yaml, winreg
│  ├── tauri.conf.json        # 窗口配置 + Bundle + Updater
│  ├── capabilities/default.json  # 权限声明
│  ├── src/
│  │  ├── lib.rs              # 插件注册 + splash/main + 命令注册
│  │  ├── config.rs          # AppConfig 读写 + 迁移 + 默认值
│  │  ├── registry.rs        # Windows Registry 读写
│  │  ├── commands/mod.rs    # Tauri 命令 (→ sidecar + config + auth)
│  │  └── sidecar.rs          # Sidecar 进程管理
│  └── binaries/              # Sidecar 二进制文件
├── sidecar/                    # Node.js Sidecar
│  └── src/
│      ├── handlers/          # 10 个 handler
│      ├── utils/paths.ts      # 路径工具 + InstanceConfig
│      └── protocol/types.ts  # IPC 消息类型
├── splash.html                # 启动动画 HTML 入口
├── build-vs.cmd                # VS 环境编译脚本
└── dev-vs.cmd                  # VS 环境开发脚本
```
 
---
 
## 页面路由
 
### 顶层路由 (标题栏可见)
 
| Key | Label | 组件 | 说明 |
|---|---|---|---|
| `home` | 首页 | `pages/home/index.tsx` | StartCard 启动组件 |
| `store` | 资源 | `pages/store/index.tsx` | 🚧 装修中 |
| `today` | 资讯 | `pages/today/index.tsx` | 🚧 装修中 |
| `play-link` | 联机 | `pages/play-link/index.tsx` | 🚧 装修中 |
| `setting` | 设置 | `pages/setting/index.tsx` | 侧边栏 + 内容区 |
 
### 隐藏路由
 
| Key | Label | 组件 |
|---|---|---|
| `task-queue` | 任务队列 | `pages/task-queue.tsx` |
| `debug` | 调试 | `pages/debug/index.tsx` |
| `debug-splash` | 启动动画调试 | `pages/debug/splash-debug.tsx` |
| `debug-display` | 显示效果调试 | `pages/debug/display-debug.tsx` |
| `debug-version-card` | 版本卡片调试 | `pages/debug/version-card-debug.tsx` |
| `debug-task` | 任务队列调试 | `pages/debug/task-debug.tsx` |
 
### 路由导航 (历史栈)
 
路由使用动态历史栈替代静态 parentMap。每次 `navigate()` 压入历史,`goBack()` 弹出。
 
---
 
## Zustand Stores
 
### configStore (统一配置中心)
 
所有用户设置的单一数据源。读写通过 Tauri invoke 与 `Koring.yml` 同步。
 
```ts
config: AppConfig      // 完整配置
loaded: boolean        // 是否已从 Rust 加载
 
init()                  // 从 Rust 加载配置
setTheme(patch)        // 部分更新 + debounce 300ms 写回
setA11y(patch)
setBackground(patch)
setGame(patch)
setJava(patch)
setAdvanced(patch)
setDownload(patch)
setNetwork(patch)
```
 
### themeStore (委托 configStore)
 
```ts
darkMode: "auto" | "light" | "dark"
parallax: boolean
setDarkMode(mode)      // 更新 DOM + configStore
setParallax(v)          // configStore
syncThemeFromConfig()  // 启动时从 config 同步
```
 
### a11yStore (委托 configStore)
 
```ts
reduceMotion, reduceTransparency, highContrast, contentBlurOpacity
syncA11yFromConfig()
```
 
### backgroundStore (委托 configStore)
 
```ts
type: "image" | "color", image, blur, opacity
setImage / setColor / setBlur / setOpacity / reset
syncBackgroundFromConfig()
```
 
### authStore (委托 Registry)
 
```ts
user: AuthResult | null
initFromRegistry()      // 从 Windows Registry 加载
loginOffline(username) // 通过 sidecar + 保存到 registry
logout()                // 清除 registry
```
 
### routeStore (历史栈导航)
 
```ts
current: RouteKey
history: RouteKey[]    // 导航历史栈
navigate(key)          // 压入历史
goBack()                // 弹出历史
```
 
### taskStore (localStorage)


=== taskStore (localStorage) ===
任务队列。localStorage 持久化历史 (max 50)。
任务队列。localStorage 持久化历史 (max 50)。


### 其他 Store
=== 其他 Store ===


- `devStore` — 开发者调试 (内存)
* <code>devStore</code> — 开发者调试 (内存)
- `installStore` — Minecraft 安装 (内存,ephemeral)
* <code>installStore</code> — Minecraft 安装 (内存,ephemeral)
- `launchStore` — 游戏启动 (内存,ephemeral)
* <code>launchStore</code> — 游戏启动 (内存,ephemeral)
- `modsStore` — Mod 搜索 (内存,ephemeral)
* <code>modsStore</code> — Mod 搜索 (内存,ephemeral)
- `updateStore` — 应用更新 (内存,ephemeral)
* <code>updateStore</code> — 应用更新 (内存,ephemeral)
- `instanceStore` — 实例管理 (sidecar 查询)
* <code>instanceStore</code> — 实例管理 (sidecar 查询)


---
----


## 核心组件
== 核心组件 ==


### 三层布局 (RootLayout)
=== 三层布局 (RootLayout) ===
 
<code>z-0  BackgroundLayer    全屏背景图 + 视差 + 模糊 + 强内容遮罩
```
z-1  ContentLayer        页面内容区 (top: 40px, overflow-auto)
z-0  BackgroundLayer    全屏背景图 + 视差 + 模糊 + 强内容遮罩
z-100 SystemLayer        自定义标题栏 (TitleBar)
z-1  ContentLayer        页面内容区 (top: 40px, overflow-auto)
z-200 StartupPopup        启动弹窗 (环境变量控制)</code>
z-100 SystemLayer        自定义标题栏 (TitleBar)
z-200 StartupPopup        启动弹窗 (环境变量控制)
```
 
### TitleBar 标题栏


=== TitleBar 标题栏 ===
三种模式:
三种模式:
- **`default`**: 左侧品牌文字 + 中间胶囊菜单 (可拖拽切换) + 右侧窗口控制
- **`sub`**: 左侧返回按钮 + 品牌文字 + 右侧窗口控制 (隐藏 TaskButton)
- **`window`**: 仅窗口控制


### BackgroundLayer 背景层
* <code>default</code>: 左侧品牌文字 + 中间胶囊菜单 (可拖拽切换) + 右侧窗口控制
* <code>sub</code>: 左侧返回按钮 + 品牌文字 + 右侧窗口控制 (隐藏 TaskButton)
* <code>window</code>: 仅窗口控制


- 支持 `image` (CSS background-image) 和 `color` (CSS background-color) 两种类型
=== BackgroundLayer 背景层 ===
- 视差效果: 鼠标移动时背景偏移 ±20px, scale(1.05)
- 强内容遮罩: 非 home 页面自动显示 (可通过 `contentBlurOpacity` 控制)
- 深色模式叠加层: `bg-black/35`


### StartCard 启动组件 (首页)
* 支持 <code>image</code> (CSS background-image) 和 <code>color</code> (CSS background-color) 两种类型
* 视差效果: 鼠标移动时背景偏移 ±20px, scale(1.05)
* 强内容遮罩: 非 home 页面自动显示 (可通过 <code>contentBlurOpacity</code> 控制)
* 深色模式叠加层: <code>bg-black/35</code>


=== StartCard 启动组件 (首页) ===
胶囊形启动组件,位于首页左下角:
胶囊形启动组件,位于首页左下角:
- 左: 设置齿轮图标 (→ setting)
- 中: "启动游戏" 按钮 (primary 色, rounded-full)
- 右: 实例选择图标 (Package)
### TaskQueue 任务系统
- 执行器模式: `addTask(type, title, desc, async (ctx) => {...})`
- 支持并行执行 (多个任务同时运行)
- AbortController 取消机制
- localStorage 持久化历史 (max 50)
- 任务类型: `install` / `download` / `update` / `launch` / `auth` / `sync` / `custom`
---


## Tauri 窗口配置
* 左: 设置齿轮图标 (→ setting)
* 中: "启动游戏" 按钮 (primary 色, rounded-full)
* 右: 实例选择图标 (Package)


| 窗口 | 尺寸 | 特性 |
=== TaskQueue 任务系统 ===
|---|---|---|
| splashscreen | 480×320 | 无边框, 透明, 不可缩放, 居中 |
| main | 900×600 (min 800×600) | 无边框, 透明, 隐藏启动 |


## 权限 (capabilities/default.json)
* 执行器模式: <code>addTask(type, title, desc, async (ctx) => {...})</code>
* 支持并行执行 (多个任务同时运行)
* AbortController 取消机制
* localStorage 持久化历史 (max 50)
* 任务类型: <code>install</code> / <code>download</code> / <code>update</code> / <code>launch</code> / <code>auth</code> / <code>sync</code> / <code>custom</code>


```
----
core:default, core:window:default, core:window:allow-*,
core:webview:allow-create-webview-window,
opener:default, process:default, shell:allow-execute,
updater:default, dialog:default
```


## Rust 依赖
== Tauri 窗口配置 ==
{| class="wikitable"
!窗口
!尺寸
!特性
|-
|splashscreen
|480×320
|无边框, 透明, 不可缩放, 居中
|-
|main
|900×600 (min 800×600)
|无边框, 透明, 隐藏启动
|}


```toml
== 权限 (capabilities/default.json) ==
tauri = "2"
<code>core:default, core:window:default, core:window:allow-*,
tauri-plugin-opener, tauri-plugin-process, tauri-plugin-dialog,
core:webview:allow-create-webview-window,
tauri-plugin-shell, tauri-plugin-updater
opener:default, process:default, shell:allow-execute,
serde = { version = "1", features = ["derive"] }
updater:default, dialog:default</code>
serde_json = "1"
serde_yaml = "0.9"
uuid = { version = "1", features = ["v4"] }
tokio = { version = "1", features = ["time"] }
[target.'cfg(windows)'.dependencies]
winreg = "0.52"
```


## IPC 协议
== Rust 依赖 ==
tauri = "2"
tauri-plugin-opener, tauri-plugin-process, tauri-plugin-dialog,
tauri-plugin-shell, tauri-plugin-updater
serde = { version = "1", features = ["derive"] }
serde_json = "1"
serde_yaml = "0.9"
uuid = { version = "1", features = ["v4"] }
tokio = { version = "1", features = ["time"] }
[target.'cfg(windows)'.dependencies]
winreg = "0.52"


前端 → `invoke()` → Rust `commands::*` → sidecar stdin (JSON) → sidecar stdout (JSON) → Tauri 事件 → 前端
== IPC 协议 ==
前端 → <code>invoke()</code> → Rust <code>commands::*</code> → sidecar stdin (JSON) → sidecar stdout (JSON) → Tauri 事件 → 前端


Sidecar 命令: `install-minecraft`, `install-mod-loader`, `get-version-list`, `launch-game`, `offline-login`, `search-mods`, `install-mod`, `create-instance`, `list-instances`
Sidecar 命令: <code>install-minecraft</code>, <code>install-mod-loader</code>, <code>get-version-list</code>, <code>launch-game</code>, <code>offline-login</code>, <code>search-mods</code>, <code>install-mod</code>, <code>create-instance</code>, <code>list-instances</code>


Rust 直接命令: `get_config`, `save_config`, `get_auth`, `save_auth`, `delete_auth_cmd`
Rust 直接命令: <code>get_config</code>, <code>save_config</code>, <code>get_auth</code>, <code>save_auth</code>, <code>delete_auth_cmd</code>

2026年7月9日 (四) 20:17的最新版本

Koring Launcher — 开发文档

技术栈

技术
Frontend React 19 + Vite 7 + TypeScript
UI Tailwind CSS v4 + shadcn/ui (base-ui)
状态管理 Zustand
Backend Rust / Tauri 2
Sidecar Node.js / TypeScript / @xmcl/*
配置存储 YAML (serde_yaml) + Windows Registry
包管理 pnpm
目标平台 ARM64 Windows (aarch64-pc-windows-msvc)

快速命令

pnpm dev                # 前端 dev server (port 1420)
pnpm dev:t              # 前端 + Rust dev (需 VS 环境)
./dev-vs.cmd            # VS ARM64 环境启动 dev
pnpm build              # 生产构建 (switch-icon run + tsc + vite build)
pnpm build:beta         # Beta 构建 (switch-icon beta + tsc + vite build --mode beta)
./build-vs.cmd          # Rust 编译 (production, NSIS 打包)
./build-vs.cmd --mode beta  # Rust 编译 (beta, 跳过打包)

构建模式

模式 VITE_BUILD_MODE 图标 Badge 说明
dev "dev" dev.png 🟢 DEV 开发预览版
beta "beta" beta.png 🟡 BETA 测试版
run "run" run.png 正式版

模式由 src/lib/mode.ts 导出 BUILD_MODE, isDev, isBeta, isRun

环境变量 (.env.*)

VITE_BUILD_MODE=dev|beta|run
VITE_APP_ICON=/dev.png|/beta.png|/run.png
VITE_START_POP=true|false              # 启动弹窗开关
VITE_START_POP_TITLE="..."             # 弹窗标题
VITE_START_POP_INFO="..."              # 弹窗内容
VITE_START_POP_BOUTTON="..."           # 弹窗按钮文字

配置存储架构

概览

数据类型 存储位置 格式 说明
用户设置 程序目录 Koring.yml YAML 所有可配置项
账户凭证 Windows Registry HKCU\Software\KoringLauncher REG_SZ token/xboxProfile
实例配置 实例目录 koring-instance.json JSON per-instance
任务历史 localStorage koring-task-history JSON 临时,max 50

Koring.yml 结构

version: 1

theme:
  darkMode: auto          # auto | light | dark
  parallax: true

a11y:
  reduceMotion: false
  reduceTransparency: false
  highContrast: false
  contentBlurOpacity: 50  # 0-100

background:
  bgType: image           # image | color
  image: /background.png
  blur: 0                 # 0-20
  opacity: 100            # 0-100

game:
  gameDir: .minecraft
  resourceDir: ""
  savesDir: ""
  instancesDir: .minecraft/instances

java:
  javaPath: ""
  memMode: auto           # auto | custom
  memGB: 4                # 1-16
  gc: auto                # auto | zgc | g1
  jvmArgs: ""

advanced:
  afterLaunch: close      # close | minimize | keep
  winMode: default        # default | fullscreen | custom
  customWidth: 854
  customHeight: 480
  gameArgs: ""
  preLaunchCmd: ""
  debugMode: false

download:
  fileSource: mirror      # mirror | official | official-only
  versionSource: mirror
  threads: 16             # 1-64
  speedLimit: 0           # KB/s, 0=不限速

network:
  securityId:
    enabled: false
    authUrl: ""

注册表结构

HKCU\Software\KoringLauncher
  └─ auth
       ├─ username      (REG_SZ)
       ├─ uuid          (REG_SZ)
       ├─ accessToken   (REG_SZ)
       ├─ refreshToken  (REG_SZ)
       └─ xboxProfile   (REG_SZ, JSON string)

向上兼容策略

  1. 版本号 — version 字段,每次结构变更递增
  2. 默认值填充 — 加载时缺失字段自动补全,不丢数据
  3. 迁移函数 — migrate_v0_to_v1() 等,按版本链执行
  4. 未知字段保留 — YAML 解析器保留不认识的字段
  5. Debounce 写入 — 300ms debounce 避免频繁 IO

Rust 实现

新文件:

  • src-tauri/src/config.rsAppConfig 结构体、load_config()save_config()merge_defaults()migrate()
  • src-tauri/src/registry.rsread_auth()write_auth()delete_auth()

Tauri 命令:

  • get_config → 返回 AppConfig JSON
  • save_config(cfg) → 写入 Koring.yml
  • get_auth → 从注册表读取 AuthData
  • save_auth(auth) → 写入注册表
  • delete_auth_cmd → 删除注册表认证数据

前端实现

新文件:

  • src/api/config.tsgetConfig()saveConfig() 类型定义
  • src/api/auth-registry.tsgetAuth()saveAuth()deleteAuth()
  • src/stores/configStore.ts — 统一配置 Zustand store

configStore 接口:

useConfigStore.getState().config         // 完整配置
useConfigStore.getState().loaded         // 是否已加载
useConfigStore.getState().init()         // 从 Rust 加载
useConfigStore.getState().setTheme({...})  // 部分更新 + debounce 写回
useConfigStore.getState().setA11y({...})
useConfigStore.getState().setBackground({...})
useConfigStore.getState().setGame({...})
useConfigStore.getState().setJava({...})
useConfigStore.getState().setAdvanced({...})
useConfigStore.getState().setDownload({...})
useConfigStore.getState().setNetwork({...})

Store 委托模式: themeStore / a11yStore / backgroundStore / authStore 都是 configStore 的薄包装层:

  • 读取时从 configStore.config.* 同步
  • 写入时通过各自的 set*() 同时更新本地状态和 configStore
  • 提供 sync*FromConfig() 函数在 App 启动时同步

App 启动流程:

configStore.init() → syncThemeFromConfig() → syncA11yFromConfig() → syncBackgroundFromConfig() → authStore.initFromRegistry()

项目结构

koring-launcher/
├── src/                        # 前端源码
│   ├── App.tsx                 # 路由入口 + configStore 初始化
│   ├── index.css               # 全局样式 + CSS 变量 + 动画
│   ├── layouts/
│   │   └── RootLayout.tsx      # 三层布局: BackgroundLayer + ContentLayer + SystemLayer
│   ├── components/
│   │   ├── background/
│   │   │   └── BackgroundLayer.tsx    # 全屏背景层 + 视差 + 强内容遮罩
│   │   ├── system/
│   │   │   ├── SystemLayer.tsx        # 系统层容器 (z-[100])
│   │   │   ├── TitleBar.tsx           # 自定义标题栏 (40px, 胶囊菜单/返回按钮)
│   │   │   └── WindowControls.tsx     # 窗口按钮 + DEV/BETA badge + TaskButton
│   │   ├── splash/
│   │   │   └── Splash.tsx             # 启动动画 (独立窗口, HTML+React)
│   │   ├── silk/
│   │   │   └── Silk.tsx               # WebGL 丝绸着色器 (Three.js)
│   │   ├── task/
│   │   │   ├── TaskButton.tsx         # 标题栏任务指示器 (SVG 圆弧动画)
│   │   │   └── TaskCard.tsx           # 单个任务卡片 (进度条+日志)
│   │   ├── ui/                        # shadcn/ui 组件
│   │   │   ├── sheet.tsx, button.tsx, switch.tsx, slider.tsx
│   │   │   ├── progress.tsx, badge.tsx, separator.tsx
│   │   │   ├── label.tsx, radio-group.tsx, alert-dialog.tsx
│   │   ├── VersionCard.tsx            # 版本/更新卡片 (Silk 背景+毛玻璃)
│   │   ├── UnderConstruction.tsx      # "装修中" 占位组件
│   │   └── StartupPopup.tsx           # 启动弹窗 (环境变量控制)
│   ├── stores/
│   │   ├── configStore.ts     # 统一配置 store (→ Koring.yml)
│   │   ├── themeStore.ts      # 主题 (委托 configStore)
│   │   ├── a11yStore.ts       # 无障碍 (委托 configStore)
│   │   ├── backgroundStore.ts # 背景 (委托 configStore)
│   │   ├── authStore.ts       # 认证 (→ Registry)
│   │   ├── routeStore.ts      # 路由 (历史栈)
│   │   ├── taskStore.ts       # 任务队列 (localStorage)
│   │   ├── instanceStore.ts   # 实例管理
│   │   ├── installStore.ts    # Minecraft 安装
│   │   ├── launchStore.ts     # 游戏启动
│   │   ├── modsStore.ts       # Mod 搜索
│   │   ├── updateStore.ts     # 应用更新
│   │   └── devStore.ts        # 开发者调试
│   ├── api/
│   │   ├── config.ts          # AppConfig 读写 (→ Tauri invoke)
│   │   ├── auth-registry.ts   # AuthData 读写 (→ Registry)
│   │   ├── instance.ts        # 实例 API
│   │   ├── auth.ts            # 登录 API
│   │   ├── sidecar.ts         # 通用 sidecar IPC
│   │   └── ...
│   ├── hooks/
│   │   └── useTheme.ts         # 同步 darkMode → .dark class
│   ├── lib/
│   │   ├── mode.ts             # BUILD_MODE 常量
│   │   └── utils.ts            # cn() 工具函数
│   ├── types/
│   │   └── task.ts             # Task 类型定义
│   └── pages/                  # 页面组件
├── src-tauri/                  # Rust 后端
│   ├── Cargo.toml              # 依赖: serde, serde_json, serde_yaml, winreg
│   ├── tauri.conf.json         # 窗口配置 + Bundle + Updater
│   ├── capabilities/default.json   # 权限声明
│   ├── src/
│   │   ├── lib.rs              # 插件注册 + splash/main + 命令注册
│   │   ├── config.rs           # AppConfig 读写 + 迁移 + 默认值
│   │   ├── registry.rs         # Windows Registry 读写
│   │   ├── commands/mod.rs     # Tauri 命令 (→ sidecar + config + auth)
│   │   └── sidecar.rs          # Sidecar 进程管理
│   └── binaries/               # Sidecar 二进制文件
├── sidecar/                    # Node.js Sidecar
│   └── src/
│       ├── handlers/           # 10 个 handler
│       ├── utils/paths.ts      # 路径工具 + InstanceConfig
│       └── protocol/types.ts   # IPC 消息类型
├── splash.html                 # 启动动画 HTML 入口
├── build-vs.cmd                # VS 环境编译脚本
└── dev-vs.cmd                  # VS 环境开发脚本

页面路由

顶层路由 (标题栏可见)

Key Label 组件 说明
home 首页 pages/home/index.tsx StartCard 启动组件
store 资源 pages/store/index.tsx 🚧 装修中
today 资讯 pages/today/index.tsx 🚧 装修中
play-link 联机 pages/play-link/index.tsx 🚧 装修中
setting 设置 pages/setting/index.tsx 侧边栏 + 内容区

隐藏路由

Key Label 组件
task-queue 任务队列 pages/task-queue.tsx
debug 调试 pages/debug/index.tsx
debug-splash 启动动画调试 pages/debug/splash-debug.tsx
debug-display 显示效果调试 pages/debug/display-debug.tsx
debug-version-card 版本卡片调试 pages/debug/version-card-debug.tsx
debug-task 任务队列调试 pages/debug/task-debug.tsx

路由导航 (历史栈)

路由使用动态历史栈替代静态 parentMap。每次 navigate() 压入历史,goBack() 弹出。


Zustand Stores

configStore (统一配置中心)

所有用户设置的单一数据源。读写通过 Tauri invoke 与 Koring.yml 同步。

config: AppConfig       // 完整配置
loaded: boolean         // 是否已从 Rust 加载

init()                  // 从 Rust 加载配置
setTheme(patch)         // 部分更新 + debounce 300ms 写回
setA11y(patch)
setBackground(patch)
setGame(patch)
setJava(patch)
setAdvanced(patch)
setDownload(patch)
setNetwork(patch)

themeStore (委托 configStore)

darkMode: "auto" | "light" | "dark"
parallax: boolean
setDarkMode(mode)       // 更新 DOM + configStore
setParallax(v)          // configStore
syncThemeFromConfig()   // 启动时从 config 同步

a11yStore (委托 configStore)

reduceMotion, reduceTransparency, highContrast, contentBlurOpacity
syncA11yFromConfig()

backgroundStore (委托 configStore)

type: "image" | "color", image, blur, opacity
setImage / setColor / setBlur / setOpacity / reset
syncBackgroundFromConfig()

authStore (委托 Registry)

user: AuthResult | null
initFromRegistry()      // 从 Windows Registry 加载
loginOffline(username)  // 通过 sidecar + 保存到 registry
logout()                // 清除 registry

routeStore (历史栈导航)

current: RouteKey
history: RouteKey[]     // 导航历史栈
navigate(key)           // 压入历史
goBack()                // 弹出历史

taskStore (localStorage)

任务队列。localStorage 持久化历史 (max 50)。

其他 Store

  • devStore — 开发者调试 (内存)
  • installStore — Minecraft 安装 (内存,ephemeral)
  • launchStore — 游戏启动 (内存,ephemeral)
  • modsStore — Mod 搜索 (内存,ephemeral)
  • updateStore — 应用更新 (内存,ephemeral)
  • instanceStore — 实例管理 (sidecar 查询)

核心组件

三层布局 (RootLayout)

z-0   BackgroundLayer     全屏背景图 + 视差 + 模糊 + 强内容遮罩
z-1   ContentLayer        页面内容区 (top: 40px, overflow-auto)
z-100 SystemLayer         自定义标题栏 (TitleBar)
z-200 StartupPopup        启动弹窗 (环境变量控制)

TitleBar 标题栏

三种模式:

  • default: 左侧品牌文字 + 中间胶囊菜单 (可拖拽切换) + 右侧窗口控制
  • sub: 左侧返回按钮 + 品牌文字 + 右侧窗口控制 (隐藏 TaskButton)
  • window: 仅窗口控制

BackgroundLayer 背景层

  • 支持 image (CSS background-image) 和 color (CSS background-color) 两种类型
  • 视差效果: 鼠标移动时背景偏移 ±20px, scale(1.05)
  • 强内容遮罩: 非 home 页面自动显示 (可通过 contentBlurOpacity 控制)
  • 深色模式叠加层: bg-black/35

StartCard 启动组件 (首页)

胶囊形启动组件,位于首页左下角:

  • 左: 设置齿轮图标 (→ setting)
  • 中: "启动游戏" 按钮 (primary 色, rounded-full)
  • 右: 实例选择图标 (Package)

TaskQueue 任务系统

  • 执行器模式: addTask(type, title, desc, async (ctx) => {...})
  • 支持并行执行 (多个任务同时运行)
  • AbortController 取消机制
  • localStorage 持久化历史 (max 50)
  • 任务类型: install / download / update / launch / auth / sync / custom

Tauri 窗口配置

窗口 尺寸 特性
splashscreen 480×320 无边框, 透明, 不可缩放, 居中
main 900×600 (min 800×600) 无边框, 透明, 隐藏启动

权限 (capabilities/default.json)

core:default, core:window:default, core:window:allow-*,
core:webview:allow-create-webview-window,
opener:default, process:default, shell:allow-execute,
updater:default, dialog:default

Rust 依赖

tauri = "2"
tauri-plugin-opener, tauri-plugin-process, tauri-plugin-dialog,
tauri-plugin-shell, tauri-plugin-updater
serde = { version = "1", features = ["derive"] }
serde_json = "1"
serde_yaml = "0.9"
uuid = { version = "1", features = ["v4"] }
tokio = { version = "1", features = ["time"] }
[target.'cfg(windows)'.dependencies]
winreg = "0.52"

IPC 协议

前端 → invoke() → Rust commands::* → sidecar stdin (JSON) → sidecar stdout (JSON) → Tauri 事件 → 前端

Sidecar 命令: install-minecraft, install-mod-loader, get-version-list, launch-game, offline-login, search-mods, install-mod, create-instance, list-instances

Rust 直接命令: get_config, save_config, get_auth, save_auth, delete_auth_cmd