fix(stage): return valid response for empty stage binary requests

GetStageBinary and WaitStageBinary silently dropped the ACK when
the requested stage did not exist, leaving the client waiting
indefinitely. Additionally, BinaryType1 == 4 and unknown binary
types returned a completely empty response (zero bytes), which
earlier clients cannot parse as a counted structure.

Return a 4-byte zero response (empty entry count) in all fallback
paths so the client always receives a valid ACK it can parse.
This commit is contained in:
Houmgaor
2026-02-18 23:02:44 +01:00
parent 151af1a202
commit 2ac8c8cf62

View File

@@ -393,17 +393,19 @@ func handleMsgSysGetStageBinary(s *Session, p mhfpacket.MHFPacket) {
if binaryData, exists := stage.rawBinaryData[stageBinaryKey{pkt.BinaryType0, pkt.BinaryType1}]; exists { if binaryData, exists := stage.rawBinaryData[stageBinaryKey{pkt.BinaryType0, pkt.BinaryType1}]; exists {
doAckBufSucceed(s, pkt.AckHandle, binaryData) doAckBufSucceed(s, pkt.AckHandle, binaryData)
} else if pkt.BinaryType1 == 4 { } else if pkt.BinaryType1 == 4 {
// Unknown binary type that is supposedly generated server side // Server-generated binary used for guild room checks and lobby state.
// Temporary response // Earlier clients (G1) crash on a completely empty response when parsing
doAckBufSucceed(s, pkt.AckHandle, []byte{}) // this during lobby initialization, so return a minimal valid structure
// with a zero entry count.
doAckBufSucceed(s, pkt.AckHandle, make([]byte, 4))
} else { } else {
s.logger.Warn("Failed to get stage binary", zap.Uint8("BinaryType0", pkt.BinaryType0), zap.Uint8("pkt.BinaryType1", pkt.BinaryType1)) s.logger.Warn("Failed to get stage binary", zap.Uint8("BinaryType0", pkt.BinaryType0), zap.Uint8("pkt.BinaryType1", pkt.BinaryType1))
s.logger.Warn("Sending blank stage binary") doAckBufSucceed(s, pkt.AckHandle, make([]byte, 4))
doAckBufSucceed(s, pkt.AckHandle, []byte{})
} }
stage.Unlock() stage.Unlock()
} else { } else {
s.logger.Warn("Failed to get stage", zap.String("StageID", pkt.StageID)) s.logger.Warn("Failed to get stage", zap.String("StageID", pkt.StageID))
doAckBufSucceed(s, pkt.AckHandle, make([]byte, 4))
} }
s.logger.Debug("MsgSysGetStageBinary Done!") s.logger.Debug("MsgSysGetStageBinary Done!")
} }
@@ -435,6 +437,7 @@ func handleMsgSysWaitStageBinary(s *Session, p mhfpacket.MHFPacket) {
doAckBufSucceed(s, pkt.AckHandle, []byte{}) doAckBufSucceed(s, pkt.AckHandle, []byte{})
} else { } else {
s.logger.Warn("Failed to get stage", zap.String("StageID", pkt.StageID)) s.logger.Warn("Failed to get stage", zap.String("StageID", pkt.StageID))
doAckBufSucceed(s, pkt.AckHandle, make([]byte, 4))
} }
s.logger.Debug("MsgSysWaitStageBinary Done!") s.logger.Debug("MsgSysWaitStageBinary Done!")
} }