mirror of
https://github.com/FlourishingWorld/hk4e.git
synced 2026-03-01 00:35:36 +08:00
优化架构
This commit is contained in:
161
gate/net/proto_endecode.go
Normal file
161
gate/net/proto_endecode.go
Normal file
@@ -0,0 +1,161 @@
|
||||
package net
|
||||
|
||||
import (
|
||||
pb "google.golang.org/protobuf/proto"
|
||||
"hk4e/logger"
|
||||
"hk4e/protocol/cmd"
|
||||
"hk4e/protocol/proto"
|
||||
)
|
||||
|
||||
type ProtoEnDecode struct {
|
||||
cmdProtoMap *cmd.CmdProtoMap
|
||||
}
|
||||
|
||||
func NewProtoEnDecode() (r *ProtoEnDecode) {
|
||||
r = new(ProtoEnDecode)
|
||||
r.cmdProtoMap = cmd.NewCmdProtoMap()
|
||||
return r
|
||||
}
|
||||
|
||||
type ProtoMsg struct {
|
||||
ConvId uint64
|
||||
CmdId uint16
|
||||
HeadMessage *proto.PacketHead
|
||||
PayloadMessage pb.Message
|
||||
}
|
||||
|
||||
type ProtoMessage struct {
|
||||
cmdId uint16
|
||||
message pb.Message
|
||||
}
|
||||
|
||||
func (p *ProtoEnDecode) protoDecode(kcpMsg *KcpMsg) (protoMsgList []*ProtoMsg) {
|
||||
protoMsgList = make([]*ProtoMsg, 0)
|
||||
protoMsg := new(ProtoMsg)
|
||||
protoMsg.ConvId = kcpMsg.ConvId
|
||||
protoMsg.CmdId = kcpMsg.CmdId
|
||||
// head msg
|
||||
if kcpMsg.HeadData != nil && len(kcpMsg.HeadData) != 0 {
|
||||
headMsg := new(proto.PacketHead)
|
||||
err := pb.Unmarshal(kcpMsg.HeadData, headMsg)
|
||||
if err != nil {
|
||||
logger.LOG.Error("unmarshal head data err: %v", err)
|
||||
return protoMsgList
|
||||
}
|
||||
protoMsg.HeadMessage = headMsg
|
||||
} else {
|
||||
protoMsg.HeadMessage = nil
|
||||
}
|
||||
// payload msg
|
||||
protoMessageList := make([]*ProtoMessage, 0)
|
||||
p.protoDecodePayloadCore(kcpMsg.CmdId, kcpMsg.ProtoData, &protoMessageList)
|
||||
if len(protoMessageList) == 0 {
|
||||
logger.LOG.Error("decode proto object is nil")
|
||||
return protoMsgList
|
||||
}
|
||||
if kcpMsg.CmdId == cmd.UnionCmdNotify {
|
||||
for _, protoMessage := range protoMessageList {
|
||||
msg := new(ProtoMsg)
|
||||
msg.ConvId = kcpMsg.ConvId
|
||||
msg.CmdId = protoMessage.cmdId
|
||||
msg.HeadMessage = protoMsg.HeadMessage
|
||||
msg.PayloadMessage = protoMessage.message
|
||||
logger.LOG.Debug("[recv] union proto msg, convId: %v, cmdId: %v", msg.ConvId, msg.CmdId)
|
||||
if protoMessage.cmdId == cmd.UnionCmdNotify {
|
||||
// 聚合消息自身不再往后发送
|
||||
continue
|
||||
}
|
||||
logger.LOG.Debug("[recv] proto msg, convId: %v, cmdId: %v, headMsg: %v", protoMsg.ConvId, protoMsg.CmdId, protoMsg.HeadMessage)
|
||||
protoMsgList = append(protoMsgList, msg)
|
||||
}
|
||||
// 聚合消息自身不再往后发送
|
||||
return protoMsgList
|
||||
} else {
|
||||
protoMsg.PayloadMessage = protoMessageList[0].message
|
||||
}
|
||||
logger.LOG.Debug("[recv] proto msg, convId: %v, cmdId: %v, headMsg: %v", protoMsg.ConvId, protoMsg.CmdId, protoMsg.HeadMessage)
|
||||
protoMsgList = append(protoMsgList, protoMsg)
|
||||
return protoMsgList
|
||||
}
|
||||
|
||||
func (p *ProtoEnDecode) protoDecodePayloadCore(cmdId uint16, protoData []byte, protoMessageList *[]*ProtoMessage) {
|
||||
protoObj := p.decodePayloadToProto(cmdId, protoData)
|
||||
if protoObj == nil {
|
||||
logger.LOG.Error("decode proto object is nil")
|
||||
return
|
||||
}
|
||||
if cmdId == cmd.UnionCmdNotify {
|
||||
// 处理聚合消息
|
||||
unionCmdNotify, ok := protoObj.(*proto.UnionCmdNotify)
|
||||
if !ok {
|
||||
logger.LOG.Error("parse union cmd error")
|
||||
return
|
||||
}
|
||||
for _, unionCmd := range unionCmdNotify.GetCmdList() {
|
||||
p.protoDecodePayloadCore(uint16(unionCmd.MessageId), unionCmd.Body, protoMessageList)
|
||||
}
|
||||
}
|
||||
*protoMessageList = append(*protoMessageList, &ProtoMessage{
|
||||
cmdId: cmdId,
|
||||
message: protoObj,
|
||||
})
|
||||
}
|
||||
|
||||
func (p *ProtoEnDecode) protoEncode(protoMsg *ProtoMsg) (kcpMsg *KcpMsg) {
|
||||
logger.LOG.Debug("[send] proto msg, convId: %v, cmdId: %v, headMsg: %v", protoMsg.ConvId, protoMsg.CmdId, protoMsg.HeadMessage)
|
||||
kcpMsg = new(KcpMsg)
|
||||
kcpMsg.ConvId = protoMsg.ConvId
|
||||
kcpMsg.CmdId = protoMsg.CmdId
|
||||
// head msg
|
||||
if protoMsg.HeadMessage != nil {
|
||||
headData, err := pb.Marshal(protoMsg.HeadMessage)
|
||||
if err != nil {
|
||||
logger.LOG.Error("marshal head data err: %v", err)
|
||||
return nil
|
||||
}
|
||||
kcpMsg.HeadData = headData
|
||||
} else {
|
||||
kcpMsg.HeadData = nil
|
||||
}
|
||||
// payload msg
|
||||
if protoMsg.PayloadMessage != nil {
|
||||
cmdId, protoData := p.encodeProtoToPayload(protoMsg.PayloadMessage)
|
||||
if cmdId == 0 || protoData == nil {
|
||||
logger.LOG.Error("encode proto data is nil")
|
||||
return nil
|
||||
}
|
||||
if cmdId != 65535 && cmdId != protoMsg.CmdId {
|
||||
logger.LOG.Error("cmd id is not match with proto obj, src cmd id: %v, found cmd id: %v", protoMsg.CmdId, cmdId)
|
||||
return nil
|
||||
}
|
||||
kcpMsg.ProtoData = protoData
|
||||
} else {
|
||||
kcpMsg.ProtoData = nil
|
||||
}
|
||||
return kcpMsg
|
||||
}
|
||||
|
||||
func (p *ProtoEnDecode) decodePayloadToProto(cmdId uint16, protoData []byte) (protoObj pb.Message) {
|
||||
protoObj = p.cmdProtoMap.GetProtoObjByCmdId(cmdId)
|
||||
if protoObj == nil {
|
||||
logger.LOG.Error("get new proto object is nil")
|
||||
return nil
|
||||
}
|
||||
err := pb.Unmarshal(protoData, protoObj)
|
||||
if err != nil {
|
||||
logger.LOG.Error("unmarshal proto data err: %v", err)
|
||||
return nil
|
||||
}
|
||||
return protoObj
|
||||
}
|
||||
|
||||
func (p *ProtoEnDecode) encodeProtoToPayload(protoObj pb.Message) (cmdId uint16, protoData []byte) {
|
||||
cmdId = p.cmdProtoMap.GetCmdIdByProtoObj(protoObj)
|
||||
var err error = nil
|
||||
protoData, err = pb.Marshal(protoObj)
|
||||
if err != nil {
|
||||
logger.LOG.Error("marshal proto object err: %v", err)
|
||||
return 0, nil
|
||||
}
|
||||
return cmdId, protoData
|
||||
}
|
||||
Reference in New Issue
Block a user