refactor(controller): 重构ParseCmd函数并优化Init方法

- 修改ParseCmd函数参数,移除不必要的泛型参数T
- 为Init函数添加详细注释说明参数含义
- 优化getCmd函数的注释和代码结构
- 重命名ParseCmdTagWithStructField为parseCmdTagWithStructField以符合私有函数命名规范

refactor(pet_info): 统一玩家参数命名从c到player

- 将pet_info.go中所有方法的player参数名从c改为player
- 保持代码逻辑不变,仅统一参数命名规范
- 更新相关
This commit is contained in:
2025-12-25 12:21:15 +08:00
parent 164e70519f
commit d84100a52f
5 changed files with 149 additions and 137 deletions

View File

@@ -33,59 +33,65 @@ type Controller struct {
// ParseCmd 将字节数组数据解析到指定类型的变量中
// 该函数使用struc库进行数据解包操作
func ParseCmd[T any](a T, data []byte) T {
// := info.NewLoginSidInfo()
// 使用struc.Unpack将字节数据解包到变量a中
struc.Unpack(bytes.NewBuffer(data), &a)
return a
//fmt.Println(pinfo)
//login.OnData_1001(pinfo, player)
//fmt.Println(data)
// 参数 data: 需要解析的字节数据
// 返回值: 解析后的指定类型实例
func ParseCmd[T any](data []byte) T {
var result T
// 使用struc.Unpack将字节数据解包到result变量中
struc.Unpack(bytes.NewBuffer(data), &result)
return result
}
func Init(isgame bool) { //默认初始化扫描
// Init 初始化控制器注册所有cmd处理方法
// 参数 isGame: 标识是否为游戏服务器(true)或登录服务器(false)
func Init(isGame bool) {
// 获取控制器实例的反射值
controllerValue := reflect.ValueOf(Maincontroller)
// 获取控制器类型
controllerType := controllerValue.Type()
// 获取对象的反射值和类型
value := reflect.ValueOf(Maincontroller)
// 遍历控制器的所有方法
for i := 0; i < controllerType.NumMethod(); i++ {
method := controllerType.Method(i)
methodValue := controllerValue.MethodByName(method.Name)
// 获取类型
typ := value.Type()
// 获取方法第一个参数的类型(请求结构体)
if methodValue.Type().NumIn() == 0 {
continue
}
for i := 0; i < typ.NumMethod(); i++ {
method := typ.Method(i)
methodValue := value.MethodByName(method.Name)
//fmt.Println("找到注册方法", method.Name)
methodValue.Type().NumIn()
for _, funcCmd := range getCmd(methodValue.Type().In(0)) {
if funcCmd == 0 { //说明不是注册方法
// 解析请求结构体中的cmd标签
for _, cmd := range getCmd(methodValue.Type().In(0)) {
if cmd == 0 { // 说明不是有效的注册方法
glog.Warning(context.Background(), "方法参数必须包含CMD参数", method.Name, "跳过注册")
continue
}
if !isgame && funcCmd > 1000 { //判断login服务器
// 根据服务器类型过滤cmd
// 登录服务器只处理小于1000的cmd
if !isGame && cmd > 1000 {
continue
}
if isgame && funcCmd < 1000 { //判断login服务器
// 游戏服务器只处理大于等于1000的cmd
if isGame && cmd < 1000 {
continue
}
glog.Debug(context.Background(), "注册方法", funcCmd, method.Name)
_, ok := cool.CmdCache.LoadOrStore(funcCmd, cool.Cmd{
// 注册命令处理函数
glog.Debug(context.Background(), "注册方法", cmd, method.Name)
cmdInfo := cool.Cmd{
Func: methodValue,
Req: methodValue.Type().In(0).Elem(),
// Res: ,
}) //TODO 待实现对不同用户初始化方法以取消全局cmdcache
if ok { //方法已存在init
glog.Error(context.Background(), "方法已存在init,不会初始化后面的方法", funcCmd)
// Res: , // TODO 待实现对不同用户初始化方法以取消全局cmdcache
}
_, exists := cool.CmdCache.LoadOrStore(cmd, cmdInfo)
if exists { // 方法已存在
glog.Error(context.Background(), "命令处理方法已存在,跳过注册", cmd, method.Name)
}
}
}
}
@@ -95,33 +101,30 @@ var targetType = reflect.TypeOf(common.TomeeHeader{})
const defaultCmdValue = 0
// getCmd 从结构体类型中提取绑定的cmd指令递归查找嵌套结构体支持值/指针类型的TomeeHeader
// 参数 typ待解析的结构体类型支持多层指针
// 返回值解析到的cmd切片无匹配/解析失败时返回[defaultCmdValue]
// 参数 typ: 待解析的结构体类型(支持多层指针)
// 返回值: 解析到的cmd切片无匹配/解析失败时返回[defaultCmdValue]
func getCmd(typ reflect.Type) []uint32 {
// 初始化目标类型(仅第一次调用时执行
// 1. 递归解引用所有指针类型(处理 *struct、**struct 等场景)
// 递归解引用所有指针类型(处理 *struct、**struct 等场景
for typ.Kind() == reflect.Ptr {
typ = typ.Elem()
}
// 2. 非结构体类型直接返回默认值
// 非结构体类型直接返回默认值
if typ.Kind() != reflect.Struct {
return []uint32{defaultCmdValue}
}
// 3. 遍历结构体字段查找TomeeHeader字段并解析cmd
// 遍历结构体字段查找TomeeHeader字段并解析cmd
for i := 0; i < typ.NumField(); i++ {
field := typ.Field(i)
// 4. 调用解析函数,判断是否为目标类型并解析cmd
cmdSlice, err := ParseCmdTagWithStructField(field)
// 尝试解析当前字段的cmd标签
cmdSlice, err := parseCmdTagWithStructField(field)
if err == nil { // 解析成功,直接返回结果
return cmdSlice
}
// 5. 递归处理嵌套结构体(值/指针类型)
// 递归处理嵌套结构体(值/指针类型)
nestedTyp := field.Type
if nestedTyp.Kind() == reflect.Ptr {
nestedTyp = nestedTyp.Elem()
@@ -134,15 +137,14 @@ func getCmd(typ reflect.Type) []uint32 {
}
}
// 6. 未找到目标字段/所有解析失败,返回默认值
// 未找到目标字段/所有解析失败,返回默认值
return []uint32{defaultCmdValue}
}
// ParseCmdTagWithStructField 校验字段是否为TomeeHeader值/指针并解析cmd标签
// 参数 field结构体字段元信息
// 返回值解析后的cmd切片非目标类型/解析失败返回错误
func ParseCmdTagWithStructField(field reflect.StructField) ([]uint32, error) {
// parseCmdTagWithStructField 校验字段是否为TomeeHeader值/指针并解析cmd标签
// 参数 field: 结构体字段元信息
// 返回值: 解析后的cmd切片非目标类型/解析失败返回错误
func parseCmdTagWithStructField(field reflect.StructField) ([]uint32, error) {
// 判断字段类型是否为 TomeeHeader 或 *TomeeHeader
var isTomeeHeader bool
switch {