WallpaperEngineLover/embarrassed-shina-linux-proton
GitHub: WallpaperEngineLover/embarrassed-shina-linux-proton
一个多层兼容性修复包,使基于旧版 RPG Developer Bakin 引擎的《害羞的小雫》能够在 Linux Proton 下正常运行,解决灰屏、隐形角色与 UI、音频卡死等问题。
Stars: 0 | Forks: 0
# 害羞的小雫:Linux / Proton 修复包
使 **Embarrassed Shina-chan~ the Naked Wandering College Girl**(Steam AppID
`2326780`,使用 RPG Developer Bakin 构建)能够在 Linux 下的 Proton 中运行。开箱
即用时,游戏会进入灰/白屏然后卡死。即使它能够启动,角色精灵图和所有 2D 菜单也
是隐形的。此修复包将一系列微小的、有文档记录且可逆的修复应用到你本地的游戏副本中,以便
游戏可以启动、加载完整的 3D 地图,并正常渲染角色、菜单和 UI。

这些 Bug 存在于这个较旧的 Bakin 引擎版本(`kmyCore.dll` ~5.4 MB,v1.1.0)中。
较新的 Bakin 游戏无需任何更改即可在相同的 Proton 下运行,因为
引擎在上游已经修复了这些问题。此修复包将该行为向后移植到了
旧版本中。
## 它不能做什么
它不提供任何游戏文件:没有 `kmyCore.dll`,没有 `bakinplayer.exe`,也没有着色器。它
仅包含用于转换你已安装副本的脚本和源代码,并且在
进行任何操作之前,它会验证原始字节和哈希值。每一项更改
都有备份,并且可以通过 `uninstall.sh` 恢复。
## 系统要求
- 通过 Proton 运行的游戏的 Linux Steam 安装(在 Proton
Experimental / 11 上测试过)。
- `gcc`、`patch`、`python3`、`od`/`dd`(在任何桌面 Linux 上都是标准的)。
- .NET SDK(`dotnet`),仅用于为修复 2 构建约 30 行的 IL patcher。
首次构建会从 NuGet 获取 Mono.Cecil,因此它需要一次
网络访问。
## 安装
```
git clone && cd shina-linux-patch
./install.sh # auto-detects the game, or pass its folder explicitly
```
克隆到一个不包含空格或 `:` 的路径(例如 `~/shina-linux-patch`)。
`LD_PRELOAD` 无法处理此类路径,安装程序会拒绝它们。
然后,按照安装程序打印的说明操作:
1. Steam -> 游戏 -> 属性 -> 启动选项:
"/abs/path/to/launcher.installed.sh" %command%
2. 仅限 Wayland(键盘焦点):完全关闭游戏,然后执行
bash patches/05-wayland-keyboard.sh "/path/to/.../Embarrassed Shina-chan~ ..."
从 Steam 启动。随时还原:`./uninstall.sh "/path/to/...game folder"`。
## 修复详情
| # | 症状 | 根本原因 | 修复内容 | 层级 |
|----|---------|-----------|-------------------|-------|
| 1 | 灰屏,无模型 | `scanPlugin` 读取内存中的 `data.rbpack` 文件系统,其中不包含 `.dlp` 资产加载器 | 对一个 `call` 指令进行 1 字节的重新定向,使其使用磁盘上的文件系统创建器 | `kmyCore.dll` (native) |
| 2 | (同上)未找到 `.dlp` | `Entry.initialize("", null)` 导致原生路径推导在 Wine 下失败 | IL 重写:传入 `AppDomain.CurrentDomain.BaseDirectory` 而不是 `null` | `bakinplayer.exe` (managed) |
| 3 | 白屏,“Vertex Attribute Problem”,卡死 | Mesa 的跨阶段 DCE 将 `vin_*` 顶点输入标记为非活动状态,因此 `glGetAttribLocation` 返回 -1 | 在着色器中添加引用每个输入的保活项,由 Mesa 无法折叠为 0 的 uniform 进行缩放 | 游戏 GLSL (文本) |
| 4a | 角色、菜单和所有 2D UI 隐形 | 引擎在默认 VAO (0) 上设置 2D 精灵图/UI 顶点属性。在 OpenGL 兼容性配置文件中是合法的,但 Wine 提供了一个核心配置文件,此时 `glVertexAttribPointer` 会以 `GL_INVALID_OPERATION` 失败,驱动程序拒绝了每一次默认 VAO 的绘制 | 每当游戏使用 VAO 0 时,`LD_PRELOAD` 都会绑定一个真实的 VAO | 宿主机 GL (preload) |
| 4b | 地图加载后立即卡死 | WASAPI 初始化失败(`SndError 923`);线程在“音频就绪”事件上永久等待 | `LD_PRELOAD` 将 INFINITE `NtWaitForSingleObject` 限制在 10 秒 | Wine/ntdll (preload) |
| 5 | 鼠标可用,键盘无效 (Wayland) | 窗口使用 ICCCM “Globally Active” 输入模型;合成器保留了键盘焦点 | Wine 注册表 `UseTakeFocus=N`(被动模型) | Wine 注册表 |
修复 4a 和 4b,以及 IBL BRDF LUT 光照纹理,都位于一个小型的
`LD_PRELOAD` 钩子中:
[`patches/04-runtime-hook/bakin_minimal.c`](patches/04-runtime-hook/bakin_minimal.c)。
修复 4a 是使角色和菜单出现的关键。
完整的技术分析:[docs/TECHNICAL.md](docs/TECHNICAL.md)。
## 如何审查
一切都是源代码或纯文本:
- 修复 1,[`patches/01-kmycore-diskfs.sh`](patches/01-kmycore-diskfs.sh):
验证完整的 5 字节 `call` 指令(`e8 58 92 fd ff`)以及哈希
检查,然后更改一个字节(`0x58` 更改为 `0xB8`)。
- 修复 2,[`patches/02-pluginpath/Program.cs`](patches/02-pluginpath/Program.cs):
Mono.Cecil IL 重写,约 30 行。
- 修复 3,[`patches/03-shader-vin-keepalive.patch`](patches/03-shader-vin-keepalive.patch):
着色器 include 文件的统一 diff。
- 修复 4a/4b,[`patches/04-runtime-hook/bakin_minimal.c`](patches/04-runtime-hook/bakin_minimal.c):
VAO 修复是 `ensure_vao()` 以及 `glVertexAttribPointer` /
`glEnableVertexAttribArray` / `glBindVertexArray` 包装器;音频修复是
`NtWaitForSingleObject` 拼接;以及 IBL LUT 丢弃。
- 修复 5,[`patches/05-wayland-keyboard.sh`](patches/05-wayland-keyboard.sh):
单个注册表值。
## VAO Bug 是如何被发现的
在角色绘制时,每一个可观察到的 GL 状态都与可见的
3D 模型相同:相同的 program、framebuffer、线程、深度/混合/模板/剔除、
视口,甚至附加的纹理。然而,什么都没有渲染出来。突破口是在角色绘制后立即调用 `glGetError` 发现的(它返回了 `GL_INVALID_OPERATION`),然后安装了
`glDebugMessageCallback`,它报告了确切的原因:
`glVertexAttribPointer(no array object bound)`。当一次绘制是隐形的,尽管在你可读取的每个状态中都与可见的绘制匹配时,绘制本身
可能被拒绝了;检查该绘制的 `glGetError` 并打开 GL 调试
输出。
## 已知限制
一些街道道具(`bus`、`Traffic light`、`Swing_ch1`、`ParkClock_ch1` 等)
在地图加载期间会记录非致命的“Vertex Attribute Problem”,并且可能显示错误
或缺失纹理映射。游戏以全速运行,其他所有内容包括
角色和 UI,都能正常渲染。
## 将此应用于其他 Bakin 游戏
其中一些修复同样适用于基于同样较旧的 Bakin 引擎构建的其他游戏
(OpenGL 构建,`kmyCore.dll` 约 5.4 MB)。其他修复则绑定到此款
游戏的文件。
较新的 Bakin 游戏不需要任何这些操作。它们附带 `kmyDX12.dll` 并通过 vkd3d 使用
DirectX 12 渲染,避免了 OpenGL bug。游戏 貢げ!女神様 基于
较新的构建,无需任何补丁即可在 Proton 上运行。
保持不变适用的内容:
- VAO 修复,这是最主要的一项。它是一个普通的 LD_PRELOAD 钩子,每当游戏
使用默认的 VAO 0 时就绑定一个真实的 VAO,并且它从不引用此
游戏。将它加载到 Wine 或 Proton 下任何旧的 Bakin OpenGL 游戏中,它应该会
带回隐形的角色、菜单和 UI。任何假设在 Compatibility profile 中存在默认 VAO 的旧版 OpenGL Windows
游戏都会遇到相同的 bug 并
采取相同的修复。
- 音频等待限制和 Wayland `UseTakeFocus` 注册表值。两者都作用于
Wine,而不是游戏。
绑定到此构建的内容:
- 修复 1(单字节 `kmyCore.dll` 编辑)和修复 2(`bakinplayer.exe` IL
重写)被固定到一个 `kmyCore.dll`(md5 `68590231...`)。相同的构建
以相同的方式进行修补,不同版本具有不同的偏移量。脚本
会检查确切的字节,如果不匹配则停止,因此在错误的
构建上运行它们不会产生任何不良影响。它只会拒绝执行。
- 修复 3(着色器保活)仅在游戏附带相同的
`v2_vpcommon.cgh` 时才适用。
- 音频钩子的 `ntdll` 偏移量(`0x5b530`)遵循 Proton 构建,而不是
游戏。
要在另一款旧版 Bakin 游戏上尝试:
1. 从单独的钩子开始(VAO 修复和音频限制)。将 `install.sh` 中硬编码的
`APPID=2326780` 更改为新游戏的 ID,以便 `@TMPBASE@` 解析为
其 prefix,然后将该启动器设置为该游戏的启动选项。这
通常足以恢复角色和菜单。
2. 如果游戏也打开后是灰色的、空旷的场景,你还需要修复 1 和 2,
它们的偏移量需要从该游戏的 `kmyCore.dll` 重新推导。
3. 仅当日志中填满“Vertex Attribute Problem”时,修复 3 才值得进行。
这些在任何人都未测试过的构建上都没有保证,但 VAO 修复
足够通用,可以作为首选方案。
## 法律声明
此修复包的存在是为了互操作性:使合法购买的游戏能够在
Linux 上运行。未重新分发任何受版权保护的游戏内容;这些工具在你自己的
文件上运行。附带的 `ibl_brdf_lut.bmp` 是标准的预计算 BRDF
查找表(Karis split-sum 函数),不是游戏内容。
`bakin_minimal.c` 和脚本采用 MIT 许可(参见 `LICENSE`)。“RPG
Developer Bakin”和游戏是其各自所有者的商标。
标签:Cutter, Steam Proton, Wine, 云资产清单, 兼容性补丁, 游戏, 逆向工具, 逆向工程