本文档面向 EndProtocol 贡献者,说明环境要求、构建、CI/CD 与代码规范。
更详细的逐文件功能参考请见 docs/reference/ 与 docs/README.md 的快速定位表。
- Node.js 20+(CI 使用 Node 24)
- pnpm 10(包管理器,仓库使用
pnpm-lock.yaml;package-lock.json已废弃,请勿用它安装) - Rust 最新稳定版
- Windows 构建环境(当前发布目标为
x86_64-pc-windows-msvc)
锁文件规则:仓库根
Cargo.toml是 cargo workspace 根(members = ["src-tauri"]),因此根目录的Cargo.lock才是有效锁文件;src-tauri/Cargo.lock已被移除,不要在子目录重新生成(会与 workspace 锁文件打架、并让构建解析到不同版本的tauricrate)。
Tauri 版本一致性:Tauri CLI 要求
@tauri-apps/*的 NPM 包与对应 Rust crate 同主次版本。package.json与src-tauri/Cargo.toml都用~锁定到当前解析版本(tauri 2.12.x/@tauri-apps/api 2.12.x等);升级时两边一起改,或直接改动Cargo.toml后让 CI 的Sync Tauri NPM packages with Rust crates步骤对齐。报错Found version mismatched Tauri packages即说明两者不同次版本。
git clone https://github.com/mon3tr-dev/endprotocol.git
cd endprotocol
pnpm installpnpm tauri devVite 开发服务器固定使用 1420 端口(strictPort),HMR 使用 1421。
pnpm tauri build产物位于 src-tauri/target/release/,安装包为 NSIS .exe(同时生成 updater 签名产物)。
版本号由 CI 从 Git 标签注入
package.json与src-tauri/tauri.conf.json,本地构建的版本号无实际意义。
| 技术 | 版本 | 用途 |
|---|---|---|
| React | 19.x | UI 框架 |
| TypeScript | 7.0.x(native tsgo) | 类型系统 |
| Vite | 8.x(Rolldown) | 构建工具(双入口) |
| Tailwind CSS | 4.3.x | 样式框架 |
| aura-glass | 3.5.x | 玻璃拟态组件库 |
| React Router | 7.18.x | 路由 |
| i18next / react-i18next | 27.x / 18.x | 国际化 |
| ECharts | 6.1.x | 抽卡统计图表 |
| dnd-kit | 6.x / 9.x / 10.x | 卡片拖拽排序 |
| morphicons / lucide | 2.0.x / 1.70.x | 图标 |
| qrcode | 1.5.x | 扫码登录二维码生成 |
| tailwind-variants / clsx | 4.0.x / 2.1.x | 类名工具 |
| uuid | 14.x | 卡片实例 ID |
| 技术 | 版本 | 用途 |
|---|---|---|
| Tauri | 2.12.x | 桌面应用框架(启用 tray-icon) |
| Rust | edition 2021 | 后端语言 |
| reqwest | 0.13 | HTTP 客户端(native-tls + query feature) |
| tokio | 1.x | 异步运行时 |
| serde / serde_json | 1.x | 序列化 |
| windows-sys | 0.61 | Win32 API(GDI 截屏、窗口、Shell) |
| rfd | 0.18 | 原生文件 / 目录选择框 |
| walkdir | 2.x | 安装目录文件扫描 |
| zip | 9.x | 游戏补丁包解压(aes-crypto + deflate-flate2) |
| sysinfo | 0.40 | 系统资源采集 |
| rand | 0.10 | 随机数(rsa 0.9 专用路径仍用 rand_core 0.6) |
| 用途 | 算法 |
|---|---|
| 森空岛请求签名 | HMAC-SHA256 → MD5(密钥派生自 x-signature-key) |
| 设备指纹 (dId) | RSA + AES-128-CBC / 3DES |
| 鹰角启动器清单解密 | AES-256-CBC(hg_crypto) |
| 文件完整性 | MD5、SHA-256 |
| 其他 | Gzip (flate2)、Base64、Hex |
注:RustCrypto 栈已统一到 digest 0.11 / cipher 0.5(aes 0.9、cbc/ecb 0.2、des 0.9、hmac 0.13、sha2/md-5 0.11); 唯一例外是 rsa 0.9(仍绑 digest 0.10 / rand_core 0.6,经
rsa::rand_core::OsRng使用),待 rsa 0.10 稳定后收口。
tauri-plugin-updater、tauri-plugin-process、tauri-plugin-opener、tauri-plugin-fs。
endprotocol/
├── src/ # React 前端
│ ├── pages/ # 页面
│ ├── components/
│ │ ├── cards/ # 卡片系统
│ │ ├── ui/glass/ # 自建 Glass 组件(21 个)
│ │ └── ui/ # 通用 UI
│ ├── lib/ # 服务层(launcherService、accountService 等)
│ ├── stores/ # 轻量 store
│ ├── hooks/ # 自定义 Hook
│ ├── layouts/ # 应用外壳
│ ├── locales/{en,zh}/translation.json # 全局翻译
│ ├── types/ # 类型定义
│ ├── styles/globals.css # 全局样式与玻璃主题
│ ├── App.tsx # 路由与启动检查
│ ├── main.tsx # 入口
│ ├── provider.tsx # 错误边界与全局宿主
│ ├── i18n.ts # i18next 初始化
│ └── tray-panel.tsx # 托盘面板入口(第二入口)
├── src-tauri/ # Rust 后端
│ ├── src/
│ │ ├── commands/ # Tauri 命令层
│ │ ├── services/ # 业务服务层
│ │ ├── models/ # 数据模型
│ │ ├── utils/ # 工具类(加密、HTTP、日志、路径等)
│ │ ├── tray.rs # 托盘图标与面板窗口
│ │ ├── lib.rs # 插件注册、状态托管、启动任务
│ │ └── main.rs
│ ├── capabilities/ # 权限配置
│ ├── icons/ # 应用图标
│ ├── tauri.conf.json # 窗口、打包、更新配置
│ └── Cargo.toml
├── docs/ # 开发文档
├── public/assets/icons/ # 游戏数据图标
├── .github/workflows/release.yml # 自动构建与发布
├── index.html # 主窗口入口
├── tray-panel.html # 托盘面板入口
└── vite.config.ts
- 前端日志:使用
src/utils/logger.ts,禁止裸露console.log - 用户可见文本:使用 i18next (
src/locales/),禁止硬编码字符串 - 前端→后端调用:在
src/utils/*Service.ts中封装invoke,包含类型与显式失败返回 - 后端错误:使用
Result<T, AppError>(src-tauri/src/utils/error.rs);I/O 操作使用 async;使用tracing/log_*记录日志 - 样式:Tailwind +
src/components/ui/glass玻璃组件 - 图标:禁止在应用 UI、元数据或示例中使用 emoji;使用
lucide/morphicons或现有 SVG 图标组件;持久化图标标识符而非 emoji 字符 - 状态/配置:后端使用
ConfigService(app_config.json,点分键),禁止 ad-hoc 文件写入 - 禁止读取或修改:
dist/、target/、node_modules/、src-tauri/gen/(生成文件)
仓库未配置 lint 或测试脚本。使用以下命令检查:
npx tsc --noEmit # TypeScript 7 全量类型检查(零错误为通过)
npm run build # vite build(Rolldown 打包,出现 Circular chunk: 视为失败)
npm run dev # vite dev server
cargo check # 在 src-tauri/ 目录下运行(已有警告属预期)
cargo test # 在 src-tauri/ 目录下运行(72 个测试)Vite 8 的文件监听器是 Rust 实现、启动即递归建树。本仓库根目录下的 target/(Rust
workspace 构建目录)在本机有 35 GB / 5.6 万个文件,若不排除,首个模块请求会被阻塞数十秒
(实测冷启动 /src/main.tsx 耗时 46 秒)。症状是 tauri dev 起来后窗口长时间只有启动
splash、DevTools 控制台没有任何输出,看起来像"窗口没有内容"。
vite.config.ts 的 server.watch.ignored 必须包含 **/target/**、**/dist/**、
**/dist-linux/**(以及 **/src-tauri/**);加上后同一测量降到 0.13 秒。新增产物目录时
记得同步加入。
.github/workflows/release.yml 在推送 v* 标签时触发:
- 同步版本号:去掉标签的
v前缀,写入package.json与src-tauri/tauri.conf.json - 判定通道:版本号带后缀 →
preview,否则stable;并查找同通道的上一个标签 - 生成更新日志:按 Conventional Commits 分类,写入
CHANGELOG.md - 并行构建:Node 24 + pnpm 10 + Rust stable,Windows 与 Linux 作为独立 job 并行构建——Windows x64 出 NSIS 安装包,Linux x64(ubuntu-22.04,保证 glibc 兼容)出 AppImage,均含签名 updater 包
- 生成更新清单:将各平台的 updater 包与 minisign 签名汇总到 Release 的
latest.json - 发布:先创建草稿 Release,再将其公开并标记是否为预发布
需配置的 Secrets:TAURI_SIGNING_PRIVATE_KEY 与 TAURI_SIGNING_PRIVATE_KEY_PASSWORD(GITHUB_TOKEN 由 Actions 自动提供)。
每条提交信息必须遵循 Conventional Commits 并携带前缀:
<type>(<scope>): <lowercase imperative summary, no trailing period>
<optional body: one bullet per coherent change>
<optional trailers, e.g. Co-authored-by: ...>
- Types:
feat,fix,docs,style,refactor,perf,test,build,ci,chore - Scope 可选但推荐,例如
feat(launcher)、fix(updater)、docs(agents) - 无前缀的提交也有效,例如
feat: enable cross-platform builds and updates
保持一条连贯的更改 per commit;不相关的工作应分开提交。
提交前运行 §6 验证,并确保 docs/ 索引已同步更新。禁止不带前缀提交,禁止将不相关功能混入现有提交。