Files
IC.Rebuild/diagnostics/2026-10-11-status-block-setter.md

44 lines
5.3 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 0.1.12:编号 8 的转换后状态更新过滤
国际服客户端 2026.09.15.0000.0000;只读检查本机游戏文件,SHA256 为 `5BBC501DD5C7F22FD61A11D08C25356041D878DB7CD83203ADAE393E4DFACC44`。沿用当前 API 15 SDK。未调用运行中游戏的原生函数,效果仍待实测。
## 本次交付
编号 8 现在有可测试实现:在 StatusManager.SetStatus 入口,将本地角色后续收到的已选状态替换为空条目,原函数恰好调用一次,并保留其返回值和 refreshFlags。默认仅选 1257(Forced March),名单可逐项选取已审计的 38 个候选;空名单完全放行。界面提供本次启用的拦截次数与最近状态 ID。
不解析或改写原始网络载荷,不依赖 36、37,不直接清空客户端状态数组。首次启用前已有状态须等待下一次 SetStatus 更新。关闭后正常接收后续更新,不把旧状态写回已经变化的角色。服务器状态和机制判定不因此被删除。
## 原生入口与调用依据
| 路径 | 当前 RVA 与核对结果 |
| --- | --- |
| 状态 ID 转换 | PacketDispatcher 0x18D97FC 分支复制消息并按 12 字节条目减去会话相关值;最终处理发生在转换之后。沿用 0.1.11 的分派依据,不在捕获文件上猜测还原 ID |
| 普通列表 | 0xB385F0 → 0xB37F90 → 0x8A78F0;业务载荷 +0x14,30 个 12 字节条目 |
| 玩家专用单列表 | 0xB37D70 从全局本地角色取 StatusManager,再调用 0x8A78F0 |
| 双列表 | 0xB38A20 先以 r9b=1 调用公共前缀处理,跳过单列表写入,再将两块交给 0x8A7980;玩家专用入口 0xB37DD0 也调用 0x8A7980 |
| 特殊区域列表 | 0xB38600、0xB38760 将载荷 +4 交给 0xB37F90,附加区域字段仍由原生函数处理 |
| 批量写入 | 0x8A78F0 写槽位 0—29;0x8A7980 写 0—29 和 30—59。两者逐项调用 0x8A6BF0,并 OR 返回的变化标记,最后按需调用 0x8A9AD0 |
| 公共 setter | 0x8A6BF0,参数为 manager、int index、ushort id、float remaining、ushort param、64 位 source、byte refreshFlags;返回 byte 变化标记。SDK 的 SetStatus 委托与此一致(bool 以原生 byte 表达) |
| 状态变化与标志 | setter 对比旧 ID/source,更新条目,调用 0x8A1C20 的失去状态路径及 0x89FCB0 的获得状态路径;refreshFlags 非零时调用 0x8A9AD0。批量调用传 0,在批末统一刷新 |
| 标志刷新 | 0x8A9AD0 清零 +0x3C8 的七字节标志,按 +0x3D8 的有效范围和 16 字节状态项重算;另更新 +0x3D9 的部分位。其余状态通知继续由 setter 原函数执行 |
setter 的第 6 参数是完整 64 位 GameObjectId,不能截成网络列表的 uint32 来源字段。第 4 参数使用浮点 ABI。被屏蔽条目传入 id=0、remaining=0、param=0、source=0,保留槽位及 refreshFlags;不跳过 setter,以免旧槽位残留和批末标志不更新。
调用者中还有动作效果及其他入口。本版不宣称覆盖所有直接复制状态数组的路径;仅保证通过这个已核对 setter 的更新适用。回放分组会选择不同角色/管理器,另外通过 DutyRecorderPlayback 帧标记和条件变化事件暂停整个过滤,不改写回放记录。回放、特殊区域和首次角色载入仍需现场验收。
## 本地对象与生命周期
- Framework.Update 发布本地角色地址、EntityId、StatusManager 地址和回放标记;原生回调不读取 ObjectTable 或其他线程绑定服务。
- SDK 元数据确认 BattleChara.StatusManager=0x23B0、GameObject.EntityId=0x78。游戏 getter 0xAFF9E0/0xAFF9F0 返回角色 +0x23B0。启用时检查 SDK 字段偏移,客户端版本不符拒绝启用。
- 本地角色加载签名唯一匹配 0xB37D7A,RIP 引用全局地址 0x142AA0410。只对选中的本地候选更新,通过 SafeMemory 再读当前全局角色指针和实体 ID,与帧快照同时匹配。绝不依赖可能为空的 manager.Owner。
- setter 签名唯一匹配 0x8A6BF0。模块启用清空旧快照;切区、注销与进入回放清空快照;无登录角色或切区期间不发布有效快照。原有半秒过期规则继续生效,指针复用但实体不同会放行。
- Hook 和三个事件订阅都纳入现有 ResourceScope,启动失败、关闭和卸载释放。不保存状态内存副本,不在停用时写回。
## 验证与待验收
Release 构建通过,0 警告、0 错误;70 项离线测试通过。新增四组验证覆盖:当前身份/指针复用/过期与清空/回放,双列表槽位边界和不可变名单,空条目替换及原生返回/标志保留,放行时所有参数保真及异常时只调用一次。已有生命周期测试继续覆盖启动回滚和重复启停。没有用离线代理调用冒充原生 Hook 验收。
首轮游戏检查只聚焦一个状态:重新加载后进入编号 8,保留默认 1257,开启后再触发对应的 Forced March。观察最近状态 ID、拦截次数及实际强制移动表现;关闭后再次触发同一状态应恢复正常。若当前场景使用另一个 ID,在折叠名单中仅选该已审计 ID再测试。开启前已有状态不作立即消除预期。
仍待确认:目标状态效果、未选状态和其他角色正常、关闭后后续同步、切区/回放/卸载。先取得首个目标效果反馈,再扩展逐项状态验收。无需为本版泛化重抓网络样本。