Skip to content

Releases: hazjy/ZSteamTool

v1.2.1

Choose a tag to compare

@hazjy hazjy released this 22 Oct 08:59

修复

  • 未安装的已入库游戏整批不出现在库里:启动 Steam 后只有已安装(或曾经下载过)的游戏能看到,其余全部缺席。现在它们会正常出现在库中。

升级方式

  • 完全退出 Steam(托盘图标也要退出)。
  • 把 Release\ 里的 OpenSteamTool.dll、dwmapi.dll、xinput1_4.dll 覆盖到 Steam 根目录(steam.exe 所在文件夹),覆盖前先备份原文件。
  • 重新启动 Steam。配置、lua 与已入库游戏都不受影响,无需重新入库。

v1.2.0

Choose a tag to compare

@hazjy hazjy released this 19 Oct 10:01

ZSteamTool v1.2.0

适用版本:v1.2.0(对比 v1.1.4)

新增

  • 联机会话(P2P 链路增强):opensteamtool.toml 中 [onlinefix] env_session = true(默认开)。GUI「联机」页选「宿主会话」启动时,会话身份在客户端、大厅与游戏侧保持一致,可创建并加入 Steam 官方大厅;此前的 -onlinefix 命令行路线只能拿到 480 会话、拿不到大厅。P2P 直连仍未打通,不属本版范围。
  • 好友广播开关:[presence] display = "spacewar"(默认)或 "none"(关闭全部好友广播改写,仅用于排查)。
  • 快捷方式富状态:无需配置。仅用 addappid 的单机游戏,游玩状态会以「非 Steam 游戏」形式广播,好友侧能看到游戏名。
  • 家庭共享许可分类:无需配置。借来的游戏不再被记为已拥有,删改 lua 也不会让它从库中消失。
  • 排查脚本:tools/diag/(Steam 更新后的定位链)、tools/p2ptest/(双机 P2P 连通性探针)。

修复与改进

  • 签名表改缓存优先:按客户端 DLL 哈希命中即不联网,启动 49–76 s 降到 0.7 s。
  • 毒缓存自愈:缓存表解析出 0 条目或缺必需接口时丢弃并重取一次。
  • 下载失败分级:传输故障每镜像重试一次,404 不重试;整条链都 404 才算上游未发布。
  • 镜像链补第二活源 mmxlyo/steam-monitor。
  • 签名表懒刷新:缓存命中但确有函数查不到时后台重取一次,下次启动生效。
  • 弹窗:改为中文;MessageBoxW 修正中文乱码;按线程 DPI 绘制修正边缘发虚;文案统一书面表述。
  • 许可向量扩容后回写长度:注入的 depot 对按长度遍历的逻辑可见,删 lua 能真正摘净。
  • 包 0 注入去重、移除时一次摘净:热重载的「先加后删」不再留残影。
  • app 返回 0 个 depot 时判失败:不再写入空 depot 配置(原先表现为「入库后瞬间完成 / 0 mounted depots」)。
  • 家庭共享与已移除应用的移除保护:lua 变更不再让共享游戏从库中消失。
  • 伪造票供体改为 228980 → 480 → 7 梯度:AppId 7 缺票时不再整条失败(error 54)。
  • 交付前校验票据长度(≥20 字节)与签名边界:坏票不再按正常偏移交给游戏(error 54)。
  • 密钥读取改用 from_chars、键名兼容 /:异常不再从钩子抛进 steamclient。
  • ConfigStore 指针改原子读写:修复跨线程裸读写。
  • 在线铸造失败时清掉本会话内旧 eticket:不再交付绑定旧 nonce 的票(88500012)。
  • 票据扩展数据响应前预检缓冲容量:补丁不再被静默丢弃。
  • 报文头部长度改减法比较:消除 uint32 回绕导致的越界读。
  • 清单取码异步结果加异常保护:异常不再穿过收包钩子。
  • 云待投递队列满时丢最旧一条:对应 RPC 不再永久挂起。
  • 库移除通知仅在应用对象存在后发出:不再触发未初始化断言。
  • Detours 事务失败即回滚、Attach 失败清句柄:钩子装不上时不再假装已装。
  • 进程退出时改为 detach 目录监听线程(不 join):避免在 loader lock 下等待已终止的线程,也不再出现退出时的 abort()。
  • 目录监听改为跨线程取消并等待读取结束:修复退出或重载瞬间的释放后使用。
  • 覆盖层、崩溃上报、Steamworks 运行库等伴生进程拉起时不再清除联机会话。
  • Steam 安装目录按宿主 exe 定位;两个代理垫片加固(重复加载幂等、按自身目录绝对路径加载、失败不连累宿主)。

升级方式

  • 完全退出 Steam(托盘图标也要退出)。
  • 把 Release\ 里的 OpenSteamTool.dll、dwmapi.dll、xinput1_4.dll 覆盖到 Steam 根目录(steam.exe 所在文件夹),覆盖前先备份原文件。
  • 重新启动 Steam。配置模板 opensteamtool.toml 可整体替换(新增 [presence] 段);若改过配置,保留原文件即可,缺失的段按默认值工作。

v1.1.4

Choose a tag to compare

@hazjy hazjy released this 14 Oct 09:12

ZSteamTool v1.1.4 —— 适配新版 Steam(必须更新)

一句话:Steam 10/14 更新后,旧内核会让 Steam 启动约 5 秒自己退出、游戏全部变未解锁。换上这一版即可恢复。

必须更新吗

必须,而且与账号、机器无关:所有还在用 v1.1.3 及更早内核的人,在 10/14 之后的 Steam 正式版上都会中招。

为什么

新版 Steam 改了内部结构 CNetPacket 的字段位置——数据指针整体后移 8 字节。旧内核按老位置读,读到的是客户端写的哨兵值 0xFFFFFFFF;它不是空指针,于是绕过检查被当成地址解引用,Steam 当场崩溃。崩溃发生在解锁状态生效之前,所以看起来像是"游戏全被收回了"。

不是签名/映射表的问题(新版客户端的签名表当天正常命中,逐条核对全对)。

这一版做了什么

  • 按新结构对齐,并加编译期断言:客户端将来再动布局,编译就会失败,不会带着这个病发布
  • 数据指针改为判断"能不能读",遇到异常值只跳过这一个包并写一行日志,不再把 Steam 带走

安装(1 分钟)

  1. 完全退出 Steam(右下角托盘图标也要退出)
  2. 把 Release\ 里的三个 DLL 覆盖到你的 Steam 根目录(steam.exe 所在文件夹):
    OpenSteamTool.dll / dwmapi.dll / xinput1_4.dll
  3. 开 Steam。原有配置与已入库游戏都在,不用重新入库

几个提示

  • 日常用 Release\;要查日志就换成 Debug\ 那三个(日志在 <Steam>\opensteamtool\,Release 不带日志)
  • 首次遇到新版客户端会联网拉该版本的签名表(几秒到一分钟)。期间游戏可能仍显示未解锁,等它拉完再操作;拉过一次就有缓存,之后启动很快
  • 用 OSTGUI 的可在「信息」页看到内核版本,显示 1.1.4 即已生效

v1.1.3

Choose a tag to compare

@hazjy hazjy released this 19 Sep 00:20

ZSteamTool v1.1.3 更新说明

适用版本:v1.1.3(对比 v1.1.2;只修 -onlinefix 会话状态的清理,并给 DLL 补上 Windows 版本信息,无其他功能变更)

修复

  • -onlinefix 的会话状态会跨启动残留。这份状态(真实 AppId、P2P 身份翻转、-realappid、会话身份)只属于那一个游戏进程,旧版却要等到"Steam 下次自己启动一个不带 -onlinefix 的游戏"才清空。于是用 -onlinefix 玩过之后,再改用不经过 Steam 启动链的方式起游戏(例如配套 GUI 的「其他 → DLL 注入」),状态会继续作用于整场 Steam 会话:好友状态被持续改写(好友处在 480 世界时,你这边会把他显示成真实游戏名而不是 Spacewar),LobbyInvite 改写、GamesPlayed 名字补丁、P2P 翻转门控也都停留在"已激活"状态——换成别的游戏就可能出真问题。
  • 现在状态随游戏进程一起结束:游戏管道握手时把会话绑定到该游戏进程并抓取其句柄,看门狗线程等它退出,一退出立即清空。

新增

  • OpenSteamTool.dll 带上了 Windows 版本信息:从此可以直接读到内核版本号(资源管理器 → 属性 → 详细信息,或配套 GUI 的「信息」页)。以前版本号只写在日志与诊断弹窗里,Release 版连日志都没有,外部无从得知。

升级方式

替换 Steam 根目录下的 OpenSteamTool.dll / dwmapi.dll / xinput1_4.dll(日常用 Release\,排障用 Debug\,日志在 <Steam>\opensteamtool\),重启 Steam 生效。opensteamtool.toml 无需改动。

一个正常现象:480 方案下双方都以 Spacewar(480) 身份运行,好友列表里互相显示"正在玩 480"是预期结果,不是故障。

v1.1.2

Choose a tag to compare

@hazjy hazjy released this 14 Sep 05:44

ZSteamTool v1.1.2 更新说明

适用版本:v1.1.2(对比 v1.1.1;只改 Lua 目录解析,无其他功能变更)

修复

  • 相对路径写了等于没写。opensteamtool.toml 里相对路径(如 config/lua)之前是按进程当前工作目录解析的,而内核注入进 Steam 后工作目录并不保证是安装目录,于是它去找一个别的地方、多半不存在 → 一个 lua 都读不到。现在相对路径一律以 Steam 目录为基准解析。
  • [lua] paths 现在只认一处。之前是「你写的目录 + 默认 config\lua」两处全都扫,同一批 lua 可能被加载两次、定义互相覆盖。现在:
    • 写了 [lua] paths → 只扫这里(不再顺带扫 config\lua);
    • 没写 / 写空 → 用默认 <Steam>\config\lua。
  • 默认目录不再读 config\stplug-in。v1.1.1 为兼容旧配置会同时读取该目录,现按"单一来源"原则取消;仍留在里面的 lua 请移到 config\lua。

与 GUI 的配合

OSTGUI 设置页的「Lua 路径」写的就是 [lua] paths:填 Steam 目录内的目录会写成相对路径(如 config/lua),盘外目录才写绝对路径;保存后内核热重载,不必重启 Steam。GUI 未改动该设置时,内核使用默认 config\lua。

升级方式

替换 Steam 根目录下的 OpenSteamTool.dll / dwmapi.dll / xinput1_4.dll(日常用 Release\,排障用 Debug\,日志在 <Steam>\opensteamtool\),重启 Steam 生效。

已有的 opensteamtool.toml 无需改动,但请确认一处:

  • 里面若还写着 paths = [".../config/stplug-in"](或任何空目录),新内核会只扫那个目录——把该行删掉或改成 config/lua 即可。

相关文档:上游基线与本地改动见 docs/dev/UPSTREAM-SYNC.md;构建 / Lua API 等技术细节见 docs/upstream/README-en.md。

v1.1.1

Choose a tag to compare

@hazjy hazjy released this 14 Sep 04:18

ZSteamTool v1.1.1 更新说明

适用版本:v1.1.1(对比 v1.1.0;补丁修正,无功能变更)

修复

  • 新机器"装了但没用":默认 Lua 目录不一致。内核此前默认只监视 <Steam>\config\stplug-in(对齐 BetterSteamTools 时引入),而图形界面 OSTGUI 把入库配置写到 <Steam>\config\lua —— 两者只有在内核配置里显式写 [lua] paths 时才打通。因此全新机器(没有 opensteamtool.toml)上入库 / DLC / 解锁全部不生效。
    现在:默认读取 <Steam>\config\lua,并继续读取 <Steam>\config\stplug-in 以兼容旧配置;配置文件热重载后同样保持这两个默认目录的监视。
  • DLL 内嵌版本号错误。OPENSTEAMTOOL_VERSION 原为 CMake 缓存变量,构建目录沿用了旧版本的缓存值,导致 v1.1.0 的 DLL 内部仍报告 1.0.0(仅影响诊断信息中的版本号显示,不影响功能)。现改为唯一来源 project(VERSION ...)。

配置说明

  • opensteamtool.toml 不是必需的:文件不存在时内核按全套默认值运行 —— D 加密模式 normal、Lua 目录 config\lua、stats API 开启、云存档重定向关闭、不注入任何库。
  • 需要 compat(D 加密兼容模式) 时:在 toml 里写 [denuvo] mode = "compat",或直接用 OSTGUI 设置页切换(会自动创建该文件)。新建 / 修改都会触发热重载,不必重启 Steam。
  • [lua] paths 只在需要额外目录时才写;默认的 config\lua(以及兼容读取的 config\stplug-in)无需任何配置。

升级方式

替换 Steam 根目录下的 OpenSteamTool.dll / dwmapi.dll / xinput1_4.dll(Release\ 日常用、Debug\ 排障用,日志在 <Steam>\opensteamtool\),重启 Steam 生效。已有的 opensteamtool.toml 无需改动。

相关文档:上游基线与本地改动见 docs/dev/UPSTREAM-SYNC.md;开发笔记 docs/dev/DEV-NOTES.md;构建 / Lua API / 兼容性等技术细节见 docs/upstream/README-en.md。

v1.1.0

Choose a tag to compare

@hazjy hazjy released this 13 Sep 09:53

ZSteamTool v1.1.0 更新说明

适用版本:v1.1.0(对比上一版本 1.0.0)
基线:OpenSteamTool 上游 2a08b0b + BetterSteamTools 主体对齐 + 本地补丁(同 1.0.0)

新功能

  • D 加密模式开关([denuvo] mode):配置文件新增 [denuvo] 段,二选一,改完热重载,无需重启 Steam:
    • mode = "normal"(默认,= 上游 OpenSteamTool 语义):GetSteamID 只在 D 加密授权握手窗口内使用票据所属账号,窗口外返回你当前登录的账号 → 游戏按 SteamID 派生的用户数据(存档目录、云存档、设置)始终绑定你自己的账号;
    • mode = "compat"(= BST 行为,1.0.0 的既有行为):整场使用票据所属账号,供少数在窗口外仍会复验 SteamID 的严格标题使用;代价是该游戏的用户数据会绑定出票账号(保存档请自行迁移)。
    • 模式生效范围覆盖三处触点(GetSteamID 窗口门、窗口外所有权票源、授权窗口结束时的 SteamID 持久化),保证每种模式内部自洽,不会出现"半场伪装"。

修复与增强

  • 修复 D 加密游戏"读不到自己的存档"(身份一致性):根因是 1.0.0(BST 语义)把 SteamID 整场伪装成票据账号,导致游戏按出票账号的 账号ID 建立/读取存档目录。本次改动:
    1. GetSteamID 恢复授权窗口门(窗口外不伪装);
    2. 窗口外所有权票源改回 ForgeOnly(forge 票取自 app 7 缓存票,身份 = 当前登录账号),与窗口外 GetSteamID 一致;
    3. 单写者:授权窗口结束时不再把"当时登录的账号"写进注册表 HKCU\...\Apps\<appid>\SteamID——该值是身份随登录账号漂移、进而串档的第二来源;
    4. GetSpoofSteamID 在 normal 下只认票据内身份,忽略注册表里旧 compat 运行遗留的值(避免窗口内身份与票据不符 → 012 / 54)。
  • 承接 1.0.0 的三条本地补丁不变:858 OwnershipTicket Forge 兜底、manifest 请求码等待窗口 30s、config/lua/manifest.lua 短路防第三方码注入。

构建与发布

  • OpenSteamTool.dll 内嵌版本号同步为 1.1.0(VERSION 文件即当前版本);
  • 发布包 ZSteamTool-v1.1.0.zip 内含 Debug\(带日志,排障用)与 Release\(日常用)两个版本,各含三个 DLL,附 opensteamtool.toml 与 README-v1.1.0.txt。

配置说明

  • 配置文件 opensteamtool.toml 置于 Steam 根目录;旧版 toml 不带 [denuvo] 段也能直接用(缺省即 normal)。
  • 关键小节:[denuvo] mode(本次新增)、[log] 日志级别、[manifest] 码源与超时、[lua] paths 附加配置目录、[cloud] 云存档重定向(默认关)、[inject] 游戏进程注入(默认关)。

已知限制

  • compat 模式下"用户数据绑定出票账号"是协议层必然:eticket 内的 SteamID 由 Valve 加密签名,无法伪造;若某标题确实需要整场以出票账号运行,其存档/云存档绑定该账号无法通过工具消除,只能手动迁移。
  • 若某标题在 normal 下启动报 012 / 88500012,说明它会在授权窗口外复验 SteamID → 将该游戏切到 compat(或在 lua 中 forcedenuvo(appid) 辅助识别)。
  • Steam 客户端大更新预警(Beta #1788989629) 仍在:请勿手动切换 Beta 通道,正式版当前链路可用(适配要点见 docs/dev/UPSTREAM-SYNC.md 的「Steam 客户端大更新」一节)。
  • 下载:请求码收口环境下正路仍是清单投喂 depotcache;第三方码源可恢复部分游戏下载,属外部依赖,稳定性与可用性自担。
  • Denuvo:设备 token 优先;eticket 在线铸造后端未启用(默认关闭,无网络请求)。

升级方式

替换 Steam 根目录下的 OpenSteamTool.dll / dwmapi.dll / xinput1_4.dll 三个文件(升级前建议备份旧文件),opensteamtool.toml 按需更新(补上 [denuvo] 段即可显式选择模式),重启 Steam 生效。

相关文档:上游基线与本地改动见 docs/dev/UPSTREAM-SYNC.md;开发笔记 docs/dev/DEV-NOTES.md;构建 / Lua API / 兼容性等技术细节见 docs/upstream/README-en.md。

v1.0.0

Choose a tag to compare

@hazjy hazjy released this 13 Sep 09:52

ZSteamTool v1.0.0 更新说明

适用版本:v1.0.0(首个正式版)
基线:OpenSteamTool 上游 2a08b0b + BetterSteamTools 主体对齐(含上游 PR#146 multi-inject/P2P、PR#148 env-less/结构检测)+ 本地特有合入项

新功能

  • 自定义联机会话身份:-onlinefix=<appid>(或 -onlinefix <appid>)可把联机会话身份从默认的 Spacewar(480) 换成任意 AppID——免费联机游戏不止 480 一个,也可挑选带 Steam Input 手柄配置的 AppID 以解决 480 无手柄配置的问题;不带参时行为与旧版完全一致(回落 480)。对端联机需使用相同会话身份;
  • 覆盖范围:P2P 身份翻转、LobbyInvite 校验、Persona 好友同玩、GamesPlayed、控制器 opt-in、票据身份还原、覆盖层身份、RichPresence topmost 全部随会话身份一致化。

修复与增强

  • 858 所有权票据 Forge 兜底:无凭据库票据、无铸造后端时以本地伪造票据应答,修复下载前"更新所有权票 AccessDenied"导致的流程中断;
  • manifest 请求码等待窗口 12→30 秒:内置码源慢响应时不再因等待窗口过短而丢码(表现为下载报"无法获取清单请求码");
  • 请求码注入短路:<Steam>/config/lua/manifest.lua 采用返回 "0" 的短路实现——阻止一切第三方注入码覆盖 CM 原始应答(避免无效码导致的 CDN 401 干扰)。

构建与发布

  • 构建修复:显式指定 /utf-8,Release 配置可正常编译(此前仅 Debug 携带该选项,Release 因源码中文注释按 CP936 解码而编译失败);
  • 双版本发布包:ZSteamTool-v1.0.0.zip 内含 Debug\(带日志,排障用)与 Release\(日常使用)两个版本,各含三个 DLL。

配置说明

  • 配置文件 opensteamtool.toml 置于 Steam 根目录;
  • 关键小节:[log] 日志级别、[manifest] 码源与超时、[lua] paths 附加配置目录、[cloud] 云存档重定向(默认关)、[inject] 游戏进程注入(默认关)。

已知限制

  • Steam 客户端大更新预警(Beta #1788989629):客户端内部重构,Beta 通道强制更新;请勿手动切换 Beta 通道,正式版当前链路可用(适配要点见 docs/dev/UPSTREAM-SYNC.md 的「Steam 客户端大更新」一节);
  • 下载依赖清单投喂:服务器对非拥有账号的清单请求码签发受限,新游戏下载需将清单文件放入 steam\depotcache\(说明见仓库 README 的「本发行版相对上游的差异」一节);
  • Denuvo:设备 token 优先;eticket 在线铸造后端未启用(默认关闭,无网络请求)。

升级方式

替换 Steam 根目录下的 OpenSteamTool.dll / dwmapi.dll / xinput1_4.dll 三个文件(升级前建议备份旧文件),opensteamtool.toml 按需更新,重启 Steam 生效。

相关文档:上游基线与本地改动见 docs/dev/UPSTREAM-SYNC.md;开发笔记 docs/dev/DEV-NOTES.md;构建 / Lua API / 兼容性等技术细节见 docs/upstream/README-en.md。