Files
GaCy-GO/internal/gameserver/handlers_ui.go
T
CAtlas0784 29b16b5cf9 fix(scene): never answer GetMapRotationData with an empty ScRsp
Client session 02:20 died in AdventurePhase._EnterStep1_InitializeMapInfo
('AdventureModule should not be null' -> RuntimeGroupManager
_InitMissionToLegacyGroupRelation NRE) and never left the loading screen.

The 01:00 session reached the scene when this request was dropped; the
empty reply added in the auto-empty round put the client into map-rotation
mode with a null state. Drop it again until real RotaterData is built.
2026-10-07 02:28:32 +07:00

79 lines
2.8 KiB
Go

package gameserver
import (
goproto "gac-hkrpg-go/protocol/proto"
)
// Handlers for cmds the real 4.6.51 client sends during normal play that were
// dropped in the first test session (2026-10-07 01:00) — several of them gate
// UI state (pause menu, Endgame entry, map rotation) on the server's reply.
func init() {
// client pauses itself when opening menus/map — must be acked
handle("SetClientPaused", func(s *Session, req *goproto.SetClientPausedCsReq, rsp *goproto.SetClientPausedScRsp) error {
rsp.Retcode = 0
rsp.Paused = req.Paused
return nil
})
// the Endgame entrance waits for this before opening its UI
// (4.6.51: CsReq 4190 -> ScRsp 4112, retcode = tag 14 — the Rust build
// answered the wrong id 4130 and the client stalled)
rawHandlers[4190] = func(s *Session, payload []byte) error {
return s.SendRaw(&NetPacket{CmdType: 4112, Body: []byte{0x70, 0x00}})
}
handle("TakeQuestReward", func(s *Session, req *goproto.TakeQuestRewardCsReq, rsp *goproto.TakeQuestRewardScRsp) error {
rsp.Retcode = 0
rsp.SuccQuestIdList = req.SuccQuestIdList
return nil
})
handle("GetFirstTalkNpc", func(s *Session, req *goproto.GetFirstTalkNpcCsReq, rsp *goproto.GetFirstTalkNpcScRsp) error {
rsp.Retcode = 0
return nil
})
handle("QuitBattle", func(s *Session, req *goproto.QuitBattleCsReq, rsp *goproto.QuitBattleScRsp) error {
rsp.Retcode = 0
return nil
})
// NOTE: GetMapRotationData (6827) must NOT be answered with an empty
// ScRsp - the client enters map-rotation mode with a null state and NREs
// in AdventurePhase._EnterStep1_InitializeMapInfo (no scene load).
// Implement real RotaterData before answering this one.
handle("GetPamSkinData", func(s *Session, req *goproto.GetPamSkinDataCsReq, rsp *goproto.GetPamSkinDataScRsp) error {
rsp.Retcode = 0
rsp.CurSkin = 0
rsp.UnlockSkinList = []uint32{0}
return nil
})
handle("GetAllServerPrefsData", func(s *Session, req *goproto.GetAllServerPrefsDataCsReq, rsp *goproto.GetAllServerPrefsDataScRsp) error {
rsp.Retcode = 0
return nil
})
handle("UpdateServerPrefsData", func(s *Session, req *goproto.UpdateServerPrefsDataCsReq, rsp *goproto.UpdateServerPrefsDataScRsp) error {
rsp.Retcode = 0
return nil
})
// simple empty-but-valid data replies (auto-empty also covers these, but
// keeping them explicit documents that they are safe to answer)
handle("GetHeartDialInfo", func(s *Session, req *goproto.GetHeartDialInfoCsReq, rsp *goproto.GetHeartDialInfoScRsp) error {
rsp.Retcode = 0
return nil
})
handle("GetPetData", func(s *Session, req *goproto.GetPetDataCsReq, rsp *goproto.GetPetDataScRsp) error {
rsp.Retcode = 0
return nil
})
handle("GetShopList", func(s *Session, req *goproto.GetShopListCsReq, rsp *goproto.GetShopListScRsp) error {
rsp.Retcode = 0
return nil
})
}