dwgx@blog:~$dwgx
> cd ../posts

给东方 STG 整个联机平台 TH-Platform

// created

TH-Platform 是给东方弹幕 STG 做的第三方桌面客户端,给 TH06、TH07、TH08、TH09 套上大厅、匹配、房间这套联机功能。官方不做联机,这是自己填的坑。

联机分两半,一半是人怎么凑一起,一半是游戏进程里两边状态怎么同步。后半是脏活,要注入 DLL、hook 游戏逻辑,还得跟原版 exe 的内存布局较劲,单独放在伴生仓库 TH08-Platform 慢慢啃。这个仓库只管前一半:客户端本身,大厅、房间、群组、私信、资料、设置一整套页面。UI 和逆向缠在一起太难受,拆开各推各的清爽。

前端 Vite 6 + React 18 + TypeScript,样式走 Tailwind,组件用 Radix primitive,图标 lucide,外面套 Tauri 2 原生壳,要的是无边框、固定 1440x900 的桌面窗口,不是浏览器那玩意。路由没上库,自己写了个 hash router,#/lobby/th08#/room/4912 这种够用,还白嫖浏览器前进后退,零依赖。后端还没有,数据层先做成 mock,关键是 types.ts 这份类型契约,mock 和真门面共用一套类型,真后端接上来调用点一行不改,直接换掉 mock 就行。主题默认暗色三挡,存 localStorageth-platform-theme,index.html 塞了段预渲染脚本,防进来先白闪一下再变黑。

最硬的一块是 Windows 专用的游戏加载器,Rust 写在 Tauri 侧,暴露成 launch_game / terminate_game。老派注入那套:挂起方式启动目标进程,注入配套 DLL,CreateRemoteThreadLoadLibraryA,然后恢复执行。联机参数不走命令行,走环境变量传给子进程:

变量 作用
TH08_PLATFORM_PEER 对端地址 ip:port
TH08_PLATFORM_HOST 标记本端是房主
TH08_PLATFORM_LISTEN 监听端口 房主默认 7480 对端 7481
TH08_PLATFORM_DISABLE_MULTIPLAYER 联机行为的总开关

TS 这边 src/lib/tauri/loader.ts 包了个 launchGame,把游戏路径、DLL 路径、host 模式拼好丢给 Rust。这东西只在 Tauri 壳里活,纯 pnpm devwindow.__TAURI__ 不存在会直接抛错,故意的,省得开发时误触。

现在 v0.1.0 还在进行中,本质是 UI 脚手架加 mock 数据,真后端没接,Rust 加载器搭好了但只认 Windows。接下来补主题预设、频道、完整资料这些页面,把 Tauri 打包弄利索,然后把 mock 接真后端,跟 TH08-Platform 那边的 DLL 注入器真正串起来。