- item_tooltip_view.gd: 新增 avoid_rect 属性,tooltip 与装备窗口重叠时自动推到左侧 - inventory_ui.gd: 悬停装备时传入窗口矩形作为避让区域 - 包含其他累积的功能开发和测试文件
7.6 KiB
7.6 KiB
network.error_timeout_server_state
Scope
对比认证失败、连接失败、超时、频道状态检查、服务器状态通知和恢复/回到登录界面的完整分支。
Reference call chain
UserInterface/AccountConnector.cppUserInterface/ServerStateChecker.cppUserInterface/PythonNetworkStreamPhaseLogin.cppEterLib/NetStream.cpp
Current call chain
extension/src/net/auth_client.hextension/src/net/classic/classic_session.cppproject/net/channel_status.gdproject/net/serverinfo.gdproject/app_flow.gdproject/ui/reconnect_ui.gd
Branch matrix
| 场景 | 40250 | 当前端 | 结论 |
|---|---|---|---|
| auth 失败 | AccountConnector 消费错误并通知 login UI,断开 auth/game 状态 | login_failed 返回 AppFlow 登录页;旧 session 清理顺序未完全证明 |
PARTIAL |
| 连接超时 | Process/connector failure 进入 offline/disconnect |
ClassicStream 与 NetStream 均保留 3 秒 non-blocking deadline,并在 socket 可写后再用 SO_ERROR 确认连接完成 |
MAPPED:仍缺少所有上层失败通知组合证明 |
| channel status | ServerStateChecker 请求首 channel,解析 count 和 {port,status},逐频道通知 |
当前查询首频道,解析 classic 210;失败时 fallback TCP probe | PARTIAL:功能相近但多了 approximation |
| 部分响应 | NetStream 保留接收缓存等待完整状态包 | 当前已缓存状态 body,遇到半条记录会继续等待后续 TCP 数据 | MAPPED:分片行为已补回归测试 |
| 空/非法 count | 由包长度和状态处理逻辑拒绝 | _try_parse_classic 检查范围;body 内仍需完善负值/超大值保护 |
PARTIAL |
| 恢复 | 失败后按 connector/server state 回调回到正确 phase | 当前由 AppFlow signal 和 ReconnectUI timer 驱动 | PARTIAL |
Equivalence matrix
| 项目 | 状态 | 证据 |
|---|---|---|
| Preconditions | PARTIAL | 认证/连接和状态请求有检查;完整失败通知、远端关闭与上层重入仍需补齐 |
| Branch structure | PARTIAL | auth/channel/fallback 主分支存在,失败通知和超时分支不同 |
| Algorithms/formulas | MAPPED | classic count/record 解析和分片 body 累积已有实现与测试 |
| State transition order | PARTIAL | 当前 signal/UI retry,参考 connector/phase offline 回调顺序不同 |
| Constants/units | MAPPED | classic/m2dev socket 与 channel probe 均为 3 秒;状态 count 上限为 4096,仍需边界夹具覆盖 |
| Timing/event sources | PARTIAL | timer/fallback probe 与参考 network process/state checker 不同 |
| Resource/data sources | PARTIAL | serverinfo 推导端口,参考接收显式 channel entries |
| Protocol side effects | PARTIAL | 206/210 classic 包存在;fallback TCP probe 是当前扩展副作用 |
| Interruption/failure/cleanup | PARTIAL | 连接中断、重复 probe、重试终止仍缺少测试 |
Deep audit round 2026-09-20
本轮沿 40250 AccountConnector::Connect/Process、CServerStateChecker::Request/Update、CPythonNetworkStream::LoginPhase 和 CNetworkStream::Process/Connect 逐分支核对,得到以下结论:
- 40250 的认证连接通过
CNetworkStream::Connect建立非阻塞 socket,Process用 socket 可写事件确认连接成功,并使用m_connectLimitTime超时清理;当前NetStream与ClassicStream现在都保留 3 秒 deadline,且只有可写事件后才用SO_ERROR确认完成。连接超时/远端错误的上层通知组合仍需扩展测试。 - 40250
CAccountConnector::__AuthState_RecvPhase发送CG_LOGIN3后立即ClearLoginInfo()清掉密码;当前AuthClient在构造登录包后清零并清空m_pw,M2Client::pump_auth()同步丢弃 host-sidecfg_pw,没有 login key 时的空密码重连会被拒绝。该边界已有 loopback 断言。 - 40250 的
ServerStateChecker::Request只连接首频道并发送一次HEADER_CG_STATE_CHECKER,连接/发送失败时将所有已登记频道通知为关闭;Update收到HEADER_GC_RESPOND_CHANNELSTATUS后按端口通知并Initialize()。当前AppFlow::_probe_channels使用ChannelStatus查询首频道,未知端口则逐频道做额外 TCP probe,属于当前端的 approximation,不是 1:1 分支;多个“检测频道”点击可以并行创建查询节点,未见 in-flight/cancel/generation 保护。 - 当前状态查询的 206/210 classic 解析已累积 body,负数和大于 4096 的 count 会拒绝;
ChannelStatus现在会先取消旧 probe,并在回调重入时固定旧 callback,避免旧结果投递给新请求。自动测试仍未覆盖连接后无响应超时、count=0/截断/尾随包及远端关闭。默认协议和MT_PROTOCOL=classic两次测试均通过。 - 当前 AppFlow 登录失败/断线的 signal 分类存在,但账号/游戏连接失败后由
M2Client直接 reset session,再由 AppFlow 重建 Login;这与 40250 的统一 Offline phase /SetLoginPhase顺序不同。p10_test还暴露了 Loading→Game 未隐藏和无 SceneTree 时 char-select timer 空树的测试/生命周期问题,恢复链不能标记为完成。
Required tests
- auth success/failure、connect refusal、connect timeout、remote close。
- 206/210 完整包、分片包、半条 record、count=0、负值和超大 count。
- channel status 失败后的 fallback、重试上限和回到登录页。
- 同一 session 同时 login/reconnect/probe 的竞态与清理。
Evidence run
godot --headless --path project --script channel_status_test.gd:PASS。MT_PROTOCOL=classic godot --headless --path project --script channel_status_test.gd:PASS,覆盖 40250 classic 的 206 请求和 210 响应夹具。- 认证 loopback 成功路径、密码清除、挂起连接 deadline 已在
extension/tests/net_loopback_test.cpp覆盖;classic transport 的同等 deadline/可写门禁在extension/tests/net_classic_stream_test.cpp覆盖。 - 当前合同继续
PARTIAL:通过的状态包解析测试不能替代 40250 的认证失败、远端关闭、失败通知顺序、count 边界和完整恢复链证据。
Active UserInterface server-state checker review
ServerStateChecker.h/ServerStateCheckerModule.cpp维护独立CNetworkStream、channel 地址/端口表、Create/AddChannel/Request/Update/Initialize 和 Python window 回调;它是登录前服务器状态探测链,不等同于游戏 session 的重连。- 当前端 channel status 有 classic packet smoke test,且单个
ChannelStatus的旧 socket/重入 callback 已有清理逻辑;仍没有证明多 channel 请求的超时、远端关闭、失败通知顺序、窗口销毁后回调和与 login phase 的竞态清理一致;本轮纳入 active source 证据,合同仍为PARTIAL。
Implementation fix round 2026-09-20
AuthClient::on_phase(PHASE_AUTH)先把密码拷贝进CG_LOGIN3,随后显式清零并清空m_pw,再检查send_packet();M2Client::pump_auth()看到同一边界后清空cfg_pw,reconnect()在没有 login key 时拒绝空凭据重试。NetStream和ClassicStream都增加 3000ms non-blocking connect deadline;classic 路径改为select可写后再SO_ERROR,修复第一次 process 把仍在连接中的 socket 误报 Online 的差异。ChannelStatus取消旧 probe、清空 mutable callback 后再发done,支持 callback 内启动下一次查询;AppFlow增加 channel probe in-flight guard。- 新增/扩展
net_loopback_test、net_classic_stream_test、channel_status_test.gd,覆盖凭据清除、挂起连接 deadline 和 re-entrant probe callback;成功路径及默认/classic 两套状态包夹具通过。
Status
PARTIAL。