初级玩家

- 贡献度
- 0
- 金元
- 397
- 积分
- 40
- 精华
- 0
- 注册时间
- 2026-3-25
|
本帖最后由 greenhell9527 于 2026-10-11 22:47 编辑
# 在 macOS 上运行 SPT 4.1.6(2026-10-06)
在 MacBook Pro(M5 Pro,24 GB 统一内存)上,用 CrossOver 26.3 跑《逃离塔科夫》单机版 SPT 4.1.6。游戏客户端在瓶子里,服务端在 macOS 本机。
## 环境
| 项目 | 值 |
|---|---|
| 系统 | macOS,Apple Silicon |
| CrossOver | 26.3,瓶子名 `tkf`,Windows 10 |
| 图形 | D3DMetal。MSync 关闭。不要开 High Resolution Mode |
| SPT | 4.1.6,对应客户端构建 `0.16.9.5.40743` |
| 服务端运行时 | `~/Downloads/aspnetcore-runtime-10.0.12-osx-x64/dotnet`(x64,走 Rosetta) |
| 端口 | `https://127.0.0.1:6969` |
| 档案 | 用户名 `spt`,角色 `spt`,69 级,BEAR,版本 SPT Developer |
| 档案 ID | `6ac4ba21b9ca8e7fb581d2e8` |
24 GB 内存低于 SPT 建议的 32 GB。大城市图可能卡或闪退。
## 两个目录,不要混
客户端和服务器不在同一个目录。
| 用途 | 路径 |
|---|---|
| 游戏客户端 | `C:\SPT416`,也就是瓶子里的 `drive_c/SPT416` |
| 正在使用的服务端和角色档案 | `C:\SPT\SPT_Runtime` |
| 角色档案文件 | `C:\SPT\SPT_Runtime\user\profiles\6ac4ba21b9ca8e7fb581d2e8.json` |
| 空档案,不要改 | `C:\SPT416\SPT_Runtime\user\profiles\` 里的同名文件 |
`C:\SPT416\play.bat` 启动的是 `C:\SPT416\EscapeFromTarkov.exe`,然后连接 `https://127.0.0.1:6969`。听这个端口的是 macOS 上的 `dotnet`,工作目录是 `C:\SPT\SPT_Runtime`。
瓶子根目录:
`/Users/Foo/Library/Application Support/CrossOver/Bottles/tkf/drive_c`
## 服务端:在 macOS 上跑,不要在 CrossOver 里跑
在瓶子里运行 `SPT.Server.exe` 时,进程能起来,但端口不监听。原因是 Wine 下生成 HTTPS 证书失败(`CryptographicException`,错误文字是「成功。」)。日志会先写「webserver 已于 https://0.0.0.0:6969 启动」,然后进程退出,端口是空的。
macOS 上没有官方的 SPT 服务端。安装目录里的 `SPT.Server.Linux` 是 Linux x64 程序,不能在这台机器上跑。`SPT.Server.dll` 是 Windows x64,不是纯 IL,arm64 的 `dotnet` 加载不了。
可用的办法:
1. 使用 osx-x64 的 ASP.NET Core 运行时(Rosetta)。
2. 把 `libargon2_sharp_core.dylib`(Mach-O x86_64)放到 `C:\SPT\SPT_Runtime\`,和 `SPT.Server.dll` 放在一起。没有这个库时,服务端会在加载 `argon2_sharp_core` 时退出。
3. 若运行时被隔离,对运行时目录执行 `xattr -dr com.apple.quarantine`。
启动(在 macOS 终端,不要在瓶子里再开一个服务端):
```bash
cd "/Users/Foo/Library/Application Support/CrossOver/Bottles/tkf/drive_c/SPT/SPT_Runtime"
/Users/Foo/Downloads/aspnetcore-runtime-10.0.12-osx-x64/dotnet SPT.Server.dll
```
确认:
```bash
curl -sk https://127.0.0.1:6969/health
```
正常返回 `{"status":"healthy","version":"4.1.6"}`。
网页:
- 主页:`https://127.0.0.1:6969/`
- 档案:`https://127.0.0.1:6969/profiles`
- 本机默认账号 `spt` / `spt`。`http.json` 里 `requireCredentialsOnLocalhost` 为 false。
`6969` 已被占用时,再启动 `SPT.Server` 会报 `AddressAlreadyInUse (48)`。关掉多开的那个窗口即可,不要改端口。
## 用 SPT Installer 安装
安装器从 https://sp-mod.com/installer 下载,在瓶子里运行。这次用的是 **SPT Installer v2.301.0.0**。它不能指定安装某一个旧版本:连上 `patcher.sp-tushonka.com` 后装的是当前发布,这次是 `SPT-4.1.6-40743-731d7a2`。官方 BSG 启动器只能装当前正式版,不能选 4.1.6。
安装器做两件事:从已安装的塔科夫复制一份客户端,再把 SPT 4.1.6 解压进这个新目录。界面里选的路径是**目标目录**,必须是空的,不能选已经放着游戏的 `C:\SPT`。
### 它怎么找已安装的游戏
它不看你在文件对话框里点的源目录,只读注册表:
1. Steam:`HKLM\Software\Microsoft\Windows\CurrentVersion\Uninstall\Steam App 3932890` 的 `InstallLocation`,再进里面的 `build` 子目录。
2. 否则:`HKLM\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall\EscapeFromTarkov` 的 `InstallLocation`。
注册表里没有这项时,界面会报 `Could not find where you installed the game. Do you own and have the game installed?`。17:22 到 17:33 之间的几次安装都停在这里。当时本机客户端在 `C:\SPT`,在瓶子里执行:
```bat
reg add "HKLM\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall\EscapeFromTarkov" /v InstallLocation /t REG_SZ /d "C:\SPT" /f
```
这项只给安装器找源目录。游戏运行时不读它。
### 安装前检查
17:41 那次目标目录是 `C:\SPT416`。预检全部通过:
| 检查 | 结果 |
|---|---|
| 游戏已安装 | `C:\SPT` |
| .NET Framework 4.7.2 | 已安装 4.7.3190 |
| .NET 10 Desktop Runtime | 10.0.12 |
| ASP.NET Core 10 Runtime | 10.0.9 |
| C: 剩余空间 | 约 234 GB,安装大约需要 66.77 GB(含约 10 GB 余量) |
| 游戏启动器已关闭 | 通过 |
这些运行时都装在瓶子里面,不是 macOS 上的。
### 安装过程
日志:
`C:\users\crossover\AppData\Roaming\spt-installer\spt-installer.log`
对应瓶子里的 `dosdevices/c:/users/crossover/AppData/Roaming/spt-installer/spt-installer.log`。
17:41:52 到 17:43:04 的顺序:
1. `Installed Game Path: C:\SPT`,`Installed Game Version: 40743`。
2. 向 `https://patcher.sp-tushonka.com/mirrors.json` 查补丁。日志里大量 `8.8.8.8`、`1.1.1.1`、`1.0.0.1` 的 SSL 失败是安装器走公共 DNS 失败,随后改走系统 DNS,下载仍然成功。
3. `Current Release: 40743 - No Patch Needed`。源客户端已经是 40743,安装器**跳过**把正式版降到 40743 的版本补丁。它不会重写 `Assembly-CSharp.dll`。
4. 下载 `https://patcher.sp-tushonka.com/ ... 6-40743-731d7a2.7z`。期望 MD5:`57408a73a8125c27a175de55430b0ade`。缓存里原来没有这份压缩包。
5. `Copying Client Files`:把 `C:\SPT` 复制到 `C:\SPT416`(大约 17:42:15–17:43:01)。
6. `Extracting Release`:把 7z 解压进 `C:\SPT416`,盖上 BepInEx、`SPT_Runtime` 和启动器。
7. `Creating Shortcuts`,然后 `Cleanup`。压缩包不留在缓存里。
8. `Install Complete. Happy Playing!`
装完后的 `C:\SPT416\EscapeFromTarkov_Data\Managed\Assembly-CSharp.dll` 仍是 2026-08-02、15,994,432 字节。直接开游戏会在 `EasyAssetsPatch` 上报找不到 `EFT.IEftSession`。客户端程序集要另打下面的增量。
## 客户端补丁
4.1.6 的客户端改动在这个增量文件里,本来由启动器在开游戏时套用:
`C:\SPT416\SPT_Runtime\SPT_Data\Launcher\Patches\SPT-core\EscapeFromTarkov_Data\Managed\Assembly-CSharp.dll.delta`
文件头是 `HDIFF13`,后面紧跟 zstd 压缩流(`hpatchz` 打印为 `diffDataType: HDiff`,`compressType: "zstd"`)。增量约 4,459,070 字节。启动器在 D3DMetal 下白屏,所以没有走启动器,而是在 macOS 上用 [HDiffPatch](https://github.com/sisong/HDiffPatch) 的 `hpatchz` 把增量直接打进 DLL。
### 准备 hpatchz
用的是 v5.1.3 的 macOS 通用二进制(arm64 + x86_64):
https://github.com/sisong/HDiffP ... 5.1.3_bin_macos.zip
压缩包里的可执行文件是 `macos/hpatchz`。用法是三个路径,顺序固定:旧文件、增量、输出文件。
```text
hpatchz oldFile diffFile outNewFile
```
下载并去掉隔离属性:
```bash
tmp=$(mktemp -d)
cd "$tmp"
curl -fsSL -A 'Mozilla/5.0' -o hdiff.zip \
"https://github.com/sisong/HDiffPatch/releases/download/v5.1.3/hdiffpatch_v5.1.3_bin_macos.zip"
unzip -q hdiff.zip
xattr -dr com.apple.quarantine macos/hpatchz
```
### 打补丁
游戏必须先退出。`hpatchz` 不会改原文件,输出要写到另一个路径,成功后再替换。
```bash
base="/Users/Foo/Library/Application Support/CrossOver/Bottles/tkf/drive_c/SPT416"
dll="$base/EscapeFromTarkov_Data/Managed/Assembly-CSharp.dll"
delta="$base/SPT_Runtime/SPT_Data/Launcher/Patches/SPT-core/EscapeFromTarkov_Data/Managed/Assembly-CSharp.dll.delta"
cp -p "$dll" "$dll.bak-20260802"
"$tmp/macos/hpatchz" "$dll.bak-20260802" "$delta" "$dll.patched"
mv "$dll.patched" "$dll"
```
当时的输出:
```text
input oldDataSize: 15994432
diffDataSize: 4459070
diffDataType: HDiff
saved oldDataSize: 15994432
saved newDataSize: 16233472
compressType: "zstd" (need decompress 2)
patch ok!
```
结果:
| 文件 | 大小 | 说明 |
|---|---:|---|
| `Assembly-CSharp.dll.bak-20260802` | 15,994,432 | 2026-08-02 的原版,缺少可解析的 `EFT.IEftSession` |
| `Assembly-CSharp.dll` | 16,233,472 | 2026-10-06 17:49 打完补丁。里面能搜到 `Assets\Scripts\Backend\Client\IEftSession.cs` |
补丁只能打在那份 15,994,432 字节的原 DLL 上。已经打过的 16,233,472 字节文件不能再当旧文件用,否则 `hpatchz` 会对不上增量里的旧文件长度。要重打,先把 `.bak-20260802` 拷回去。
不要再开 `SPT.Launcher.exe`。它会按未打补丁的 DLL 做校验,并可能再套一次增量。启动器白屏是 Avalonia 在 D3DMetal 下的问题,没有可用的环境变量能改成软件渲染。MSync 打开时启动器起不来。
`HKCU\SOFTWARE\Microsoft\Avalon.Graphics` 现在是空的,里面没有 `DisableHWAcceleration`。那是 WPF 项,不影响 Unity 游戏。
## 图形
- 瓶子图形后端:`CX_GRAPHICS_BACKEND=d3dmetal`
- 游戏日志里的显卡名会显示成 `AMD Compatibility Mode`,这就是 D3DMetal,不是真的 AMD 显卡
- vkd3d 的 `fixme` / HLSL 输出表示瓶子不在 D3DMetal 上
- DLSS 在 CrossOver 里只是 MetalFX 映射,和塔科夫无关。瓶子里 `D3DM_ENABLE_METALFX=0`
进对局后只有风声、画面全黑时,先看这两项(游戏自己写在 `HKCU\Software\Battlestate Games\EscapeFromTarkov`):
- `Screenmanager Fullscreen mode` 为独占全屏,分辨率曾是 2560×1440
- `Screenmanager Stereo 3D` 为 1 时,CrossOver 没有立体输出,画面会黑,声音继续
可在游戏完全退出后改成窗口、并关掉立体显示:
```bat
reg add "HKCU\Software\Battlestate Games\EscapeFromTarkov" /v "Screenmanager Stereo 3D_h1665754519" /t REG_DWORD /d 0 /f
reg add "HKCU\Software\Battlestate Games\EscapeFromTarkov" /v "Screenmanager Fullscreen mode_h3630240806" /t REG_DWORD /d 3 /f
```
## 每次怎么开
1. 确认 macOS 上的服务端已经在听 `6969`,健康检查是 4.1.6。
2. 不要在瓶子里再启动 `SPT.Server.exe` 或 `SPT.Launcher.exe`。
3. 瓶子图形保持 D3DMetal,MSync 关闭。
4. 在 CrossOver 里运行 `C:\SPT416\play.bat`。
`play.bat` 内容:
```bat
@echo off
cd /d C:\SPT416
start "" EscapeFromTarkov.exe -force-gfx-jobs native -token=6ac4ba21b9ca8e7fb581d2e8 -config="{'BackendUrl':'https://127.0.0.1:6969','MatchingVersion':'live','Version':'live'}"
```
不要启动 `C:\SPT\EscapeFromTarkov.exe`。那个目录里的 `Assembly-CSharp.dll` 仍是 2026-08-02 的,会再次报 `IEftSession`。
改档案之前必须先退出游戏,再停掉 macOS 上的 `dotnet`。服务端把档案放在内存里,游戏还开着时会把旧数据写回去。19:40 重新创建角色时,SPT Developer 模板把每种货币写回了 500,000,000,并盖掉了之前的修改。
## 金钱和商人
网页 `https://127.0.0.1:6969/profiles` 不能改钱,也不能改装备。它能改等级、经验、藏身处、技能、商人忠诚度和销售额、任务、声望、对话。
SPT Developer 模板把卢布、美元、欧元各放了 500,000,000,而且全在一叠里。客户端单叠上限是:
| 货币 | 单叠上限 |
|---|---:|
| 卢布 | 1,000,000 |
| 美元 | 50,000 |
| 欧元 | 50,000 |
超过上限时,仓库里能看见数字,成交栏把这一叠当成无效,显示「缺少」,不能勾选。叠数刚好等于上限时,成交栏同样可能不勾。三种货币在图鉴(Encyclopedia)里若是 `false`(未检查),成交栏也不会用它们。
为了能交易,档案里做过的修改:
- 把仓库里的三叠改到上限以下,并标成已检查。当时写成卢布 500,000、美元 20,000、欧元 20,000。
- `Info.lockedMoveCommands` 从 `true` 改成 `false`(PMC 和 Scav 都改了)。创建角色时声望奖励没加完,这个锁会让商店打得开、但买卖指令不执行。
- 12 个商人的 `unlocked` 都设为 `true`。不要改 `SPT_Data/database/traders/*/base.json`。服务端会校验这些文件的哈希,改过就拒绝启动。
价格是卢布、美元或欧元时,用对应的那一叠付款。价格是物品图标时,那是以物易物,钱不能勾。
写这份记录时,档案里的钱又变回了超上限的大叠,图鉴也回到未检查:
| 货币 | 当时叠数 | 图鉴 |
|---|---:|---|
| 卢布 | 99,987,864 | 未检查 |
| 美元 | 99,997,211 | 未检查 |
| 欧元 | 99,999,999 | 未检查 |
这三叠再次无法用于交易。要恢复交易,退出游戏、停掉服务端,把叠数改到上限以下(例如卢布 500,000、美元 20,000、欧元 20,000),并把这三项图鉴改成已检查,然后只启动一次服务端,再开 `play.bat`。
商人里 BTR、Arena、Storyteller 默认锁定。档案里已全部解锁。BTR 是战局内商人。
## 相关文件
- 服务端日志:`C:\SPT\SPT_Runtime\user\logs\spt\`
- 客户端日志:瓶子里 `users\crossover\AppData\LocalLow\Battlestate Games\EscapeFromTarkov\Player.log`
- BepInEx 日志:`C:\SPT416\BepInEx\LogOutput.log`
- 安装器日志:`users\crossover\AppData\Roaming\spt-installer\spt-installer.log`
- 图形设置:`C:\SPT\SPT_Runtime\user\sptSettings\Graphics.ini`
|
|