Files
mtgodot-poc/audit/contracts/social.party-guild-messenger.md
T
shenleiandClaude Opus 5 a989b8f19b chore: delete 106 unreachable *_system.gd and their parity tests
These files were loaded only by their own test_*_parity.gd and never by
the runtime (transitively checked, incl. client_phase_integration_system).
Removes 76 manifest implementation/evidence references across 18
contracts; contract docs get a note that conclusions based on them are
void. Live systems kept: chest, consumable, item_attr, metin_socket,
whisper_chat.

Full headless suite: no new failures (7 failing + 5 headless-hanging
render tests are identical before the deletion).

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-22 17:51:52 +09:00

15 KiB
Raw Blame History

social.party_guild_messenger

Scope

审计组队邀请/接受/离队、队员状态/HP/角色、经验分配模式和组队技能;公会信息、成员/权限、技能、公告、公会战和邀请;好友/Messenger 在线与移动状态;以及会徽/战旗下载、缓存、上传和角色头顶徽章刷新。判断标准是当前端是否以 40250 的网络回包和资源服务为权威,并复现 UI 分支、协议副作用、失败清理和角色显示更新,而不是本地系统类能否独立模拟同样数值。

Reference call chain

  • UserInterface/PythonNetworkStreamPhaseGame.cpp / PythonNetworkStreamPhaseGameActor.cpp
    • 解析 GC_PARTY_*GC_GUILD_*GC_MESSENGERGC_CHARACTER_*;组队邀请、加入、移除、角色/HP/affect、分配模式由服务器回包驱动。
    • 公会 INFO/LIST/GRADE/GRADE_NAME/GRADE_AUTH/CHANGE_EXP/SKILL_INFO/COMMENTS/WAR/WAR_POINT/GUILD_NAME/MONEY_CHANGE 都只更新 CPythonGuild/窗口状态,客户端不计算经验、战绩奖励或权限结果。
    • Messenger 通过 CPythonMessenger 维护好友、公会和家族三组,登录/登出/移动回调 UI;添加/删除和邀请应答走 CG_MESSENGER/messenger_auth
  • UserInterface/PythonGuild.cpp / PythonMessenger.cpp / PythonCharacterManager.cpp
    • 公会成员、等级名称/权限、公告、技能、战争列表和角色 guild id 由网络同步;ChangeGVG/RefreshAllGuildMark 使角色关系和会徽资源刷新。
    • CPythonCharacterManager 不负责本地结算公会战奖励或自动增长公会技能点;这些结果由服务器 GC_GUILD/聊天提示给出。
  • UserInterface/GuildMarkDownloader.cpp / GuildMarkUploader.cpp / MarkManager.cpp
    • 会徽是独立连接和资源链:登录握手→mark index→本地 CRC 列表→压缩 block→拼接 mark image;符号另有 CRC/数据包;完成后通知角色刷新。
    • 上传前检查会长/权限、BMP/尺寸和数据;成功以 mark server 回包为准,不是把像素写入一个脚本字典就完成。
  • Client/Eternexus/root/uiparty.py / uiguild.py / uimessenger.py / uiuploadmark.py
    • UI 只展示网络状态、发送请求和等待回包;队伍角色/affect、经验和公会战积分不能由客户端本地 authoritative 计算。

Current call chain

  • native M2Client/ClassicSession 已提供 party invite/answer/remove/state/skill/parameterfriend add/remove/answerguild 成员/权限/公告/技能/战争/邀请和 mark download/upload 等接口;EntityStore 也有对应的 party/friend/guild/war/mark 状态、dirty 标记和事件队列。
  • project/ui/party_ui.gdguild_ui.gdfriend_ui.gd 已连接 live native signal/getter,主要操作会发送 M2Client 请求;这部分是当前实现中最接近 40250 的路径。
  • project/party_management_system.gd 是独立本地系统:直接创建队伍、计算按等级/均分经验、分配角色光环和数值加成;project/guild_skill_system.gd 本地计算公会升级/技能点/技能 buff;project/guild_war_system.gd 本地计算比分、目标分、天梯变化和 1,000,000 公会金币奖励。这些算法不是 40250 客户端的 authority 链,主要由 parity 测试使用。
  • project/messenger_system.gd 直接修改 friends/guild/family 字典并记录事件;live FriendUI 则使用 native get_friendsadd_friendremove_friendfriend_answer,两套状态源未统一。
  • project/guild_mark_uploader_system.gd 直接把上传数据写入本地 cached_markslive game_scene.gd/GuildUI 使用 native mark server 方法,且默认图源可能是 res://ui/default_guild_mark.png 或运行时生成的 16x12 占位图。
  • extension/src/net/classic/classic_mark_client.*M2Client 已有独立 mark 连接/缓存/图片接口,app_flow.gd 会在登录/选人后启动下载并在 guild_mark_updated 后重试;但现有自动测试主要用 fake client,缺真实 mark packet/压缩 block/CRC/断线恢复证明。

Branch matrix

场景 40250 当前端 结论
组队邀请/应答/移除 CG 请求→GC 邀请/加入/移除;失败由服务器提示 native 包、store、UI 对应存在 PARTIAL:真实拒绝/重复/断线序列不足
队员状态/HP/affect/VID GC_PARTY_ADD/UPDATE/LINK/UNLINK/PARAMETER 驱动 UI EntityStore 与 PartyUI 能展示 PARTIALunordered map 顺序与重连恢复未验证
经验分配/角色光环 客户端只显示 server state/affects,结算在服务器 本地 helper 直接计算 exp 与 buff GAPhelper 不等于 40250 implementation
Messenger 好友 server list/login/logout/mobile/remove,邀请用 auth 流程 native live 路径完整,独立 helper 直接改字典 PARTIAL:两套状态源及真实拒绝/恢复缺证据
公会 info/member/grade/auth GC_GUILD 回包更新,权限由服务器执行 native parser/getter/UI 操作链存在 PARTIAL:请求结果、顺序、权限拒绝和重连未完整覆盖
公会技能/捐献/公告 client 发请求,skill/exp/point/comments 由 GC 回包提供 live UI/native 请求存在;本地 GuildSkillSystem 另算升级/技能点 PARTIAL/GAP:本地 helper 不能作为 parity 证明
公会战声明/状态/列表/积分 GC_WAR/WAR_LIST/WAR_POINT/END 驱动展示,结算权威在服务端 native status/event/score 存在;本地 war system 自己结算奖励 PARTIALlive native 近似,helper 分支为 GAP
公会邀请/创建 对话/确认后 CG_GUILD,结果 GC/command UI/native 应答和创建请求存在 PARTIAL:失败文案和回包清理不足
会徽下载 独立 mark session、index/CRC/block、解压/缓存、角色刷新 classic mark client/native API/app_flow 与 Sprite3D 刷新存在 PARTIAL:真实资源协议和损坏 block 恢复未测
会徽/战旗上传 权限、BMP/尺寸/实际数据→mark server 回包 native upload 存在;本地 uploader 另有直接缓存 helper,默认可上传占位图 PARTIAL/GAP:本地 helper 不是服务端上传结果
角色徽章刷新/移除 RefreshAllGuildMark 与 guild id/mark 数据共同驱动 NetWorld 根据 mark image 创建/刷新 Sprite3D PARTIAL:实际角色模型/换图/死亡/重连资源生命周期未端到端验证

Implementation-equivalence matrix

项目 状态 证据/限制
Preconditions PARTIAL native 对 VID/PID/阶段和部分字段做边界校验;本地 party/guild/mark helper 可绕过服务端权限、当前角色和会长身份
Branch structure PARTIAL live party/guild/friend/mark 主干存在;helper 本地结算、公会战奖励、技能升级、Messenger 缓存和上传缓存形成额外旁路
Algorithms/formulas GAP 40250 客户端不拥有经验分配、公会技能升级、公会战奖励公式;当前 helper 的计算不能宣称与 40250 客户端实现统一
State transition order PARTIAL live native 是请求→GC 回包→dirty/signal→UI;本地系统是立即改字典/发 signal,未按权威回包顺序运行
Constants/units PARTIAL PARTY 角色/affect槽、guild grade/skill、mark 16x12/64x128 和协议布局部分存在;本地 buff、奖励、等级阈值需由 server 数据证明
Timing/event sources PARTIAL live signal/dirty/mark retry 存在;好友/公会/队伍登录、重连、mark block 分片和战争连续事件未完整验证
Resource/data sources PARTIAL native mark store 与角色资源接口存在;默认上传图源和本地缓存 helper 可能取代真实用户资源/服务器 mark 数据
Protocol side effects PARTIAL classic party/guild/friend/mark wire 基础存在;服务器错误、权限拒绝、命令提示和 mark 独立连接所有副作用缺完整测试
Interruption/failure/cleanup GAP 本地 helper 可在无回包时进入成功状态;断线/换图/离会/好友清空/重复 mark 下载、坏 block、战争结束和 UI 弹窗清理未端到端覆盖

Regression evidence

  • project/test_party_management_parity.gd:30/30 通过,但验证的是本地队伍创建、经验和角色 buff helper,未启动服务端或消费 GC_PARTY_*
  • project/test_messenger_parity.gd27/27 通过,但验证的是独立 messenger_system.gd 字典/事件;live native Messenger list/login/logout/mobile/邀请回包未被此测试覆盖。
  • project/test_guild_mark_uploader_parity.gd12/12、project/guild_mark_test.gdproject/guild_mark_tail_test.gd 通过;主要使用本地 uploader/fake client,未覆盖真实 mark server index/CRC/compressed block 和坏数据清理。
  • project/test_guild_war_parity.gd25/25、test_guild_war_observer_arena_parity.gd21/21、test_guild_skill_parity.gd31/31、guild_creation_ui_test.gd:通过;公会战/技能测试主要验证本地公式和状态机,不等价于 40250 GC_GUILD 权威结果。
  • project/test_privilege_empire_guild_parity.gdproject/p8_test.gd:通过;覆盖 UI/辅助系统,不覆盖所有 social 回包拒绝/乱序/重连。
  • build/extension/net_entity_testbuild/extension/net_classic_session_testparty/messenger/guild 基础 parser/session 检查通过;没有完整 GC_GUILDGC_MESSENGERGC_PARTY 错误序列和 mark client packet 测试。

Deep audit round 2026-09-21

Fresh regression results

  • godot --headless --path project --script test_party_management_parity.gd:退出码 0,30/30 通过;覆盖本地队伍创建、离队、角色光环和经验分配 helper。
  • godot --headless --path project --script test_messenger_parity.gd:退出码 0,27/27 通过;覆盖独立 messenger 字典/事件状态。
  • godot --headless --path project --script test_guild_mark_uploader_parity.gd:退出码 0,12/12 通过;覆盖本地尺寸、权限和缓存 helper。
  • godot --headless --path project --script guild_mark_test.gdguild_mark_tail_test.gd:均退出码 0;会徽 UI/尾标局部路径通过。
  • godot --headless --path project --script test_guild_war_parity.gd:退出码 025/25 通过;test_guild_war_observer_arena_parity.gd:21/21 通过;均主要验证本地战争/观察者状态机。
  • godot --headless --path project --script test_guild_skill_parity.gd:退出码 0,31/31 通过;覆盖本地公会技能等级、消耗、buff 和 cooldown 公式。
  • godot --headless --path project --script guild_creation_ui_test.gdtest_privilege_empire_guild_parity.gdp8_test.gd:均退出码 0;UI/权限辅助路径通过。
  • build/extension/net_entity_testbuild/extension/net_classic_session_test:均退出码 0;基础 party/messenger/guild/mark parser/session 检查通过。

Static parity findings

  • 40250 的队伍成员、经验分配、角色光环和公会技能/战争结果都由 GC_PARTY_*/GC_GUILD_* 与服务器状态驱动;当前 PartyManagementSystemGuildSkillSystemGuildWarSystem 仍可在无回包时直接计算并发成功信号,不能作为等价实现。
  • live FriendUI 使用 native friend list/请求,MessengerSystem 却直接改本地 friends/guild/family 字典;两套状态源在拒绝、重复、离会、重连时可能分叉。
  • 会徽 native mark client 已有独立连接、index/CRC/block 和缓存骨架,但当前测试没有真实 mark server 分片、压缩/CRC 失败、断线恢复和完成后所有角色刷新 fixture;本地 uploader helper 直接写 cached_marks 仍是旁路。
  • 公会创建、邀请、权限、公告、技能和战争的 live native 入口存在,但错误文本、权限拒绝、事件顺序、换图/离会清理和重复回包没有形成统一状态合同。
  • 角色徽章/公会关系刷新当前由 NetWorld 的 Sprite3D 适配承接,没有证明与 40250 RefreshAllGuildMark、真实角色模型、死亡/重连/换图资源生命周期保持一致。

Round conclusion

本轮仍为 PARTIAL:native 社交协议和 UI 主干较完整,局部测试全部通过;但本地结算/缓存旁路、真实权限与错误回包、队伍/公会/好友重连清理以及会徽独立连接仍未与 40250 统一。本轮未修改实现代码。

Active UserInterface guild-mark and social-state review

  • GuildMarkDownloader.h 的可达状态机是独立 CNetworkStream:离线/登录/握手/ping/mark-index/mark-block/symbol/key-agreement/完成,并在请求前发送本地 mark CRC/index 列表;GuildMarkUploader.h 还要求读取并校验 BMP/符号、发送 mark 或 symbol、等待完成后断开。
  • MarkImage.cpp/h 不是单个图片缓存:它按 mark/block 网格保存压缩块,使用 LZO 安全解压、CRC、差异 block 列表、空槽分配和本地持久化;MarkManager.h 维护 guild id→mark id、index、图片文件和 block CRC 的持久映射。
  • PythonGuild.h 明确区分 guild 基础信息、等级/权限、成员 grade/job/level/offer、公告、技能点和敌对公会;PythonMessenger.h 暴露好友、公会成员、登录/登出、移动状态和删除回调。这些都属于回包驱动状态,不是本地公会战或 messenger 字典的 authority。
  • 当前端虽有 classic_mark_client 和 native guild/messenger 入口,但本地 GuildMarkUploaderSystemMessengerSystem 仍可旁路直接写缓存/字典;真实分片、CRC/LZO 失败、权限拒绝、重连清理和完成后的全部角色刷新仍无等价证据,合同保持 PARTIAL

Static review evidence

已将 GuildMarkDownloader.hGuildMarkUploader.hMarkImage.cpp/hMarkManager.hPythonGuild.hPythonMessenger.h 纳入本合同的 active source 证据;未因此提升状态。

Status

PARTIAL。当前端的 native 社交协议和主要 UI 已有较完整骨架,组队、公会、好友和会徽 live 主路径大体接上 40250;但本地 party/guild skill/war/messenger/mark helper 仍把服务端权威逻辑复制成直接状态机,且真实权限拒绝、回包顺序、重连清理和独立会徽连接缺端到端证据。因此不能把现有 parity 测试通过等同于实现统一。本轮完成审计并记录,未修改实现代码。

2026-09-22 死代码删除

以下文件只被自身测试引用、运行时从不加载,已删除;本文中以它们为实现或证据的结论作废,相关行为需按 40250 源码单元重新移植:guild_mark_uploader_system.gd, guild_skill_system.gd, guild_war_system.gd, messenger_system.gd, party_management_system.gd, test_guild_mark_uploader_parity.gd, test_guild_skill_parity.gd, test_guild_war_observer_arena_parity.gd, test_guild_war_parity.gd, test_messenger_parity.gd, test_party_management_parity.gd, test_privilege_empire_guild_parity.gd