fix(challenge,scene): challenge id auto-detect, real ScRsp ids, teleport ownership

Round-2 fixes from the 01:44-01:53 client session:

- StartChallenge (MoC/PF/AS normal start) decoded challenge_id=0 -> client
  retried and aborted. detectChallengeID scans top-level varints for the
  first plausible id (challenge_data + known mode ranges) when the strict
  tag-14 decode misses; payload hexdump logged when still 0
- StartChallengeScRsp now carries stage_info (tag 13) with boss node buff
  echo, per the 4.6.51 proto
- GetSwitchHandData replies 8108 (the real ScRsp) - 8104 is
  SwitchHandStartCsReq, we were sending a request id back at the client
- GetSceneMapInfo: strict proto parse failed on some payloads (layout
  drift) which stalled the map UI ('no pillars / navigation loading') -
  now a raw handler with a lenient wire walk fallback + hexdump logging
- teleport destination ('AA teleport landed in AP'): teleport ids repeat
  on every floor and teleports.json was scanned globally in random map
  order. Map clicks now resolve floor-first via scene_identifier, and the
  global id scan never touches teleports.json
- tierce: arena 3014101 -> 3000101 fallback (client has no MapEntrance
  3014101), same as StartChallenge
This commit is contained in:
CAtlas0784 committed 2026-10-07 02:13:45 +07:00
1 parent d364b9616f
commit 876f20d857
4 files changed
+229 -29

No files matched your search

+9 -1
View File
@@ -79,7 +79,7 @@ func handleNamed[ReqT any, RspT any](name, rspName string, fn func(s *Session, r
if len(payload) > 0 {
if m, okc := any(req).(proto.Message); okc {
if err := proto.Unmarshal(payload, m); err != nil {
PacketLog(fmt.Sprintf("[ERROR] Failed to decode cmd_id %d (%s): %v", reqID, name, err))
PacketLog(fmt.Sprintf("[ERROR] Failed to decode cmd_id %d (%s): %v payload=%s", reqID, name, err, hexDump(payload, 256)))
return nil
}
}
@@ -127,6 +127,14 @@ func isDangerCmd(cmdID uint16) bool {
return false
}
// hexDump returns a bounded hex preview for debugging wire-format issues.
func hexDump(b []byte, max int) string {
if len(b) > max {
b = b[:max]
}
return fmt.Sprintf("%x", b)
}
// DispatchMessage is the Go port of CommandHandler::on_message.
func DispatchMessage(s *Session, cmdID uint16, payload []byte) {
PacketLog(fmt.Sprintf("[PACKET RECV] cmd_id: %d %s (len: %d)", cmdID, goproto.NameByCmdID[cmdID], len(payload)))