这个项目能做什么
itch 是用于游玩 itch.io 游戏的桌面应用程序。其既定目标是让用户下载并运行游戏、接收更新通知并保持游戏更新,而不取代 itch.io 网站本身。
架构
该应用是一个采用多进程设计的 Electron 应用程序。主进程(Node.js)使用 Redux 处理状态管理、业务逻辑以及与配套组件的协调;它使用“reactor”模式来处理 Redux action 产生的副作用。渲染进程是基于 React 的 UI,其状态通过 electron-redux 从主进程同步。
两个配套的 Go 组件为其提供支持:
- butler:一个守护进程,负责游戏的下载、安装、更新和启动,维护安装数据的 SQLite 数据库,并通过基于 TCP 的 RPC 与应用通信。它作为子进程启动,与应用的声明周期绑定。
- itch-setup:一个可执行文件,负责所有平台上的初始安装,并管理自更新检查和重启。
版本管理(broth)
该应用通过一个名为 broth 的系统管理 butler 和 itch-setup 版本,broth 是一项代理 itch.io API 的服务,为二进制文件和资源提供固定的下载 URL。二进制文件托管在 broth.itch.zone 下,带有平台标识符,如 linux-amd64、darwin-arm64 和 windows-386。在本地,版本存储在 broth 目录下(例如 Linux 上的 ~/.config/itch/broth/),其中包含解压后的二进制文件、临时下载文件和 .chosen-version 标记。
版本选择使用定义在 src/main/broth/formulas.ts 中的 semver 约束(butler ^15.20.0,itch-setup ^1.8.0)。应用获取 /versions 端点,并选择满足约束的最新版本;canary 构建使用 -head 通道,没有约束。启动时,它会验证所选版本,当应用版本发生变化时检查新的组件版本,下载并解压并进行 CRC32 校验,运行健全性检查,然后更新标记并清理旧版本。开发覆盖选项(BROTH_USE_LOCAL=butler)允许使用本地构建的 butler。
butlerd 绑定
与 butler 的通信使用一种名为 butlerd 的 JSON-RPC 2.0 协议。请求、通知和数据类型的 TypeScript 定义位于 src/common/butlerd/messages.ts,并使用名为 generous 的工具从 Go 类型定义自动生成。生成的代码依赖于 @itchio/butlerd npm 包,该包提供用于启动守护进程、通过 TCP 连接并交换 JSON-RPC 消息的运行时。当 butler 仓库作为同级目录检出时,可以使用 npm run sync-butler 重新生成绑定。
itch 与 kitch
该代码库支持两个变体:itch(稳定版)和 kitch(canary 版),可并排安装。变体由构建时的 git 标签决定:以 -canary 结尾的标签生成 kitch,否则生成 itch。本地开发始终以 kitch 运行,因为 package.json 的 name 默认为 "kitch";生产打包会为非 canary 构建将其覆盖为 "itch"。差异包括 URL 协议(itchio:// 和 itch:// 与 kitchio:// 和 kitch://)、broth 通道(常规与 -head)、semver 约束(存在与无)、macOS bundle ID、托盘/窗口图标以及产物名称。
开发与测试
开发需要 npm install,然后 npm start 以在开发模式下运行,并带有监听和重新构建。其他脚本包括用于类型检查的 npm run ts-check 和用于构建资源的 npm run compile。集成测试使用 ChromeDriver 控制 Electron 应用,并演练登录、安装游戏和导航 UI 等流程。它们需要 Go(测试运行器用 Go 编写)、显示器(Linux CI 上为 xvfb)以及来自测试账户的 itch.io API 密钥。ChromeDriver 版本必须与 Electron 版本匹配;当 package.json 中的 Electron 版本发生变化时,必须相应更新 integration-tests/versions.go。测试可以针对打包构建(npm run integration-tests)或开发版本(node release/test.js --test-dev)运行。
许可证与相关项目
itch 在 MIT 许可证下发布。README 还提到了 Mitch,这是一个由其他开发者启动的 Android 客户端。
评论
0 评分人数达到10人后显示
登录后参与讨论。