fix(gameserver): answer UI-gating cmds the 4.6.51 client stalls on

First real-client session (2026-10-07 01:00) showed the client walking and
attacking but UI interactions stalling: ~120 CsReq dropped with no reply.

- auto-empty responder: any unknown CsReq with a Cmd-enum ScRsp pair now
  gets an empty ScRsp, except the danger families (GridFight/ChessRogue/
  EvolveBuild/ChimeraDuel/Jukebox/CycleScore) which must stay dropped
  (client Sync(nil) NREs on empty, per the Rust lessons)
- GetUnreleasedBlockInfo: the Endgame entry waits on this - 4.6.51 wire is
  CsReq 4190 -> ScRsp 4112 retcode tag 14 (the Rust build answered 4130,
  an id this client never sends)
- SetClientPaused acked (client pauses itself when opening menus/map)
- explicit handlers: TakeQuestReward, GetFirstTalkNpc, QuitBattle,
  GetMapRotationData (Amphoreus teleport pillars), GetPamSkinData,
  GetAllServerPrefsData/UpdateServerPrefsData, GetHeartDialInfo, GetPetData,
  GetShopList
- SendRaw now logs (dummy/raw replies were invisible in gameserver.log)
- cmdpairs.go: req->rsp id pairs generated from the Cmd enum (865 pairs),
  stable across message renames
- smoke test extended: 4190->4112 and SetClientPaused ack verified
This commit is contained in:
CAtlas0784 committed 2026-10-07 01:19:56 +07:00
1 parent 580717c3d8
commit 91ee027eb7
8 files changed
+1154 -115

No files matched your search

+30
View File
@@ -126,6 +126,36 @@ func TestGatewayHandshakeAndLogin(t *testing.T) {
t.Fatalf("expected battle to start for a real monster target")
}
t.Log("SceneCastSkill verified: battle starts for real monster target")
// 6. GetUnreleasedBlockInfo (4190): Endgame entry gates on this reply
if err := client.sendCmd(4190, nil); err != nil {
t.Fatalf("send GetUnreleasedBlockInfo: %v", err)
}
cmdID, body, err = client.recvCmd(3 * time.Second)
if err != nil {
t.Fatalf("no GetUnreleasedBlockInfo response: %v", err)
}
if cmdID != 4112 {
t.Fatalf("unexpected GetUnreleasedBlockInfoScRsp id: got %d want 4112", cmdID)
}
if len(body) != 2 || body[0] != 0x70 || body[1] != 0x00 {
t.Fatalf("unexpected UnreleasedBlockInfo body: %x", body)
}
t.Log("GetUnreleasedBlockInfo verified: 4190 -> 4112 retcode 0")
// 7. SetClientPaused must be acked (pause menu waits for it)
pauseReq, _ := proto.Marshal(&goproto.SetClientPausedCsReq{Paused: true})
if err := client.sendCmd(1466, pauseReq); err != nil {
t.Fatalf("send SetClientPaused: %v", err)
}
cmdID, body, err = client.recvCmd(3 * time.Second)
if err != nil {
t.Fatalf("no SetClientPaused response: %v", err)
}
if cmdID != 1490 { // SetClientPausedScRsp
t.Fatalf("unexpected SetClientPausedScRsp id: got %d want 1490", cmdID)
}
t.Log("SetClientPaused verified: acked")
}
// ---------------------------------------------------------------------------