面向参与 USTBL 开发、构建和发布的贡献者。普通用户请从 README 的下载与使用说明开始。
| 层级 | 技术与职责 |
|---|---|
| 桌面运行时 | Tauri v2 负责原生窗口、系统能力、打包和前后端通信。 |
| 前端 | Next.js 15 的静态导出模式、React 18、TypeScript 与 Chakra UI。 |
| 后端 | Rust 2021,处理账户、实例、资源下载、游戏启动、配置与本地文件。 |
| 构建与发布 | npm、Cargo、Tauri CLI、GitHub Actions 和 NSIS(Windows 安装包)。 |
应用的数据流如下:
页面 / 组件 → Context 与 Service → Tauri invoke → Rust command / domain helper → 文件、进程与网络服务
前端仅作为静态资源构建到 out/;Tauri 在开发时启动 Next.js,在生产构建时将静态资源打包进应用。
src/pages/_app.tsx负责国际化初始化和入口组装。components/special/launcher-providers.tsx管理全局 Provider 顺序,托盘窗口只挂载 Chakra;layouts/page-layout.tsx使用静态布局映射,实例详情页切换标签时保留布局与 Context。hooks/webview-behavior.ts管理 WebView 键盘和菜单事件,卸载时移除监听。- 资源加速页与 IPv6 设置组件负责展示;
hooks/resource-acceleration.ts和hooks/ipv6-acceleration.ts分别管理状态、操作和轮询。Service 负责 Tauri 通信,原生进程、凭据、权限和网络恢复留在 Rust。 utils/subscription.ts处理晚到的异步监听注册和清理;utils/polling.ts在每轮请求完成后安排下一轮,防止慢请求积压。加速 hook 使用操作版本拒绝过期响应,轮询不覆盖用户正在编辑的绕过规则。
详见 资源加速验证说明。
| 路径 | 说明 |
|---|---|
src/pages/ |
Next.js 页面与路由。 |
src/components/ |
可复用界面、模态框和交互组件。 |
src/contexts/ |
全局状态与跨页面交互。 |
src/services/ |
前端对 Tauri invoke 命令的类型化封装。 |
src/models/、src/enums/ |
前端模型、枚举和 mock 数据。 |
src/locales/ |
界面翻译文件。 |
src-tauri/src/ |
Rust 代码;按账户、实例、资源、启动、任务和配置等领域组织。 |
src-tauri/capabilities/ |
Tauri 权限声明。 |
src-tauri/tauri.conf.json |
应用窗口、深度链接、打包目标和资源配置。 |
scripts/ |
版本、本地化、游戏元数据、安装器和发布辅助脚本。 |
.github/workflows/ |
Windows 构建、夜间构建、发布和数据更新自动化。 |
- Node.js LTS 与 npm(CI 使用 Node.js LTS)。
- Rust stable,且版本不低于
1.91.0(见src-tauri/Cargo.toml)。 - Windows 开发环境需要 Microsoft C++ Build Tools 与对应的 Windows SDK;建议通过 Visual Studio Build Tools 安装“Desktop development with C++”。
- 用于运行桌面界面的 Microsoft Edge WebView2 Runtime。
- 需要制作便携包或运行部分发布脚本时,安装 Python 3。
在 PowerShell 中检查环境:
node --version
npm --version
rustc --version
cargo --version克隆项目并安装锁定的前端依赖:
git clone https://github.com/LYOfficial/USTBL.git
cd USTBL
npm cisrc-tauri/build.rs 会在本地构建时读取 .env;没有 .env 时会回退到 .env.template。如需安装 CurseForge 整合包,请复制模板并填写 API Key:
Copy-Item .env.template .envUSTBL_CURSEFORGE_API_KEY="your-key"以 USTBL_ 开头的变量会在编译期传入 Rust 二进制。不要将个人密钥提交到仓库;发布包含此类变量的构建前,也应确认它们适合公开分发。
npm run tauri dev该命令会启动 Next.js 开发服务器,并打开 Tauri 桌面窗口。npm run dev 只启动前端服务器,适合单独调整页面样式;涉及 invoke、文件系统、账户或游戏启动的功能必须在 Tauri 环境中验证。
在提交前至少执行:
npm run lint
npm run build构建 Windows 桌面程序:
npm run tauri build指定 Rust 目标三元组时,将参数透传给 Tauri CLI:
npm run tauri build -- --target x86_64-pc-windows-msvc构建产物位于 src-tauri/target/<target>/release/,NSIS 安装程序位于对应的 bundle/nsis/ 目录。便携版不是裸 USTBL.exe,需要由 scripts/release/bundle_portable_assets.py 注入所需资源,Release workflow 会自动完成这一步。
常用维护命令:
| 命令 | 用途 |
|---|---|
npm run lint |
运行 ESLint 与 Prettier 规则。 |
npm run build |
执行 Next.js 静态导出。 |
npm run version check |
检查前端、Tauri 与 Cargo 的版本一致性。 |
npm run version bump <version> |
更新项目版本;提交前仍应运行版本检查。 |
npm run locale diff en |
检查英文翻译键与基准翻译的差异。 |
npm run locale diff zh-Hans |
检查简体中文翻译键与基准翻译的差异。 |
npm run assets:installer |
在 Windows 上重新生成 NSIS 安装器图像资源。 |
启动器的下载分为两类,各由一个独立的策略开关控制(设置 → 下载 → 源),取值均为 auto、official、mirror:
| 内容 | 配置项 | 候选源 |
|---|---|---|
| 游戏本体、依赖库、资源索引、Java 与加载器 | download.source.strategy |
Mojang 官方、BMCLAPI |
| 模组、光影、资源包、整合包等 Modrinth / CurseForge 资源 | download.resource.strategy |
官方源、MCIM 镜像站 |
auto 与游戏文件一致,按 basic_info.is_china_mainland_ip 决定优先级。
MCIM 同时镜像 Modrinth 与 CurseForge 的元数据与文件,接口路径、参数与响应结构与官方完全一致,因此只需替换域名:
| 原始地址 | 镜像地址 |
|---|---|
api.modrinth.com |
mod.mcimirror.top/modrinth |
cdn.modrinth.com |
mod.mcimirror.top |
api.curseforge.com |
mod.mcimirror.top/curseforge |
edge.forgecdn.net |
mod.mcimirror.top |
mediafilez.forgecdn.net |
不替换,MCIM 不镜像该域名 |
实现位于 src-tauri/src/resource/helpers/mcim.rs。get_content_source_priority_list 给出源顺序,content_file_source_candidates 把单个文件地址展开为「镜像 + 官方」候选,并由 tasks/download.rs 的 DownloadTask 统一消费,因此模组、光影、资源包、整合包文件、Fabric API 自动下载与模组更新都能回退到备选源,无需各调用点单独处理。使用 Resumable 重试策略时,DownloadTask 会改为轮换候选源,避免 with_retry 的指数退避在尝试镜像之前长时间阻塞。
接入 MCIM 的约定:
- 请求需携带形如
USTBL/<version>的 User-Agent;utils::web::build_ustbl_client已统一设置。 - 不要对镜像做压力测试,也不要在镜像之外再套一层中转服务。
- 镜像返回缓存数据,带有
sync_at/checked_at;时效性敏感的场景应回退官方源。 - 官方 CurseForge API 需要 API Key,镜像不需要。未配置
USTBL_CURSEFORGE_API_KEY时,启动器会跳过官方 CurseForge 直接使用镜像。
如需将 USTBL 登记为 MCIM 的已知启动器,可在 mcim-rust-api#12 按格式提交启动器名称与版本号。
- 在
src-tauri/src/<domain>/中实现模型、辅助逻辑与commands.rs命令。 - 将命令注册到
src-tauri/src/lib.rs的tauri::generate_handler!。 - 若使用了新的 Tauri 权限或插件能力,更新
src-tauri/capabilities/中的声明。 - 在
src/services/新增或扩展对应的 TypeScript 服务,用invoke调用 Rust 命令,并通过现有responseHandler统一处理响应。 - 在页面、组件与 Context 中消费服务;为加载、空状态、取消和失败路径提供界面反馈。
- 使用
npm run tauri dev实测完整调用链,并运行 lint 与构建检查。
不要在 React 组件中直接散落原生调用或复杂业务逻辑;优先保持“页面 / 组件 → service → Rust command”的边界。涉及删除、覆盖或启动外部进程的操作,应在前端提供明确确认,并在 Rust 端验证输入路径和状态。
界面文案放在 src/locales/*.json,新增键时应同步更新至少英文与简体中文,并运行相应的 npm run locale diff 命令。避免把面向用户的长文案硬编码在组件内。
- 使用仓库中的
.prettierrc和.eslintrc.json;项目采用 2 空格缩进、双引号与分号。 - Husky 与 lint-staged 会在提交时检查变更的 TypeScript、Rust、脚本与翻译文件。
- 保持提交聚焦:不要把自动生成数据、格式化和功能改动混在同一提交,除非它们不可分割。
- 修改版本或安装器资源前,先阅读相关脚本与 GitHub Actions 工作流,避免前端、Cargo 和 Tauri 版本不一致。
ci.yml:推送与 Pull Request 时执行版本一致性、ESLint、翻译键、脚本测试、前端构建、改动 Rust 文件的格式检查和cargo test --locked --lib。release.yml:只基于默认分支运行,构建 Windows x86_64 产物并创建草稿 Release。以下两种方式都会触发:- 推送到
main的提交中新增或修改了合法命名的.github/release-notes/v<version>.md(版本号须与package.json一致;删除文案文件不会触发,一次推送改动多个文案文件会报错)。 - 同一版本尚未发布的草稿会在新构建成功后被替换;已发布的版本不会重新构建,修改其文案请直接在 GitHub Release 页面编辑。
- 在 Actions 页面选择 Release 并点击 Run workflow,填写不带
v的版本号;此时文案文件可选,previous_tag留空时使用最近的v*标签。
- 推送到
发布步骤:
- 用
npm run version bump <version>更新版本。 - 按
.github/release-notes/TEMPLATE.md编写.github/release-notes/v<version>.md,与版本更新一起合入main,即自动开始构建;手动运行且未提供文案文件时,发布文案改为罗列本次包含的提交(提交号 + 标题)。Full Changelog 链接会自动追加。 - 在草稿 Release 中核对文案和文件后手动发布,发布时 GitHub 才会在构建提交上创建
v<version>标签。
每个 Release 固定包含以下文件,启动器自动更新与 vUSTB 的 Release 同步依赖这些文件名:
| 文件 | 说明 |
|---|---|
USTBL_<version>_x64-setup.exe |
NSIS 安装版 |
USTBL_<version>_windows_x86_64_portable.exe |
注入资源的便携版 |
SHA256SUMS.txt |
上述两个文件的 SHA-256 |
Release 构建需要仓库 Secret USTBL_CURSEFORGE_API_KEY(CI 中不读取 .env)。上游仓库缺少该 Secret 时构建失败;fork 中仅给出警告,可用于测试流程。
请先搜索 Issues,再按模板报告问题或提出功能建议。提交 Pull Request 前,请说明问题背景、实现范围与手动验证方式。
USTBL 基于 SJMCL 开发,采用 GPL-3.0 并附加 额外许可条款。分发修改版本前,必须满足两份许可文件中的要求,包括必要的来源说明与命名限制。