package main import ( "bytes" "crypto/md5" "encoding/gob" "encoding/hex" "fmt" "io" "math" "math/rand" "os" "slices" "sort" "strconv" "time" "github.com/globalsign/mgo/bson" "mongo.games.com/goserver/core/basic" "mongo.games.com/goserver/core/logger" "mongo.games.com/goserver/core/netlib" "mongo.games.com/goserver/core/task" "mongo.games.com/goserver/srvlib" srvlibproto "mongo.games.com/goserver/srvlib/protocol" "mongo.games.com/game/common" "mongo.games.com/game/model" "mongo.games.com/game/proto" "mongo.games.com/game/protocol/bag" hallproto "mongo.games.com/game/protocol/gamehall" loginproto "mongo.games.com/game/protocol/login" msgproto "mongo.games.com/game/protocol/message" playerproto "mongo.games.com/game/protocol/player" "mongo.games.com/game/protocol/rankmatch" serverproto "mongo.games.com/game/protocol/server" shopproto "mongo.games.com/game/protocol/shop" webapiproto "mongo.games.com/game/protocol/webapi" "mongo.games.com/game/srvdata" "mongo.games.com/game/worldsrv/internal" ) // 对应到客户端的一个玩家对象. const ( PlayerStateOnline int = iota PlayerStateOffline ) const ( UpdateField_Coin int64 = 1 << iota UpdateField_SafeBoxCoin UpdateField_VIP UpdateField_CoinPayTotal UpdateField_TotalConvertibleFlow UpdateField_Ticket UpdateField_Grade UpdateField_Diamond UpdateField_VCoin UpdateField_ChessGrade UpdateField_RankScore UpdateField_PhoneScore UpdateField_InviteScore ) const ( CurrencyType_Card int32 = iota CurrencyType_Coin CurrencyType_Money CurrencyType_RMB ) var VIP_RandWeight = []int64{30, 30, 20, 10, 5, 5} type ErrorString struct { code string } func (this *ErrorString) Error() string { return this.code } type Player struct { *model.PlayerData //po 持久化对象 diffData model.PlayerDiffData //差异数据 gateSess *netlib.Session //所在GateServer的session scene *Scene //当前所在个Scene thrscene int //是否在三方 sid int64 //对应客户端的sessionId state int //玩家状态 PlayerStateOnline PlayerStateOffline lastSaved time.Time //最后保存的时间 dirty bool //脏标记 pos int //位置 msgs map[string]*model.Message // beUnderAgent bool //是否隶属于代理 lastSceneId map[int32][]int32 //上一个房间id;gamefreeid:房间号 ollenSecs int32 //在线时长 currClubId int32 //当前所在的俱乐部id takeCoin int64 //携带金币 sceneCoin int64 //房间里当前的金币量 isNewbie bool //是否是新用户 applyPos int32 //申请的场景位置 flag int32 //Game服务器的用户状态 hallId int32 //所在游戏大厅 changeIconTime time.Time //上次修改头像时间 enterts time.Time //进入时间 lastChangeScene time.Time //上次换桌时间 isAudience bool //是否是观众 customerToken string //客服会话token isDelete bool //是否已删档用户 thridBalanceRefreshReqing bool //玩家请求刷新三方金额进行中 thridBalanceReqIsSucces bool //三方请求刷新成功 params *model.PlayerParams //客户端登陆游戏带上来的临时参数 exchangeState bool //订单操作状态 lastOnDayChange time.Time lastOnWeekChange time.Time lastOnMonthChange time.Time //例如["WWG平台"][true:已经刷新过不用再次刷新,false:未知需要刷新] //注意:该数据不会落地到mgo,游服第一次启动的时候会请求全部三方刷新余额,之后就会根据标记来进行刷新。 //确保thirdBalanceRefreshMark只在主协程里面操作 thirdBalanceRefreshMark map[string]bool EnterCoinSceneQueueTs int64 CoinSceneQueueRound int32 CoinSceneQueue *CoinScenePool EnterQueueTime time.Time //进入队列的时间 //比赛 cparams map[string]string //平台登陆数据 "name", "head", "geo-info", "lang", "ip" Iparams map[int]int64 //整形参数 sparams map[int]string //字符参数 //用户登录时获取 单用户活动开关控制 layered map[int]bool //true 为关 false为开 //用户分层ids layerlevels []int //缓存玩家身上所有分层数据 miniScene map[int32]*Scene //当前所在个Scene leavechan chan int // 比赛环境 matchCtx *PlayerMatchContext // 在线记录 onlineLog *model.OnlineLog // 数据埋点 DeviceName string // 设备名称 PackageName string // 包名 AppVersion string // app版本 BuildVersion string // app构建版本 AppChannel string // app渠道(玩家本次登录使用的包的渠道类型,换登录包,这个值也会变;玩家model.PlayerData存储的渠道是玩家第一次登录的渠道,不会修改) // 最后玩的游戏id LastGameId int GameID []int32 // 最近三天玩的游戏 ApplyList []int32 //玩家申请好友记录 TaskInviteList map[int32]int // 邀请好友私人桌对局 好友id:房间id } func NewPlayer(sid int64, pd *model.PlayerData, s *netlib.Session) *Player { // 玩家数据初始化 p := &Player{ PlayerData: pd, sid: sid, gateSess: s, msgs: make(map[string]*model.Message), cparams: make(map[string]string), Iparams: make(map[int]int64), sparams: make(map[int]string), pos: -1, beUnderAgent: pd.BeUnderAgentCode != "", thirdBalanceRefreshMark: make(map[string]bool), layered: make(map[int]bool), miniScene: make(map[int32]*Scene), TaskInviteList: make(map[int32]int), } if p.IsRob { p.RobotRandName() } if p.init() { return p } return nil } // 玩家数据初始化 func (this *Player) init() bool { this.SetOnline() this.isNewbie = this.CreateTime == this.LastLoginTime if this.WelfData == nil { this.WelfData = model.NewWelfareData() } if this.VCardCost < 0 { this.VCardCost = 0 } return true } func (this *Player) GenCustomerToken() string { if this.customerToken != "" { return this.customerToken } raw := fmt.Sprintf("%v%v%v%v%v", this.SnId, this.AccountId, this.sid, common.GetAppId(), time.Now().UnixNano()) h := md5.New() io.WriteString(h, raw) token := hex.EncodeToString(h.Sum(nil)) return token } func (this *Player) SyncBagData(itemInfo []*bag.ItemInfo) { pack := &bag.SCSyncBagData{ Infos: itemInfo, } this.SendToClient(int(bag.SPacketID_PACKET_SC_SYNCBAGDATA), pack) logger.Logger.Tracef("背包数据变更(%v): %v", this.SnId, pack) } // SendToClient 给客户端发消息,玩家需要在线 func (this *Player) SendToClient(packetid int, rawpack interface{}) bool { if this.IsOffline() { logger.Logger.Trace("Player if offline.") return false } return this.SendRawToClientIncOffLine(this.sid, this.gateSess, packetid, rawpack) } // SendRawToClientIncOffLine 给客户端发消息,不关心是否在线 func (this *Player) SendRawToClientIncOffLine(sid int64, gateSess *netlib.Session, packetid int, rawpack interface{}) bool { if gateSess == nil { logger.Logger.Tracef("[%v] sess == nil ", this.SnId, packetid) return false } if rawpack == nil { logger.Logger.Trace(" rawpack == nil ") return false } return common.SendToGate(sid, packetid, rawpack, gateSess) } func (this *Player) SendToGame(packetid int, rawpack interface{}) bool { if this.scene == nil || this.scene.gameSess == nil || this.scene.gameSess.Session == nil { logger.Logger.Tracef("[%v] sess == nil ", this.Name) return false } if rawpack == nil { logger.Logger.Trace(" rawpack == nil ") return false } return this.scene.SendToGame(packetid, rawpack) } func (this *Player) LoadAfter() { var replays []*internal.PlayerLoadReplay task.New(nil, task.CallableWrapper(func(o *basic.Object) interface{} { for _, v := range internal.GetPlayerLoads() { replays = append(replays, v.LoadAfter(this.Platform, this.SnId)) } return nil }), task.CompleteNotifyWrapper(func(i interface{}, t task.Task) { if len(replays) != len(internal.GetPlayerLoads()) { return } for k, v := range internal.GetPlayerLoads() { if v == nil || replays[k] == nil { continue } v.CallbackAfter(replays[k]) } })).StartByFixExecutor(fmt.Sprintf("Player%v", this.SnId)) } func (this *Player) OnLogined() { logger.Logger.Tracef("(this *Player) OnLogined() %v", this.SnId) this.lastSaved = time.Now() isFirstLogin := false if this.CreateTime.Unix() > this.LastLogoutTime.Unix() { isFirstLogin = true } if !this.IsRob { this.ResetPermit() } // 跨天业务处理 tNow := time.Now() tLastLogout := this.PlayerData.LastLogoutTime this.PlayerData.LastLoginTime = tNow this.PlayerData.LastLogoutTime = tNow this.dirty = true if !common.InSameDay(tNow, tLastLogout) { //跨天 logger.Logger.Infof("(this *Player) OnLogined(%v) inSameDay LastLogoutTime(%v)", this.SnId, tLastLogout) isContinueDay := common.IsContinueDay(tNow, tLastLogout) // 计算跨了多少天 var t int t1 := tLastLogout t2 := tNow out := time.Date(t1.Year(), t1.Month(), t1.Day(), 0, 0, 0, 0, t1.Location()) in := time.Date(t2.Year(), t2.Month(), t2.Day(), 0, 0, 0, 0, t2.Location()) t = int(math.Floor(in.Sub(out).Hours() / 24)) this.OnDayTimer(true, isContinueDay, t) } // 跨月 inSameMoney := common.InSameMonth(tNow, tLastLogout) if !inSameMoney { this.OnMonthTimer() } // 跨周 inSameWeek := common.InSameWeek(tNow, tLastLogout) if !inSameWeek { this.OnWeekTimer() } this.SetOnline() //测试用 if !this.IsRob { old := this.VIP this.VIP = this.GetVIPLevel() if old != this.VIP { this.dirty = true } } else { this.VIP = rand.Int31n(6) + 1 //机器人随机vip和头像 this.RobRandVip() } this.VipExtra = VipMgrSington.GetVipPointsExtra(this.Platform, this.VIP) // 头像决定性别 this.Sex = (this.Head%2 + 1) % 2 // 初始化差异数据 this.BackDiffData() this.BindGroupTag([]string{this.Platform}) gameStateMgr.PlayerClear(this) //玩家登录事件 FirePlayerLogined(this) this.RandRobotExData() this.SendJackPotInit() this.GetPayGoodsInfo() if !this.IsRob { PlayerOnlineSington.Check = true this.LoadMessage(tLastLogout.Unix(), isFirstLogin, !inSameWeek) //登录次数 this.LoginTimes++ //登录事件 this.ReportLoginEvent() //抽奖次数兼容老玩家 if !this.InitLotteryStatus && WelfareMgrSington.GetPhoneLotteryStatus(this.Platform) == model.WelfareOpen { this.addLotteryCount(20) this.InitLotteryStatus = true this.dirty = true LogChannelSingleton.WriteMQData(model.GeneratePhoneLottery(this.SnId, this.Platform, "", 3, 20, 5, 0)) } //登录日志 logState := LoginStateMgrSington.GetLoginStateBySid(this.sid) var clog *model.ClientLoginInfo if logState != nil { clog = logState.clog } LogChannelSingleton.WriteLog(model.NewLoginLog(this.SnId, common.LoginLogTypeLogin, this.Tel, this.Ip, this.Platform, this.Channel, this.BeUnderAgentCode, this.PackageID, this.City, clog, this.GetTotalCoin(), 0, 0, this.DeviceName, this.PackageName, this.AppVersion, this.BuildVersion, this.AppChannel)) this.OnlineLogLogin() this.SendToRepSrv(this.PlayerData) //红点检测 this.CheckShowRed() TaskSubjectSingleton.Touch(common.TaskTypeLogin, &TaskData{SnId: this.SnId, Num: 1}) // 登录游戏 this.LoadAfter() } } func (this *Player) OnRehold() { logger.Logger.Tracef("(this *Player) OnRehold() %v", this.SnId) this.SetOnline() var gameid int if this.scene != nil && this.scene.gameSess != nil { //if this.scene.sceneId == SceneMgrSingleton.GetDgSceneId() { // // DG特殊处理 // //如果是之前进入的是DG游戏,就退出DG游戏 // this.DgGameLogout() //} else { // 告诉游戏服务玩家重连 var gateSid int64 if this.gateSess != nil { if srvInfo, ok := this.gateSess.GetAttribute(srvlib.SessionAttributeServerInfo).(*srvlibproto.SSSrvRegiste); ok && srvInfo != nil { sessionId := srvlib.NewSessionIdEx(srvInfo.GetAreaId(), srvInfo.GetType(), srvInfo.GetId(), 0) gateSid = sessionId.Get() } } pack := &serverproto.WGPlayerRehold{ Id: proto.Int32(this.SnId), Sid: proto.Int64(this.sid), SceneId: proto.Int(this.scene.sceneId), GateSid: proto.Int64(gateSid), } proto.SetDefaults(pack) this.SendToGame(int(serverproto.SSPacketID_PACKET_WG_PLAYERREHOLD), pack) logger.Logger.Tracef("WG PlayerRehold: %v", pack) //} gameid = this.scene.gameId } this.BindGroupTag([]string{this.Platform}) //登录事件 this.ReportLoginEvent() gameStateMgr.PlayerClear(this) //玩家重连事件 FirePlayerRehold(this) FriendMgrSington.ApplyList(this.Platform, this.SnId) FriendUnreadMgrSington.CheckSendFriendUnreadData(this.Platform, this.SnId) this.CheckShowRed() this.SendJackPotInit() this.GetPayGoodsInfo() RankMgrSingleton.CheckShowRed(this.SnId) if !this.IsRob { PlayerOnlineSington.Check = true // 记录重连日志 logState := LoginStateMgrSington.GetLoginStateBySid(this.sid) var clog *model.ClientLoginInfo if logState != nil { clog = logState.clog } LogChannelSingleton.WriteLog(model.NewLoginLog(this.SnId, common.LoginLogTypeRehold, this.Tel, this.Ip, this.Platform, this.Channel, this.BeUnderAgentCode, this.PackageID, this.City, clog, this.GetTotalCoin(), gameid, 0, this.DeviceName, this.PackageName, this.AppVersion, this.BuildVersion, this.AppChannel)) this.OnlineLogRehold() } } func (this *Player) CheckShowRed() { this.MessageShowRed() //商城红点 ShopMgrSington.ShopCheckShowRed(this) //数据依赖于背包数据 放入加载背包数据之后执行 PetMgrSington.CheckShowRed(this) //福利红点 WelfareMgrSington.WelfareShowRed(this) } // 为了worldsrv和gamesrv上机器人信息一致 func (this *Player) RandRobotExData() { if !this.IsRob { return } // 角色 datas := srvdata.PBDB_Game_IntroductionMgr.Datas.GetArr() if datas != nil { //随机 //var roles = []int32{} //for _, data := range datas { // if data.Type == 1 { //角色 // roles = append(roles, data.Id) // } //} //if roles != nil && len(roles) > 0 { // randId := common.RandInt32Slice(roles) // this.Roles = new(model.RolePetInfo) // this.Roles.ModUnlock = make(map[int32]int32) // this.Roles.ModUnlock[randId] = 1 // this.Roles.ModId = randId //} //女8男2 rand := common.RandInt(100) randId := int32(2000001) if rand < 20 { randId = 2000002 } this.Roles = new(model.RolePetInfo) this.Roles.ModUnlock = make(map[int32]int32) this.Roles.ModUnlock[randId] = 1 this.Roles.ModId = randId } // 宠物 // datas := srvdata.PBDB_Game_IntroductionMgr.Datas.GetArr() // if datas != nil { // var pets = []int32{} // for _, data := range datas { // if data.Type == 2 { //宠物 // pets = append(pets, data.Id) // } // } // if pets != nil && len(pets) > 0 { // randId := common.RandInt32Slice(pets) // this.Pets = new(model.RolePetInfo) // this.Pets.ModUnlock = make(map[int32]int32) // this.Pets.ModUnlock[randId] = 1 // this.Pets.ModId = randId // } // } } // SendGameConfig 玩家断线重连时,获取玩家所有游戏的配置信息 func (this *Player) SendGameConfig(gameId int32, plf, chl string) { pack := &hallproto.SCGetGameConfig{ GameId: gameId, } gps := PlatformMgrSingleton.GetGameFrees(this.Platform) for _, v := range gps { if v.Status && PlatformMgrSingleton.GetGlobalConfig().GameStatus[v.DbGameFree.Id] { if v.DbGameFree.GetGameRule() != 0 && v.DbGameFree.GetGameId() == gameId { // 场次配置 lgc := &hallproto.GameConfig1{ LogicId: proto.Int32(v.DbGameFree.Id), LimitCoin: proto.Int64(v.DbGameFree.GetLimitCoin()), MaxCoinLimit: proto.Int64(v.DbGameFree.GetMaxCoinLimit()), BaseScore: proto.Int32(v.DbGameFree.GetBaseScore()), BetScore: proto.Int32(v.DbGameFree.GetBetLimit()), OtherIntParams: v.DbGameFree.GetOtherIntParams(), MaxBetCoin: v.DbGameFree.GetMaxBetCoin(), MatchMode: proto.Int32(v.DbGameFree.GetMatchMode()), Status: v.Status, SceneType: v.DbGameFree.GetSceneType(), ChessGradeLimit: v.DbGameFree.GetChessGradeLimit(), RankType: v.DbGameFree.GetRankType(), SceneAdd: v.DbGameFree.GetSceneAdd(), } // 排位场参数 if v.DbGameFree.GetRankType() > 0 { lgc.RankType = v.DbGameFree.GetRankType() lgc.SceneAdd = v.DbGameFree.GetSceneAdd() } pack.GameCfg = append(pack.GameCfg, lgc) } } } // 游戏配置 if srvdata.GameFreeMgr.IsGameDif(gameId, common.GameDifChess) { cfg := ChessRankMgrSington.GetChessRankConfig(this.GetPlatform().Name, gameId) for _, v := range cfg.GetDatas() { pack.ChessRanks = append(pack.ChessRanks, &hallproto.ChessRankInfo{ Score: v.Score, Name: v.Name, }) } } this.SendToClient(int(hallproto.GameHallPacketID_PACKET_SC_GETGAMECONFIG), pack) logger.Logger.Tracef("SendGameConfig:%v", pack) } func (this *Player) LoadMessage(lastLogoutTime int64, isFirstLogin, isSkipWeek bool) { task.New(nil, task.CallableWrapper(func(o *basic.Object) interface{} { //msgs, err := model.GetMessageByNotState(this.SnId, model.MSGSTATE_REMOVEED) //if err == nil { // return msgs //} else { // logger.Logger.Warnf("[%v] LoadMessage err:%v", this.Name, err) //} msgs, err := model.GetMessage(this.Platform, this.SnId) // model.GetNotDelMessage(this.Platform, this.SnId) if err == nil { return msgs } else { logger.Logger.Warnf("[%v] LoadMessage err:%v", this.Name, err) } return nil }), task.CompleteNotifyWrapper(func(data interface{}, tt task.Task) { if data != nil { if msgs, ok := data.([]model.Message); ok { for i := 0; i < len(msgs); i++ { this.msgs[msgs[i].Id.Hex()] = &msgs[i] } } //跨周 邮件>0 if isSkipWeek && len(this.msgs) > 0 { //过期邮件处理 for key, msg := range this.msgs { if msg.AttachState == model.MSGATTACHSTATE_DEFAULT && msg.Ticket > 0 { this.TicketTotalDel += msg.Ticket this.DelMessage(key, 1) } } this.dirty = true } var dbMsgs []*model.Message //第一次登录需要屏蔽订阅的邮件 if !isFirstLogin { msgs := MsgMgrSington.GetSubscribeMsgs(this.Platform, lastLogoutTime) for _, msg := range msgs { bHasAddToPlayer := false for _, pMsg := range this.msgs { if pMsg.Pid == msg.Id.Hex() { bHasAddToPlayer = true break } } if bHasAddToPlayer == false { newMsg := model.NewMessage(msg.Id.Hex(), msg.SrcId, "", this.SnId, msg.MType, msg.Title, msg.Content, msg.Coin, msg.Diamond, model.MSGSTATE_UNREAD, msg.CreatTs, msg.AttachState, msg.GiftId, msg.Params, msg.Platform, msg.ShowId, msg.Channel) dbMsgs = append(dbMsgs, newMsg) } } } if len(dbMsgs) != 0 { task.New(nil, task.CallableWrapper(func(o *basic.Object) interface{} { return model.InsertMessage(this.Platform, dbMsgs...) }), task.CompleteNotifyWrapper(func(data interface{}, tt task.Task) { if data == nil { for _, msg := range dbMsgs { bHasAddToPlayer := false for _, pMsg := range this.msgs { if pMsg.Pid == msg.Id.Hex() { bHasAddToPlayer = true break } } if bHasAddToPlayer == false { this.AddMessage(msg) } } // 邮件由客户端拉取 //this.SendMessage() } }), "InsertMessage").StartByFixExecutor("logic_message") } else { // this.SendMessage() } if len(this.msgs) > model.MSG_MAX_COUNT { maxTs := int64(0) for _, m := range this.msgs { if m.CreatTs > maxTs { maxTs = m.CreatTs } } this.verifyMessage(maxTs) } this.MessageShowRed() } }), "GetMessage").StartByFixExecutor("logic_message") } func (this *Player) SendMessage(showId int64) { pack := &msgproto.SCMessageList{} if len(this.msgs) != 0 { for _, msg := range this.msgs { if msg.State != model.MSGSTATE_REMOVEED && (msg.ShowId == model.HallAll || msg.ShowId&showId != 0) { if len(msg.Channel) > 0 && !common.InSliceString(msg.Channel, this.LastChannel) { continue } giftState := int32(0) //if len(msg.GiftId) > 0 { // gift := GiftMgrSington.GetFromRecvGift(this.SnId, msg.GiftId) // if gift != nil { // giftState = gift.State // } else { // logger.Logger.Error("player: ", this.SnId, " not find gift : ", msg.GiftId) // } //} pack.Msgs = append(pack.Msgs, &msgproto.MessageData{ Id: proto.String(msg.Id.Hex()), Title: proto.String(msg.Title), Content: proto.String(msg.Content), MType: proto.Int32(msg.MType), SrcId: proto.Int32(msg.SrcId), SrcName: proto.String(msg.SrcName), Coin: proto.Int64(msg.Coin), Diamond: proto.Int64(msg.Diamond), Ticket: proto.Int64(msg.Ticket), Grade: proto.Int64(msg.Grade), State: proto.Int32(msg.State), Ts: proto.Int32(int32(msg.CreatTs)), Params: msg.Params, AttachState: proto.Int32(msg.AttachState), GiftId: proto.String(msg.GiftId), GiftState: proto.Int32(giftState), }) } } proto.SetDefaults(pack) } //nil的msg需要发给前端便于覆盖前一个玩家的信息 this.SendToClient(int(msgproto.MSGPacketID_PACKET_SC_MESSAGELIST), pack) } func (this *Player) ReadMessage(id string) { if msg, exist := this.msgs[id]; exist { if msg.State == model.MSGSTATE_UNREAD { msg.State = model.MSGSTATE_READED task.New(nil, task.CallableWrapper(func(o *basic.Object) interface{} { return model.ReadMessage(msg.Id, msg.Platform) }), task.CompleteNotifyWrapper(func(data interface{}, tt task.Task) { if data == nil { pack := &msgproto.SCMessageRead{ Id: proto.String(id), } proto.SetDefaults(pack) this.SendToClient(int(msgproto.MSGPacketID_PACKET_SC_MESSAGEREAD), pack) } }), "ReadMessage").StartByFixExecutor("logic_message") } } } func (this *Player) WebDelMessage(id string) { if msg, exist := this.msgs[id]; exist { if msg.State != model.MSGSTATE_REMOVEED { // 未删除状态通知客户端 pack := &msgproto.SCMessageDel{ Id: id, } proto.SetDefaults(pack) this.SendToClient(int(msgproto.MSGPacketID_PACKET_SC_MESSAGEDEL), pack) } //删除此邮件 delete(this.msgs, id) } } func (this *Player) DelMessage(id string, del int32) bool { if msg, exist := this.msgs[id]; exist { if msg.State != model.MSGSTATE_REMOVEED { task.New(nil, task.CallableWrapper(func(o *basic.Object) interface{} { args := &model.DelMsgArgs{ Platform: msg.Platform, Id: msg.Id, Del: del, } return model.DelMessage(args) }), task.CompleteNotifyWrapper(func(data interface{}, tt task.Task) { if data == nil { pack := &msgproto.SCMessageDel{ Id: id, } proto.SetDefaults(pack) this.SendToClient(int(msgproto.MSGPacketID_PACKET_SC_MESSAGEDEL), pack) msg.State = model.MSGSTATE_REMOVEED //删除此邮件 delete(this.msgs, id) } }), "DelMessage").StartByFixExecutor("logic_message") return true } } return false } func (this *Player) MessageShowRed() { msgMap := make(map[int64]int) for _, msg := range this.msgs { if msg.State == model.MSGSTATE_UNREAD || (msg.State == model.MSGSTATE_READED && msg.AttachState == model.MSGATTACHSTATE_DEFAULT && (msg.Coin > 0 || msg.Diamond > 0 || len(msg.Params) > 0)) { if msg.ShowId == model.HallAll { msgMap[model.HallMain] = 1 msgMap[model.HallTienlen] = 1 msgMap[model.HallFish] = 1 } else { msgMap[msg.ShowId] = 1 } } } for showId := range msgMap { this.SendShowRed(hallproto.ShowRedCode_Mail, int32(showId), 1) } } /* func (this *Player) DelAllMessage() bool { var keys []string args := &model.DelAllMsgArgs{} pack := &msg_proto.SCMessageDel{} for key, _ := range this.msgs { if msg, exist := this.msgs[key]; exist { if msg.State == model.MSGSTATE_REMOVEED { break } msg.State = model.MSGSTATE_REMOVEED // model.DelMessage(msg.Id, msg.Platform) keys = append(keys, key) pack.Ids = append(pack.Ids, msg.Id.Hex()) args.Ids = append(args.Ids, msg.Id) } } for _, key := range keys { delete(this.msgs, key) } task.New(nil, task.CallableWrapper(func(o *basic.Object) interface{} { return model.DelAllMessage(args) }), task.CompleteNotifyWrapper(func(data interface{}, tt task.Task) { if data == nil { pack := &msg_proto.SCMessageDel{} for _, id := range keys { pack.Ids = append(pack.Ids, id) delete(this.msgs, id) } proto.SetDefaults(pack) this.SendToClient(int(msg_proto.MSGPacketID_PACKET_SC_MESSAGEDEL), pack) for _, msg := range this.msgs { if msg.State == model.MSGSTATE_REMOVEED { break } msg.State = model.MSGSTATE_REMOVEED } //删除此邮件 } }), "DelMessage").StartByFixExecutor("logic_message") proto.SetDefaults(pack) this.SendToClient(int(msg_proto.MSGPacketID_PACKET_SC_MESSAGEDEL), pack) return true }*/ func (this *Player) AddMessage(msg *model.Message) { if msg == nil { return } if len(msg.Channel) > 0 && !common.InSliceString(msg.Channel, this.LastChannel) { return } if _, exist := this.msgs[msg.Id.Hex()]; !exist { this.msgs[msg.Id.Hex()] = msg //giftState := int32(0) //if len(msg.GiftId) > 0 { // gift := GiftMgrSington.GetFromRecvGift(this.SnId, msg.GiftId) // if gift != nil { // giftState = gift.State // } else { // logger.Logger.Error("player: ", this.SnId, " not find gift : ", msg.GiftId) // } //} //pack := &msg_proto.SCMessageAdd{ // Msg: &msg_proto.MessageData{ // Id: proto.String(msg.Id.Hex()), // Title: proto.String(msg.Title), // Content: proto.String(msg.Content), // MType: proto.Int32(msg.MType), // SrcId: proto.Int32(msg.SrcId), // SrcName: proto.String(msg.SrcName), // Coin: proto.Int64(msg.Coin), // Ticket: proto.Int64(msg.Ticket), // Grade: proto.Int64(msg.Grade), // State: proto.Int32(msg.State), // Ts: proto.Int32(int32(msg.CreatTs)), // Params: msg.Params, // AttachState: proto.Int32(msg.AttachState), // GiftId: proto.String(msg.GiftId), // GiftState: proto.Int32(giftState), // }, //} // //proto.SetDefaults(pack) //this.SendToClient(int(msg_proto.MSGPacketID_PACKET_SC_MESSAGEADD), pack) //if len(this.msgs) > model.MSG_MAX_COUNT { //如果邮件达到上限,删除最旧的一封邮件,调整一下,如果有附件没有领取,就不删除 // OldestKeyId := msg.Id.Hex() this.verifyoneMessage(msg) // 最新的一封时间最大 //} msgMap := make(map[int64]int) if msg.ShowId == model.HallAll { msgMap[model.HallMain] = 1 msgMap[model.HallTienlen] = 1 msgMap[model.HallFish] = 1 } else { msgMap[msg.ShowId] = 1 } for showId := range msgMap { this.SendShowRed(hallproto.ShowRedCode_Mail, int32(showId), 1) } } } func (this *Player) verifyoneMessage(msg *model.Message) { var len int for _, m := range this.msgs { if m.ShowId == model.HallAll || m.ShowId&msg.ShowId != 0 { len++ } } OldestKeyId := msg.Id.Hex() OldestCreatTs := msg.CreatTs if len > model.MSG_MAX_COUNT { for id, m := range this.msgs { if m.ShowId == model.HallAll || m.ShowId&msg.ShowId != 0 { if m.CreatTs < OldestCreatTs { OldestCreatTs = m.CreatTs OldestKeyId = id } } } this.DelMessage(OldestKeyId, 1) } } type msgsort struct { Id []string Ts []int64 } func (p *msgsort) Len() int { return len(p.Id) } func (p *msgsort) Less(i, j int) bool { return p.Ts[i] > p.Ts[j] } func (p *msgsort) Swap(i, j int) { p.Id[i], p.Id[j] = p.Id[j], p.Id[i] p.Ts[i], p.Ts[j] = p.Ts[j], p.Ts[i] } func (p *msgsort) Sort() { sort.Sort(p) } // 初始化 func (this *Player) verifyMessage1() { var delId []string // delmap := make(map[string]bool) var mainsort, tiensort, fishsort msgsort for id, m := range this.msgs { if m.ShowId == model.HallAll { // 所有可见 mainsort.Id = append(mainsort.Id, id) mainsort.Ts = append(mainsort.Ts, m.CreatTs) tiensort.Id = append(tiensort.Id, id) tiensort.Ts = append(tiensort.Ts, m.CreatTs) fishsort.Id = append(fishsort.Id, id) fishsort.Ts = append(fishsort.Ts, m.CreatTs) } else { if m.ShowId&model.HallMain != 0 { mainsort.Id = append(mainsort.Id, id) mainsort.Ts = append(mainsort.Ts, m.CreatTs) } else if m.ShowId&model.HallTienlen != 0 { tiensort.Id = append(tiensort.Id, id) tiensort.Ts = append(tiensort.Ts, m.CreatTs) } else if m.ShowId&model.HallFish != 0 { fishsort.Id = append(fishsort.Id, id) fishsort.Ts = append(fishsort.Ts, m.CreatTs) } } } if mainsort.Len() > model.MSG_MAX_COUNT { sort.Sort(&mainsort) delId = append(delId, mainsort.Id[model.MSG_MAX_COUNT:]...) } if tiensort.Len() > model.MSG_MAX_COUNT { sort.Sort(&tiensort) delId = append(delId, tiensort.Id[model.MSG_MAX_COUNT:]...) } if fishsort.Len() > model.MSG_MAX_COUNT { sort.Sort(&fishsort) delId = append(delId, fishsort.Id[model.MSG_MAX_COUNT:]...) } for _, id := range delId { this.DelMessage(id, 1) } } func (this *Player) verifyMessage(maxCreatTs int64) { var OldmainKeyId, OldsunKeyId []string var mainnum, sunnum int for id, m := range this.msgs { if m.CreatTs < maxCreatTs { if m.ShowId == model.HallAll || m.ShowId&model.HallMain != 0 { mainnum++ } else { sunnum++ } if mainnum > model.MSG_MAX_COUNT { // 主大厅 OldmainKeyId = append(OldmainKeyId, id) } else if sunnum > model.MSG_MAX_COUNT { // 子大厅 OldsunKeyId = append(OldsunKeyId, id) } /*if (m.Coin <= 0 && m.Ticket <= 0 && m.Grade <= 0) || m.AttachState == model.MSGATTACHSTATE_GOT { OldestCreatTs = m.CreatTs }*/ } } for _, id := range OldmainKeyId { this.DelMessage(id, 1) } for _, id := range OldsunKeyId { this.DelMessage(id, 1) } } func (this *Player) EditMessage(msg *model.Message) { if msg == nil { return } if _, exist := this.msgs[msg.Id.Hex()]; exist { this.msgs[msg.Id.Hex()] = msg } } func (this *Player) SendIosInstallStableMail() { if this.layered[common.ActId_IOSINSTALLSTABLE] { logger.Logger.Trace("this.layered[common.ActId_IOSINSTALLSTABLE] is true") return } var newMsg *model.Message task.New(nil, task.CallableWrapper(func(o *basic.Object) interface{} { newMsg = model.NewMessage("", 0, "", this.SnId, model.MSGTYPE_IOSINSTALLSTABLE, "系统通知", fmt.Sprintf("感谢您下载稳定版本,额外奖励%d元,请查收", int(model.GameParamData.IosStableInstallPrize/100)), int64(model.GameParamData.IosStableInstallPrize), 0, 0, time.Now().Unix(), 0, "", nil, this.Platform, model.HallAll, nil) return model.InsertMessage(this.Platform, newMsg) }), task.CompleteNotifyWrapper(func(data interface{}, t task.Task) { if data == nil { this.AddMessage(newMsg) } }), "SendMessage").Start() } func (this *Player) TestMail() { var newMsg *model.Message task.New(nil, task.CallableWrapper(func(o *basic.Object) interface{} { var otherParams []int32 otherParams = append(otherParams, 10001, 3) otherParams = append(otherParams, 20001, 3) otherParams = append(otherParams, 20002, 3) newMsg = model.NewMessage("", 0, "", this.SnId, model.MSGTYPE_ITEM, "系统通知道具test", "测试", 100000, 100, model.MSGSTATE_UNREAD, time.Now().Unix(), 0, "", otherParams, this.Platform, 0, nil) return model.InsertMessage(this.Platform, newMsg) }), task.CompleteNotifyWrapper(func(data interface{}, t task.Task) { if data == nil { this.AddMessage(newMsg) } }), "TestSendMessage").Start() } func (this *Player) TestSubMail() { var newMsg *model.Message task.New(nil, task.CallableWrapper(func(o *basic.Object) interface{} { var otherParams []int32 otherParams = append(otherParams, 10001, 3) otherParams = append(otherParams, 20001, 3) otherParams = append(otherParams, 20002, 3) newMsg = model.NewMessage("", 0, "", 0, model.MSGTYPE_ITEM, "系统", "测试", 100000, 100, model.MSGSTATE_UNREAD, time.Now().Unix(), 0, "", otherParams, this.Platform, model.HallTienlen, nil) return model.InsertMessage(this.Platform, newMsg) }), task.CompleteNotifyWrapper(func(data interface{}, t task.Task) { if data == nil { MsgMgrSington.AddMsg(newMsg) } }), "TestSubSendMessage").Start() } func (this *Player) ClubChangeCoin(gainWay int32, coin int64, remark string) { this.AddCoin(coin, 0, gainWay, "", remark) } func (this *Player) GetMessageAttach(id string) { if msg, exist := this.msgs[id]; exist { if msg.AttachState == model.MSGATTACHSTATE_DEFAULT && (msg.Coin > 0 || msg.Ticket > 0 || msg.Grade > 0 || len(msg.Params) > 0 || msg.Diamond > 0) { task.New(nil, task.CallableWrapper(func(o *basic.Object) interface{} { gift, err := model.GetMessageById(msg.Id.Hex(), msg.Platform) if err != nil || gift == nil { return nil } if gift.AttachState == model.MSGATTACHSTATE_GOT { return nil } err = model.GetMessageAttach(msg.Id, msg.Platform) if err != nil { return nil } return gift }), task.CompleteNotifyWrapper(func(data interface{}, tt task.Task) { attach_msg, ok := data.(*model.Message) dirtyCoin := int64(0) if ok && attach_msg != nil { msg.AttachState = model.MSGATTACHSTATE_GOT notifyClient := true var remark string var gainWay int32 = common.GainWay_MessageAttach // 领取道具 addItem := func() { items := make([]*Item, 0) if num := len(msg.Params); num > 0 && num%2 == 0 { for i := 0; i < num; i += 2 { items = append(items, &Item{ ItemId: msg.Params[i], // 物品id ItemNum: int64(msg.Params[i+1]), // 数量 ObtainTime: time.Now().Unix(), }) if gainWay == common.GainWayItemPermitRank { tp := int32(-1) if msg.Params[i] == common.ItemIDCoin { tp = model.SystemFreeGive_CoinType_Coin } else if msg.Params[i] == common.ItemIDDiamond { tp = model.SystemFreeGive_CoinType_Diamond } if tp != -1 { LogChannelSingleton.WriteMQData( model.GenerateSystemFreeGive(this.SnId, this.Name, this.Platform, this.Channel, model.SystemFreeGive_GiveType_TaskPermitRank, tp, int64(msg.Params[i+1]))) } } } if _, code, _ := BagMgrSingleton.AddItems(this, items, 0, gainWay, "mail", remark, 0, 0, false); code != bag.OpResultCode_OPRC_Sucess { // 领取失败 logger.Logger.Errorf("CSPlayerSettingHandler AddItems err", code) pack := &msgproto.SCGetMessageAttach{ Id: proto.String(""), } proto.SetDefaults(pack) this.SendToClient(int(msgproto.MSGPacketID_PACKET_SC_GETMESSAGEATTACH), pack) } this.dirty = true } } switch msg.MType { case model.MSGTYPE_ITEM: remark = "领取道具" gainWay = common.GainWay_MAIL_MTEM dirtyCoin = msg.Coin addItem() case model.MSGTYPE_IOSINSTALLSTABLE: remark = "IOS下载稳定版本" gainWay = common.GainWay_IOSINSTALLSTABLE dirtyCoin = msg.Coin case model.MSGTYPE_GIFT: remark = "礼物" case model.MSGTYPE_GOLDCOMERANK: remark = "财神降临奖励" gainWay = common.GainWay_GoldCome notifyClient = false dirtyCoin = msg.Coin case model.MSGTYPE_RANDCOIN: remark = "红包雨" gainWay = common.GainWay_OnlineRandCoin notifyClient = false dirtyCoin = msg.Coin case model.MSGTYPE_REBATE: remark = "流水返利" gainWay = common.GainWay_RebateTask notifyClient = false dirtyCoin = msg.Coin //邮件领取 添加日志 task.New(nil, task.CallableWrapper(func(o *basic.Object) interface{} { return model.InsertRebateLog(this.Platform, &model.Rebate{ SnId: this.SnId, RebateCoin: msg.Coin, ReceiveType: 1, CodeCoin: 0, }) }), nil, "InsertRebateLog").StartByFixExecutor("ReceiveCodeCoin") case model.MSGTYPE_ClubGet: //if len(msg.Params) != 0 { // //如果俱乐部解散 就存msg.Params[0] // remark = fmt.Sprintf("%v", msg.Params[0]) //} //gainWay = common.GainWay_ClubGetCoin //dirtyCoin = msg.Coin case model.MSGTYPE_ClubPump: //if len(msg.Params) != 0 { // remark = fmt.Sprintf("%v", msg.Params[0]) //} //gainWay = common.GainWay_ClubPumpCoin //notifyClient = false //dirtyCoin = msg.Coin case model.MSGTYPE_MATCH_SIGNUPFEE: gainWay = common.GainWay_MatchBreakBack notifyClient = false case model.MSGTYPE_MATCH_TICKETREWARD: gainWay = common.GainWay_MatchSystemSupply notifyClient = false this.TicketTotal += msg.Ticket case model.MSGTYPE_MATCH_SHOPEXCHANGE: remark = "积分商城兑换" gainWay = common.GainWay_Exchange case model.MSGTYPE_MATCH_SHOPERETURN: remark = "撤单返还" gainWay = common.GainWay_GradeShopReturn case model.MSGTYPE_RANK_REWARD: remark = "排位赛段位奖励" gainWay = common.GainWay_RankMatch addItem() case model.MSGTYPE_RANK_PermitReward: remark = "通行证排行奖励" gainWay = common.GainWayItemPermitRank addItem() } if msg.Coin > 0 { this.AddCoin(msg.Coin, 0, gainWay, msg.Id.Hex(), remark) //增加泥码 this.AddDirtyCoin(0, dirtyCoin) //俱乐部获取不算系统赠送 if msg.MType != model.MSGTYPE_ClubGet { this.ReportSystemGiveEvent(int32(msg.Coin), gainWay, notifyClient) //邮件附件算是系统赠送 } else { //俱乐部获取算充值 this.AddCoinGiveLog(msg.Coin, 0, 0, gainWay, model.COINGIVETYPE_PAY, "club", "club") } this.AddPayCoinLog(msg.Coin, model.PayCoinLogType_Coin, "mail") if msg.Oper == 0 { //系统赠送 if !this.IsRob { LogChannelSingleton.WriteMQData(model.GenerateSystemFreeGive(this.SnId, this.Name, this.Platform, this.Channel, model.SystemFreeGive_GiveType_MailSystemGive, model.SystemFreeGive_CoinType_Coin, int64(msg.Coin))) } } } if msg.Ticket > 0 { //增加报名券 this.AddTicket(msg.Ticket, gainWay, msg.Id.Hex(), remark) } if msg.Grade > 0 { //增加积分 this.AddGrade(msg.Grade, gainWay, msg.Id.Hex(), remark) } if msg.Diamond > 0 { this.AddDiamond(msg.Diamond, 0, gainWay, msg.Id.Hex(), remark) if msg.Oper == 0 { //系统赠送 if !this.IsRob { LogChannelSingleton.WriteMQData(model.GenerateSystemFreeGive(this.SnId, this.Name, this.Platform, this.Channel, model.SystemFreeGive_GiveType_MailSystemGive, model.SystemFreeGive_CoinType_Diamond, int64(msg.Diamond))) } } } pack := &msgproto.SCGetMessageAttach{ Id: proto.String(id), } proto.SetDefaults(pack) this.SendToClient(int(msgproto.MSGPacketID_PACKET_SC_GETMESSAGEATTACH), pack) } }), "GetMessageAttach").StartByFixExecutor("logic_message") } } } // 一键领取 func (this *Player) GetMessageAttachs(ids []string) { var msgs []*model.Message var Ids []string // 可以领取的邮件 var platform string for _, id := range ids { if msg, exist := this.msgs[id]; exist { if msg.AttachState == model.MSGATTACHSTATE_DEFAULT && (msg.Coin > 0 || msg.Ticket > 0 || msg.Grade > 0 || len(msg.Params) > 0 || msg.Diamond > 0) { Ids = append(Ids, id) platform = msg.Platform } } } task.New(nil, task.CallableWrapper(func(o *basic.Object) interface{} { magids, err := model.GetMessageAttachs(Ids, platform) if err != nil { logger.Logger.Trace("GetMessageAttachs err ", err) } return magids }), task.CompleteNotifyWrapper(func(data interface{}, tt task.Task) { magids, ok := data.(*[]string) if ok && magids != nil { for _, id := range *magids { if msg, exist := this.msgs[id]; exist { if msg.AttachState == model.MSGATTACHSTATE_DEFAULT && (msg.Coin > 0 || msg.Ticket > 0 || msg.Grade > 0 || len(msg.Params) > 0 || msg.Diamond > 0) { msgs = append(msgs, msg) platform = msg.Platform } } } pack := &msgproto.SCGetMessageAttach{ // Id: proto.String(id), } for _, msg := range msgs { pack.Ids = append(pack.Ids, msg.Id.Hex()) dirtyCoin := int64(0) msg.AttachState = model.MSGATTACHSTATE_GOT notifyClient := true var remark string var gainWay int32 = common.GainWay_MessageAttach switch msg.MType { case model.MSGTYPE_ITEM: remark = "领取道具" gainWay = common.GainWay_MAIL_MTEM dirtyCoin = msg.Coin items := make([]*Item, 0) if num := len(msg.Params); num > 0 && num%2 == 0 { for i := 0; i < num; i += 2 { items = append(items, &Item{ ItemId: msg.Params[i], // 物品id ItemNum: int64(msg.Params[i+1]), // 数量 ObtainTime: time.Now().Unix(), }) } if _, code, _ := BagMgrSingleton.AddItems(this, items, 0, gainWay, "mail", remark, 0, 0, false); code != bag.OpResultCode_OPRC_Sucess { // 领取失败 logger.Logger.Errorf("CSPlayerSettingHandler AddItems err", code) /* pack := &msg_proto.SCGetMessageAttach{ Id: proto.String(""), } proto.SetDefaults(pack) this.SendToClient(int(msg_proto.MSGPacketID_PACKET_SC_GETMESSAGEATTACH), pack) */ } this.dirty = true } case model.MSGTYPE_IOSINSTALLSTABLE: remark = "IOS下载稳定版本" gainWay = common.GainWay_IOSINSTALLSTABLE dirtyCoin = msg.Coin case model.MSGTYPE_GIFT: remark = "礼物" case model.MSGTYPE_GOLDCOMERANK: remark = "财神降临奖励" gainWay = common.GainWay_GoldCome notifyClient = false dirtyCoin = msg.Coin case model.MSGTYPE_RANDCOIN: remark = "红包雨" gainWay = common.GainWay_OnlineRandCoin notifyClient = false dirtyCoin = msg.Coin case model.MSGTYPE_REBATE: remark = "流水返利" gainWay = common.GainWay_RebateTask notifyClient = false dirtyCoin = msg.Coin //邮件领取 添加日志 task.New(nil, task.CallableWrapper(func(o *basic.Object) interface{} { return model.InsertRebateLog(this.Platform, &model.Rebate{ SnId: this.SnId, RebateCoin: msg.Coin, ReceiveType: 1, CodeCoin: 0, }) }), nil, "InsertRebateLog").StartByFixExecutor("ReceiveCodeCoin") case model.MSGTYPE_ClubGet: //if len(msg.Params) != 0 { // //如果俱乐部解散 就存msg.Params[0] // remark = fmt.Sprintf("%v", msg.Params[0]) //} //gainWay = common.GainWay_ClubGetCoin //dirtyCoin = msg.Coin case model.MSGTYPE_ClubPump: //if len(msg.Params) != 0 { // remark = fmt.Sprintf("%v", msg.Params[0]) //} //gainWay = common.GainWay_ClubPumpCoin //notifyClient = false //dirtyCoin = msg.Coin case model.MSGTYPE_MATCH_SIGNUPFEE: gainWay = common.GainWay_MatchBreakBack notifyClient = false case model.MSGTYPE_MATCH_TICKETREWARD: gainWay = common.GainWay_MatchSystemSupply notifyClient = false this.TicketTotal += msg.Ticket case model.MSGTYPE_MATCH_SHOPEXCHANGE: remark = "积分商城兑换" gainWay = common.GainWay_Exchange case model.MSGTYPE_MATCH_SHOPERETURN: remark = "撤单返还" gainWay = common.GainWay_GradeShopReturn } if msg.Coin > 0 { this.AddCoin(msg.Coin, 0, gainWay, msg.Id.Hex(), remark) //增加泥码 this.AddDirtyCoin(0, dirtyCoin) //俱乐部获取不算系统赠送 if msg.MType != model.MSGTYPE_ClubGet { this.ReportSystemGiveEvent(int32(msg.Coin), gainWay, notifyClient) //邮件附件算是系统赠送 } else { //俱乐部获取算充值 this.AddCoinGiveLog(msg.Coin, 0, 0, gainWay, model.COINGIVETYPE_PAY, "club", "club") } this.AddPayCoinLog(msg.Coin, model.PayCoinLogType_Coin, "mail") if msg.Oper == 0 { //系统赠送 if !this.IsRob { LogChannelSingleton.WriteMQData(model.GenerateSystemFreeGive(this.SnId, this.Name, this.Platform, this.Channel, model.SystemFreeGive_GiveType_MailSystemGive, model.SystemFreeGive_CoinType_Coin, int64(msg.Coin))) } } } if msg.Ticket > 0 { //增加报名券 this.AddTicket(msg.Ticket, gainWay, msg.Id.Hex(), remark) } if msg.Grade > 0 { //增加积分 this.AddGrade(msg.Grade, gainWay, msg.Id.Hex(), remark) } if msg.Diamond > 0 { this.AddDiamond(msg.Diamond, 0, gainWay, msg.Id.Hex(), remark) if msg.Oper == 0 { //系统赠送 if !this.IsRob { LogChannelSingleton.WriteMQData(model.GenerateSystemFreeGive(this.SnId, this.Name, this.Platform, this.Channel, model.SystemFreeGive_GiveType_MailSystemGive, model.SystemFreeGive_CoinType_Diamond, int64(msg.Diamond))) } } } } proto.SetDefaults(pack) this.SendToClient(int(msgproto.MSGPacketID_PACKET_SC_GETMESSAGEATTACH), pack) } }), "GetMessageAttach").StartByFixExecutor("logic_message") } func (this *Player) GetMessageByGiftId(id string) *model.Message { for _, msg := range this.msgs { if msg.GiftId == id && msg.State != model.MSGSTATE_REMOVEED { return msg } } return nil } // 踢掉线 func (this *Player) Kickout(reason int32) { if this.IsOnLine() { logger.Logger.Trace("(this *Player) Kickout()", this.SnId) scDisconnect := &loginproto.SSDisconnect{ SessionId: proto.Int64(this.sid), Type: proto.Int32(reason), } proto.SetDefaults(scDisconnect) this.SendToClient(int(loginproto.GatePacketID_PACKET_SS_DICONNECT), scDisconnect) LoginStateMgrSington.LogoutBySid(this.sid) this.DropLine() this.DgGameLogout() } TournamentMgr.ForceQuit(this.Platform, this.SnId) } // DropLine 掉线 // 1.玩家登出 // 2.玩家网络断开 // 3.被踢掉线 func (this *Player) DropLine() { logger.Logger.Tracef("(this *Player) DropLine() %v", this.SnId) if !this.IsRob { TournamentMgr.Quit(this.Platform, this.SnId) // 记录掉线日志 logState := LoginStateMgrSington.GetLoginStateBySid(this.sid) var clog *model.ClientLoginInfo if logState != nil { clog = logState.clog } var gameid int if this.scene != nil && this.scene.gameSess != nil { gameid = this.scene.gameId } LogChannelSingleton.WriteLog(model.NewLoginLog(this.SnId, common.LoginLogTypeDrop, this.Tel, this.Ip, this.Platform, this.Channel, this.BeUnderAgentCode, this.PackageID, this.City, clog, this.GetTotalCoin(), gameid, this.LastGameId, this.DeviceName, this.PackageName, this.AppVersion, this.BuildVersion, this.AppChannel)) this.SendPlayerCoin() this.OnlineLogDrop() PlayerOnlineSington.Check = true } this.SetOffline() this.PlayerData.LastLogoutTime = time.Now().Local() FriendMgrSington.UpdateLogoutTime(this.Platform, this.SnId) if this.scene != nil && this.scene.gameSess != nil { pack := &serverproto.WGPlayerDropLine{ Id: proto.Int32(this.SnId), SceneId: proto.Int(this.scene.sceneId), } proto.SetDefaults(pack) this.SendToGame(int(serverproto.SSPacketID_PACKET_WG_PLAYERDROPLINE), pack) } PlayerMgrSington.DroplinePlayer(this) this.sid = 0 this.gateSess = nil //统计在线时长日志 //this.StatisticsOllen(this.PlayerData.LastLogoutTime) gameStateMgr.PlayerClear(this) //玩家掉线事件 FirePlayerDropLine(this) } // 退出 func (this *Player) Logout() { logger.Logger.Tracef("(this *Player) Logout() %v", this.SnId) //退出比赛 //this.QuitMatch(false) // 在线奖励:累计在线时长 //this.OnlineRewardAddUpOnlineDuration() scLogout := &loginproto.SCLogout{ OpRetCode: loginproto.OpResultCode_OPRC_Sucess, } proto.SetDefaults(scLogout) this.SendToClient(int(loginproto.LoginPacketID_PACKET_SC_LOGOUT), scLogout) this.SetOffline() this.LastLogoutTime = time.Now().Local() FriendMgrSington.UpdateLogoutTime(this.Platform, this.SnId) //clubManager.DropLinePlayer(this.SnId) PlayerMgrSington.DroplinePlayer(this) if !this.IsRobot() { PlayerOnlineSington.Check = true } this.sid = 0 this.gateSess = nil this.DgGameLogout() gameStateMgr.PlayerClear(this) this.OnlineLogLogout() } func (this *Player) DgGameLogout() { //if this.scene != nil { // if this.scene.sceneId == SceneMgrSingleton.GetDgSceneId() { // var agentName, agentKey, thirdPlf string // if len(this.BakDgHboName) > 0 { // if strings.Contains(this.BakDgHboName, "dg") { // agentName, agentKey, thirdPlf = model.OnlyGetDgConfigByPlatform(this.Platform) // } else { // agentName, agentKey, thirdPlf = model.OnlyGetHboConfigByPlatform(this.Platform) // } // // task.New(nil, task.CallableWrapper(func(o *basic.Object) interface{} { // webapi.API_DgLogout(thirdPlf, common.GetAppId(), this.DgGame, this.DgPass, agentName, agentKey) // return nil // }), task.CompleteNotifyWrapper(func(data interface{}, t *task.Task) { // this.scene = nil // }), "DgGameLogout").Start() // } // // } //} } func (this *Player) ThirdGameLogout() { _LeaveTransferThird2SystemTask(this) } func (this *Player) IsOnLine() bool { return this.state != PlayerStateOffline } func (this *Player) SetOnline() { this.state = PlayerStateOnline } func (this *Player) IsOffline() bool { return this.state == PlayerStateOffline } func (this *Player) SetOffline() { this.state = PlayerStateOffline } // OnLogouted 玩家登出 func (this *Player) OnLogouted() { logger.Logger.Tracef("(this *Player) OnLogouted() %v", this.SnId) //在线时长日志 //this.WriteOllenLog() if !this.IsRob { FriendUnreadMgrSington.SaveFriendUnreadData(this.Platform, this.SnId) } //平台数据 //PlayerSingleAdjustMgr.DelPlayerData(this.Platform, this.SnId) //离线玩家清空俱乐部信息 //delete(clubManager.theInClubId, this.SnId) //玩家登出事件 FirePlayerLogouted(this) //登录日志 logState := LoginStateMgrSington.GetLoginStateBySid(this.sid) var clog *model.ClientLoginInfo if logState != nil { clog = logState.clog } //排除掉机器人 if !this.IsRob { LogChannelSingleton.WriteLog(model.NewLoginLog(this.SnId, common.LoginLogTypeLogout, this.Tel, this.Ip, this.Platform, this.Channel, this.BeUnderAgentCode, this.PackageID, this.City, clog, this.GetTotalCoin(), 0, 0, this.DeviceName, this.PackageName, this.AppVersion, this.BuildVersion, this.AppChannel)) this.OnlineLogLogout() } //退出通知 //ActMonitorMgrSington.SendActMonitorEvent(ActState_Login, this.SnId, this.Name, this.Platform, 0, 0, "", 1) // 更新数据库 logger.Logger.Tracef("###%v unmount from DBSaver[DelPlayer]", this.Name) DbSaver_Inst.UnregisteDbSaveTask(this) this.Save(true) } func (this *Player) MarshalData(gameid int) (d []byte, e error) { d, e = netlib.Gob.Marshal(this.PlayerData) return } func (this *Player) MarshalSingleAdjustData(gamefreeid int32) (d []byte, e error) { if this.IsRob { return } sa := PlayerSingleAdjustMgr.GetSingleAdjust(this.Platform, this.SnId, gamefreeid) if sa != nil { d, e = netlib.Gob.Marshal(sa) } return } // UnmarshalData 更新玩家数据 // 例如游戏服数据同步 func (this *Player) UnmarshalData(data []byte, scene *Scene) { pd := &model.PlayerData{} if err := netlib.Gob.Unmarshal(data, pd); err != nil { logger.Logger.Warn("Player.SyncData err:", err) return } // GDatas 同步 for _, v := range []string{ strconv.Itoa(int(scene.dbGameFree.GetId())), strconv.Itoa(int(scene.dbGameFree.GetGameId())), common.GetKeyNoviceGameId(int(scene.dbGameFree.GetGameId())), common.GetKeyGameType(int(scene.dbGameFree.GetGameType())), } { if d, ok := pd.GDatas[v]; ok { this.GDatas[v] = d } } this.LastRechargeWinCoin = pd.LastRechargeWinCoin oldRecharge := int64(0) oldExchange := int64(0) if this.PlayerData.TodayGameData != nil { oldRecharge = this.PlayerData.TodayGameData.RechargeCoin oldExchange = this.PlayerData.TodayGameData.ExchangeCoin } this.PlayerData.TodayGameData = pd.TodayGameData if this.PlayerData.TodayGameData != nil { this.PlayerData.TodayGameData.RechargeCoin = oldRecharge this.PlayerData.TodayGameData.ExchangeCoin = oldExchange } this.PlayerData.YesterdayGameData = pd.YesterdayGameData this.PlayerData.IsFoolPlayer = pd.IsFoolPlayer //this.PlayerData.TotalGameData = pd.TotalGameData this.PlayerData.WinTimes = pd.WinTimes this.PlayerData.FailTimes = pd.FailTimes this.PlayerData.DrawTimes = pd.DrawTimes this.PlayerData.WinCoin = pd.WinCoin this.PlayerData.FailCoin = pd.FailCoin this.PlayerData.TotalIn = pd.TotalIn this.PlayerData.TotalOut = pd.TotalOut this.PlayerData.ChessGrade = pd.ChessGrade this.PlayerData.MoneyPond = pd.MoneyPond this.PlayerData.Level = pd.Level this.PlayerData.Exp = pd.Exp this.PlayerData.UnMaxPower = pd.UnMaxPower this.PlayerData.PowerList = pd.PowerList this.PlayerData.PlayerTax = pd.PlayerTax this.PlayerData.TotalFlow = pd.TotalFlow if this.WelfData != nil && this.WelfData.PigBank != nil && pd.WelfData != nil && pd.WelfData.PigBank != nil { this.WelfData.PigBank.BankCoin = pd.WelfData.PigBank.BankCoin this.WelfData.PigBank.TakeTimes = pd.WelfData.PigBank.TakeTimes this.WelfData.PigBank.DayBuyTimes = pd.WelfData.PigBank.DayBuyTimes } this.ItemRecExpireTime = pd.ItemRecExpireTime this.IsTakeExpireItem = pd.IsTakeExpireItem this.dirty = true } func (this *Player) MarshalIParam() []*serverproto.PlayerIParam { var params []*serverproto.PlayerIParam for i, v := range this.Iparams { params = append(params, &serverproto.PlayerIParam{ ParamId: proto.Int(i), IntVal: proto.Int64(v), }) } return params } func (this *Player) UnmarshalIParam(params []*serverproto.PlayerIParam) { for _, p := range params { this.Iparams[int(p.GetParamId())] = p.GetIntVal() } } func (this *Player) MarshalSParam() []*serverproto.PlayerSParam { var params []*serverproto.PlayerSParam for i, v := range this.sparams { params = append(params, &serverproto.PlayerSParam{ ParamId: proto.Int(i), StrVal: proto.String(v), }) } return params } func (this *Player) UnmarshalSParam(params []*serverproto.PlayerSParam) { for _, p := range params { this.sparams[int(p.GetParamId())] = p.GetStrVal() } } func (this *Player) MarshalCParam() []*serverproto.PlayerCParam { var params []*serverproto.PlayerCParam for k, v := range this.cparams { params = append(params, &serverproto.PlayerCParam{ StrKey: proto.String(k), StrVal: proto.String(v), }) } return params } func (this *Player) SendToRepSrv(pd *model.PlayerData) { //replaySess := srvlib.ServerSessionMgrSington.GetSession(common.GetSelfAreaId(), ReplayServerType, ReplayServerId) //if replaySess != nil { // var buf bytes.Buffer // enc := gob.NewEncoder(&buf) // err := enc.Encode(pd) // if err != nil { // logger.Logger.Info("(this *Player) SendToRepSrv json.Marshal error", err) // } else { // pack := &server_proto.WRPlayerData{ // PlayerData: buf.Bytes(), // } // proto.SetDefaults(pack) // replaySess.Send(int(server_proto.SSPacketID_PACKET_WR_PlayerData), pack) // } //} } func (this *Player) CanDelete() bool { if this.isDelete { return true } return !this.IsOnLine() && !this.dirty && time.Now().Sub(this.lastSaved) > time.Minute*5 && this.scene == nil } func (this *Player) Time2Save() { this.Save(false) if this != nil && this.CanDelete() { PlayerMgrSington.DelPlayer(this.SnId) } } func (this *Player) Save(force bool) { if this.isDelete { return } // 用户缓存数据清除前同步到player_logicleveldata if !this.IsRob { pi := model.ClonePlayerData(this.PlayerData) if pi != nil { this.SendToRepSrv(pi) } this.SendPlayerCoin() } if !this.dirty && !force { return } this.dirty = false if !this.IsRob { //机器人数据不再保存 logger.Logger.Infof("(this *Player) Time2Save() %v", this.SnId) pi := model.ClonePlayerData(this.PlayerData) if pi != nil { this.SendToRepSrv(pi) // 跨天任务依赖LastLogoutTime的准确性,跨天任务是定时器ClockMgrSington触发的,所以这里要用定时器的触发时间 pi.LastLogoutTime = ClockMgrSington.LastTickTime t := task.New(nil, task.CallableWrapper(func(o *basic.Object) interface{} { if !model.SavePlayerData(pi) { //save 失败先写到json里面 model.BackupPlayerData(pi) return false } for _, v := range internal.GetPlayerLoads() { v.Save(pi.Platform, pi.SnId, true, force) } return true }), task.CompleteNotifyWrapper(func(i interface{}, t task.Task) { if saved, ok := i.(bool); ok && saved { bak := fmt.Sprintf("%v.json", pi.AccountId) if exist, _ := common.PathExists(bak); exist { os.Remove(bak) } } }), "SavePlayerTask") if b := t.StartByExecutor(strconv.Itoa(int(this.SnId))); b { this.lastSaved = time.Now() } } } } func (this *Player) GetCoin() int64 { return this.Coin } //func (this *Player) TotalData(num int64, gainWay int32) { // if this.IsRob { // return // } // //num = int64(math.Abs(float64(num))) // //sort := common.GetSortByGainWay(gainWay) // //switch sort { // //case common.GainWaySort_Act: // // //活动金额累加 // // this.ActivityCoin += int32(num) // //case common.GainWaySort_Club: // // switch gainWay { // // case common.GainWay_ClubGiveCoin: //出账 // // //俱乐部出账 // // this.ClubOutCoin += num // // case common.GainWay_ClubGetCoin: // // //俱乐部入账 // // this.ClubInCoin += num // // } // //case common.GainWaySort_Rebate: // // //返利获取 也叫 手动洗码 // // this.TotalRebateCoin += num // //} //} // AddDiamond 添加钻石 // num 总数 // add num总数中有多少是加成获得 func (this *Player) AddDiamond(num, add int64, gainWay int32, oper, remark string) { if num == 0 { return } logger.Logger.Tracef("snid(%v) AddDiamond(%v)", this.SnId, num) //async := false //if num > 0 && this.scene != nil && !this.scene.IsTestScene() && this.scene.sceneMode != common.SceneMode_Thr { //游戏场中加币,需要同步到gamesrv上 // if StartAsyncAddCoinTransact(this, num, gainWay, oper, remark, true, 0, true) { // async = true // } //} if num != 0 /*&& !async*/ { this.dirty = true if num > 0 { this.Diamond += num } else { if -num > this.Diamond { logger.Logger.Errorf("Player.AddCoin exception!!! num(%v) oper(%v)", num, oper) num = -this.Diamond this.Diamond = 0 } else { this.Diamond += num } switch gainWay { case common.GainWay_MatchSignup: // 排除的 default: TaskSubjectSingleton.Touch(common.TaskTypeCostDiamond, &TaskData{ SnId: this.SnId, Num: -num, }) } } this.SendDiffData() if !this.IsRob { log := model.NewCoinLogEx(&model.CoinLogParam{ Platform: this.Platform, SnID: this.SnId, Channel: this.Channel, ChangeType: common.BillTypeDiamond, ChangeNum: num, RemainNum: this.Diamond, Add: add, LogType: gainWay, GameID: 0, GameFreeID: 0, BaseCoin: 0, Operator: oper, Remark: remark, }) if log != nil { LogChannelSingleton.WriteLog(log) } } } } // AddCoin 添加钻石 // num 总数 // add num总数中有多少是加成获得 func (this *Player) AddCoin(num, add int64, gainWay int32, oper, remark string) { if num == 0 { return } logger.Logger.Tracef("snid(%v) AddCoin(%v)", this.SnId, num) //this.TotalData(num, gainWay) async := false if num > 0 && this.scene != nil && !this.scene.IsTestScene() && this.scene.sceneMode != common.SceneMode_Thr { //游戏场中加币,需要同步到gamesrv上 if StartAsyncAddCoinTransact(this, num, gainWay, oper, remark, true, 0, true) { async = true } } if num != 0 && !async { this.dirty = true if num > 0 { this.Coin += num } else { if -num > this.Coin { logger.Logger.Errorf("Player.AddCoin exception!!! num(%v) oper(%v)", num, oper) num = -this.Coin this.Coin = 0 } else { this.Coin += num } } this.SendDiffData() if !this.IsRob { log := model.NewCoinLogEx(&model.CoinLogParam{ Platform: this.Platform, SnID: this.SnId, Channel: this.Channel, ChangeType: common.BillTypeCoin, ChangeNum: num, RemainNum: this.Coin, Add: add, LogType: gainWay, GameID: 0, GameFreeID: 0, BaseCoin: 0, Operator: oper, Remark: remark, }) if log != nil { LogChannelSingleton.WriteLog(log) } } } } func (this *Player) AddCoinAsync(num, add int64, gainWay int32, oper, remark string, broadcast bool, retryCnt int, writeLog bool) bool { if num == 0 { return false } //if retryCnt == 0 { // this.TotalData(num, gainWay) //} //玩家可能正在换房间 async := false if num > 0 && retryCnt < 3 && this.scene != nil && !this.scene.IsTestScene() && this.scene.sceneMode != common.SceneMode_Thr { //游戏场中加币,需要同步到gamesrv上 if StartAsyncAddCoinTransact(this, num, gainWay, oper, remark, broadcast, retryCnt, writeLog) { async = true } } if num != 0 && !async { this.dirty = true if num > 0 { this.Coin += num } else { if -num > this.Coin { logger.Logger.Errorf("Player.AddCoin exception!!! num(%v) oper(%v)", num, oper) num = -this.Coin this.Coin = 0 } else { this.Coin += num } } this.SendDiffData() if !this.IsRob && writeLog { log := model.NewCoinLogEx(&model.CoinLogParam{ Platform: this.Platform, SnID: this.SnId, Channel: this.Channel, ChangeType: common.BillTypeCoin, ChangeNum: num, RemainNum: this.Coin, Add: add, LogType: gainWay, GameID: 0, GameFreeID: 0, BaseCoin: 0, Operator: oper, Remark: remark, }) if log != nil { LogChannelSingleton.WriteLog(log) } } } return async } //func (this *Player) AddClubCoin(num int64, gainWay int32, oper, remark string) { // if num == 0 { // return // } // this.TotalData(num, gainWay) // this.ClubCoin += num // // if num != 0 { // this.dirty = true // this.SendDiffData() // restCnt := this.ClubCoin // log := model.NewCoinLogEx(this.SnId, num, restCnt, this.SafeBoxCoin, this.Ver, gainWay, 0, // oper, remark, this.Platform, this.Channel, this.BeUnderAgentCode, 0, this.PackageID, 0) // if log != nil { // CoinLogChannelSington.Write(log) // } // } //} // 增加泥码 func (this *Player) AddDirtyCoin(paycoin, givecoin int64) { if this.IsRob { return } //if cfg, ok := ProfitControlMgrSington.GetCfg(this.Platform); ok && cfg != nil && paycoin >= 0 { // //洗码折算率=(玩家剩余泥码*洗码折算率+期望营收)/(充值额+赠送额+泥码余额) // this.RecalcuWashingCoinConvRate(cfg.Rate, paycoin, givecoin) //} // //this.DirtyCoin += paycoin + givecoin //if this.DirtyCoin < 0 { // this.DirtyCoin = 0 //} this.dirty = true } // 洗码 func (this *Player) WashingCoin(coin int64) int64 { if this.IsRob { return 0 } if coin <= 0 { return 0 } //if this.DirtyCoin > coin { // this.DirtyCoin -= coin // this.dirty = true // return coin //} // ////剩余多少泥码,清洗多少 //coin = this.DirtyCoin //this.DirtyCoin = 0 return coin } func (this *Player) AddTicket(num int64, gainWay int32, oper, remark string) { if num == 0 { return } if num > 0 { this.Ticket += num } else { if -num > this.Ticket { logger.Logger.Errorf("Player.AddTicket exception!!! num(%v) oper(%v)", num, oper) num = -this.Ticket this.Ticket = 0 } else { this.Ticket += num } } if num != 0 { this.dirty = true this.diffData.Ticket = -1 this.SendDiffData() //restCnt := this.Ticket //log := model.NewTicketLogEx(this.SnId, num, restCnt, this.Ver, gainWay, oper, remark, this.Platform, this.Channel, this.BeUnderAgentCode, this.PackageID, this.InviterId) //if log != nil { // TicketLogChannelSington.Write(log) //} } } func (this *Player) AddGrade(num int64, gainWay int32, oper, remark string) { if num == 0 { return } if num > 0 { this.Grade += num } else { if -num > this.Grade { logger.Logger.Errorf("Player.AddGrade exception!!! num(%v) oper(%v)", num, oper) num = -this.Grade this.Grade = 0 } else { this.Grade += num } } if num != 0 { this.dirty = true this.diffData.Grade = -1 this.SendDiffData() //restCnt := this.Grade //log := model.NewGradeLogEx(this.SnId, num, restCnt, this.Ver, gainWay, oper, remark, this.Platform, this.Channel, this.BeUnderAgentCode, this.PackageID, this.InviterId) //if log != nil { // GradeLogChannelSington.Write(log) //} } } func (this *Player) AddChessScore(num int64) { if num == 0 { return } if num > 0 { this.ChessGrade += num } else { if -num > this.ChessGrade { logger.Logger.Errorf("Player.AddChessGrade exception!!! num(%v) oper(%v)", num) num = -this.ChessGrade this.ChessGrade = 0 } else { this.ChessGrade += num } } if num != 0 { this.dirty = true this.diffData.ChessGrade = -1 this.SendDiffData() //restCnt := this.Grade //log := model.NewGradeLogEx(this.SnId, num, restCnt, this.Ver, gainWay, oper, remark, this.Platform, this.Channel, this.BeUnderAgentCode, this.PackageID, this.InviterId) //if log != nil { // GradeLogChannelSington.Write(log) //} } } func (this *Player) OnSecTimer() { FirePlayerSecTimer(this) //BagMgrSingleton.AddMailByItem(this.Platform, this.SnId, this.Name, this.SnId, 1, []int32{60001, 12}) } func (this *Player) OnMiniTimer() { FirePlayerMiniTimer(this) TaskSubjectSingleton.Touch(common.TaskTypeOnlineTs, &TaskData{ SnId: this.SnId, Num: 60, }) } func (this *Player) OnHourTimer() { FirePlayerHourTimer(this) } func (this *Player) OnDayTimer(login, continuous bool, t int) { // 校验,跨天操作一天之内只执行一次 if common.InSameDayNoZero(time.Now().Local(), this.lastOnDayChange) { return } this.lastOnDayChange = time.Now().Local() logger.Logger.Infof("(this *Player) (%v) OnDayTimer(%v,%v) ", this.SnId, login, continuous) FirePlayerDayTimer(this, login, continuous) this.dirty = true if login || this.scene == nil { //跨天登录 数据给昨天,今天置为空 this.YesterdayGameData = this.TodayGameData this.TodayGameData = model.NewPlayerGameCtrlData() /* for k, v := range this.YesterdayGameData.CtrlData { t := &model.PlayerGameStatics{} t.AvgBetCoin = v.AvgBetCoin this.TodayGameData.CtrlData[k] = t } */ } //this.OnTimeDayTotal(continuous, t) //商城数据更新 this.ShopTotal = make(map[int32]*model.ShopTotal) this.ShopLastLookTime = make(map[int32]int64) // 福利活动更新 WelfareMgrSington.OnDayChanged(this) this.VipMatchTimes = 0 //VIP商城数据更新 this.UpdateVipShopData() // 重置每日任务 if this.WelfData != nil { if this.WelfData.Task != nil { for _, v := range srvdata.TaskMgr.GetActivityType(common.TaskActivityTypeEveryDay) { this.WelfData.Task[v.GetId()] = &model.TaskData{} } for _, v := range srvdata.TaskMgr.GetActivityType(common.TaskActivityTypePermitEveryDay) { this.WelfData.Task[v.GetId()] = &model.TaskData{} } } } //周卡数据更新 this.WeekCardAward = make(map[int32]bool) //周卡领取奖励 now := time.Now().Unix() for id, endTime := range this.WeekCardTime { if endTime < now { this.WeekCardTime[id] = 0 continue } if this.WeekCardTime[id] == 0 { continue } if now > this.WeekCardTime[id] { logger.Logger.Trace("周卡已过期,不能领取!") continue } if !this.WeekCardAward[id] { this.GetWeekCardAwary(id) } } // 赛季通行证活动 this.ResetPermit() TaskSubjectSingleton.Touch(common.TaskTypeFirstLogin, &TaskData{SnId: this.SnId, Num: 1}) // 首次登录游戏 TaskSubjectSingleton.Touch(common.TaskTypeLogin, &TaskData{SnId: this.SnId, Num: 1}) // 登录游戏 } func (this *Player) ResetPermit() { permitStartTs := PlatformMgrSingleton.GetConfig(this.Platform).PermitStartTs if (this.PermitStartTs == 0 || this.PermitStartTs < permitStartTs) && permitStartTs > 0 { this.PermitStartTs = permitStartTs this.Permit = time.Time{} if this.WelfData == nil { this.WelfData = model.NewWelfareData() } this.WelfData.PermitAward = make(map[int32]int64) this.WelfData.PermitExchange = make(map[int32][]int64) if this.WelfData.Task != nil { for _, v := range srvdata.TaskMgr.GetActivityType(common.TaskActivityTypePermit) { this.WelfData.Task[v.GetId()] = &model.TaskData{} } } this.dirty = true // 清理数据 bag := BagMgrSingleton.GetBagInfo(this.SnId) if bag != nil { delete(bag.BagItem, common.ItemIDPermit) if model.GameParamData.PermitInitScore > 0 { bagInfo := BagMgrSingleton.GetBagInfo(this.SnId) if bagInfo != nil { bagInfo.BagItem[common.ItemIDPermit] = &Item{ ItemId: common.ItemIDPermit, ItemNum: model.GameParamData.PermitInitScore, ObtainTime: time.Now().Unix(), } this.Permit = time.Now() } } } } } //func (this *Player) OnTimeDayTotal(continuous bool, t int) { // for k, tgd := range this.TotalGameData { // for i := 0; i < t; i++ { // tgd = append(tgd, new(model.PlayerGameTotal)) // } // if len(tgd) > 30 { // tgd = tgd[len(tgd)-30:] // } // this.TotalGameData[k] = tgd // } //} func (this *Player) OnMonthTimer() { //判断是否一天即可过滤0点多次切换 if common.InSameDayNoZero(time.Now().Local(), this.lastOnMonthChange) { return } this.lastOnMonthChange = time.Now().Local() FirePlayerMonthTimer(this) } func (this *Player) OnWeekTimer() { logger.Logger.Tracef("OnWeekTimer %v", time.Now()) //判断是否一天即可过滤0点多次切换 if common.InSameDayNoZero(time.Now().Local(), this.lastOnWeekChange) { return } this.lastOnWeekChange = time.Now().Local() FirePlayerWeekTimer(this) //清理比赛券 ticket := this.Ticket if ticket > 0 { this.AddTicket(-ticket, common.GainWay_Expire, "system", "过期清理") this.TicketTotalDel += ticket this.dirty = true } if len(this.msgs) > 0 { //自然过渡执行 //过期邮件处理 var keysId []string for key, msg := range this.msgs { if msg.AttachState == model.MSGATTACHSTATE_DEFAULT && msg.Ticket > 0 { this.TicketTotalDel += msg.Ticket keysId = append(keysId, key) } } this.dirty = true for _, v := range keysId { this.DelMessage(v, 1) } } // 重置周任务 if this.WelfData != nil { if this.WelfData.Task != nil { for _, v := range srvdata.TaskMgr.GetActivityType(common.TaskActivityTypeWeek) { this.WelfData.Task[v.GetId()] = &model.TaskData{} } } } // 重置周任务 // 重置邀请积分 CheckNewWeek(this.Platform, this.SnId) } func (this *Player) GetName() string { return this.Name } func (this *Player) setName(newName string) string { this.Name = newName return this.Name } func (this *Player) GetIP() string { return this.Ip } func (this *Player) CreateScene(sceneId, gameId, gameMode, sceneMode int, numOfGames int32, params []int64, dbGameFree *serverproto.DB_GameFree) (*Scene, hallproto.OpResultCode_Game) { gs := GameSessMgrSington.GetMinLoadSess(gameId) if gs == nil { logger.Logger.Warnf("(this *Player) EnterScene %v, %v GameSessMgrSington.GetMinLoadSess() = nil ", this.SnId, gameId) return nil, hallproto.OpResultCode_Game_OPRC_SceneServerMaintain_Game } s := SceneMgrSingleton.CreateScene(0, this.SnId, sceneId, gameId, gameMode, sceneMode, 1, numOfGames, params, gs, this.GetPlatform(), 0, dbGameFree, dbGameFree.GetId()) if s == nil { logger.Logger.Tracef("(this *Player) EnterScene %v, SceneMgrSingleton.CreateScene() = nil ", this.SnId) return nil, hallproto.OpResultCode_Game_OPRC_Error_Game } return s, hallproto.OpResultCode_Game_OPRC_Sucess_Game } func (this *Player) CreateLocalGameScene(sceneId, gameId, gameSite, sceneMode, playerNum int, params []int64, dbGameFree *serverproto.DB_GameFree, baseScore, groupId int32) (*Scene, hallproto.OpResultCode_Game) { gs := GameSessMgrSington.GetMinLoadSess(gameId) if gs == nil { logger.Logger.Warnf("(this *Player) CreateLocalGameScene %v, %v GameSessMgrSington.GetMinLoadSess() = nil ", this.SnId, gameId) return nil, hallproto.OpResultCode_Game_OPRC_SceneServerMaintain_Game } s := SceneMgrSingleton.CreateLocalGameScene(this.SnId, sceneId, gameId, gameSite, sceneMode, 1, params, gs, this.GetPlatform(), playerNum, dbGameFree, baseScore, groupId, dbGameFree.GetId()) if s == nil { logger.Logger.Tracef("(this *Player) EnterScene %v, SceneMgrSingleton.CreateScene() = nil ", this.SnId) return nil, hallproto.OpResultCode_Game_OPRC_Error_Game } return s, hallproto.OpResultCode_Game_OPRC_Sucess_Game } func (this *Player) ReturnScene(isLoaded bool) *Scene { logger.Logger.Tracef("(this *Player) ReturnScene %v", this.SnId) if this.scene == nil { logger.Logger.Warnf("(this *Player) ReturnScene this.scene == nil snid:%d", this.SnId) return nil } if !this.scene.HasPlayer(this) && !this.scene.HasAudience(this) { logger.Logger.Warnf("(this *Player) ReturnScene !this.scene.HasPlayer(this) && !this.scene.HasAudience(this) snid:%d", this.SnId) return nil } pack := &serverproto.WGPlayerReturn{ PlayerId: proto.Int32(this.SnId), IsLoaded: proto.Bool(isLoaded), RoomId: proto.Int(this.scene.sceneId), } ctx := this.scene.GetPlayerGameCtx(this.SnId) if ctx != nil { pack.EnterTs = proto.Int64(ctx.enterTs) } proto.SetDefaults(pack) if this.SendToGame(int(serverproto.SSPacketID_PACKET_WG_PLAYERRETURN), pack) { //比赛场返场检查 //MatchMgrSington.OnPlayerReturnScene(this.scene, this) return this.scene } //不应该这这里处理,因为 miniGame中小游戏玩家 player.Scene是不存在的。 //FirePlayerReturnScene(this) return nil } func (this *Player) BackDiffData() { this.diffData.Coin = this.Coin this.diffData.SafeBoxCoin = this.SafeBoxCoin } func (this *Player) UpdateVip() { if this.IsRob { return } this.VIP = this.GetVIPLevel() //clubManager.UpdateVip(this) } func (this *Player) AddMoneyPayTotal(amount int64) { if amount > 0 { this.MoneyPayTotal += amount this.SendDiffData() //更新vip } } func (this *Player) SendDiffData() { this.UpdateVip() var dirty bool pack := &playerproto.SCPlayerDataUpdate{} pack.UpdateField = 0 //金币 if this.diffData.Coin != this.Coin { dirty = true pack.Coin = proto.Int64(this.Coin) this.diffData.Coin = this.Coin pack.UpdateField += UpdateField_Coin } //钻石 if this.diffData.Diamond != this.Diamond { dirty = true pack.Diamond = proto.Int64(this.Diamond) this.diffData.Diamond = this.Diamond pack.UpdateField += UpdateField_Diamond } //保险箱金币 if this.diffData.SafeBoxCoin != this.SafeBoxCoin { dirty = true pack.SafeBoxCoin = proto.Int64(this.SafeBoxCoin) this.diffData.SafeBoxCoin = this.SafeBoxCoin pack.UpdateField += UpdateField_SafeBoxCoin } //VIP等级 if this.diffData.VIP != this.VIP { dirty = true pack.Vip = proto.Int32(this.VIP) this.diffData.VIP = this.VIP pack.UpdateField += UpdateField_VIP } //手机积分 if this.diffData.PhoneScore != this.PhoneScore { dirty = true pack.PhoneScore = this.PhoneScore this.diffData.PhoneScore = this.PhoneScore pack.UpdateField += UpdateField_PhoneScore } // 邀请积分 if this.diffData.InviteScore != this.IScore { dirty = true pack.InviteScore = this.IScore this.diffData.InviteScore = this.IScore pack.UpdateField += UpdateField_InviteScore } //总充值金额 if this.diffData.CoinPayTotal != this.CoinPayTotal { dirty = true pack.CoinPayTotal = proto.Int64(this.CoinPayTotal) this.diffData.CoinPayTotal = this.CoinPayTotal pack.UpdateField += UpdateField_CoinPayTotal } //流水差异 if this.diffData.TotalConvertibleFlow != this.TotalConvertibleFlow { dirty = true pack.TotalConvertibleFlow = proto.Int64(this.TotalConvertibleFlow) this.diffData.TotalConvertibleFlow = this.TotalConvertibleFlow pack.UpdateField += UpdateField_TotalConvertibleFlow } //比赛报名券 if this.diffData.Ticket != this.Ticket { dirty = true pack.Ticket = proto.Int64(this.Ticket) this.diffData.Ticket = this.Ticket pack.UpdateField += UpdateField_Ticket } //积分 if this.diffData.Grade != this.Grade { dirty = true pack.Grade = proto.Int64(this.Grade) this.diffData.Grade = this.Grade pack.UpdateField += UpdateField_Grade } //象棋积分 if this.diffData.ChessGrade != this.ChessGrade { dirty = true pack.ChessGrade = proto.Int64(this.ChessGrade) this.diffData.ChessGrade = this.ChessGrade pack.UpdateField += UpdateField_ChessGrade } // 排位积分 if this.diffData.RankScore == nil { this.diffData.RankScore = make(map[int32]int64) } if p := RankMgrSingleton.GetPlayerSeason(this.SnId); p != nil { for k := range p.RankType { if this.diffData.RankScore[k] != p.RankType[k].Score { dirty = true if pack.RankScore == nil { pack.RankScore = make(map[int32]int64) } pack.RankScore[k] = proto.Int64(p.RankType[k].Score) this.diffData.RankScore[k] = p.RankType[k].Score pack.UpdateField += UpdateField_RankScore } } } if len(pack.RankScore) == 0 { pack.RankScore = nil } if dirty { FriendMgrSington.UpdateInfo(this.Platform, this.SnId) this.SendToClient(int(playerproto.PlayerPacketID_PACKET_SC_PLAYERDATAUPDATE), pack) logger.Logger.Trace("(this *Player) SendDiffData() ", pack) } } func GetExchangeFlow(pd *model.PlayerData) int32 { if pd == nil { return 0 } platform := PlatformMgrSingleton.GetPlatform(pd.Platform) if platform != nil { if (platform.ExchangeFlag & ExchangeFlag_Flow) != 0 { key, err := GetPromoterKey(pd.PromoterTree, pd.BeUnderAgentCode, pd.Channel) if err == nil { cfg := PromoterMgrSington.GetConfig(key) if cfg != nil { if (cfg.ExchangeFlag & ExchangeFlag_Flow) != 0 { return cfg.ExchangeFlow } } } return platform.ExchangeFlow } } return 0 } func GetExchangeGiveFlow(pd *model.PlayerData) int32 { if pd == nil { return 0 } platform := PlatformMgrSingleton.GetPlatform(pd.Platform) if platform != nil { if (platform.ExchangeFlag & ExchangeFlag_Flow) != 0 { key, err := GetPromoterKey(pd.PromoterTree, pd.BeUnderAgentCode, pd.Channel) if err == nil { cfg := PromoterMgrSington.GetConfig(key) if cfg != nil { if (cfg.ExchangeFlag & ExchangeFlag_Flow) != 0 { return cfg.ExchangeGiveFlow } } } return platform.ExchangeGiveFlow } } return 0 } func GetExchangeForceTax(pd *model.PlayerData) int32 { if pd == nil { return 0 } platform := PlatformMgrSingleton.GetPlatform(pd.Platform) if platform != nil { if (platform.ExchangeFlag & ExchangeFlag_Force) != 0 { key, err := GetPromoterKey(pd.PromoterTree, pd.BeUnderAgentCode, pd.Channel) if err == nil { cfg := PromoterMgrSington.GetConfig(key) if cfg != nil { if (cfg.ExchangeFlag & ExchangeFlag_Force) != 0 { return cfg.ExchangeForceTax } } } return platform.ExchangeForceTax } } return 0 } func GetExchangeTax(pd *model.PlayerData) int32 { if pd == nil { return 0 } platform := PlatformMgrSingleton.GetPlatform(pd.Platform) if platform != nil { if (platform.ExchangeFlag & ExchangeFlag_Tax) != 0 { key, err := GetPromoterKey(pd.PromoterTree, pd.BeUnderAgentCode, pd.Channel) if err == nil { cfg := PromoterMgrSington.GetConfig(key) if cfg != nil { if (cfg.ExchangeFlag & ExchangeFlag_Tax) != 0 { return cfg.ExchangeTax } } } return platform.ExchangeTax } } return 0 } func GetExchangeFlag(pd *model.PlayerData) int32 { if pd == nil { return 0 } platform := PlatformMgrSingleton.GetPlatform(pd.Platform) if platform != nil { if (platform.ExchangeFlag & ExchangeFlag_Flow) != 0 { key, err := GetPromoterKey(pd.PromoterTree, pd.BeUnderAgentCode, pd.Channel) if err == nil { cfg := PromoterMgrSington.GetConfig(key) if cfg != nil { if (cfg.ExchangeFlag & ExchangeFlag_Flow) != 0 { return 2 } } } return 1 } } return 0 } func (this *Player) GetRegisterPrize() int32 { platform := this.GetPlatform() key, err := this.GetPromoterKey() var cfg *PromoterConfig if err == nil { cfg = PromoterMgrSington.GetConfig(key) } return GGetRegisterPrize(platform, cfg) } func GGetRegisterPrize(platform *Platform, cfg *PromoterConfig) int32 { if platform != nil { if cfg != nil { if (cfg.ExchangeFlag & ExchangeFlag_UpAcc) != 0 { return cfg.NewAccountGiveCoin } } return platform.NewAccountGiveCoin } return 0 } func (this *Player) GetUpdateAccPrize() int32 { platform := this.GetPlatform() key, err := this.GetPromoterKey() var cfg *PromoterConfig if err == nil { cfg = PromoterMgrSington.GetConfig(key) } return GGetUpdateAccPrize(platform, cfg) } func GGetUpdateAccPrize(platform *Platform, cfg *PromoterConfig) int32 { if platform != nil { if cfg != nil { if (cfg.ExchangeFlag & ExchangeFlag_UpAcc) != 0 { return cfg.UpgradeAccountGiveCoin } } return platform.UpgradeAccountGiveCoin } return 0 } func (this *Player) GetPromoterKey() (string, error) { return GetPromoterKey(this.PromoterTree, this.BeUnderAgentCode, this.Channel) } //计算流水可以兑换的值 返回 还需要多少流水 赠送扣除 强制费用 合计流水 //func GetExchangeFlowTotal(pd *model.PlayerData, playerTotalFlow int64, givesInfo []*model.CoinGiveLog) (int64, // int64, int64, int64) { // //可兑换的流水 // var flow int64 // // var giveLostCoin int64 //赠送扣除 // var forceTax int64 //强制费用 // var needTotalFlow int64 //需要的流水 // var lockCoin int64 //多少金额无法兑换,如果兑换需要强制扣除行政费用 // // retIds := []string{} // retAllIds := []string{} // // exchangeFlow := GetExchangeFlow(pd) // exchangeGiveFlow := GetExchangeGiveFlow(pd) // exchangeForceTax := GetExchangeForceTax(pd) // // if GetExchangeFlag(pd) > 0 { // // //逐笔计算兑换流水金额,从上到下 // curTotalFlow := playerTotalFlow // // //按照时间排序 // sort.Slice(givesInfo, func(i, j int) bool { return givesInfo[i].Ts > givesInfo[j].Ts }) // // for i := 0; i < len(givesInfo); i++ { // info := givesInfo[i] // if info.Ts > pd.LastExchangeTime { // retAllIds = append(retAllIds, info.LogId.Hex()) // //计算是否通过稽核 // needFlow := int64(0) // curTotalFlow += info.FLow // //如果是系统赠送的,需要全部扣除 // if info.RecType == model.COINGIVETYPE_SYSTEM { // exchangeGiveFlowS := exchangeGiveFlow // t := ActMgrSington.GetExchangeFlow(pd.Platform, info.LogType) // if t != 0 { // exchangeGiveFlowS = t // } // // if info.NeedGiveFlowRate > 0 { // exchangeGiveFlowS = info.NeedGiveFlowRate // } // // needFlow = int64(math.Floor(float64(info.GiveCoin)*float64(exchangeGiveFlowS)/100)) * 100 // // if curTotalFlow < needFlow { // //需要扣除 // giveLostCoin += info.GiveCoin // lockCoin += info.GiveCoin // flow += needFlow - curTotalFlow // curTotalFlow = 0 // } else { // curTotalFlow -= needFlow // retIds = append(retIds, info.LogId.Hex()) // } // } else { // exchangeGiveFlowS := exchangeGiveFlow // t := ActMgrSington.GetExchangeFlow(pd.Platform, info.LogType) // if t != 0 { // exchangeGiveFlowS = t // } // if info.NeedGiveFlowRate > 0 { // exchangeGiveFlowS = info.NeedGiveFlowRate // } // // exchangePayFlowS := exchangeFlow // if info.NeedFlowRate > 0 { // exchangePayFlowS = info.NeedFlowRate // } // // //分两部分扣除 // needFlow = int64(math.Floor(float64(info.GiveCoin)*float64(exchangeGiveFlowS)/100)) * 100 // needFlow += int64(math.Floor(float64(info.PayCoin)*float64(exchangePayFlowS)/100)) * 100 // if curTotalFlow < needFlow { // //需要扣除 // giveLostCoin += info.GiveCoin // //强制费用 // forceTax += info.PayCoin * int64(exchangeForceTax) / 10000 // lockCoin += info.GiveCoin // lockCoin += info.PayCoin // flow += needFlow - curTotalFlow // curTotalFlow = 0 // } else { // curTotalFlow -= needFlow // retIds = append(retIds, info.LogId.Hex()) // } // } // needTotalFlow += needFlow // } // } // } // // return flow, giveLostCoin, forceTax, needTotalFlow //} // ////pageNo 1开始 //func GetExchangeFlowTotalPacket(playerTotalFlow int64, givesInfo []*model.CoinGiveLog, pd *model.PlayerData, // pageNo, pageNum int32, isCheck bool) *shop_proto.SCGetPlayerPayFlowList { // pack := &shop_proto.SCGetPlayerPayFlowList{} // var giveLostCoin int64 //赠送扣除 // var forceTax int64 //强制费用 // var needTotalFlow int64 //需要的流水 // startIndex := (pageNo - 1) * pageNum // endIndex := pageNo * pageNum // //platform := this.GetPlatform() // exchangeFlow := GetExchangeFlow(pd) // exchangeGiveFlow := GetExchangeGiveFlow(pd) // exchangeForceTax := GetExchangeForceTax(pd) // // //按照时间排序 // sort.Slice(givesInfo, func(i, j int) bool { return givesInfo[i].Ts > givesInfo[j].Ts }) // //逐笔计算兑换流水金额,从上到下p // curTotalFlow := playerTotalFlow // // index := int32(0) // // if GetExchangeFlag(pd) > 0 { // for i := 0; i < len(givesInfo); i++ { // info := givesInfo[i] // if isCheck || info.Ts > pd.LastExchangeTime { // tInfo := &shop_proto.PlayerPayFlowLog{} // tInfo.Ts = proto.Int64(info.Ts) // tInfo.PayType = proto.Int32(info.RecType) // tInfo.PayCoin = proto.Int64(info.PayCoin) // tInfo.GiveCoin = proto.Int64(info.GiveCoin) // tInfo.FinishFlow = proto.Int64(info.FLow) // tInfo.OrderID = proto.String(info.LogId.Hex()) // //计算是否通过稽核 // needFlow := int64(0) // isPass := int32(0) // curTotalFlow += info.FLow // //如果是系统赠送的,需要全部扣除 // if info.RecType == model.COINGIVETYPE_SYSTEM { // exchangeGiveFlowS := exchangeGiveFlow // t := ActMgrSington.GetExchangeFlow(pd.Platform, info.LogType) // if t != 0 { // exchangeGiveFlowS = t // } // if info.NeedGiveFlowRate > 0 { // exchangeGiveFlowS = info.NeedGiveFlowRate // } // needFlow = int64(math.Floor(float64(info.GiveCoin)*float64(exchangeGiveFlowS)/100)) * 100 // tInfo.GiveNeedFlow = proto.Int64(needFlow) // if curTotalFlow < needFlow { // //需要扣除 // giveLostCoin += info.GiveCoin // tInfo.ForceGiveCoin = proto.Int64(info.GiveCoin) // // curTotalFlow = 0 // } else { // curTotalFlow -= needFlow // isPass = 1 // } // } else { // exchangeGiveFlowS := exchangeGiveFlow // t := ActMgrSington.GetExchangeFlow(pd.Platform, info.LogType) // if t != 0 { // exchangeGiveFlowS = t // } // // if info.NeedGiveFlowRate > 0 { // exchangeGiveFlowS = info.NeedGiveFlowRate // } // exchangePayFlowS := exchangeFlow // if info.NeedFlowRate > 0 { // exchangePayFlowS = info.NeedFlowRate // } // //分两部分扣除 // needFlow = int64(math.Floor(float64(info.GiveCoin)*float64(exchangeGiveFlowS)/100)) * 100 // tInfo.GiveNeedFlow = proto.Int64(needFlow) // // payNeedFlow := int64(math.Floor(float64(info.PayCoin)*float64(exchangePayFlowS)/100)) * 100 // tInfo.PayNeedFlow = proto.Int64(payNeedFlow) // needFlow += payNeedFlow // // if curTotalFlow < needFlow { // //需要扣除 // giveLostCoin += info.GiveCoin // tInfo.ForceGiveCoin = proto.Int64(info.GiveCoin) // // //强制费用 // forceTax += info.PayCoin * int64(exchangeForceTax) / 10000 // tInfo.ForceTax = proto.Int64(info.PayCoin * int64(exchangeForceTax) / 10000) // curTotalFlow = 0 // } else { // curTotalFlow -= needFlow // isPass = 1 // } // } // // tInfo.IsPass = proto.Int32(isPass) // needTotalFlow += needFlow // // if index >= startIndex && index < endIndex { // pack.Data = append(pack.Data, tInfo) // } // // index += 1 // } // } // } // pack.PageNo = proto.Int32(int32(pageNo)) // pack.PageSum = proto.Int32(int32(math.Ceil(float64(index) / float64(pageNum)))) // pack.PageSize = proto.Int32(pageNum) // pack.TotalNum = proto.Int32(index) // proto.SetDefaults(pack) // return pack //} func (this *Player) SendPlayerInfo() { this.UpdateVip() scPlayerData := &playerproto.SCPlayerData{ OpRetCode: playerproto.OpResultCode_OPRC_Sucess, Data: &playerproto.PlayerData{ AccId: proto.String(this.AccountId), //账号ID Platform: proto.String(this.Platform), //平台 Channel: proto.String(this.Channel), //渠道 Promoter: proto.String(this.BeUnderAgentCode), //推广员 Name: proto.String(this.Name), //名字 SnId: proto.Int32(this.SnId), //数字账号 Head: proto.Int32(this.Head), //头像 Sex: proto.Int32(this.Sex), //性别 GMLevel: proto.Int32(this.GMLevel), //GM等级 Coin: proto.Int64(this.Coin), //金币 SpecailFlag: proto.Int32(int32(this.Flags)), //特殊标记 Tel: proto.String(this.Tel), //手机号码 InviterId: proto.Int32(this.InviterId), //邀请人ID SafeBoxCoin: proto.Int64(this.SafeBoxCoin), //保险箱金币 VIP: proto.Int32(this.VIP), //VIP帐号 AlipayAccount: proto.String(this.AlipayAccount), //支付宝账号 AlipayAccName: proto.String(this.AlipayAccName), //支付宝实名 Bank: proto.String(this.Bank), //银行 BankAccount: proto.String(this.BankAccount), //银行帐号 BankAccName: proto.String(this.BankAccName), //银行开户名 HeadOutLine: proto.Int32(this.HeadOutLine), //头像框 CoinPayTotal: proto.Int64(this.CoinPayTotal), //总充值金额 CreateTs: proto.Int64(this.CreateTime.Unix()), //角色创建时间 //ClubCoin: proto.Int64(this.ClubCoin), //俱乐部金币 Ticket: proto.Int64(this.Ticket), //比赛入场券 Grade: proto.Int64(this.Grade), //积分 Diamond: proto.Int64(this.Diamond), //钻石 HeadUrl: proto.String(this.HeadUrl), //VipExp: proto.Int64(this.GetCurrentVIPExp()), ChessGrade: proto.Int64(this.ChessGrade), RankScore: make(map[int32]int64), UnMaxPower: proto.Int64(this.UnMaxPower), PowerList: this.PowerList, Level: proto.Int64(this.Level), Exp: proto.Int64(this.Exp), VipShopRefreshCount: proto.Int32(this.VipShopRefreshCount), Signature: this.Signature, Age: this.Age, }, } if this.Roles != nil { scPlayerData.Data.UseRoleId = this.Roles.ModId } if this.Pets != nil { scPlayerData.Data.UsePetId = this.Pets.ModId } if this.WelfData != nil { scPlayerData.Data.ReliefFundTimes = this.WelfData.ReliefFundTimes } if item := BagMgrSingleton.GetItem(this.SnId, common.ItemIDVCard); item != nil { scPlayerData.Data.VCoin = item.ItemNum //V卡 } // 排位积分 scPlayerData.Data.RankScore = RankMgrSingleton.GetPlayerRankScore(this.SnId) raw := fmt.Sprintf("%v%v", model.DEFAULT_PLAYER_SAFEBOX_PWD, common.GetAppId()) h := md5.New() io.WriteString(h, raw) pwd := hex.EncodeToString(h.Sum(nil)) if this.SafeBoxPassword != pwd { scPlayerData.Data.SafeBoxIsExist = proto.Int32(1) } else { scPlayerData.Data.SafeBoxIsExist = proto.Int32(0) } if this.scene != nil { scPlayerData.RoomId = proto.Int(this.scene.sceneId) scPlayerData.GameId = proto.Int(this.scene.gameId) //增加gameFreeId scPlayerData.LogicId = this.scene.dbGameFree.Id } platform := PlatformMgrSingleton.GetPlatform(this.Platform) if platform != nil { scPlayerData.BindOption = proto.Int32(platform.BindOption) } else { scPlayerData.BindOption = proto.Int32(7) } //周卡数据 for id, endTime := range this.WeekCardTime { if endTime == 0 { continue } weekInfo := playerproto.WeekInfo{ Id: id, WeekCardTime: endTime, WeekCardAward: this.WeekCardAward[id], } scPlayerData.Data.WeekCard = append(scPlayerData.Data.WeekCard, &weekInfo) } this.SendToClient(int(playerproto.PlayerPacketID_PACKET_SC_PLAYERDATA), scPlayerData) logger.Logger.Tracef("Send SCPlayerData %v", scPlayerData) if !this.IsRob { this.SyncPlayerDataToGateSrv(this.PlayerData) } // 判断玩家是否在游戏内 if this.scene != nil && this.thrscene == 0 { this.SendGameConfig(int32(this.scene.gameId), this.Platform, this.Channel) } this.SCItems() //this.SendJackpotInfo() } //func (this *Player) SendJackpotInfo() { // //通知所有的gamesrv向玩家发送奖池信息 // if this.gateSess != nil { // var gateSid int64 // if srvInfo, ok := this.gateSess.GetAttribute(srvlib.SessionAttributeServerInfo).(*srvlibproto.SSSrvRegiste); ok && srvInfo != nil { // sessionId := srvlib.NewSessionIdEx(srvInfo.GetAreaId(), srvInfo.GetType(), srvInfo.GetId(), 0) // gateSid = sessionId.Get() // } // // //查找当前平台下所以开放的游戏id // info := make([]*server_proto.GameInfo, 0) // gps := PlatformMgrSingleton.GetGameFrees(this.Platform) // for _, v := range gps { // if v.Status { // if v.DbGameFree.GetGameRule() != 0 { // //lgi := &server_proto.GameInfo{ // // GameId: proto.Int32(v.DbGameFree.GetGameId()), // // GameFreeId: proto.Int32(v.DbGameFree.GetId()), // // GameType: proto.Int32(v.DbGameFree.GetGameType()), // //} // info = append(info, &server_proto.GameInfo{ // GameId: proto.Int32(v.DbGameFree.GetGameId()), // GameFreeId: proto.Int32(v.DbGameFree.GetId()), // GameType: proto.Int32(v.DbGameFree.GetGameType()), // }) // } // } // } // // servers := GameSessMgrSington.GetAllGameSess() // for _, v := range servers { // pack := &server_proto.WGGameJackpot{ // Sid: this.sid, // GateSid: gateSid, // Platform: this.Platform, // Info: info, // } // v.Send(int(server_proto.SSPacketID_PACKET_WG_GAMEJACKPOT), pack) // } // } //} func (this *Player) IsGM() bool { if this.GMLevel > 0 { return true } return false } func (this *Player) IsAgentor() bool { return false } func (this *Player) IsPlayer() bool { return true } func (this *Player) HasAuthority(role int) bool { switch role { case common.ClientRole_Agentor: return this.IsAgentor() case common.ClientRole_GM: return this.IsGM() case common.ClientRole_Player: return true } return false } func (this *Player) RobRandVip() { if this.IsRob { dbvip := srvdata.PBDB_VIPMgr.GetData(this.VIP) if dbvip != nil { outlines := dbvip.GetRewardOutlineID() n := len(outlines) this.HeadOutLine = outlines[rand.Intn(n)] logger.Logger.Tracef("(this *Player) RobRandVip() %d HeadOutLine=%d", this.SnId, this.HeadOutLine) this.dirty = true } this.Head = rand.Int31n(common.HeadRange) //0:男 1:女 this.Sex = (this.Head%2 + 1) % 2 } } func (this *Player) ReportLoginEvent() { //用户登录 if !this.IsRob { isBindPhone := int32(0) if this.Tel != "" { isBindPhone = 1 if this.UpgradeTime.IsZero() { this.UpgradeTime = this.CreateTime } } LogChannelSingleton.WriteMQData(model.GenerateLogin(model.CreatePlayerLoginEvent(this.SnId, this.Channel, this.BeUnderAgentCode, this.Platform, this.City, this.DeviceOS, this.Ip, this.CreateTime, this.UpgradeTime, isBindPhone, this.TelephonePromoter, this.DeviceId))) //登录通知 //ActMonitorMgrSington.SendActMonitorEvent(ActState_Login, this.SnId, this.Name, this.Platform, // 0, 0, "", 0) } } func (this *Player) ReportBindPhoneEvent() { //升级账号事件 if !this.IsRob { //LogChannelSingleton.WriteMQData(model.GenerateBindEvent(model.CreatePlayerBindPhoneEvent( // this.SnId, this.Channel, this.BeUnderAgentCode, this.Platform, this.City, this.DeviceOS, // this.CreateTime, this.TelephonePromoter))) } } func (this *Player) ReportBindAlipayEvent() { //绑定支付宝事件 //if !this.IsRob { // d, e := model.MarshalPlayerBindAlipayEvent(2, this.SnId, this.Channel, this.BeUnderAgentCode, // this.Platform, this.City, this.DeviceOS, this.TelephonePromoter) // if e == nil { // rmd := model.NewInfluxDBData("hj.player_bind_alipay", d) // if rmd != nil { // InfluxDBDataChannelSington.Write(rmd) // } // } //} } func (this *Player) AddCoinGiveLog(payCoin, giveCoin int64, coinType, logType, recType int32, remark, oper string) { plt := PlatformMgrSingleton.GetPlatform(this.Platform) curVer := int32(0) if plt != nil { curVer = plt.ExchangeVer } log := model.NewCoinGiveLogEx(this.SnId, this.Name, payCoin, giveCoin, coinType, logType, this.PromoterTree, recType, curVer, this.Platform, this.Channel, this.BeUnderAgentCode, remark, oper, this.PackageID, 0, 0) if log != nil { task.New(nil, task.CallableWrapper(func(o *basic.Object) interface{} { err := model.InsertGiveCoinLog(log) if err == nil { if this.LastExchangeOrder != "" && this.TotalConvertibleFlow > 0 { err = model.UpdateGiveCoinLastFlow(log.Platform, this.LastExchangeOrder, this.TotalConvertibleFlow) } } return err }), task.CompleteNotifyWrapper(func(ud interface{}, t task.Task) { if ud == nil { //清空流水,更新id this.TotalConvertibleFlow = 0 this.LastExchangeOrder = log.LogId.Hex() } }), "UpdateGiveCoinLastFlow").StartByGroupFixExecutor(log.Platform, "UpdateGiveCoinLastFlow") } } func ReportSystemGiveEvent(pd *model.PlayerData, amount, tag int32, notifyClient bool) { //系统赠送 if !pd.IsRob { //插入本地表 if amount > 0 { if ActMgrSington.GetIsNeedGive(pd.Platform, tag) { plt := PlatformMgrSingleton.GetPlatform(pd.Platform) curVer := int32(0) if plt != nil { curVer = plt.ExchangeVer } log := model.NewCoinGiveLogEx(pd.SnId, pd.Name, 0, int64(amount), 0, tag, pd.PromoterTree, model.COINGIVETYPE_SYSTEM, curVer, pd.Platform, pd.Channel, pd.BeUnderAgentCode, "", "system", pd.PackageID, 0, 0) if log != nil { task.New(nil, task.CallableWrapper(func(o *basic.Object) interface{} { err := model.InsertGiveCoinLog(log) if err == nil { if pd.LastExchangeOrder != "" && pd.TotalConvertibleFlow > 0 { err = model.UpdateGiveCoinLastFlow(log.Platform, pd.LastExchangeOrder, pd.TotalConvertibleFlow) } } return err }), task.CompleteNotifyWrapper(func(ud interface{}, t task.Task) { if ud == nil { //清空流水,更新id pd.TotalConvertibleFlow = 0 pd.LastExchangeOrder = log.LogId.Hex() player := PlayerMgrSington.GetPlayerBySnId(pd.SnId) if player == nil { //需要回写数据库 task.New(nil, task.CallableWrapper(func(o *basic.Object) interface{} { model.UpdatePlayerExchageFlowAndOrder(pd.Platform, pd.SnId, 0, pd.LastExchangeOrder) return nil }), nil, "UpdatePlayerExchageFlowAndOrder").StartByGroupFixExecutor(log.Platform, pd.AccountId) } } }), "UpdateGiveCoinLastFlow").StartByGroupFixExecutor(log.Platform, "UpdateGiveCoinLastFlow") } } if notifyClient { player := PlayerMgrSington.GetPlayerBySnId(pd.SnId) if player != nil { //通知客户端 sendPack := &shopproto.SCNotifyGiveCoinInfo{ GiveCoin: proto.Int64(int64(amount)), GiveTag: proto.Int32(tag), } proto.SetDefaults(sendPack) player.SendToClient(int(shopproto.SPacketID_SHOP_SC_GIVECOIN_INFO), sendPack) } } } } } func (this *Player) ReportSystemGiveEvent(amount, tag int32, notifyClient bool) { ReportSystemGiveEvent(this.PlayerData, amount, tag, notifyClient) } // 破产事件 func (this *Player) ReportBankRuptcy(gameid, gamemode, gamefreeid int32) { //if !this.IsRob { // d, e := model.MarshalBankruptcyEvent(2, this.SnId, this.TelephonePromoter, this.Channel, this.BeUnderAgentCode, // this.Platform, this.City, this.CreateTime, gameid, gamemode, gamefreeid) // if e == nil { // rmd := model.NewInfluxDBData("hj.player_bankruptcy", d) // if rmd != nil { // InfluxDBDataChannelSington.Write(rmd) // } // } //} } func (this *Player) CheckType(gameid, gamefreeId int32) *serverproto.DB_PlayerType { types := srvdata.PlayerTypeMgrSington.GetPlayerType(gamefreeId) cnt := len(types) if cnt > 0 { var pgs model.PlayerGameStatics if this.GDatas != nil { if d, exist := this.GDatas[strconv.Itoa(int(gameid))]; exist { pgs = d.Statics } } //赔率 产出/投入 万分比 odds := int64(float64(float64(pgs.TotalOut+1)/float64(pgs.TotalIn+1)) * 10000) if odds > 10000000 { odds = 10000000 } for i := 0; i < cnt; i++ { t := types[i] logger.Logger.Warn("Player CheckType 0 ", this.CoinPayTotal, t.GetPayLowerLimit(), t.GetPayUpperLimit(), pgs.GameTimes, t.GetGameTimeLowerLimit(), t.GetGameTimeUpperLimit(), pgs.TotalIn, t.GetTotalInLowerLimit(), t.GetTotalInUpperLimit(), odds, t.GetOddsLowerLimit(), t.GetOddsUpperLimit()) if t != nil { if this.CoinPayTotal >= int64(t.GetPayLowerLimit()) && this.CoinPayTotal <= int64(t.GetPayUpperLimit()) && pgs.GameTimes >= int64(t.GetGameTimeLowerLimit()) && pgs.GameTimes <= int64(t.GetGameTimeUpperLimit()) && pgs.TotalIn >= int64(t.GetTotalInLowerLimit()) && pgs.TotalIn <= int64(t.GetTotalInUpperLimit()) && odds >= int64(t.GetOddsLowerLimit()) && odds <= int64(t.GetOddsUpperLimit()) { return t } } } } return nil } // 线程不安全,避免异步任务调用 func (this *Player) GetPlatform() *Platform { platform := PlatformMgrSingleton.GetPlatform(this.Platform) if platform != nil && platform.Isolated { return platform } return PlatformMgrSingleton.GetPlatform(DefaultPlatform) } func (this *Player) RobotRandName() { if this.IsRob { //if rand.Int31n(100) < 60 { pool := srvdata.PBDB_NameMgr.Datas.GetArr() cnt := int32(len(pool)) if cnt > 0 { this.Name = pool[rand.Int31n(cnt)].GetName() } //} else { // this.Name = "Guest" //} } return } func (this *Player) PlayerMacAbnormal() bool { return false //s.HasSameIp(p.Ip) || s.HasSameMac() || s.HasSameTel() || s.HasSamePostion() } // 这个冲账记录不可随便写,需要加该日志时,请找lyk确认,暂定依据是金币直接加到身上,不依赖其他数据状态的可以写该日志 // 业务准则:先更新标记,再写冲账记录 func (this *Player) AddPayCoinLog(coin int64, coinType int32, oper string) { ts := time.Now().UnixNano() billNo := ts log := model.NewPayCoinLog(billNo, this.SnId, coin, 0, oper, coinType, 0) if log != nil { ts = log.TimeStamp task.New(nil, task.CallableWrapper(func(o *basic.Object) interface{} { err := model.InsertPayCoinLog(this.Platform, log) if err != nil { logger.Logger.Errorf("InsertPayCoinLog err:%v log:%v", err, log) return err } return err }), task.CompleteNotifyWrapper(func(data interface{}, t task.Task) { switch coinType { case model.PayCoinLogType_Coin: if this.CoinPayTs < ts { this.CoinPayTs = ts this.dirty = true } case model.PayCoinLogType_SafeBoxCoin: if this.SafeBoxCoinTs < ts { this.SafeBoxCoinTs = ts this.dirty = true } } }), "InsertPayCoinLog").StartByFixExecutor("InsertPayCoinLog") } } // 充值回调 func (this *Player) SendPlayerRechargeAnswer(coin int64) { if this.Tel == "" { pack := &playerproto.SCPlayerRechargeAnswer{ OpParam: proto.Int64(1), AddCoin: proto.Int64(coin), Coin: proto.Int64(this.Coin), SafeBoxCoin: proto.Int64(this.SafeBoxCoin), } proto.SetDefaults(pack) this.SendToClient(int(playerproto.PlayerPacketID_PACKET_SC_PLAYERRECHARGEANSWER), pack) } } // //// 在线奖励: 重置, 清零在线时长及奖励领取信息 //func (this *Player) OnlineRewardReset() { // this.PlayerData.OnlineRewardData.OnlineDuration = 0 // this.PlayerData.OnlineRewardData.RewardReceived = 0 // this.PlayerData.OnlineRewardData.Ts = time.Now().Unix() // this.dirty = true //} // //// 在线奖励: (Logout时)累计在线时长 //func (this *Player) OnlineRewardAddUpOnlineDuration() { // if this.state != PlayerState_Online { // return // } // // tNow := time.Now() // inSameDay := common.InSameDay(tNow, time.Unix(this.PlayerData.OnlineRewardData.Ts, 0)) // if inSameDay { // this.PlayerData.OnlineRewardData.OnlineDuration += uint32(tNow.Unix() - this.PlayerData.OnlineRewardData.Ts) // } else { // this.PlayerData.OnlineRewardData.OnlineDuration = uint32(tNow.Unix() - now.New(tNow).BeginningOfDay().Unix()) // } // // this.PlayerData.OnlineRewardData.Ts = tNow.Unix() // this.dirty = true //} // //// 在线奖励: (实时)获取在线时长 //func (this *Player) OnlineRewardGetOnlineDuration() uint32 { // this.OnlineRewardAddUpOnlineDuration() // return this.PlayerData.OnlineRewardData.OnlineDuration //} // 幸运转盘 //func (this *Player) LuckyTurntableSwitchScore(continuous bool) { // if continuous { // this.PlayerData.LuckyTurnTableData.Score = this.PlayerData.LuckyTurnTableData.TomorrowScore + // int64(this.PlayerData.LuckyTurnTableData.TomorrowFloatScore/100) // } else { // this.PlayerData.LuckyTurnTableData.Score = 0 // } // // this.PlayerData.LuckyTurnTableData.TomorrowScore = 0 // this.PlayerData.LuckyTurnTableData.TomorrowFloatScore = 0 // this.dirty = true //} func (this *Player) SyncSafeBoxCoinToGame() { pack := &serverproto.WGSyncPlayerSafeBoxCoin{ SnId: proto.Int32(this.SnId), SafeBoxCoin: proto.Int64(this.SafeBoxCoin), } proto.SetDefaults(pack) this.SendToGame(int(serverproto.SSPacketID_PACKET_WG_SyncPlayerSafeBoxCoin), pack) } //func (this *Player) GetDgHboPlayerName(plt *Platform) (string, string) { // if plt == nil { // return "", "" // } // if plt.DgHboConfig == 0 { // return this.DgGame, this.DgPass // } else if plt.DgHboConfig == 1 { // return this.StoreDgGame, this.StoreDgPass // } else if plt.DgHboConfig == 2 { // return this.StoreHboGame, this.StoreHboPass // } // return "", "" //} // //func (this *Player) SetDgHboPlayerName(plt *Platform, name, pass string) { // if plt == nil { // return // } // // if plt.DgHboConfig == 0 { // this.DgGame = name // this.DgPass = pass // if strings.Contains(name, "dg") { // this.StoreDgGame = name // this.StoreDgPass = pass // } else { // this.StoreHboGame = name // this.StoreHboPass = pass // } // } else if plt.DgHboConfig == 1 { // this.StoreDgGame = name // this.StoreDgPass = pass // } else if plt.DgHboConfig == 2 { // this.StoreHboGame = name // this.StoreHboPass = pass // } // //} func (this *Player) AddCoinPayTotal(coin int64) { this.CoinPayTotal += coin } // 当用户充值 func OnPlayerPay(pd *model.PlayerData, coin int64) { if pd == nil { return } buf, err := pd.GetPlayerDataEncoder() if err == nil { pack := &serverproto.WTPlayerPay{ AddCoin: proto.Int64(coin), PlayerData: buf.Bytes(), } proto.SetDefaults(pack) common.SendToActThrSrv(int(serverproto.SSPacketID_PACKET_WT_PLAYERPAY), pack) } //ActFPayMgrSington.OnPlayerPay(pd.SnId, pd.Platform, coin) } func (this *Player) SendPlatformCanUsePromoterBind() { state := int32(0) plt := PlatformMgrSingleton.GetPlatform(this.Platform) if plt != nil { if plt.IsCanUserBindPromoter { state = 1 if this.BeUnderAgentCode != "" && this.BeUnderAgentCode != "0" { state = 2 } } } pack := &playerproto.SCBindPromoterState{ BindState: proto.Int32(state), } proto.SetDefaults(pack) this.SendToClient(int(playerproto.PlayerPacketID_PACKET_SC_BINDPROMOTERSTATE), pack) } func (this *Player) RedirectByGame(packetid int, rawpack interface{}) bool { if this.scene == nil || this.scene.gameSess == nil || this.scene.gameSess.Session == nil { logger.Logger.Tracef("[%v] sess == nil ", this.Name) return false } if rawpack == nil { logger.Logger.Trace(" rawpack == nil ") return false } data, err := netlib.MarshalPacket(packetid, rawpack) if err == nil { pack := &serverproto.SSRedirectToPlayer{ SnId: proto.Int32(this.SnId), PacketId: proto.Int(packetid), Data: data, } proto.SetDefaults(pack) return this.SendToGame(int(serverproto.SSPacketID_PACKET_SS_REDIRECTTOPLAYER), pack) } return false } // SyncPlayerDataToGateSrv 玩家信息同步到网关 func (this *Player) SyncPlayerDataToGateSrv(pd *model.PlayerData) { var buf bytes.Buffer enc := gob.NewEncoder(&buf) err := enc.Encode(pd) if err != nil { logger.Logger.Info("(this *Player) UpdateToGateSrv gob.Marshal error", err) } else { pack := &serverproto.WRPlayerData{ Sid: this.sid, PlayerData: buf.Bytes(), } proto.SetDefaults(pack) this.gateSess.Send(int(serverproto.SSPacketID_PACKET_WR_PlayerData), pack) } } func (this *Player) BindGroupTag(tags []string) { if this.gateSess == nil { return } pack := &serverproto.SGBindGroupTag{ Sid: proto.Int64(this.sid), Code: serverproto.SGBindGroupTag_OpCode_Add, Tags: tags, } proto.SetDefaults(pack) this.gateSess.Send(int(serverproto.SSPacketID_PACKET_SG_BINDGROUPTAG), pack) } func (this *Player) UnBindGroupTag(tags []string) { if this.gateSess == nil { return } pack := &serverproto.SGBindGroupTag{ Sid: proto.Int64(this.sid), Code: serverproto.SGBindGroupTag_OpCode_Del, Tags: tags, } proto.SetDefaults(pack) this.gateSess.Send(int(serverproto.SSPacketID_PACKET_SG_BINDGROUPTAG), pack) } func (this *Player) TryRetrieveLostGameCoin(sceneid int) { //发送一个探针,等待ack后同步金币 logProbe := model.NewCoinLog() logProbe.SnId = this.SnId logProbe.Count = 0 //必须是0,探针标识 logProbe.RestCount = 0 //this.Coin logProbe.SeqNo = this.GameCoinTs logProbe.RoomId = int32(sceneid) LogChannelSingleton.WriteLog(logProbe) //先把玩家身上的钱清掉 //this.Coin = 0 this.SendDiffData() } func (this *Player) SyncGameCoin(sceneid int, enterts int64) { //游服金币冲账 endts := time.Now().UnixNano() var err error var gamecoinlogs []model.CoinWAL task.New(nil, task.CallableWrapper(func(o *basic.Object) interface{} { gamecoinlogs, err = model.GetCoinWALBySnidAndInGameAndGreaterTs(this.Platform, this.SnId, int32(sceneid), enterts) return err }), task.CompleteNotifyWrapper(func(data interface{}, t task.Task) { if err == nil && len(gamecoinlogs) != 0 { oldCoin := this.Coin var cnt int64 for i := 0; i < len(gamecoinlogs); i++ { ts := gamecoinlogs[i].Ts if ts >= enterts && ts <= endts { cnt = gamecoinlogs[i].Count this.Coin += cnt if ts > this.GameCoinTs { this.GameCoinTs = ts } } } newCoin := this.Coin newTs := this.GameCoinTs logger.Logger.Warnf("PlayerData(%v) SyncGameCoin before:enterts=%v before:Coin=%v after:GameCoinTs=%v after:Coin=%v", this.SnId, enterts, oldCoin, newTs, newCoin) } this.SendDiffData() }), "GetCoinWALBySnidAndInGameAndGreaterTs").Start() } func (this *Player) SendShowRed(showType hallproto.ShowRedCode, showChild, isShow int32) { pack := &hallproto.SCShowRed{ ShowRed: &hallproto.ShowRed{ ShowType: showType, ShowChild: proto.Int32(showChild), IsShow: proto.Int32(isShow), }, } proto.SetDefaults(pack) logger.Logger.Trace("SCShowRed:", pack) this.SendToClient(int(hallproto.HallPacketID_PACKET_SC_SHOWRED), pack) } func (this *Player) SCVIPBuy(buy int64) { //buy *= 10000 //this.AddMoneyPayTotal(buy) //this.GetVIPLevel(0) // 更新下vip等级 pack := &playerproto.SCVIPBuy{ OpRetCode: playerproto.OpResultCode_OPRC_Sucess, } pack.TolVipExp, pack.Money = this.GetCurrentVIPExp() // 获取经验会更新vip等级 pack.Vip = this.VIP this.SendToClient(int(playerproto.PlayerPacketID_PACKET_SC_VIPBUY), pack) } func (this *Player) SCVIPInfo() { if this.IsRob { return } pack := &playerproto.SCVIPInfo{ OpRetCode: playerproto.OpResultCode_OPRC_Error, } vips := VipMgrSington.GetVIPcfg(this.Platform) if vips != nil { pack.MoneyRatio = int32(vips.MoneyRatio) for _, cfg := range vips.List { data := &playerproto.VIPcfg{ VipId: cfg.VipId, VipEx: cfg.VipEx, Price: cfg.Price, Privilege1: cfg.Privilege1, Privilege2: cfg.Privilege2, Privilege3: cfg.Privilege3, Privilege4: cfg.Privilege4, Privilege5: cfg.Privilege5, Privilege6: cfg.Privilege6, Privilege7Price: cfg.Privilege7Price, Privilege8: cfg.Privilege8, LineId: cfg.RewardOutlineID, ShopId2: cfg.ShopId2, ShopId7: cfg.ShopId7, MatchFreeTimes: cfg.MatchFreeTimes, } for itemId, itemNum := range cfg.Award { data.Item = append(data.Item, &playerproto.ItemInfo{ ItemId: int32(itemId), ItemNum: itemNum, }) } for itemId, itemNum := range cfg.Privilege7 { data.Privilege7 = append(data.Privilege7, &playerproto.ItemInfo{ ItemId: int32(itemId), ItemNum: itemNum, }) } data.BagStatus = make([]int32, 3) data.BagStatus[0] = 0 //每日礼包 0可领取 1不可领取 只能领取当前VIP等级的 data.BagStatus[1] = 0 //每日金币礼包 0可领取 1不可领取 只能领取当前VIP等级的 data.BagStatus[2] = this.GetPlayerVipBagStatus(cfg.ShopId7, cfg.VipId) //固定VIP礼包 0可领取 1不可领取 可以领取所有VIP等级的奖励 if cfg.VipId != this.VIP { data.BagStatus[0] = 1 //每日礼包 0可领取 1不可领取 只能领取当前VIP等级的 data.BagStatus[1] = 1 //每日金币礼包 0可领取 1不可领取 只能领取当前VIP等级的 } else { data.BagStatus[0] = this.GetPlayerVipBagStatus(0, cfg.VipId) data.BagStatus[1] = this.GetPlayerVipBagStatus(cfg.ShopId2, cfg.VipId) } pack.List = append(pack.List, data) } pack.TolVipExp, pack.Money = this.GetCurrentVIPExp(vips) pack.Vip = this.VIP pack.OpRetCode = playerproto.OpResultCode_OPRC_Sucess //WelfareMgrSington.MonitorWelfData(this) //pack.VipId = append(pack.VipId, this.WelfData.VIPGift...) } this.SendToClient(int(playerproto.PlayerPacketID_PACKET_SC_VIPINFO), pack) } func (this *Player) GetVIPExpByPay(payTotal int32) int32 { vips := VipMgrSington.GetVIPcfg(this.Platform) return int32(math.Floor(float64(payTotal) * vips.MoneyRatio / 100)) } func (this *Player) VIPDraw(id int32) { //WelfareMgrSington.MonitorWelfData(this) pack := &playerproto.SCVIPDraw{ Id: id, OpRetCode: playerproto.OpResultCode_OPRC_Error, } if id != 0 { this.SendToClient(int(playerproto.PlayerPacketID_PACKET_SC_DRAWVIPGIFT), pack) return } if this.WelfData.VIPBag == nil { this.WelfData.VIPBag = make(map[int32]map[int32]int32) } if innerMap, ok := this.WelfData.VIPBag[this.VIP]; ok { if _, ok := innerMap[0]; ok { logger.Logger.Trace("VIPDraw VIP is repeat id%v ", id) this.SendToClient(int(playerproto.PlayerPacketID_PACKET_SC_DRAWVIPGIFT), pack) return } } else { this.WelfData.VIPBag[this.VIP] = make(map[int32]int32) } vips := VipMgrSington.GetVIPcfg(this.Platform) if vips != nil { for _, data := range vips.List { if data.VipId == this.VIP { pack.OpRetCode = playerproto.OpResultCode_OPRC_Sucess this.WelfData.VIPBag[this.VIP][0] = 1 //金币数量 money := data.Privilege1[0] //vip经验 addVipExp := int64(float64(data.Privilege1[1]) / vips.MoneyRatio) this.AddCoin(int64(money), 0, common.GainWay_VIPGift, "sys", "VIP每日礼包") this.AddMoneyPayTotal(addVipExp) pack.Vip = this.VIP logger.Logger.Tracef("玩家领取VIP每日礼包成功!snid = %v,Vip = %v,金币数量 = %v,addVipEx = %v", this.SnId, this.VIP, money, addVipExp) //VIP礼包统计数据 task.New(nil, task.CallableWrapper(func(o *basic.Object) interface{} { var item []model.ItemInfo item = append(item, model.ItemInfo{ItemId: 1, ItemNum: int64(money)}) log := model.NewDbVip(this.Platform, this.SnId, this.VIP, 0, 0, 0, item, 0, "Vip每日礼包") return model.InsertDbVipLog(log) }), task.CompleteNotifyWrapper(func(data interface{}, t task.Task) { if data != nil { logger.Logger.Errorf("err:", data.(error)) } }), "VIPDraw").Start() break } } } this.SendToClient(int(playerproto.PlayerPacketID_PACKET_SC_DRAWVIPGIFT), pack) } func (this *Player) GetCurrentVIPExp(vipcfg ...*webapiproto.VIPcfgDataList) (exp int64, money int64) { var vips *webapiproto.VIPcfgDataList if len(vipcfg) == 0 { vips = VipMgrSington.GetVIPcfg(this.Platform) } else { vips = vipcfg[0] } exp = int64(float64(this.MoneyPayTotal) * vips.MoneyRatio) tolexp := int32(0) oldVipLevel := this.VIP if vips != nil && this.MoneyPayTotal != 0 { allExp := int64(float64(this.MoneyPayTotal) * vips.MoneyRatio) for _, v := range vips.List { tolexp = v.VipEx if allExp >= int64(v.VipEx) { this.VIP = v.VipId this.VipExtra = v.Privilege4 } else { break } } } money = int64(tolexp) - exp if money < 0 { money = 0 } if oldVipLevel != this.VIP { //玩家VIP升级 this.SCVIPInfo() logger.Logger.Trace("VIP升级!") } return // 默认 } func (this *Player) GetVIPLevel() int32 { if this.IsRob { return 0 } vips := VipMgrSington.GetVIPcfg(this.Platform) vip := int32(0) if vips != nil && this.MoneyPayTotal != 0 { allExp := int64(float64(this.MoneyPayTotal) * vips.MoneyRatio) for _, v := range vips.List { if allExp >= int64(v.VipEx) { vip = v.VipId this.VipExtra = v.Privilege4 } else { break } } } if vip != this.VIP { //玩家VIP升级 this.SCVIPInfo() logger.Logger.Trace("VIP升级!") } this.VIP = vip return this.VIP } func (this *Player) GetMaxVIPLevel() int32 { vips := VipMgrSington.GetVIPcfg(this.Platform) if vips != nil && len(vips.List) > 0 { vn := len(vips.List) - 1 return vips.List[vn].VipId } return 0 } // GetMatchFreeTimes 比赛场免费次数 func (this *Player) GetMatchFreeTimes() int32 { cfg := VipMgrSington.GetVIPLevelCfg(this.Platform, this.VIP) if cfg != nil { return cfg.GetMatchFreeTimes() } return 0 } // 玩家登录 检查充值状态 func (this *Player) GetPayGoodsInfo() { if this.IsRob { return } task.New(nil, task.CallableWrapper(func(o *basic.Object) interface{} { info := model.GetDbShopLogsByState(this.Platform, this.SnId) if info != nil { for _, shop := range info { err := model.UpdateDbShopState(shop.Platform, shop.LogId.Hex(), 1) if err != nil { logger.Logger.Error("GetPayGoodsInfo.UpdateDbShopState err:", err) return nil } } } return info }), task.CompleteNotifyWrapper(func(data interface{}, tt task.Task) { if data != nil { infos := data.([]*model.DbShop) for _, info := range infos { switch info.PageId { case ShopPageBackend: logger.Logger.Tracef("GetPayGoodsInfo ShopPageBackend %+v", *info) default: var itemInfo []*playerproto.PayItem var items []*Item if len(info.Amount) > 0 { this.AddCoin(int64(info.Amount[0]), 0, info.GainWay, "Callback_login", info.Remark) this.AddDiamond(int64(info.Amount[1]), 0, info.GainWay, "Callback_login", info.Remark) } this.AddMoneyPayTotal(int64(info.ConsumeNum)) this.MoneyTotal += int64(info.ConsumeTypeNum) if info.ItemInfo != nil { for _, v := range info.ItemInfo { items = append(items, &Item{ItemId: v.ItemId, ItemNum: v.ItemNum}) itemInfo = append(itemInfo, &playerproto.PayItem{ ItemId: v.ItemId, ItemNum: v.ItemNum, }) } } //钻石存储罐 if info.PageId == ShopPageDiamondBank { WelfareMgrSington.DiamondBankTakeCoin(this) } if info.PageId == ShopPagePermit { this.Permit = info.CreateTs.Local() LogChannelSingleton.WriteLog(&model.BackendPermitJoin{ Platform: this.Platform, StartTs: PlatformMgrSingleton.GetConfig(this.Platform).PermitStartTs, SnId: this.SnId, Ts: time.Now().Unix(), }) TaskSubjectSingleton.Touch(common.TaskTypeBuyPermit, &TaskData{ SnId: this.SnId, Num: 1, }) } switch info.Remark { case "BlindBox": if len(info.OtherParams) > 0 { this.WelfData.BlindBoxId = info.OtherParams[0] } else { logger.Logger.Errorf("GetPayGoodsInfo BlindBox OtherParams is nil") } case "FirstRecharge": if len(info.OtherParams) > 0 { this.WelfData.FirstPayDay = info.OtherParams[0] this.WelfData.FirstPayTickets = info.Ts } else { logger.Logger.Errorf("GetPayGoodsInfo FirstRecharge OtherParams is nil") } case "ContinuousPay": if len(info.OtherParams) > 0 { this.WelfData.ContinuousPayDay = info.OtherParams[0] this.WelfData.ContinuousPayTickets = info.Ts } else { logger.Logger.Errorf("GetPayGoodsInfo ContinuousPay OtherParams is nil") } } this.UpdatePlayerVipBag(info.ShopId) this.UpdateShopID(info.ShopId) this.dirty = true this.SendDiffData() info.Amount[2] = this.GetVIPExpByPay(info.ConsumeNum) BagMgrSingleton.AddItems(this, items, 0, info.GainWay, info.Operator, info.Remark, 0, 0, false) PayGoodsInfo := &playerproto.SCPayGoodsInfo{ Gold: info.Amount, Item: itemInfo, } proto.SetDefaults(PayGoodsInfo) this.SendToClient(int(playerproto.PlayerPacketID_PACKET_SC_PAYGOODSINFO), PayGoodsInfo) } if info.ConsumeNum > 0 { TaskSubjectSingleton.Touch(common.TaskTypePay, &TaskData{ SnId: this.SnId, Num: int64(info.ConsumeNum), }) } } } })).StartByFixExecutor("GetPayGoodsLogs") } func (this *Player) SendJackPotInit() { var pack = &hallproto.SCHundredSceneGetGameJackpot{} gameFreeIds := []int32{ 3010001, 3010002, 3010003, 3010004, 3020001, 3020002, 3020003, 3020004, 3030001, 3030002, 3030003, 3030004, 3040001, 3040002, 3040003, 3050001, 3050002, 3050003} for _, id := range gameFreeIds { data := srvdata.PBDB_GameFreeMgr.GetData(id) if data != nil && len(data.Jackpot) > 0 { jpfi := &hallproto.GameJackpotFundInfo{ GameFreeId: proto.Int32(data.Id), JackPotFund: proto.Int64(int64(data.BaseScore * data.Jackpot[0])), } pack.GameJackpotFund = append(pack.GameJackpotFund, jpfi) } } if len(pack.GameJackpotFund) > 0 { this.SendToClient(int(hallproto.HundredScenePacketID_PACKET_SC_GAMEJACKPOT), pack) } } func (this *Player) OnlineLogLogin() { if this.IsRob { return } if this.onlineLog == nil { this.onlineLog = model.NewOnlineLog(bson.NewObjectId(), this.SnId, common.LoginLogTypeLogin, this.Platform) LogChannelSingleton.WriteLog(*this.onlineLog) } } func (this *Player) OnlineLogRehold() { if this.IsRob { return } if this.onlineLog == nil { this.onlineLog = model.NewOnlineLog(bson.NewObjectId(), this.SnId, common.LoginLogTypeRehold, this.Platform) LogChannelSingleton.WriteLog(*this.onlineLog) } } func (this *Player) OnlineLogDrop() { if this.IsRob { return } if this.onlineLog != nil && this.onlineLog.OfflineTs == 0 { this.onlineLog.OfflineType = common.LoginLogTypeDrop this.onlineLog.OfflineTs = time.Now().Unix() LogChannelSingleton.WriteLog(*this.onlineLog) this.onlineLog = nil } } func (this *Player) OnlineLogLogout() { if this.IsRob { return } if this.onlineLog != nil && this.onlineLog.OfflineTs == 0 { this.onlineLog.OfflineType = common.LoginLogTypeLogout this.onlineLog.OfflineTs = time.Now().Unix() LogChannelSingleton.WriteLog(*this.onlineLog) this.onlineLog = nil } } func (this *Player) AddDiamondToCoin(n int64) { if n > 0 { this.dirty = true this.DiamondToCoin += n } } // SendRankSeason 通知客户端赛季信息 func (this *Player) SendRankSeason() { pack := &rankmatch.SCRMSeasonInfo{} cfg := RankMgrSingleton.GetSeasonConfig(this.Platform) if cfg == nil { this.SendToClient(int(rankmatch.RankMatch_PACKET_RM_SCRMSeasonInfo), pack) return } pack = &rankmatch.SCRMSeasonInfo{ Id: cfg.SeasonId, TimeStamp: []int64{cfg.StartTs, cfg.EndTs}, } rank := RankMgrSingleton.GetPlayerSeason(this.SnId) if rank != nil && rank.PlayerRankSeason != nil && rank.RankType != nil { for k, v := range rank.RankType { if v == nil { continue } info := &rankmatch.SeasonInfo{Id: k} info.Lv, info.Score = RankMgrSingleton.GetPlayerRankLV(k, this.SnId) info.LastLv, info.LastScore = RankMgrSingleton.GetPlayerLastRankLV(k, this.SnId) se := RankMgrSingleton.GetPlayerSeason(this.SnId) if se != nil && se.RankType[k] != nil { if se.RankType[k].LastScore < se.RankType[k].Score { oldLv := srvdata.RankLevelMgr.GetRankLevel(k, se.RankType[k].LastScore) if info.Lv > oldLv { var awards *rankmatch.AwardItem var maxLv int32 = -1 for _, item := range RankMgrSingleton.GetRankAwardList(k) { // 1 可领取 2已领取 if info.Lv >= item.Lv { has := false // 是否已领取 for _, vv := range v.Awards { if vv.Id == item.Id { if vv.Ts > 0 { has = true } break } } if !has { if item.Lv > maxLv { awards = item maxLv = item.Lv } } } } if awards != nil { info.Award = awards } } se.RankType[k].LastScore = se.RankType[k].Score } } pack.Seasons = append(pack.Seasons, info) } } this.SendToClient(int(rankmatch.RankMatch_PACKET_RM_SCRMSeasonInfo), pack) logger.Logger.Trace("SCTMSeasonInfo:", pack) } func (this *Player) SendPlayerCoin() { LogChannelSingleton.WriteLog(&model.RankPlayerCoin{ Platform: this.Platform, SnId: this.SnId, Name: this.Name, Sex: this.Sex, HeadUrl: this.HeadUrl, Coin: this.GetTotalCoin(), ModId: this.GetRoleId(), }) } // 解锁炮倍 func (this *Player) UnPlayerPowerEx(power int64) { logger.Logger.Tracef("解锁炮倍 当前最大解锁炮倍:%v,要解锁的炮倍:%v", this.UnMaxPower, power) if this.UnPlayerPower(power) { pack := &playerproto.SCPlayerUnPower{ UnMaxpower: power, } this.UnMaxPower = power this.SendToClient(int(playerproto.PlayerPacketID_PACKET_SC_PlayerUnPower), pack) logger.Logger.Tracef("通知客户端解锁最大炮倍,snid = %v,power = %v", this.SnId, power) } } // 道具解锁炮台 func (this *Player) ItemUnPlayerPowerListEx(itemId int32) { if itemId == 0 { return } //判断炮台存不存在 var powerId int32 = 0 for _, data := range srvdata.PBDB_ArtillerySkinMgr.Datas.GetArr() { if data.CannonId == itemId { powerId = data.Id break } } if powerId == 0 { return } if this.UnPlayerPowerList(powerId) { //通知客户端解锁炮台 pack := &playerproto.SCPlayerUnPowerList{ UnPowerList: powerId, } this.SendToClient(int(playerproto.PlayerPacketID_PACKET_SC_PlayerUnPowerList), pack) logger.Logger.Trace("通知客户端解锁炮台 snid = %v,解锁的炮台:%v,当前已有的炮台 = %v", this.SnId, powerId, this.PowerList) } } // powerId 解锁炮台 func (this *Player) UnPlayerPowerListEx(powerId int32) { data := srvdata.PBDB_ArtillerySkinMgr.GetData(powerId) if data == nil { return } if this.UnPlayerPowerList(powerId) { //通知客户端解锁炮台 pack := &playerproto.SCPlayerUnPowerList{ UnPowerList: powerId, } this.SendToClient(int(playerproto.PlayerPacketID_PACKET_SC_PlayerUnPowerList), pack) logger.Logger.Trace("通知客户端解锁炮台 snid = %v,解锁的炮台:%v,当前已有的炮台 = %v", this.SnId, powerId, this.PowerList) } } func (this *Player) UpdatePlayerVipBag(shopId int32) { //判断是否是vip商品 更新数据 shopInfo := ShopMgrSington.GetShopInfo(shopId, this) if shopInfo != nil { if shopInfo.Page == ShopPagePrivilege { if this.WelfData.VIPBag == nil { this.WelfData.VIPBag = make(map[int32]map[int32]int32) } if _, ok := this.WelfData.VIPBag[shopInfo.VipLevel]; !ok { this.WelfData.VIPBag[shopInfo.VipLevel] = make(map[int32]int32) } this.WelfData.VIPBag[shopInfo.VipLevel][shopInfo.Id] = shopInfo.Type logger.Logger.Tracef("玩家购买VIP商品成功,更新购买状态!snid = %v shopId = %v,VIP = %v", this.SnId, shopInfo.Id, shopInfo.VipLevel) pack := &playerproto.SCVIPDraw{ Id: shopInfo.Type, Vip: shopInfo.VipLevel, OpRetCode: playerproto.OpResultCode_OPRC_Sucess, } this.SendToClient(int(playerproto.PlayerPacketID_PACKET_SC_DRAWVIPGIFT), pack) //VIP金币礼包&VIP固定礼包统计数据 task.New(nil, task.CallableWrapper(func(o *basic.Object) interface{} { var item []model.ItemInfo item = append(item, model.ItemInfo{ItemId: shopInfo.Type, ItemNum: shopInfo.Amount}) log := model.NewDbVip(this.Platform, this.SnId, shopInfo.VipLevel, shopInfo.Type, shopInfo.ConstType, int64(shopInfo.CostArea[0]), item, shopInfo.Id, shopInfo.Name) return model.InsertDbVipLog(log) }), task.CompleteNotifyWrapper(func(data interface{}, t task.Task) { if data != nil { logger.Logger.Errorf("err:", data.(error)) } }), "UpdatePlayerVipBag").Start() } //判断是否是礼包周卡 if shopInfo.Page == ShopPageGift { this.UpdateWeekCardData(shopId) } } } // 判断vip特权某个礼包是否领取过 返回值:0可领取 1 不可领取 func (this *Player) GetPlayerVipBagStatus(shopId, vipLevel int32) int32 { if vipLevel > this.VIP { return 1 } if this.WelfData == nil || this.WelfData.VIPBag == nil { return 0 } if _, ok := this.WelfData.VIPBag[vipLevel]; !ok { return 0 } if _, ok := this.WelfData.VIPBag[vipLevel][shopId]; !ok { return 0 } return 1 } func (this *Player) UpdateVipShopData() { this.VipShopData = nil this.VipShopRefreshCount = 0 //每日礼包 和每日金币礼包需要初始化 if this.WelfData != nil && this.WelfData.VIPBag != nil { delKeyList := []int32{} for _, data := range this.WelfData.VIPBag { for shopId, shopType := range data { if shopId == 0 { //初始化每日礼包 delKeyList = append(delKeyList, shopId) logger.Logger.Trace("初始化VIP每日礼包!!!!!!!") } else { if shopType == 1 { delKeyList = append(delKeyList, shopId) logger.Logger.Trace("初始化VIP每日固定礼包!!!!!!!!!!") } } } } for _, delKey := range delKeyList { for _, data := range this.WelfData.VIPBag { delete(data, delKey) } } this.SCVIPInfo() } } func (this *Player) RandRobotVip(scene *Scene) { if !this.IsRobot() || scene == nil || scene.dbGameFree == nil { return } // vip config := srvdata.PBDB_PotOddMgr.GetData(scene.dbGameFree.GetId()) if config == nil || len(config.VipOdd) == 0 { return } var all int32 for _, v := range config.VipOdd { all += v } n := rand.Int31n(all) vip := 0 var sum int32 for k, v := range config.VipOdd { sum += v if n < sum { vip = k break } } this.VIP = int32(vip) } // BindTelReward 发送绑定手机号奖励 func (this *Player) BindTelReward() { // todo 奖励限额;ip日期最多赠送多少奖励 // 发送奖励 plt := PlatformMgrSingleton.GetPlatform(this.Platform) if plt != nil { var items []*Item for k, v := range plt.BindTelReward { switch k { case 1: items = append(items, &Item{ ItemId: common.ItemIDCoin, ItemNum: v, }) case 2: items = append(items, &Item{ ItemId: common.ItemIDDiamond, ItemNum: v, }) default: items = append(items, &Item{ ItemId: k, ItemNum: v, }) } } BagMgrSingleton.AddItems(this, items, 0, common.GainWay_BindTel, "system", "绑定手机号", 0, 0, false) } } func (this *Player) UpdateShopID(shopId int32) { var shopInfo = ShopMgrSington.ConfigMgr.GetShopInfo(this.Platform, shopId) if shopInfo != nil && shopInfo.FirstSwitch { if !slices.Contains(this.ShopID, int(shopInfo.Id)) { this.ShopID = append(this.ShopID, int(shopInfo.Id)) } } } // 增加抽奖次数 func (this *Player) addLotteryCount(count int32) { if WelfareMgrSington.GetPhoneLotteryStatus(this.Platform) == model.WelfareClose { return } this.LotteryCount += count if this.LotteryCount < 0 { this.LotteryCount = 0 } if this.LotteryCount >= math.MaxInt32 { this.LotteryCount = math.MaxInt32 } //通知客户端 pack := &playerproto.SCPhoneLotteryCount{ Count: this.LotteryCount, } this.SendToClient(int(playerproto.PlayerPacketID_PACKET_SC_PhoneLotteryCount), pack) } // 增加手机积分 func (this *Player) AddPhoneScore(num, add int64, gainWay int32, oper, remark string) { if num == 0 { return } if WelfareMgrSington.GetPhoneLotteryStatus(this.Platform) == model.WelfareClose { return } logger.Logger.Tracef("snid(%v) AddPhoneScore(%v)", this.SnId, num) if num != 0 /*&& !async*/ { this.dirty = true if num > 0 { this.PhoneScore += num } else { if -num > this.PhoneScore { logger.Logger.Errorf("Player.AddPhoneScore exception!!! num(%v) oper(%v)", num, oper) num = -this.PhoneScore this.PhoneScore = 0 } else { this.PhoneScore += num } } this.SendDiffData() } } // 抽奖任务 func (this *Player) PhoneLotteryTask(taskId int32, num int64) { if WelfareMgrSington.GetPhoneLotteryStatus(this.Platform) == model.WelfareClose { if this.WelfData != nil && this.WelfData.PhoneLotteryTask != nil { this.WelfData.PhoneLotteryTask = make(map[int32]*model.TaskData) } return } if this.WelfData == nil { this.WelfData = model.NewWelfareData() } if this.WelfData.PhoneLotteryTask == nil { this.WelfData.PhoneLotteryTask = make(map[int32]*model.TaskData) } if this.WelfData.PhoneLotteryTask[taskId] == nil { this.WelfData.PhoneLotteryTask[taskId] = &model.TaskData{N: 0} // 初始化任务数据 } switch taskId { case common.TaskTypePay: this.WelfData.PhoneLotteryTask[taskId].N += num if this.WelfData.PhoneLotteryTask[taskId].N/20 > 0 { count := this.WelfData.PhoneLotteryTask[taskId].N / 20 this.addLotteryCount(int32(count)) this.WelfData.PhoneLotteryTask[taskId].N = this.WelfData.PhoneLotteryTask[taskId].N % 20 LogChannelSingleton.WriteMQData(model.GeneratePhoneLottery(this.SnId, this.Platform, "", 3, int(count), 4, 0)) } case common.TaskTypeWinOrLose: this.WelfData.PhoneLotteryTask[taskId].N += num if this.WelfData.PhoneLotteryTask[taskId].N/200000000 > 0 { count := this.WelfData.PhoneLotteryTask[taskId].N / 200000000 this.addLotteryCount(int32(count)) this.WelfData.PhoneLotteryTask[taskId].N = this.WelfData.PhoneLotteryTask[taskId].N % 200000000 LogChannelSingleton.WriteMQData(model.GeneratePhoneLottery(this.SnId, this.Platform, "", 3, int(count), 3, 0)) } case common.TaskTypeTienlenCount: this.WelfData.PhoneLotteryTask[taskId].N += num if this.WelfData.PhoneLotteryTask[taskId].N/20 > 0 { count := this.WelfData.PhoneLotteryTask[taskId].N / 20 this.addLotteryCount(int32(count)) this.WelfData.PhoneLotteryTask[taskId].N = this.WelfData.PhoneLotteryTask[taskId].N % 20 LogChannelSingleton.WriteMQData(model.GeneratePhoneLottery(this.SnId, this.Platform, "", 3, int(count), 2, 0)) } case common.TaskTypeFirstLogin: this.addLotteryCount(5) LogChannelSingleton.WriteMQData(model.GeneratePhoneLottery(this.SnId, this.Platform, "", 3, 5, 1, 0)) default: logger.Logger.Errorf("手机抽奖任务未找到对应的任务ID: %d", taskId) return } } func InviteTask(platform string, psnid, snid, scoreType int32, n int64) { if snid <= 0 { return } cfg := PlatformMgrSingleton.GetConfig(platform).ActInviteConfig switch scoreType { case common.InviteScoreTypeBind: case common.InviteScoreTypePay: score, ok := cfg.GetPayScore()[n] if ok { SaveInviteScore(&model.InviteScore{ Platform: platform, SnId: snid, InviteSnId: psnid, Tp: scoreType, Score: score, Ts: time.Now().Unix(), Money: n, }) } else { SaveInviteScore(&model.InviteScore{ Platform: platform, SnId: snid, InviteSnId: psnid, Tp: common.InviteScoreTypeRecharge, Score: cfg.GetRechargeScore(), Ts: time.Now().Unix(), Money: n, }) } } } func (this *Player) ResetTaskN(tp int32) { if this.WelfData == nil || this.WelfData.Task == nil { return } for _, v := range srvdata.TaskMgr.GetTaskType(tp) { data := this.WelfData.Task[v.GetId()] if data != nil { data.N = 0 } } } func (this *Player) ResetTask(tp int32) { if this.WelfData == nil || this.WelfData.Task == nil { return } for _, v := range srvdata.TaskMgr.GetActivityType(tp) { this.WelfData.Task[v.GetId()] = &model.TaskData{} } } func (this *Player) CollectTask(taskId int32, num int64) { state := WelfareMgrSington.GetCollectSwitch(this.Platform) if state != model.WelfareOpen { return } // 每日登录游戏赠送一个 // 每日转盘抽奖赠送一个 switch taskId { case common.TaskTypeTurnplate, common.TaskTypeFirstLogin: oper := fmt.Sprintf("集卡活动%v", taskId) var items []*Item items = append(items, &Item{ ItemId: common.ItemIDCollectBox, ItemNum: num, ObtainTime: time.Now().Unix(), }) BagMgrSingleton.AddItems(this, items, 0, common.GainWayItemCollectLogin, "system", oper, 0, 0, false) default: } } // 购买周卡检查 func (this *Player) CheckWeekCard(shopId int32) bool { id := int32(-1) for _, card := range srvdata.PBDB_GiftCardMgr.Datas.GetArr() { if card.ShopID == shopId { id = card.Id break } } if id == -1 { return false } logger.Logger.Trace("玩家请求购买周卡!") //获取当前时间 now := time.Now().Unix() //计算时间差 timeDiff := int32(this.WeekCardTime[id]-now) / 86400 if timeDiff > 3 { logger.Logger.Trace("当前剩余时间大于3天,无法购买周卡!") return false } return true } // 购买周卡 func (this *Player) UpdateWeekCardData(shopId int32) bool { id := int32(-1) cardTime := 0 for _, card := range srvdata.PBDB_GiftCardMgr.Datas.GetArr() { if card.ShopID == shopId { id = card.Id cardTime = int(card.Time) break } } if id == -1 { return false } if this.WeekCardTime == nil { this.WeekCardTime = make(map[int32]int64) } logger.Logger.Trace("玩家请求购买周卡!") //获取当前时间 now := time.Now().Unix() //计算时间差 timeDiff := int32(this.WeekCardTime[id]-now) / 86400 if timeDiff > 3 { logger.Logger.Trace("当前剩余时间大于3天,无法购买周卡!") return false } //计算剩余时间 addTime := 0 if timeDiff > 0 { addTime = int(timeDiff) } //计算7天后0点时间 sevenDaysLater := time.Now().AddDate(0, 0, cardTime+addTime+1) zeroTime := time.Date(sevenDaysLater.Year(), sevenDaysLater.Month(), sevenDaysLater.Day(), 0, 0, 0, 0, sevenDaysLater.Location()) logger.Logger.Trace("购买周卡后,时间变为:", zeroTime.Unix()) this.WeekCardTime[id] = zeroTime.Unix() this.GetWeekCardAwary(id) return true } // 领取周卡奖励 func (this *Player) GetWeekCardAwary(id int32) { logger.Logger.Trace("玩家请求领取周卡奖励!") data := srvdata.PBDB_GiftCardMgr.GetData(id) if this.WeekCardAward == nil { this.WeekCardAward = make(map[int32]bool) } now := time.Now().Unix() if this.WeekCardTime[id] != 0 && now > this.WeekCardTime[id] { logger.Logger.Trace("周卡已过期,不能领取!") return } ret := &playerproto.SCGetWeekCardAwary{} if !this.WeekCardAward[id] { //获取周卡奖励 items := data.GetDayRewards() addItem := []*Item{} for itemId, itemNum := range items { item := &Item{ItemId: int32(itemId), ItemNum: itemNum, ObtainTime: time.Now().Unix()} addItem = append(addItem, item) itemInfo := &playerproto.PayItem{} itemInfo.ItemId = int32(itemId) itemInfo.ItemNum = itemNum ret.Items = append(ret.Items, itemInfo) } BagMgrSingleton.AddItems(this, addItem, 0, common.GainWay_WeekCardAward, "system", "周卡每日奖励", 0, 0, false) //返回消息 this.WeekCardAward[id] = true ret.WeekCardAward = this.WeekCardAward[id] } info := &playerproto.WeekInfo{ Id: id, WeekCardTime: this.WeekCardTime[id], WeekCardAward: this.WeekCardAward[id], } ret.WeekCard = info this.SendToClient(int(playerproto.PlayerPacketID_PACKET_SCGetWeekCardAwary), ret) return } // 获取周卡权益 // typeId : 1-破产救济金领取翻倍 2-排位赛积分提升5% func (this *Player) GetWeekCardPrivilege(typeId int32) bool { logger.Logger.Trace("玩家请求获取周卡权益!") now := time.Now().Unix() for id, endTime := range this.WeekCardTime { if endTime > now { data := srvdata.PBDB_GiftCardMgr.GetData(id) for _, equity := range data.GetEquity() { if equity == typeId { return true } } } } return false } // 增加记牌器道具时限 func (this *Player) AddItemRecExpireTime(itemId int32, num, add int64, gainWay int32, oper, remark string) { if num == 0 { return } logger.Logger.Tracef("snid(%v) AddItemRecExpireTime, itemId:(%v), num:(%v)", this.SnId, itemId, num) if num != 0 /*&& !async*/ { this.dirty = true if num > 0 { itemData := srvdata.GameItemMgr.Get(this.Platform, itemId) if itemData == nil { return } if this.ItemRecExpireTime == 0 { this.ItemRecExpireTime = time.Now().Unix() + int64(itemData.Time)*3600*num } else { if this.ItemRecExpireTime >= time.Now().Unix() { this.ItemRecExpireTime += int64(itemData.Time) * 3600 * num } else { this.ItemRecExpireTime = time.Now().Unix() + int64(itemData.Time)*3600*num } } if this.scene != nil && this.scene.gameSess != nil { msg := &serverproto.WGBuyRecTimeItem{ SnId: this.SnId, ExpireTime: this.ItemRecExpireTime, Diamond: this.Diamond, } proto.SetDefaults(msg) this.SendToGame(int(serverproto.SSPacketID_PACKET_WG_BUYRECTIMEITEM), msg) } } this.SendDiffData() } } func (this *Player) GetIsPermit() bool { startTs := PlatformMgrSingleton.GetConfig(this.Platform).PermitStartTs if startTs == 0 { return false } endTs := PlatformMgrSingleton.GetConfig(this.Platform).PermitEndTs if this.Permit.Unix() >= startTs && this.Permit.Unix() < endTs { return true } return false } func (this *Player) SCItems() { cfg := PlatformMgrSingleton.GetConfig(this.Platform).ItemConfig if cfg == nil { return } var items []*serverproto.DB_GameItem for _, v := range cfg.GetItems() { items = append(items, &serverproto.DB_GameItem{ Id: v.GetId(), Name: v.GetName(), ShowLocation: v.GetShowLocation(), Classify: v.GetClassify(), Type: v.GetType(), Effect0: v.GetEffect0(), Effect: v.GetEffect(), SaleType: v.GetSaleType(), SaleGold: v.GetSaleGold(), Composition: v.GetComposition(), CompositionMax: v.GetCompositionMax(), Time: v.GetTime(), Location: v.GetLocation(), Describe: v.GetDescribe(), Num: v.GetNum(), Value: v.GetValue(), Entity: v.GetEntity(), Icon: v.GetIcon(), }) } pack := &playerproto.SCItem{ Items: items, } this.SendToClient(int(playerproto.PlayerPacketID_PACKET_SCItem), pack) logger.Logger.Tracef("SCItem: %v", pack) }