mirror of
https://github.com/Mezeporta/Erupe.git
synced 2026-03-21 23:22:34 +01:00
Replace ~25 panic() calls in non-fatal code paths with proper s.logger.Error + return patterns. Panics in handler code crashed goroutines (caught by defer/recover but still disruptive) instead of failing gracefully. Key changes: - SJISToUTF8 now returns (string, error); all 30+ callers updated - Handler DB/IO panics replaced with log + return/ack fail - Unhandled switch-case panics replaced with logger.Error - Sign server Accept() panic replaced with log + continue - Dead unreachable panic in guild_model.go removed - deltacomp patch error logs and returns partial data Panics intentionally kept: ByteFrame sentinel, unimplemented packet stubs, os.Exit in main.go.
75 lines
2.2 KiB
Go
75 lines
2.2 KiB
Go
package scenario
|
|
|
|
import (
|
|
"fmt"
|
|
|
|
"erupe-ce/common/byteframe"
|
|
"erupe-ce/common/stringsupport"
|
|
|
|
"erupe-ce/cmd/protbot/protocol"
|
|
)
|
|
|
|
// ChatMessage holds a parsed incoming chat message.
|
|
type ChatMessage struct {
|
|
ChatType uint8
|
|
SenderName string
|
|
Message string
|
|
}
|
|
|
|
// SendChat sends a chat message via MSG_SYS_CAST_BINARY with a MsgBinChat payload.
|
|
// broadcastType controls delivery scope: 0x03 = stage, 0x06 = world.
|
|
func SendChat(ch *protocol.ChannelConn, broadcastType, chatType uint8, message, senderName string) error {
|
|
payload := protocol.BuildChatPayload(chatType, message, senderName)
|
|
pkt := protocol.BuildCastBinaryPacket(broadcastType, 1, payload)
|
|
fmt.Printf("[chat] Sending chat (type=%d, broadcast=%d): %s\n", chatType, broadcastType, message)
|
|
return ch.SendPacket(pkt)
|
|
}
|
|
|
|
// ChatCallback is invoked when a chat message is received.
|
|
type ChatCallback func(msg ChatMessage)
|
|
|
|
// ListenChat registers a handler on MSG_SYS_CASTED_BINARY that parses chat
|
|
// messages (messageType=1) and invokes the callback.
|
|
func ListenChat(ch *protocol.ChannelConn, cb ChatCallback) {
|
|
ch.OnPacket(protocol.MSG_SYS_CASTED_BINARY, func(opcode uint16, data []byte) {
|
|
// MSG_SYS_CASTED_BINARY layout from server:
|
|
// uint32 unk
|
|
// uint8 broadcastType
|
|
// uint8 messageType
|
|
// uint16 dataSize
|
|
// []byte payload
|
|
if len(data) < 8 {
|
|
return
|
|
}
|
|
messageType := data[5]
|
|
if messageType != 1 { // Only handle chat messages.
|
|
return
|
|
}
|
|
bf := byteframe.NewByteFrameFromBytes(data)
|
|
_ = bf.ReadUint32() // unk
|
|
_ = bf.ReadUint8() // broadcastType
|
|
_ = bf.ReadUint8() // messageType
|
|
dataSize := bf.ReadUint16()
|
|
if dataSize == 0 {
|
|
return
|
|
}
|
|
payload := bf.ReadBytes(uint(dataSize))
|
|
|
|
// Parse MsgBinChat inner payload.
|
|
pbf := byteframe.NewByteFrameFromBytes(payload)
|
|
_ = pbf.ReadUint8() // unk0
|
|
chatType := pbf.ReadUint8()
|
|
_ = pbf.ReadUint16() // flags
|
|
_ = pbf.ReadUint16() // senderNameLen
|
|
_ = pbf.ReadUint16() // messageLen
|
|
msg, _ := stringsupport.SJISToUTF8(pbf.ReadNullTerminatedBytes())
|
|
sender, _ := stringsupport.SJISToUTF8(pbf.ReadNullTerminatedBytes())
|
|
|
|
cb(ChatMessage{
|
|
ChatType: chatType,
|
|
SenderName: sender,
|
|
Message: msg,
|
|
})
|
|
})
|
|
}
|