2025-06-26 23:20:11 +08:00
|
|
|
package controller
|
|
|
|
|
|
|
|
|
|
import (
|
2025-07-31 07:31:25 +00:00
|
|
|
"blazing/common/socket/errorcode"
|
2025-09-04 02:00:57 +08:00
|
|
|
|
2025-07-06 11:38:02 +08:00
|
|
|
"blazing/cool"
|
2025-09-14 01:35:16 +08:00
|
|
|
|
|
|
|
|
"blazing/logic/service/player"
|
2025-08-28 19:17:03 +00:00
|
|
|
"strings"
|
2025-06-26 23:20:11 +08:00
|
|
|
|
|
|
|
|
"bytes"
|
|
|
|
|
"context"
|
|
|
|
|
"fmt"
|
|
|
|
|
"reflect"
|
|
|
|
|
|
2025-07-06 11:38:02 +08:00
|
|
|
"github.com/gogf/gf/v2/os/gcmd"
|
2025-06-26 23:20:11 +08:00
|
|
|
"github.com/gogf/gf/v2/os/glog"
|
|
|
|
|
"github.com/gogf/gf/v2/util/gconv"
|
|
|
|
|
"github.com/lunixbochs/struc"
|
|
|
|
|
)
|
|
|
|
|
|
2025-07-06 19:31:30 +08:00
|
|
|
var Maincontroller = NewController() //注入service
|
2025-10-10 23:59:54 +08:00
|
|
|
|
|
|
|
|
func NewController() *Controller {
|
|
|
|
|
return &Controller{}
|
|
|
|
|
}
|
|
|
|
|
|
2025-06-26 23:20:11 +08:00
|
|
|
// 分发cmd逻辑实现Controller
|
|
|
|
|
type Controller struct {
|
2025-07-15 13:51:10 +00:00
|
|
|
Port uint16
|
2025-07-06 19:31:30 +08:00
|
|
|
RPCClient struct {
|
2025-07-15 14:00:32 +00:00
|
|
|
Kick func(uint32) error
|
2025-07-06 22:58:39 +08:00
|
|
|
|
2025-07-17 05:20:30 +08:00
|
|
|
RegisterLogic func(uint16, uint16) error
|
2025-07-06 19:31:30 +08:00
|
|
|
}
|
2025-06-26 23:20:11 +08:00
|
|
|
}
|
|
|
|
|
|
2025-08-27 20:52:15 +00:00
|
|
|
func ParseCmd[T any](a T, data []byte) T {
|
2025-06-26 23:20:11 +08:00
|
|
|
// := info.NewLoginSidInfo()
|
|
|
|
|
struc.Unpack(bytes.NewBuffer(data), &a)
|
|
|
|
|
return a
|
|
|
|
|
//fmt.Println(pinfo)
|
|
|
|
|
//login.OnData_1001(pinfo, player)
|
|
|
|
|
//fmt.Println(data)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func init() { //默认初始化扫描
|
2025-07-06 11:38:02 +08:00
|
|
|
// 解析命令行参数
|
2025-07-17 05:20:30 +08:00
|
|
|
cool.Config.PortBL = gcmd.GetOpt("port", "1").Uint16()
|
2025-06-26 23:20:11 +08:00
|
|
|
// 获取对象的反射值和类型
|
2025-07-06 19:31:30 +08:00
|
|
|
value := reflect.ValueOf(Maincontroller)
|
2025-06-26 23:20:11 +08:00
|
|
|
|
|
|
|
|
// 获取类型
|
|
|
|
|
typ := value.Type()
|
|
|
|
|
|
|
|
|
|
for i := 0; i < typ.NumMethod(); i++ {
|
|
|
|
|
method := typ.Method(i)
|
|
|
|
|
|
|
|
|
|
methodValue := value.MethodByName(method.Name)
|
2025-08-30 00:36:08 +08:00
|
|
|
//fmt.Println("找到注册方法", method.Name)
|
2025-06-26 23:20:11 +08:00
|
|
|
methodValue.Type().NumIn()
|
|
|
|
|
|
2025-08-28 19:17:03 +00:00
|
|
|
for _, func_cmd := range getcmd(methodValue.Type().In(0)) {
|
|
|
|
|
if func_cmd == 0 { //说明不是注册方法
|
|
|
|
|
glog.Warning(context.Background(), "方法参数必须是结构体", method.Name, "跳过注册")
|
|
|
|
|
continue
|
|
|
|
|
}
|
2025-06-26 23:20:11 +08:00
|
|
|
|
2025-08-28 19:17:03 +00:00
|
|
|
if cool.Config.PortBL == 0 && func_cmd > 1000 { //判断login服务器
|
|
|
|
|
continue
|
2025-07-06 11:38:02 +08:00
|
|
|
|
2025-08-28 19:17:03 +00:00
|
|
|
}
|
2025-07-06 11:38:02 +08:00
|
|
|
|
2025-08-28 19:17:03 +00:00
|
|
|
if cool.Config.PortBL != 0 && func_cmd < 1000 { //判断login服务器
|
|
|
|
|
continue
|
2025-06-26 23:20:11 +08:00
|
|
|
|
2025-08-28 19:17:03 +00:00
|
|
|
}
|
|
|
|
|
glog.Debug(context.Background(), "注册方法", func_cmd, method.Name)
|
2025-09-14 01:35:16 +08:00
|
|
|
// fmt.Println(methodValue.Interface().(func(gnet.Conn, player.TomeeHeader)))
|
2025-08-28 19:17:03 +00:00
|
|
|
_, ok := cool.CmdCache.LoadOrStore(func_cmd, methodValue) //TODO 待实现对不同用户初始化方法以取消全局cmdcache
|
|
|
|
|
|
|
|
|
|
if ok { //方法已存在init
|
|
|
|
|
glog.Error(context.Background(), "方法已存在init,不会初始化后面的方法", func_cmd)
|
|
|
|
|
}
|
2025-06-26 23:20:11 +08:00
|
|
|
}
|
2025-08-28 19:17:03 +00:00
|
|
|
|
2025-06-26 23:20:11 +08:00
|
|
|
}
|
|
|
|
|
}
|
2025-07-06 11:38:02 +08:00
|
|
|
|
2025-08-28 19:17:03 +00:00
|
|
|
func getcmd(t reflect.Type) []uint32 {
|
2025-06-26 23:20:11 +08:00
|
|
|
// 处理指针类型
|
|
|
|
|
if t.Kind() == reflect.Ptr {
|
|
|
|
|
t = t.Elem() // 获取指针指向的类型
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 确保是结构体
|
|
|
|
|
if t.Kind() != reflect.Struct {
|
2025-07-15 11:24:49 +08:00
|
|
|
|
2025-08-28 19:17:03 +00:00
|
|
|
return []uint32{0}
|
2025-06-26 23:20:11 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 遍历结构体字段
|
|
|
|
|
// fmt.Printf("结构体 %s 的字段信息:\n", t.Name())
|
|
|
|
|
for i := 0; i < t.NumField(); i++ {
|
|
|
|
|
field := t.Field(i)
|
2025-06-27 22:40:49 +08:00
|
|
|
//fmt.Printf("- 字段名: %s\n", field.Name)
|
|
|
|
|
//fmt.Printf(" 类型: %v\n", field.Type)
|
2025-09-14 01:35:16 +08:00
|
|
|
if field.Type == reflect.TypeOf(player.TomeeHeader{}) {
|
2025-06-26 23:20:11 +08:00
|
|
|
// fmt.Println(reflect.ValueOf(field))
|
|
|
|
|
|
2025-08-28 19:17:03 +00:00
|
|
|
return gconv.SliceUint32(strings.Split(field.Tag.Get("cmd"), "|"))
|
2025-06-26 23:20:11 +08:00
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if field.Type.Kind() == reflect.Struct ||
|
|
|
|
|
(field.Type.Kind() == reflect.Ptr && field.Type.Elem().Kind() == reflect.Struct) {
|
2025-07-25 22:50:08 +08:00
|
|
|
|
2025-06-26 23:20:11 +08:00
|
|
|
nestedType := field.Type
|
|
|
|
|
if nestedType.Kind() == reflect.Ptr {
|
|
|
|
|
nestedType = nestedType.Elem()
|
|
|
|
|
}
|
|
|
|
|
getcmd(nestedType)
|
|
|
|
|
}
|
|
|
|
|
// fmt.Println()
|
|
|
|
|
}
|
2025-08-28 19:17:03 +00:00
|
|
|
return []uint32{0}
|
2025-06-26 23:20:11 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 遍历结构体方法并执行RECV_cmd
|
2025-09-14 01:35:16 +08:00
|
|
|
func Recv(c *player.Conn, data player.TomeeHeader) {
|
2025-06-26 23:20:11 +08:00
|
|
|
|
2025-07-25 06:22:16 +00:00
|
|
|
cmdlister, ok := cool.CmdCache.Load(data.CMD)
|
2025-06-26 23:20:11 +08:00
|
|
|
if !ok {
|
|
|
|
|
|
|
|
|
|
glog.Error(context.Background(), data.CMD, "cmd未注册")
|
|
|
|
|
return //TODO 待实现cmd未注册
|
|
|
|
|
}
|
2025-07-25 06:22:16 +00:00
|
|
|
|
2025-06-26 23:20:11 +08:00
|
|
|
// fmt.Println(cmdlister)
|
2025-09-01 01:03:46 +08:00
|
|
|
glog.Debug(context.Background(), "接收数据", data.UserID, data.CMD)
|
2025-06-26 23:20:11 +08:00
|
|
|
params := []reflect.Value{}
|
|
|
|
|
|
2025-06-27 22:40:49 +08:00
|
|
|
//funct := cmdlister.Type().NumIn()
|
2025-06-26 23:20:11 +08:00
|
|
|
|
|
|
|
|
// 如果需要可设置的变量(用于修改值),创建指针并解引用
|
2025-07-16 11:30:37 +08:00
|
|
|
ptrValue := reflect.New(cmdlister.Type().In(0).Elem())
|
2025-06-27 22:40:49 +08:00
|
|
|
|
|
|
|
|
tt1 := ptrValue.Elem().Addr().Interface()
|
|
|
|
|
// fmt.Println(tt1)
|
|
|
|
|
err := struc.Unpack(bytes.NewBuffer(data.Data), tt1)
|
|
|
|
|
if err != nil {
|
|
|
|
|
fmt.Println(err)
|
|
|
|
|
}
|
|
|
|
|
//fmt.Println(tt1)
|
2025-07-16 11:30:37 +08:00
|
|
|
ptrValue1 := ptrValue.Elem().Addr()
|
2025-06-27 22:40:49 +08:00
|
|
|
// 设置 Name 字段
|
|
|
|
|
nameField := ptrValue.Elem().Field(0) //首个为header
|
|
|
|
|
if nameField.IsValid() && nameField.CanSet() {
|
|
|
|
|
nameField.Set(reflect.ValueOf(data))
|
|
|
|
|
}
|
2025-09-14 01:35:16 +08:00
|
|
|
if cmdlister.Type().In(1) == reflect.TypeOf(&player.Player{}) {
|
|
|
|
|
t := player.GetPlayer(c, data.UserID)
|
2025-08-30 00:36:08 +08:00
|
|
|
// fmt.Println(data.CMD, "接收 变量的地址 ", &t.Info, t.Info.UserID)
|
|
|
|
|
err := t.WaitForLoginWithCtx(context.Background())
|
2025-07-17 06:09:52 +08:00
|
|
|
if err != nil {
|
|
|
|
|
fmt.Println("登录失败")
|
|
|
|
|
}
|
2025-06-26 23:20:11 +08:00
|
|
|
|
2025-08-30 00:36:08 +08:00
|
|
|
params = append(params, ptrValue1, reflect.ValueOf(t))
|
2025-06-27 22:40:49 +08:00
|
|
|
} else {
|
2025-07-06 23:14:57 +08:00
|
|
|
|
2025-06-27 22:40:49 +08:00
|
|
|
params = append(params, ptrValue1, reflect.ValueOf(c))
|
2025-06-26 23:20:11 +08:00
|
|
|
}
|
|
|
|
|
|
2025-07-25 22:50:08 +08:00
|
|
|
ret := cmdlister.Call(params)
|
2025-07-11 21:28:38 +08:00
|
|
|
|
2025-07-25 22:50:08 +08:00
|
|
|
if len(ret) <= 0 { //如果判断没有参数,那就说明这个包没有返回参数
|
2025-07-25 07:46:31 +00:00
|
|
|
return
|
|
|
|
|
}
|
2025-07-26 02:14:54 +00:00
|
|
|
|
2025-07-31 07:31:25 +00:00
|
|
|
aa, ok := ret[1].Interface().(errorcode.ErrorCode) //判断错误
|
2025-08-17 21:55:15 +08:00
|
|
|
data.Result = uint32(aa)
|
|
|
|
|
if aa == -1 {
|
|
|
|
|
return
|
|
|
|
|
|
|
|
|
|
}
|
2025-07-25 22:50:08 +08:00
|
|
|
|
2025-07-31 07:31:25 +00:00
|
|
|
if ok && aa != 0 { //这里实现回复错误包
|
2025-07-25 22:50:08 +08:00
|
|
|
|
2025-07-31 07:31:25 +00:00
|
|
|
cool.Loger.Error(context.Background(), aa.Code())
|
2025-07-25 22:50:08 +08:00
|
|
|
|
2025-07-26 02:14:54 +00:00
|
|
|
c.SendPack(data.Pack(nil))
|
2025-07-25 22:50:08 +08:00
|
|
|
return
|
|
|
|
|
|
2025-07-15 21:11:56 +00:00
|
|
|
}
|
2025-08-17 21:55:15 +08:00
|
|
|
|
|
|
|
|
data.Version = "7"
|
2025-08-30 00:36:08 +08:00
|
|
|
//glog.Debug(context.Background(), data.CMD, "回复数据")
|
2025-07-26 02:14:54 +00:00
|
|
|
c.SendPack(data.Pack(ret[0].Interface()))
|
2025-07-15 21:22:54 +00:00
|
|
|
|
2025-07-25 22:50:08 +08:00
|
|
|
}
|