```
refactor(common): 统一使用 common.TomeeHeader 替代 player.TomeeHeader 将多处
This commit is contained in:
114
logic/service/common/pack.go
Normal file
114
logic/service/common/pack.go
Normal file
@@ -0,0 +1,114 @@
|
||||
package common
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/binary"
|
||||
"fmt"
|
||||
"reflect"
|
||||
|
||||
"github.com/lunixbochs/struc"
|
||||
)
|
||||
|
||||
// TomeeHeader 结构体字段定义
|
||||
type TomeeHeader struct {
|
||||
Len uint32 `json:"len"`
|
||||
Version byte `json:"version" struc:"[1]byte"`
|
||||
CMD uint32 `json:"cmdId" struc:"uint32"`
|
||||
UserID uint32 `json:"userId"`
|
||||
//Error uint32 `json:"error" struc:"[0]pad"`
|
||||
|
||||
Result uint32 `json:"result"`
|
||||
Data []byte `json:"data" struc:"skip"` //组包忽略此字段// struc:"[0]pad"
|
||||
//Return []byte `struc:"[0]pad"` //返回记录
|
||||
}
|
||||
|
||||
func NewTomeeHeader(cmd uint32, userid uint32) *TomeeHeader {
|
||||
|
||||
return &TomeeHeader{
|
||||
CMD: cmd,
|
||||
// Len: 0,
|
||||
Version: 49,
|
||||
Result: 0,
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Pack 组包方法:手动编码字节流,兼容interface{}、nil、多层指针/接口
|
||||
func (h *TomeeHeader) Pack(data any) []byte {
|
||||
//h.Result = 0//默认置0
|
||||
|
||||
//t := reflect.TypeOf(data)
|
||||
tv := reflect.ValueOf(data)
|
||||
var datar []byte
|
||||
|
||||
// 处理指针类型
|
||||
if tv.Kind() == reflect.Ptr {
|
||||
//tv = t.Elem() // 获取指针指向的类型
|
||||
tv = tv.Elem() // 获取指针指向的值
|
||||
}
|
||||
|
||||
switch tv.Kind() {
|
||||
case reflect.String:
|
||||
datar = []byte(tv.String())
|
||||
case reflect.Slice:
|
||||
datar = data.([]byte)
|
||||
//p.Conn.Write(p.pack(cmd, data.([]byte))) //写入数据
|
||||
|
||||
case reflect.Struct:
|
||||
var data1 bytes.Buffer
|
||||
err := struc.Pack(&data1, data)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
}
|
||||
|
||||
datar = data1.Bytes()
|
||||
|
||||
default:
|
||||
datar = []byte{}
|
||||
// fmt.Println(err, datar)
|
||||
// p.Conn.Write(p.pack(cmd, data))
|
||||
|
||||
}
|
||||
|
||||
// 4. 手动打包包头+数据体
|
||||
return h.packHeaderWithData(datar)
|
||||
}
|
||||
|
||||
// packHeaderWithData 手动编码包头和数据体(静态指定偏移量,无自增变量)
|
||||
// 包头固定结构(大端序):
|
||||
// - 0-3 字节:Len (uint32)
|
||||
// - 4 字节:Version (byte)
|
||||
// - 5-8 字节:CMD (uint32,从uint64截断)
|
||||
// - 9-12 字节:UserID (uint32)
|
||||
// - 13-16 字节:Result (uint32)
|
||||
// 17字节后:数据体
|
||||
func (h *TomeeHeader) packHeaderWithData(data []byte) []byte {
|
||||
// 计算总长度:包头17字节 + 数据体长度
|
||||
dataLen := len(data)
|
||||
h.Len = uint32(17 + dataLen)
|
||||
|
||||
// 预分配切片(总长度 = 包头 + 数据体),避免多次扩容
|
||||
buf := make([]byte, h.Len)
|
||||
|
||||
// 1. 写入Len(固定偏移:0-3 字节,大端序)
|
||||
binary.BigEndian.PutUint32(buf[0:4], h.Len)
|
||||
|
||||
// 2. 写入Version(固定偏移:4 字节)
|
||||
buf[4] = h.Version
|
||||
|
||||
// 3. 写入CMD(固定偏移:5-8 字节,大端序)
|
||||
binary.BigEndian.PutUint32(buf[5:9], uint32(h.CMD))
|
||||
|
||||
// 4. 写入UserID(固定偏移:9-12 字节,大端序)
|
||||
binary.BigEndian.PutUint32(buf[9:13], h.UserID)
|
||||
|
||||
// 5. 写入Result(固定偏移:13-16 字节,大端序)
|
||||
binary.BigEndian.PutUint32(buf[13:17], h.Result)
|
||||
|
||||
// 6. 写入数据体(固定起始偏移:17 字节,若有数据则拷贝)
|
||||
if dataLen > 0 {
|
||||
copy(buf[17:], data)
|
||||
}
|
||||
|
||||
return buf
|
||||
}
|
||||
Reference in New Issue
Block a user