game_sync/worldsrv/player.go

4769 lines
142 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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 //上一个房间idgamefreeid:房间号
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,金币数量 = %vaddVipEx = %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)
}