package game import ( "encoding/json" "fmt" "runtime" "server/MergeConst" "server/conf" "server/db" Msg "server/game/mod/msg" GoUtil "server/game_util" "server/gamedata" "server/msg" "server/pkg/github.com/name5566/leaf/gate" "server/pkg/github.com/name5566/leaf/log" "time" "github.com/shirou/gopsutil/cpu" "github.com/shirou/gopsutil/mem" "google.golang.org/protobuf/proto" ) var AdminFuncMap = map[string]func([]interface{}) error{ "ReqAdminInfo": AdminPlayerInfo, "ReqServerInfo": ReqServerInfo, "ReqReloadServerMail": ReqReloadServerMail, "ReqReload": ReqReload, "ReqAdminGm": ReqAdminGm, "ReqAdminBan": ReqAdminBan, "ReqAdminShipping": ReqAdminShipping, } func AdminProcess(funcName string, args []interface{}) { defer func() { if r := recover(); r != nil { log.Error("uid : %d, func : %s, fatal : %s", 0, funcName, r) //GoUtil.SendFeishuFatal(0, funcName, fmt.Sprintf("fatal : %s", r)) } }() if f, ok := AdminFuncMap[funcName]; ok { err := f(args) if err != nil { log.Debug("AdminProcess error: %v", err) } return } log.Debug("AdminProcess error: %v", "Func not found") } func VerifyUser(accountInfo *db.Db_Account, detail *msg.ReqLogin) (ResLogin *msg.ResLogin, accountInfoOut *db.Db_Account) { if detail.Type == msg.LOGIN_TYPE_CODE_LOGIN { err := VerifyCode(detail.UserName, detail.Code) if err != nil { ResLogin = &msg.ResLogin{ ResultCode: MergeConst.Protocol_Error_Account_Code_Error, DwUin: 0, } return } } if detail.Type == msg.LOGIN_TYPE_SDK_LOGIN { if accountInfo == nil { accountInfo = db.GetAccountInfoFromDb(detail.Device) } if accountInfo != nil { db.UpdateAccountInfoName(accountInfo, detail.UserName) accountInfo.UserName = detail.UserName db.UpdatePlayerBaseInfoName(detail.Device, detail.UserName) } } if accountInfo == nil { ResLogin = &msg.ResLogin{ ResultCode: MergeConst.Protocol_Error_Account_NoExsit, DwUin: 0, } return } if detail.Type == msg.LOGIN_TYPE_ACCOUNT_LOGIN && accountInfo.UserPassword != detail.UserPwd { ResLogin = &msg.ResLogin{ ResultCode: MergeConst.Protocol_Error_Account_OR_PWD_ERROR, DwUin: 0, } return } if detail.Type == msg.LOGIN_TYPE_DEVICE_LOGIN { if detail.Device != accountInfo.DeviceId { ResLogin = &msg.ResLogin{ ResultCode: MergeConst.Protocol_Error_Account_Device_Error, DwUin: 0, } return } } playerbaseinfo := db.GetPlayerBaseInfoFromDbByName(detail.UserName) if playerbaseinfo == nil { ResLogin = &msg.ResLogin{ ResultCode: MergeConst.Protocol_Error_Account_NoExsit, DwUin: 0, } return } if playerbaseinfo.Ban > GoUtil.Now() || playerbaseinfo.Ban == -1 { ResLogin = &msg.ResLogin{ ResultCode: MergeConst.Protocol_Error_Account_Ban, DwUin: 0, } return } accountInfoOut = accountInfo ResLogin = &msg.ResLogin{ ResultCode: 0, DwUin: playerbaseinfo.DwUin, FaceBookId: playerbaseinfo.FaceBookId, UserName: playerbaseinfo.UserName, } return } func ReqAdminShipping(args []interface{}) error { a, buf := ParseAdminArgs(args) req := &msg.ReqAdminShipping{} proto.Unmarshal(buf, req) res := make(map[string]interface{}) res["Code"] = 0 orderInfo, err := db.GetPlayerChargeData(req.OrderSn) if err != nil { res["Code"] = 1 res["Msg"] = "order not found" AdminPlayerBack(a, res) } if orderInfo.PayStatus == MergeConst.ORDER_STATUS_SHIP { res["Msg"] = "order already shipped" AdminPlayerBack(a, res) } player := G_GameLogicPtr.GetPlayer(int64(orderInfo.Uid)) if player != nil { go player.TriggerShippingOrderOrigin(&msg.ReqShippingOrder{ OrderSn: req.OrderSn, }) res["Msg"] = "player online,triggered sync" AdminPlayerBack(a, res) } else { orderInfo.PayStatus = MergeConst.ORDER_STATUS_PAY orderInfo.PayChannelOrderId = req.ChannelOrderSn db.UpdatePlayerChargeData(orderInfo) } return nil } func AdminPlayerInfo(args []interface{}) error { a, buf := ParseAdminArgs(args) req := &msg.ReqAdminInfo{} proto.Unmarshal(buf, req) player := G_GameLogicPtr.GetPlayer(req.Uid) online := true if player == nil { player = new(Player) player.M_DwUin = req.Uid player.InitPlayerOnly() player.ZeroUpdate(nil) online = false } res := make(map[string]interface{}) res["Name"] = player.PlayMod.getBaseMod().NickName res["Uid"] = player.M_DwUin res["AreaId"] = player.PlayMod.getDecorateMod().GetAreaId() res["Face"] = player.PlayMod.getFaceMod().SetId res["Charge"] = player.PlayMod.getChargeMod().Charge res["MaxCharge"] = player.PlayMod.getChargeMod().MaxCharge res["Level"] = player.GetPlayerBaseMod().GetLevel() res["Diamond"] = player.GetPlayerBaseMod().GetDiamond() res["Star"] = player.GetPlayerBaseMod().GetStar() res["Energy"] = player.GetPlayerBaseMod().GetEnergy() res["Mac"] = player.GetPlayerBaseMod().GetName() res["Login"] = player.PlayMod.getBaseMod().LoginTime res["Cumulative"] = player.PlayMod.getBaseMod().Cumulative res["RegisterTime"] = player.GetPlayerBaseMod().GetRegisterTime() res["TodayCumulative"] = player.PlayMod.getBaseMod().TodayCumulative res["Ban"] = db.GetPlayerBan(player.PlayMod.getBaseMod().Account) if online { res["Cumulative"] = int64(player.PlayMod.getBaseMod().Cumulative) + GoUtil.Now() - int64(player.PlayMod.getBaseMod().LoginTime) res["TodayCumulative"] = int64(player.PlayMod.getBaseMod().TodayCumulative) + GoUtil.Now() - int64(player.PlayMod.getBaseMod().LoginTime) } res["Bonus"] = player.PlayMod.getLimitedTimeEventMod().Progress res["Code"] = player.PlayMod.getBaseMod().AddCode res["ChessMap"] = player.PlayMod.getChessMod().ChessMap res["ActLog"] = player.PlayMod.getFriendMod().ActivityLog res["AdWatch"] = player.PlayMod.getKvMod().GetAdValue() friendList := player.PlayMod.getFriendMod().NewFriendList type friendInfo struct { Uid int64 NickName string Avatar int Level int LogoutTime int64 LoginTime int64 } resFriendList := make([]friendInfo, 0, len(friendList)) for v := range friendList { ps := G_GameLogicPtr.GetSimplePlayerByUid(v) if ps == nil { continue } resFriendList = append(resFriendList, friendInfo{ Uid: int64(v), NickName: ps.Name, Avatar: ps.Face, Level: ps.Level, LogoutTime: ps.Loginout, LoginTime: ps.Login, }) } res["FriendList"] = resFriendList OrderMap := make(map[int]interface{}) Index := 0 for k, v := range player.PlayMod.getOrderMod().OrderList { OrderMap[Index] = map[string]interface{}{ "Id": k, "Type": v.Type, "Time": v.Timestamp, "ChessId": GoUtil.IntSliceToString(v.MergeId), "Diff": v.Diff, } Index++ } res["Order"] = OrderMap AdminPlayerBack(a, res) return nil } func AdminPlayerBack(a gate.Agent, res map[string]interface{}) { jsonBuff, _ := json.Marshal(res) response := &msg.AdminRes{} response.Func = "admin" response.Info = string(jsonBuff) a.WriteMsg(response) } func ReqServerInfo(args []interface{}) error { a, _ := ParseAdminArgs(args) res := make(map[string]interface{}) res["PlayerNum"] = G_GameLogicPtr.GetPlayerNum() res["StartTime"] = G_GameLogicPtr.GetStartTime() var m runtime.MemStats runtime.ReadMemStats(&m) res["TotalAlloc"] = fmt.Sprintf("%dM", m.TotalAlloc/(1024*1024)) // 2. 获取系统内存使用信息 vmStat, _ := mem.VirtualMemory() // 3. 获取 CPU 使用率(一秒内采样) cpuPercent, err := cpu.Percent(time.Second, false) if err == nil && len(cpuPercent) > 0 { res["CPU"] = cpuPercent[0] } res["Alloc"] = fmt.Sprintf("%dM", m.Alloc/(1024*1024)) res["Sys"] = m.Sys / (1024 * 1024) res["NumGC"] = m.NumGC res["NumGoroutine"] = runtime.NumGoroutine() if vmStat != nil { res["FreeMem"] = vmStat.Available / (1024 * 1024) res["UsageMem"] = vmStat.Used / (1024 * 1024) } else { res["UsageMem"] = 0 res["FreeMem"] = 0 } res["Version"] = conf.Server.Version AdminPlayerBack(a, res) return nil } func ReqReloadServerMail(args []interface{}) error { G_GameLogicPtr.MailMgrCall(&Msg.Msg{Type: Msg.HANDLE_TYPE_MAIL_RELOAD}) G_GameLogicPtr.NotifyAll(&Msg.Msg{Type: Msg.HANDLE_TYPE_MAIL}) log.Debug("ReqReloadServerMail success") return nil } func ReqReload(args []interface{}) error { a, _ := ParseAdminArgs(args) gamedata.Reload() res := make(map[string]interface{}) res["Code"] = 0 AdminPlayerBack(a, res) return nil } func ReqAdminGm(args []interface{}) error { a, buf := ParseAdminArgs(args) req := &msg.ReqAdminGm{} proto.Unmarshal(buf, req) res := make(map[string]interface{}) res["Code"] = 0 res["Msg"] = "ok" player := G_GameLogicPtr.GetPlayer(req.Uid) if player == nil { res["Code"] = 1 res["Msg"] = "player not found" AdminPlayerBack(a, res) return nil } player.lock.Lock() defer player.lock.Unlock() err := ReqGmCommand_(player, req.Command) if err != nil { res["Code"] = 1 res["Msg"] = err.Error() AdminPlayerBack(a, res) return err } AdminPlayerBack(a, res) return nil } func ReqAdminBan(args []interface{}) error { a, buf := ParseAdminArgs(args) req := &msg.ReqAdminBan{} proto.Unmarshal(buf, req) res := make(map[string]interface{}) res["Code"] = 0 res["Msg"] = "ok" db.UpdatePlayerBan(req.Uid, int64(req.Time)) AdminPlayerBack(a, res) return nil } func AcitivityCfgReload() { G_GameLogicPtr.ActivityMgr.Reload() } func AdminShipping(req *msg.ReqOrderShipping) (*msg.ResOrderShipping, error) { res := &msg.ResOrderShipping{} res.Code = 0 orderInfo, err := db.GetPlayerChargeData(req.OrderSn) if err != nil { res.Code = 1 res.Msg = "order not found" } if orderInfo.PayStatus == MergeConst.ORDER_STATUS_SHIP { res.Msg = "order already shipped" } // 玩家在线,通知发货 player := G_GameLogicPtr.GetPlayer(int64(orderInfo.Uid)) if player != nil { go player.TriggerShippingOrderOrigin(&msg.ReqShippingOrder{ OrderSn: req.OrderSn, }) res.Msg = "player online,triggered sync" } return res, nil } func AdminPlayerDetailInfo(req *msg.UserDetailParam) (*msg.ResUserDetail, error) { player := G_GameLogicPtr.GetPlayer(req.Uid) online := true if player == nil { player = new(Player) player.M_DwUin = req.Uid player.InitPlayerOnly() player.ZeroUpdate(nil) online = false } banTime := db.GetPlayerBan(player.PlayMod.getBaseMod().Account) actLog := make([]*msg.ActLog, 0, len(player.PlayMod.getFriendMod().ActivityLog)) for _, v := range player.PlayMod.getFriendMod().ActivityLog { actLog = append(actLog, &msg.ActLog{ Type: int32(v.Type), Time: v.Time, Param: v.Param, }) } info := &msg.ResUserDetailInfo{ Name: player.PlayMod.getBaseMod().Account, Uid: player.M_DwUin, AreaId: int32(player.PlayMod.getDecorateMod().GetAreaId()), Face: int32(player.PlayMod.getFaceMod().SetId), Charge: int32(player.PlayMod.getChargeMod().Charge), MaxCharge: int32(player.PlayMod.getChargeMod().MaxCharge), Level: int32(player.GetBaseMod().GetLevel()), Diamond: int64(player.GetBaseMod().GetDiamond()), Star: int32(player.GetBaseMod().GetStar()), Energy: int32(player.GetBaseMod().GetEnergy()), Mac: player.GetBaseMod().DiviceId, Login: int64(player.GetBaseMod().LoginTime), Cumulative: int64(player.PlayMod.getBaseMod().Cumulative), RegisterTime: player.GetPlayerBaseMod().GetRegisterTime(), TodayCumulative: int64(player.PlayMod.getBaseMod().TodayCumulative), Ban: banTime > GoUtil.Now() || banTime == -1, Bonus: int32(player.PlayMod.getLimitedTimeEventMod().Progress), Code: player.PlayMod.getBaseMod().AddCode, ActLog: actLog, AdWatch: int32(player.PlayMod.getKvMod().GetAdValue()), ChessMap: player.PlayMod.getChessMod().ChessMap, } if online { info.Cumulative = int64(player.PlayMod.getBaseMod().Cumulative) + GoUtil.Now() - int64(player.PlayMod.getBaseMod().LoginTime) info.TodayCumulative = int64(player.PlayMod.getBaseMod().TodayCumulative) + GoUtil.Now() - int64(player.PlayMod.getBaseMod().LoginTime) } friendList := player.PlayMod.getFriendMod().NewFriendList info.FriendList = make([]*msg.UserDetailFriendInfo, 0, len(friendList)) for uid := range friendList { ps := G_GameLogicPtr.GetSimplePlayerByUid(uid) if ps == nil { continue } info.FriendList = append(info.FriendList, &msg.UserDetailFriendInfo{ Uid: int64(uid), NickName: ps.Name, Avatar: int32(ps.Face), Level: int32(ps.Level), LogoutTime: ps.Loginout, LoginTime: ps.Login, }) } orderList := player.PlayMod.getOrderMod().OrderList info.Order = make([]*msg.UserDetailOrderInfo, 0, len(orderList)) for orderID, order := range orderList { info.Order = append(info.Order, &msg.UserDetailOrderInfo{ Id: fmt.Sprint(orderID), Type: int32(order.Type), Time: order.Timestamp, ChessId: GoUtil.IntSliceToString(order.MergeId), Diff: int32(order.Diff), }) } return &msg.ResUserDetail{ Code: 0, Msg: "ok", Info: info, }, nil }