refactor: 将XOR解密逻辑和事件处理移至player服务
All checks were successful
ci/woodpecker/push/my-first-workflow Pipeline was successful

This commit is contained in:
xinian
2026-02-22 01:01:37 +08:00
committed by cnb
parent ae764c946a
commit 4e313f02c7
3 changed files with 65 additions and 62 deletions

View File

@@ -4,7 +4,6 @@ import (
"context" "context"
"encoding/binary" "encoding/binary"
"errors" "errors"
"fmt"
"io" "io"
"log" "log"
"os" "os"
@@ -19,7 +18,6 @@ import (
"github.com/gogf/gf/v2/frame/g" "github.com/gogf/gf/v2/frame/g"
"github.com/gogf/gf/v2/os/gtime" "github.com/gogf/gf/v2/os/gtime"
"github.com/panjf2000/gnet/v2" "github.com/panjf2000/gnet/v2"
"github.com/valyala/bytebufferpool"
) )
func (s *Server) Boot(serverid, port uint16) error { func (s *Server) Boot(serverid, port uint16) error {
@@ -282,65 +280,10 @@ func (s *Server) onevent(c gnet.Conn, v []byte) {
header.Data = v[17:] header.Data = v[17:]
} }
if header.CMD > 1001 {
if t.Player == nil {
fmt.Println(header.UserID, "账号未注册")
return
}
if t.Player.Info == nil {
fmt.Println(header.UserID, "未创建角色")
return
}
if len(header.Data) > 0 {
header.Data = XORDecryptU(header.Data, t.Player.Hash)
}
}
if cool.Config.ServerInfo.IsDebug != 0 {
fmt.Println("接收数据", header.UserID, header.CMD)
}
s.workerPool.Submit(func() {
t.LF.Producer().Write(header) t.LF.Producer().Write(header)
})
} }
} }
// XORDecryptU 优化后的异或解密:减少内存分配,支持复用缓冲区
// XORDecryptU 基于bytebufferpool优化的异或解密函数
// 保留原有接口无侵入式优化高频调用下大幅减少内存分配和GC
func XORDecryptU(encryptedData []byte, key uint32) []byte {
if len(encryptedData) == 0 {
return []byte{}
}
// 1. 栈上分配密钥字节数组无GC压力保留原优化
var keyBytes [4]byte
binary.BigEndian.PutUint32(keyBytes[:], key)
keyLen := len(keyBytes)
// 2. 从bytebufferpool获取池化缓冲区替代make分配
buf := bytebufferpool.Get()
defer bytebufferpool.Put(buf) // 函数结束自动归还缓冲区到池
// 3. 调整缓冲区长度,匹配待解密数据(避免扩容)
buf.B = buf.B[:0] // 清空原有数据,保留底层数组
if cap(buf.B) < len(encryptedData) {
// 若缓冲区容量不足直接扩容bytebufferpool会自动管理
buf.B = make([]byte, len(encryptedData))
} else {
// 容量足够,直接调整长度
buf.B = buf.B[:len(encryptedData)]
}
// 4. 核心异或解密逻辑直接操作buf.B无额外内存分配
decrypted := buf.B
for i, b := range encryptedData {
decrypted[i] = b ^ keyBytes[i%keyLen]
}
// 5. 拷贝结果(关键:避免返回池化缓冲区,防止被后续调用覆盖)
result := make([]byte, len(decrypted))
copy(result, decrypted)
return result
}

View File

@@ -85,7 +85,7 @@ func (h Controller) ArenaFightOwner(data1 *fight.ARENA_FIGHT_OWENR, c *player.Pl
c.Info.EVPool += addev c.Info.EVPool += addev
c.SendPackCmd(8004, &info.S2C_GET_BOSS_MONSTER{ //发送EV c.SendPackCmd(8004, &info.S2C_GET_BOSS_MONSTER{ //发送EV
ItemList: []data.ItemInfo{data.ItemInfo{ ItemList: []data.ItemInfo{{
ItemId: 9, ItemId: 9,
ItemCnt: int64(addev), ItemCnt: int64(addev),
}}, }},
@@ -101,7 +101,7 @@ func (h Controller) ArenaFightOwner(data1 *fight.ARENA_FIGHT_OWENR, c *player.Pl
c.GetSpace().Owner.ARENA_Player.GetInfo().EVPool += addev c.GetSpace().Owner.ARENA_Player.GetInfo().EVPool += addev
c.GetSpace().Owner.ARENA_Player.SendPackCmd(8004, &info.S2C_GET_BOSS_MONSTER{ //发送EV c.GetSpace().Owner.ARENA_Player.SendPackCmd(8004, &info.S2C_GET_BOSS_MONSTER{ //发送EV
ItemList: []data.ItemInfo{data.ItemInfo{ ItemList: []data.ItemInfo{{
ItemId: 9, ItemId: 9,
ItemCnt: int64(addev), ItemCnt: int64(addev),
}}, }},

View File

@@ -4,6 +4,7 @@ import (
"blazing/common/socket/errorcode" "blazing/common/socket/errorcode"
"blazing/cool" "blazing/cool"
"blazing/logic/service/common" "blazing/logic/service/common"
"encoding/binary"
"sync" "sync"
"context" "context"
@@ -18,6 +19,7 @@ import (
"github.com/gogf/gf/v2/os/glog" "github.com/gogf/gf/v2/os/glog"
"github.com/lunixbochs/struc" "github.com/lunixbochs/struc"
"github.com/panjf2000/gnet/v2" "github.com/panjf2000/gnet/v2"
"github.com/valyala/bytebufferpool"
) )
// getUnderlyingValue 递归解析reflect.Value解包指针、interface{}到底层具体类型 // getUnderlyingValue 递归解析reflect.Value解包指针、interface{}到底层具体类型
@@ -45,6 +47,46 @@ func getUnderlyingValue(val reflect.Value) (reflect.Value, error) {
} }
} }
// XORDecryptU 优化后的异或解密:减少内存分配,支持复用缓冲区
// XORDecryptU 基于bytebufferpool优化的异或解密函数
// 保留原有接口无侵入式优化高频调用下大幅减少内存分配和GC
func XORDecryptU(encryptedData []byte, key uint32) []byte {
if len(encryptedData) == 0 {
return []byte{}
}
// 1. 栈上分配密钥字节数组无GC压力保留原优化
var keyBytes [4]byte
binary.BigEndian.PutUint32(keyBytes[:], key)
keyLen := len(keyBytes)
// 2. 从bytebufferpool获取池化缓冲区替代make分配
buf := bytebufferpool.Get()
defer bytebufferpool.Put(buf) // 函数结束自动归还缓冲区到池
// 3. 调整缓冲区长度,匹配待解密数据(避免扩容)
buf.B = buf.B[:0] // 清空原有数据,保留底层数组
if cap(buf.B) < len(encryptedData) {
// 若缓冲区容量不足直接扩容bytebufferpool会自动管理
buf.B = make([]byte, len(encryptedData))
} else {
// 容量足够,直接调整长度
buf.B = buf.B[:len(encryptedData)]
}
// 4. 核心异或解密逻辑直接操作buf.B无额外内存分配
decrypted := buf.B
for i, b := range encryptedData {
decrypted[i] = b ^ keyBytes[i%keyLen]
}
// 5. 拷贝结果(关键:避免返回池化缓冲区,防止被后续调用覆盖)
result := make([]byte, len(decrypted))
copy(result, decrypted)
return result
}
// 遍历结构体方法并执行RECV_cmd // 遍历结构体方法并执行RECV_cmd
func (h *ClientData) OnEvent(data common.TomeeHeader) { func (h *ClientData) OnEvent(data common.TomeeHeader) {
defer func() { defer func() {
@@ -64,6 +106,24 @@ func (h *ClientData) OnEvent(data common.TomeeHeader) {
} }
}() }()
if data.CMD > 1001 {
if h.Player == nil {
fmt.Println(data.UserID, "账号未注册")
return
}
if h.Player.Info == nil {
fmt.Println(data.UserID, "未创建角色")
return
}
if len(data.Data) > 0 {
data.Data = XORDecryptU(data.Data, h.Player.Hash)
}
}
if cool.Config.ServerInfo.IsDebug != 0 {
fmt.Println("接收数据", data.UserID, data.CMD)
}
cmdlister, ok := cool.CmdCache[data.CMD] cmdlister, ok := cool.CmdCache[data.CMD]
if !ok { if !ok {