package game import ( "fmt" "reflect" "server/MergeConst" "server/conf" "server/game/internal" GoUtil "server/game_util" "strings" "time" "server/msg" "server/pkg/github.com/name5566/leaf/gate" "server/pkg/github.com/name5566/leaf/log" "google.golang.org/protobuf/proto" "server/db" ) var ( Module = new(internal.Module) ChanRPC = internal.ChanRPC ) func handler(m interface{}, h interface{}) { Module.Skeleton.RegisterChanRPC(reflect.TypeOf(m), h) } func RegisterHandlerRPC(param []interface{}) { handler(&msg.ClientReq{}, HandleClientReq) handler(&msg.AdminReq{}, HandleAdminReq) } func init() { register() db.InitDB() db.InitRedis() // db.TestGetAllKey() GoUtil.RegisterEvent("GameModuleOnInit", RegisterHandlerRPC, nil) G_getGameLogic() } func HandleAdminReq(args []interface{}) { m := args[0].(*msg.AdminReq) // 消息的发送者 a := args[1].(gate.Agent) buf := m.GetInfo() // log.Debug("admin 消息Func : %s", m.GetFunc()) AdminProcess(m.GetFunc(), []interface{}{a, buf}) } func HandleClientReq(args []interface{}) { start := time.Now() if G_GameLogicPtr.SeverInfo.Status == SERVER_STATUS_CLOSE || G_GameLogicPtr.SeverInfo.Status == SERVER_STATUS_MAINTAIN { return // 服务器关闭或者维护中,不处理任何消息 } m := args[0].(*msg.ClientReq) // 消息的发送者 a := args[1].(gate.Agent) buf := m.GetInfo() // log.Debug("消息Func : %s", m.GetFunc()) switch m.GetFunc() { case "ClientTick": case "ReqChangePassword": detail := &msg.ReqChangePassword{} proto.Unmarshal(buf, detail) accountInfo := db.GetAccountInfoFromDb(detail.UserName) if accountInfo == nil { ResChangePassword := &msg.ResChangePassword{} ResChangePassword.ResultCode = MergeConst.Protocol_Error_Account_NoExsit data, _ := proto.Marshal(ResChangePassword) G_GameLogicPtr.PackResInfo(a, "ResChangePassword", data) return } if accountInfo.UserPassword != detail.OldPwd && detail.OldPwd != "-1" { ResChangePassword := &msg.ResChangePassword{} ResChangePassword.ResultCode = MergeConst.Protocol_Error_Account_OR_PWD_ERROR data, _ := proto.Marshal(ResChangePassword) G_GameLogicPtr.PackResInfo(a, "ResChangePassword", data) return } if strings.Count(detail.NewPwd, "")-1 < 6 { ResChangePassword := &msg.ResChangePassword{} ResChangePassword.ResultCode = MergeConst.Protocol_Error_Account_OR_PWD_Short data, _ := proto.Marshal(ResChangePassword) G_GameLogicPtr.PackResInfo(a, "ResChangePassword", data) return } accountInfo.UserPassword = detail.NewPwd err := db.UpdateAccountInfoToDb(accountInfo) if err != nil { ResChangePassword := &msg.ResChangePassword{} ResChangePassword.ResultCode = MergeConst.Protocol_Error_Account_Fail data, _ := proto.Marshal(ResChangePassword) G_GameLogicPtr.PackResInfo(a, "ResChangePassword", data) return } ResChangePassword := &msg.ResChangePassword{} ResChangePassword.ResultCode = 0 data, _ := proto.Marshal(ResChangePassword) G_GameLogicPtr.PackResInfo(a, "ResChangePassword", data) case "ReqAdminInfo": // 后台接口 AdminProcess(m.GetFunc(), []interface{}{a, buf}) case "ReqLoginCode": Detail := &msg.ReqLoginCode{} proto.Unmarshal(buf, Detail) Code, err := GeneratedCode(Detail.TelPhone) ResLoginCode := &msg.ResLoginCode{} if err != nil { ResLoginCode.ResultCode = MergeConst.Protocol_Error_Account_Code_Error ResLoginCode.Msg = err.Error() } ResLoginCode.Code = Code data, _ := proto.Marshal(ResLoginCode) G_GameLogicPtr.PackResInfo(a, "ResLoginCode", data) case "ReqServerVersion": G_GameLogicPtr.SendServerVersion(a) case "ReqRegisterAccount": detail := &msg.ReqRegisterAccount{} log.Debug("player %s start login", detail.UserName) proto.Unmarshal(buf, detail) gl := G_getGameLogic() defer func() { if r := recover(); r != nil { GoUtil.SendFeishuFatal(0, m.GetFunc(), fmt.Sprintf("username: %s, fatal: %s", detail.UserName, r)) log.Error("uid : %d, func : %s, fatal : %s", 0, m.GetFunc(), r) } }() if gl.IsExsitAccount(detail.UserName) { ResRegisterAccount := &msg.ResRegisterAccount{} ResRegisterAccount.ResultCode = MergeConst.Protocol_Error_Account_Exist data, _ := proto.Marshal(ResRegisterAccount) gl.PackResInfo(a, "ResRegisterAccount", data) break } gl.Db_AccountInfo.UserName = detail.UserName gl.Db_AccountInfo.UserPassword = detail.UserPwd if !gl.NewAccountInsertDataToDB() { ResRegisterAccount := &msg.ResRegisterAccount{} ResRegisterAccount.ResultCode = MergeConst.Protocol_Error_Account_Fail data, _ := proto.Marshal(ResRegisterAccount) gl.PackResInfo(a, "ResRegisterAccount", data) break } ResRegisterAccount := &msg.ResRegisterAccount{} ResRegisterAccount.ResultCode = 0 data, _ := proto.Marshal(ResRegisterAccount) gl.PackResInfo(a, "ResRegisterAccount", data) case "ReqLogin": // 登录请求 detail := &msg.ReqLogin{} proto.Unmarshal(buf, detail) accountInfo := db.GetAccountInfoFromDb(detail.UserName) log.Debug("player %s start login", detail.UserName) defer func() { if r := recover(); r != nil { GoUtil.SendFeishuFatal(0, m.GetFunc(), fmt.Sprintf("username: %s, fatal: %s", detail.UserName, r)) log.Error("uid : %d, func : %s, fatal : %s", 0, m.GetFunc(), r) } }() ResLogin, accountInfo := VerifyUser(accountInfo, detail) if ResLogin.ResultCode != 0 { G_GameLogicPtr.PackLoginResInfo(a, ResLogin) return } newPlayer := false if ResLogin.DwUin > 0 { PlayerInfo := G_GameLogicPtr.GetPlayer(ResLogin.DwUin) err := G_GameLogicPtr.ReplaceExistPlayerAndAgent(a, PlayerInfo) if err != nil { PlayerInfo = G_GameLogicPtr.CreateNewPlayer(a, detail.UserName) newPlayer = true } if PlayerInfo.PlayMod.getBaseMod().IdCardName == "" && conf.Server.IdVerify { ResLogin.ResultCode = MergeConst.Protocol_Error_Id_Not_Verify G_GameLogicPtr.PackLoginResInfo(a, ResLogin) return } } accountInfo.DeviceId = detail.Device db.UpdateAccountInfoDeviceToDb(accountInfo) p, _ := internal.Agents.Load(a) if p != nil { p.(*Player).lock.Lock() //加锁 defer p.(*Player).lock.Unlock() //解锁 log.Debug("player %s login success", detail.UserName) p.(*Player).PlayMod.getBaseMod().DiviceId = detail.Device //加锁 p.(*Player).PushClientRes(ResLogin) p.(*Player).LoginBackData() p.(*Player).TeLog("Login_log", nil) p.(*Player).ProcessTrigger() } log.Debug("uid : %d, init user process : %s, execTime : %v , isNew: %v", p.(*Player).M_DwUin, m.GetFunc(), time.Since(start), newPlayer) case "ReqServerTime": // 获取服务器时间 detail := &msg.ReqServerTime{} proto.Unmarshal(buf, detail) res := &msg.ResServerTime{} res.ServerTime = (int32)(time.Now().Unix()) data, _ := proto.Marshal(res) G_getGameLogic().PackResInfo(a, "ResServerTime", data) case "ReqOfflineReconnect": // 断线重连 ReqOfflineReconnectFunc(a, buf) default: p, ok := internal.Agents.Load(a) if ok && p != G_GameLogicPtr.NotInitPlayer { p.(*Player).lock.Lock() //加锁 backup := p.(*Player).BackUp() // 备份当前的 Player 值 defer func() { if r := recover(); r != nil { if m.GetFunc() != "ReqGmCommand" { // 如果不是 GM 命令,才记录日志和发送飞书告警 log.Error("uid : %d, func : %s, fatal : %s", p.(*Player).M_DwUin, m.GetFunc(), r) GoUtil.SendFeishuFatal(int(p.(*Player).M_DwUin), m.GetFunc(), fmt.Sprintf("fatal : %s", r)) } p.(*Player).Recover(backup) //还原Player的数据 } p.(*Player).lock.Unlock() //解锁 }() p.(*Player).args = make(map[string]interface{}) p.(*Player).args["func"] = m p.(*Player).args["agent"] = a err := RunNetProcessByKey(m.GetFunc(), []interface{}{a, buf}) if err != nil { log.Error("uid : %d, func : %s, err : %s", p.(*Player).M_DwUin, m.GetFunc(), err) p.(*Player).TeLog("func_exec_error", map[string]interface{}{ "method_name": m.GetFunc(), "error_info": err.Error(), }) p.(*Player).Recover(backup) //还原Player的数据 return } p.(*Player).ProcessTrigger() p.(*Player).TeLog("func_exec_time", map[string]interface{}{ "method_name": m.GetFunc(), "exec_time": fmt.Sprintf("%v", time.Since(start)), }) } } p, b := internal.Agents.Load(a) if b { p.(*Player).SendClientRes() } //log.Debug("uid : %d, func : %s, execTime : %s ", p.(*Player).M_DwUin, m.GetFunc(), time.Since(start)) }