1489 lines
44 KiB
Go
1489 lines
44 KiB
Go
package base
|
||
|
||
import (
|
||
"fmt"
|
||
rawproto "google.golang.org/protobuf/proto"
|
||
"math"
|
||
"mongo.games.com/game/common"
|
||
"mongo.games.com/game/model"
|
||
"mongo.games.com/game/proto"
|
||
"mongo.games.com/game/protocol/player"
|
||
"mongo.games.com/game/protocol/server"
|
||
"mongo.games.com/game/srvdata"
|
||
"mongo.games.com/goserver/core/logger"
|
||
"mongo.games.com/goserver/core/netlib"
|
||
"mongo.games.com/goserver/core/timer"
|
||
|
||
//rawproto "github.com/golang/protobuf/proto"
|
||
"math/rand"
|
||
"strconv"
|
||
"time"
|
||
)
|
||
|
||
// 对应到客户端的一个玩家对象.
|
||
|
||
const (
|
||
PlayerState_Online int = 1 << iota //在线标记 1
|
||
PlayerState_Ready //准备标记 2
|
||
PlayerState_SceneOwner //房主标记 3
|
||
PlayerState_Choke //呛标记 被复用于金花,是否被动弃牌 4
|
||
PlayerState_Ting //听牌标记 5 金花复用,标记最后押注时,是否看牌
|
||
PlayerState_NoisyBanker //闹庄标记 6 金花复用,标记allin时,是否看牌
|
||
PlayerState_WaitOp //等待操作标记 7
|
||
PlayerState_Auto //托管状态 8
|
||
PlayerState_Check //已看牌状态 9
|
||
PlayerState_Fold //弃牌状态 10
|
||
PlayerState_Lose //输状态 11
|
||
PlayerState_Win //赢状态 12
|
||
PlayerState_WaitNext //等待下一局游戏 13
|
||
PlayerState_GameBreak //不能继续游戏 14
|
||
PlayerState_Leave //暂离状态 15
|
||
PlayerState_Audience //观众标记 16
|
||
PlayerState_AllIn //allin标记 17
|
||
PlayerState_FinalAllIn //最后一圈,最后一个人allin标记 18
|
||
PlayerState_Show //亮牌标记 19
|
||
PlayerState_EnterSceneFailed //进场失败 20
|
||
PlayerState_PKLost //发起Pk,失败 21
|
||
PlayerState_IsChangeCard //牛牛标识是否换牌 22
|
||
PlayerState_IsPayChangeCard //牛牛标识是否充值换牌 23
|
||
PlayerState_Bankruptcy //玩家破产 24
|
||
PlayerState_MatchQuit //退赛标记 25
|
||
PlayerState_AllFollow //跟到底状态 26
|
||
PlayerState_SAdjust //单控状态 27
|
||
PlayerState_Max
|
||
)
|
||
|
||
// 玩家事件
|
||
const (
|
||
PlayerEventEnter int = iota //进入事件
|
||
PlayerEventLeave //离开事件
|
||
PlayerEventDropLine //掉线
|
||
PlayerEventRehold //重连
|
||
PlayerEventReturn //返回房间 gs 添加
|
||
PlayerEventRecharge //冲值事件
|
||
PlayerEventAddCoin //其他加减币事件(例如:小游戏)
|
||
AudienceEventEnter //观众进入事件
|
||
AudienceEventLeave //观众离开事件
|
||
AudienceEventDropLine //观众掉线
|
||
AudienceEventRehold //观众重连
|
||
)
|
||
|
||
type Player struct {
|
||
model.PlayerData //po 持久化对象
|
||
ExtraData interface{} //扩展接口
|
||
gateSess *netlib.Session //所在GateServer的session
|
||
worldSess *netlib.Session //所在WorldServer的session
|
||
scene *Scene //当前所在个Scene
|
||
ai AI //ai接口
|
||
sid int64 //对应客户端的sessionId
|
||
gateSid int64 //对应网关的sessionId
|
||
Longitude int32 //经纬度
|
||
Latitude int32 //经纬度
|
||
city string //城市
|
||
flag int //状态标记
|
||
Pos int //当前位置
|
||
dirty bool //脏标记
|
||
Billed bool //是否已经结算过了
|
||
AgentCode string //代理商编号
|
||
Coin int64 //金币
|
||
serviceFee int64 //服务费|税收
|
||
TotalBet int64 //总下注额(从进房间开始,包含多局游戏的下注)
|
||
disbandGen int //第几次解散申请
|
||
hAuto timer.TimerHandle //托管handle
|
||
GameTimes int32 //游戏次数
|
||
winTimes int //胜利次数
|
||
lostTimes int //失败次数
|
||
ActiveLeave bool //主动暂离
|
||
OpCode player.OpResultCode //错误码
|
||
takeCoin int64 //携带金币
|
||
ExpectLeaveCoin int64 //期望离场时的金币[机器人用]
|
||
ExpectGameTime int32 //期望进行的局数[机器人用]
|
||
CurIsWin int64 //当局输赢 负数:输 0:平局 正数:赢
|
||
currentCoin int64 //本局结束后剩余
|
||
CurrentBet int64 //本局下注额
|
||
CurrentTax int64 //本局税收
|
||
StartCoin int64 //本局开始金币
|
||
LastSyncCoin int64 //
|
||
IsQM bool //是否是全民推广用户
|
||
LastOPTimer time.Time //玩家最后一次操作时间
|
||
Trusteeship int32 //玩家托管了几局
|
||
ValidCacheBetTotal int64 //有效下注缓存
|
||
isFightRobot bool //测试机器人,这种机器人可以用作记录水池数据,方便模拟用户输赢
|
||
DropTime time.Time //掉线时间
|
||
cparams map[string]string //平台登陆数据
|
||
Iparams map[int]int64 //整形参数
|
||
sparams map[int]string //字符参数
|
||
WhiteLevel int32 //todo 使用WBLevel
|
||
BlackLevel int32 //todo 使用WBLevel
|
||
SingleAdjust *model.PlayerSingleAdjust
|
||
IsLocal bool //是否本地player
|
||
Items map[int32]int32 //背包数据
|
||
MatchParams []int32 //比赛参数 排名、段位、假snid、假角色
|
||
MatchRobotGrades []MatchRobotGrade
|
||
TestLog []string // 调试日志
|
||
RankScore map[int32]int64 // 段位积分
|
||
}
|
||
|
||
type MatchRobotGrade struct {
|
||
CopySnid int32
|
||
Grade int32
|
||
}
|
||
|
||
func NewPlayer(sid int64, data []byte, ws, gs *netlib.Session) *Player {
|
||
p := &Player{
|
||
sid: sid,
|
||
worldSess: ws,
|
||
gateSess: gs,
|
||
flag: PlayerState_Online,
|
||
Pos: -1,
|
||
Longitude: -1,
|
||
Latitude: -1,
|
||
cparams: make(map[string]string), //平台登陆数据
|
||
Iparams: make(map[int]int64), //整形参数
|
||
sparams: make(map[int]string), //字符参数
|
||
Items: make(map[int32]int32),
|
||
RankScore: make(map[int32]int64),
|
||
}
|
||
|
||
// 需要make的,统一在这里初始化默认值,别的地方就不用再初始化了
|
||
p.PlayerData = model.PlayerData{
|
||
TotalGameData: make(map[int][]*model.PlayerGameTotal),
|
||
GDatas: make(map[string]*model.PlayerGameInfo),
|
||
ShopTotal: make(map[int32]*model.ShopTotal),
|
||
ShopLastLookTime: make(map[int32]int64),
|
||
IsFoolPlayer: make(map[string]bool),
|
||
}
|
||
|
||
if p.init(data) {
|
||
return p
|
||
}
|
||
|
||
return nil
|
||
}
|
||
|
||
func (this *Player) init(data []byte) bool {
|
||
if !this.UnmarshalData(data) {
|
||
return false
|
||
}
|
||
if this.GMLevel > 2 {
|
||
this.Longitude = rand.Int31n(114103930-113216260) + 113216260
|
||
this.Latitude = rand.Int31n(34963671-34592702) + 34592702
|
||
}
|
||
this.city = this.City
|
||
this.LastOPTimer = time.Now()
|
||
if this.GDatas == nil {
|
||
this.GDatas = make(map[string]*model.PlayerGameInfo)
|
||
}
|
||
if this.WBLevel > 0 {
|
||
this.WhiteLevel = this.WBLevel
|
||
} else if this.WBLevel < 0 {
|
||
this.BlackLevel = -this.WBLevel
|
||
}
|
||
return true
|
||
}
|
||
|
||
func (this *Player) MarkFlag(flag int) {
|
||
this.flag |= flag
|
||
switch flag {
|
||
case PlayerState_Online, PlayerState_Ready, PlayerState_Leave:
|
||
this.SyncFlagToWorld()
|
||
}
|
||
}
|
||
|
||
func (this *Player) UnmarkFlag(flag int) {
|
||
this.flag &= ^flag
|
||
switch flag {
|
||
case PlayerState_Online, PlayerState_Ready, PlayerState_Leave:
|
||
this.SyncFlagToWorld()
|
||
}
|
||
}
|
||
|
||
func (this *Player) IsMarkFlag(flag int) bool {
|
||
if (this.flag & flag) != 0 {
|
||
return true
|
||
}
|
||
return false
|
||
}
|
||
|
||
func (this *Player) IsOnLine() bool {
|
||
return this.IsMarkFlag(PlayerState_Online)
|
||
}
|
||
|
||
func (this *Player) IsReady() bool {
|
||
return this.IsMarkFlag(PlayerState_Ready)
|
||
}
|
||
|
||
func (this *Player) IsSceneOwner() bool {
|
||
return this.IsMarkFlag(PlayerState_SceneOwner)
|
||
}
|
||
|
||
func (this *Player) IsAuto() bool {
|
||
return this.IsMarkFlag(PlayerState_Auto)
|
||
}
|
||
|
||
func (this *Player) IsGameing() bool {
|
||
return !this.IsMarkFlag(PlayerState_WaitNext) && !this.IsMarkFlag(PlayerState_GameBreak) && !this.IsMarkFlag(PlayerState_Bankruptcy) && !this.IsMarkFlag(PlayerState_Audience)
|
||
}
|
||
|
||
func (this *Player) IsAllFollow() bool {
|
||
return this.IsMarkFlag(PlayerState_AllFollow)
|
||
}
|
||
|
||
func (this *Player) SyncFlag(onlyMyself ...bool) {
|
||
if this.IsLocal {
|
||
return
|
||
}
|
||
pack := &player.SCPlayerFlag{
|
||
PlayerId: proto.Int32(this.SnId),
|
||
Flag: proto.Int(this.flag),
|
||
}
|
||
proto.SetDefaults(pack)
|
||
if len(onlyMyself) != 0 && onlyMyself[0] {
|
||
this.SendToClient(int(player.PlayerPacketID_PACKET_SC_PLAYERFLAG), pack)
|
||
} else {
|
||
this.Broadcast(int(player.PlayerPacketID_PACKET_SC_PLAYERFLAG), pack, 0)
|
||
}
|
||
//logger.Logger.Trace("SyncFlag:", pack)
|
||
}
|
||
|
||
func (this *Player) SyncFlagToWorld() {
|
||
if this.IsLocal {
|
||
return
|
||
}
|
||
if this.scene == nil || this.scene.IsCoinScene() || this.scene.IsMatchScene() || this.scene.IsHundredScene() {
|
||
return
|
||
}
|
||
pack := &server.GWPlayerFlag{
|
||
SnId: proto.Int32(this.SnId),
|
||
RoomId: proto.Int(this.scene.SceneId),
|
||
Flag: proto.Int(this.flag),
|
||
}
|
||
proto.SetDefaults(pack)
|
||
this.SendToWorld(int(server.SSPacketID_PACKET_GW_PLAYERSTATE), pack)
|
||
logger.Logger.Trace("SyncFlag to world:", pack)
|
||
}
|
||
|
||
func (this *Player) SendToClient(packetid int, rawpack interface{}, forceIgnore ...bool) bool {
|
||
if this.IsLocal {
|
||
return true
|
||
}
|
||
if !this.scene.Testing && this.scene.Gaming && this.scene.rr != nil && this.Pos != -1 && len(forceIgnore) == 0 && !this.scene.IsHundredScene() {
|
||
this.scene.rr.Record(this.Pos, -1, packetid, rawpack)
|
||
}
|
||
if this.gateSess == nil {
|
||
logger.Logger.Warnf("(this *Player) SendToClient [snid:%v packetid:%v] gatesess == nil ", this.SnId, packetid)
|
||
return false
|
||
}
|
||
if rawpack == nil {
|
||
logger.Logger.Tracef("(this *Player) SendToClient [snid:%v packetid:%v] rawpack == nil ", this.SnId, packetid)
|
||
return false
|
||
}
|
||
if !this.IsOnLine() {
|
||
logger.Logger.Warnf("(this *Player) SendToClient [snid:%v packetid:%v] Player if offline.", this.SnId, packetid)
|
||
return false
|
||
}
|
||
if this.IsMarkFlag(PlayerState_Leave) {
|
||
logger.Logger.Warnf("(this *Player) SendToClient [snid:%v packetid:%v] Player if leave.", this.SnId, packetid)
|
||
return false
|
||
}
|
||
//logger.Logger.Trace("Send to player's packet:", packetid)
|
||
return common.SendToGate(this.sid, packetid, rawpack, this.gateSess)
|
||
}
|
||
|
||
func (this *Player) Broadcast(packetid int, rawpack interface{}, excludeSid int64) bool {
|
||
if this.scene != nil {
|
||
this.scene.Broadcast(packetid, rawpack.(rawproto.Message), excludeSid)
|
||
return true
|
||
}
|
||
return false
|
||
}
|
||
|
||
func (this *Player) SendToWorld(packetid int, rawpack interface{}) bool {
|
||
if this.IsLocal {
|
||
return true
|
||
}
|
||
if this.worldSess == nil {
|
||
logger.Logger.Tracef("(this *Player) SendToWorld [%v] worldsess == nil ", this.Name)
|
||
return false
|
||
}
|
||
if rawpack == nil {
|
||
logger.Logger.Trace("(this *Player) SendToWorld rawpack == nil ")
|
||
return false
|
||
}
|
||
|
||
this.scene.SendToWorld(packetid, rawpack)
|
||
return true
|
||
}
|
||
|
||
func (this *Player) OnEnter(s *Scene) {
|
||
this.scene = s
|
||
this.TestLog = this.TestLog[:0]
|
||
//标记房主
|
||
if this.SnId == s.Creator {
|
||
this.MarkFlag(PlayerState_SceneOwner)
|
||
}
|
||
}
|
||
|
||
func (this *Player) OnAudienceEnter(s *Scene) {
|
||
this.scene = s
|
||
}
|
||
|
||
func (this *Player) OnRehold(newSid int64, newSess *netlib.Session) {
|
||
this.sid = newSid
|
||
this.gateSess = newSess
|
||
this.MarkFlag(PlayerState_Online)
|
||
// 2018-4-25
|
||
// 这里先注释掉,暂离的状态在LeaveRoom和ReturnRoom的消息中设置
|
||
// 如果这里清除暂离,那么在棋牌馆中,离开房间,用的状态更新为暂离状态,断线重连以后的话,在棋牌馆大厅界面看到的用户为非暂离状态,
|
||
// 所以这里就先注释掉,让暂离的状态在离开和返回房间的消息中成对出现
|
||
this.UnmarkFlag(PlayerState_Leave)
|
||
this.SyncFlag()
|
||
}
|
||
|
||
func (this *Player) OnDropLine() {
|
||
this.UnmarkFlag(PlayerState_Online)
|
||
if !this.scene.Gaming && this.IsReady() && !this.scene.IsMatchScene() {
|
||
this.UnmarkFlag(PlayerState_Ready)
|
||
}
|
||
this.SyncFlag()
|
||
|
||
//存在假掉线的可能吗?
|
||
//this.gateSess = nil
|
||
//this.sid = 0
|
||
}
|
||
|
||
func (this *Player) OnAudienceDropLine() {
|
||
this.gateSess = nil
|
||
}
|
||
|
||
func (this *Player) OnLeave(reason int) {
|
||
unbindGateSess := true
|
||
PlayerMgrSington.DelPlayerBySnId(this.SnId)
|
||
//解绑gamesession
|
||
if unbindGateSess && this.gateSess != nil {
|
||
pack := &server.GGPlayerSessionUnBind{
|
||
Sid: proto.Int64(this.sid),
|
||
}
|
||
proto.SetDefaults(pack)
|
||
this.gateSess.Send(int(server.SSPacketID_PACKET_GG_PLAYERSESSIONUNBIND), pack)
|
||
}
|
||
}
|
||
|
||
func (this *Player) OnAudienceLeave(reason int) {
|
||
PlayerMgrSington.DelPlayerBySnId(this.SnId)
|
||
//解绑gamesession
|
||
if this.gateSess != nil {
|
||
pack := &server.GGPlayerSessionUnBind{
|
||
Sid: proto.Int64(this.sid),
|
||
}
|
||
proto.SetDefaults(pack)
|
||
this.gateSess.Send(int(server.SSPacketID_PACKET_GG_PLAYERSESSIONUNBIND), pack)
|
||
}
|
||
}
|
||
|
||
func (this *Player) MarshalData(gameid int) (d []byte, e error) {
|
||
d, e = netlib.Gob.Marshal(&this.PlayerData)
|
||
logger.Logger.Trace("(this *Player) MarshalData(gameid int)")
|
||
return
|
||
}
|
||
|
||
func (this *Player) UnmarshalData(data []byte) bool {
|
||
if len(data) == 0 {
|
||
return true
|
||
}
|
||
err := netlib.Gob.Unmarshal(data, &this.PlayerData)
|
||
if err == nil {
|
||
this.dirty = true
|
||
return true
|
||
} else {
|
||
logger.Logger.Warn("Player.SyncData err:", err)
|
||
}
|
||
return false
|
||
}
|
||
|
||
func (this *Player) OnSecTimer() {
|
||
}
|
||
|
||
func (this *Player) OnMiniTimer() {
|
||
}
|
||
|
||
func (this *Player) OnHourTimer() {
|
||
}
|
||
|
||
func (this *Player) OnDayTimer() {
|
||
//在线跨天 数据给昨天,今天置为空
|
||
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
|
||
}
|
||
*/
|
||
}
|
||
|
||
func (this *Player) OnMonthTimer() {
|
||
}
|
||
|
||
func (this *Player) OnWeekTimer() {
|
||
}
|
||
|
||
func (this *Player) GetName() string {
|
||
return this.Name
|
||
}
|
||
|
||
func (this *Player) MarkDirty() {
|
||
this.dirty = true
|
||
}
|
||
|
||
const (
|
||
SyncFlag_ToClient = 1 << iota //同步给客户端
|
||
SyncFlag_ToWorld //同步给服务端
|
||
SyncFlag_Broadcast //广播给房间内的用户
|
||
)
|
||
|
||
func (this *Player) AddCoin(num int64, gainWay int32, syncFlag int, oper, remark string) {
|
||
if num == 0 {
|
||
return
|
||
}
|
||
this.Coin += num
|
||
if this.scene != nil {
|
||
if !this.IsRob && !this.scene.Testing { //机器人log排除掉
|
||
log := model.NewCoinLogEx(&model.CoinLogParam{
|
||
Platform: this.Platform,
|
||
SnID: this.SnId,
|
||
ChangeType: common.BillTypeCoin,
|
||
ChangeNum: num,
|
||
RemainNum: this.Coin,
|
||
Add: 0,
|
||
LogType: gainWay,
|
||
GameID: int64(int32(this.scene.GetGameId())),
|
||
GameFreeID: int64(this.scene.GetGameFreeId()),
|
||
BaseCoin: int64(this.scene.GetBaseScore()),
|
||
Operator: oper,
|
||
Remark: remark,
|
||
})
|
||
if log != nil {
|
||
this.GameCoinTs = log.Time.UnixNano()
|
||
this.dirty = true
|
||
LogChannelSingleton.WriteLog(log)
|
||
}
|
||
}
|
||
//确保金币场金币数量不小于0
|
||
if this.Coin < 0 {
|
||
this.Coin = 0
|
||
}
|
||
if this.scene.IsHundredScene() {
|
||
this.scene.NewBigCoinNotice(this, int64(num), 5)
|
||
}
|
||
}
|
||
if (syncFlag & SyncFlag_ToClient) != 0 {
|
||
pack := &player.SCPlayerCoinChange{
|
||
SnId: proto.Int32(this.SnId),
|
||
AddCoin: proto.Int64(num),
|
||
RestCoin: proto.Int64(this.Coin),
|
||
}
|
||
proto.SetDefaults(pack)
|
||
if (syncFlag & SyncFlag_Broadcast) != 0 {
|
||
this.Broadcast(int(player.PlayerPacketID_PACKET_SC_PLAYERCOINCHANGE), pack, 0)
|
||
} else {
|
||
this.SendToClient(int(player.PlayerPacketID_PACKET_SC_PLAYERCOINCHANGE), pack)
|
||
}
|
||
logger.Logger.Trace("(this *Player) AddCoin SCPlayerCoinChange:", pack)
|
||
}
|
||
}
|
||
|
||
func (this *Player) AddCoinNoLog(num int64, syncFlag int) {
|
||
if num == 0 {
|
||
return
|
||
}
|
||
this.Coin += num
|
||
if this.scene != nil {
|
||
if !this.IsRob && !this.scene.Testing { //机器人log排除掉
|
||
this.dirty = true
|
||
}
|
||
}
|
||
if (syncFlag & SyncFlag_ToClient) != 0 {
|
||
pack := &player.SCPlayerCoinChange{
|
||
SnId: proto.Int32(this.SnId),
|
||
AddCoin: proto.Int64(num),
|
||
RestCoin: proto.Int64(this.Coin),
|
||
}
|
||
proto.SetDefaults(pack)
|
||
if (syncFlag & SyncFlag_Broadcast) != 0 {
|
||
this.Broadcast(int(player.PlayerPacketID_PACKET_SC_PLAYERCOINCHANGE), pack, 0)
|
||
} else {
|
||
this.SendToClient(int(player.PlayerPacketID_PACKET_SC_PLAYERCOINCHANGE), pack)
|
||
}
|
||
logger.Logger.Trace("(this *Player) AddCoinNoLog SCPlayerCoinChange:", pack)
|
||
}
|
||
}
|
||
|
||
func (this *Player) AddCoinAsync(num int64, gainWay int32, notifyC, broadcast bool, oper, remark string, writeLog bool) {
|
||
if num == 0 {
|
||
return
|
||
}
|
||
this.Coin += num
|
||
if this.scene != nil {
|
||
if !this.IsRob && !this.scene.Testing && writeLog { //机器人log排除掉
|
||
log := model.NewCoinLogEx(&model.CoinLogParam{
|
||
Platform: this.Platform,
|
||
SnID: this.SnId,
|
||
ChangeType: common.BillTypeCoin,
|
||
ChangeNum: num,
|
||
RemainNum: this.Coin,
|
||
Add: 0,
|
||
LogType: gainWay,
|
||
GameID: int64(this.scene.GetGameId()),
|
||
GameFreeID: int64(this.scene.GetGameFreeId()),
|
||
BaseCoin: int64(this.scene.GetBaseScore()),
|
||
Operator: oper,
|
||
Remark: remark,
|
||
})
|
||
if log != nil {
|
||
this.GameCoinTs = log.Time.UnixNano()
|
||
this.dirty = true
|
||
LogChannelSingleton.WriteLog(log)
|
||
}
|
||
}
|
||
//确保金币场金币数量不小于0
|
||
if this.Coin < 0 {
|
||
this.Coin = 0
|
||
}
|
||
}
|
||
if notifyC {
|
||
pack := &player.SCPlayerCoinChange{
|
||
SnId: proto.Int32(this.SnId),
|
||
AddCoin: proto.Int64(num),
|
||
RestCoin: proto.Int64(this.Coin),
|
||
}
|
||
proto.SetDefaults(pack)
|
||
if broadcast {
|
||
this.Broadcast(int(player.PlayerPacketID_PACKET_SC_PLAYERCOINCHANGE), pack, 0)
|
||
} else {
|
||
this.SendToClient(int(player.PlayerPacketID_PACKET_SC_PLAYERCOINCHANGE), pack)
|
||
}
|
||
}
|
||
}
|
||
|
||
func (this *Player) AddChessGrade(num int64) {
|
||
if num == 0 {
|
||
return
|
||
}
|
||
this.ChessGrade += num
|
||
if this.ChessGrade < 0 {
|
||
this.ChessGrade = 0
|
||
}
|
||
}
|
||
|
||
func (this *Player) AddRankScore(rankType int32, num int64) {
|
||
if num == 0 {
|
||
return
|
||
}
|
||
oldScore := this.RankScore[rankType]
|
||
|
||
var lessScore int64
|
||
switch rankType {
|
||
case 1:
|
||
lessScore = 10001
|
||
default:
|
||
lessScore = 10001
|
||
}
|
||
|
||
if oldScore < lessScore && num < 0 {
|
||
return
|
||
}
|
||
|
||
this.RankScore[rankType] += num
|
||
|
||
if this.RankScore[rankType] < 0 {
|
||
this.RankScore[rankType] = 0
|
||
}
|
||
|
||
if oldScore >= lessScore && this.RankScore[rankType] < lessScore {
|
||
this.RankScore[rankType] = lessScore
|
||
}
|
||
}
|
||
|
||
// 保存金币变动日志
|
||
// 数据用途: 个人房间内牌局账变记录,后台部分报表使用,确保数据计算无误,否则可能影响月底对账
|
||
// takeCoin: 牌局结算前玩家身上的金币
|
||
// changecoin: 本局玩家输赢的钱,注意是税后
|
||
// coin: 结算后玩家当前身上的金币余额
|
||
// totalbet: 总下注额
|
||
// taxcoin: 本局该玩家产生的税收,这里要包含俱乐部的税
|
||
// wincoin: 本局赢取的金币,含税 wincoin==changecoin+taxcoin
|
||
// jackpotWinCoin: 从奖池中赢取的金币(拉霸类游戏)
|
||
// smallGameWinCoin: 小游戏赢取的金币(拉霸类游戏)
|
||
func (this *Player) SaveSceneCoinLog(takeCoin, changecoin, coin, totalbet, taxcoin, wincoin int64, jackpotWinCoin int64, smallGameWinCoin int64) {
|
||
if this.scene != nil {
|
||
if !this.IsRob && !this.scene.Testing && !this.scene.IsMatchScene() { //机器人log排除掉
|
||
var eventType int64 //输赢事件值 默认值为0
|
||
if coin-takeCoin > 0 {
|
||
eventType = 1
|
||
} else if coin-takeCoin < 0 {
|
||
eventType = -1
|
||
}
|
||
log := model.NewSceneCoinLogEx(this.SnId, changecoin, takeCoin, coin, eventType,
|
||
int64(this.scene.DbGameFree.GetBaseScore()), totalbet, int32(this.scene.GameId), this.PlayerData.Ip,
|
||
this.scene.paramsEx[0], this.Pos, this.Platform, this.Channel, this.BeUnderAgentCode, int32(this.scene.SceneId),
|
||
this.scene.DbGameFree.GetGameMode(), this.scene.GetGameFreeId(), taxcoin, wincoin,
|
||
jackpotWinCoin, smallGameWinCoin, this.PackageID)
|
||
if log != nil {
|
||
LogChannelSingleton.WriteLog(log)
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
// 需要关照
|
||
func (this *Player) IsNeedCare() bool {
|
||
return false
|
||
}
|
||
|
||
// 需要削弱
|
||
func (this *Player) IsNeedWeaken() bool {
|
||
return false
|
||
}
|
||
|
||
func (this *Player) GetCoinOverPercent() int32 {
|
||
return 0
|
||
}
|
||
|
||
func (this *Player) SyncCoin() {
|
||
pack := &player.SCPlayerCoinChange{
|
||
SnId: proto.Int32(this.SnId),
|
||
AddCoin: proto.Int64(0),
|
||
RestCoin: proto.Int64(this.Coin),
|
||
}
|
||
proto.SetDefaults(pack)
|
||
this.SendToClient(int(player.PlayerPacketID_PACKET_SC_PLAYERCOINCHANGE), pack)
|
||
logger.Logger.Trace("(this *Player) SyncCoin SCPlayerCoinChange:", pack)
|
||
}
|
||
|
||
func (this *Player) ReportGameEvent(tax, taxex, changeCoin, validbet, validFlow, in, out int64) {
|
||
// 记录玩家 首次参与该场次的游戏时间 游戏次数
|
||
var gameFirstTime, gameFreeFirstTime time.Time
|
||
var gameTimes, gameFreeTimes int64
|
||
data, ok := this.GDatas[this.scene.KeyGamefreeId]
|
||
if ok {
|
||
gameFirstTime = data.FirstTime
|
||
gameTimes = data.Statics.GameTimes
|
||
}
|
||
|
||
// 记录玩家 首次参与该游戏时间 游戏次数(不区分场次)
|
||
dataGame, ok := this.GDatas[this.scene.KeyGameId]
|
||
if ok {
|
||
gameFreeFirstTime = dataGame.FirstTime
|
||
gameFreeTimes = dataGame.Statics.GameTimes
|
||
}
|
||
|
||
gamingTime := int32(time.Now().Sub(this.scene.GameNowTime).Seconds())
|
||
LogChannelSingleton.WriteMQData(model.GenerateGameEvent(model.CreatePlayerGameRecEvent(this.SnId, tax, taxex, changeCoin, validbet, validFlow, in, out,
|
||
int32(this.scene.GameId), this.scene.DbGameFree.GetId(), int32(this.scene.GameMode),
|
||
this.scene.GetRecordId(), this.Channel, this.BeUnderAgentCode, this.Platform, this.City, this.DeviceOS,
|
||
this.CreateTime, gamingTime, gameFirstTime, gameFreeFirstTime, gameTimes, gameFreeTimes, this.LastLoginTime,
|
||
this.TelephonePromoter, this.DeviceId)))
|
||
}
|
||
|
||
// 破产事件
|
||
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)
|
||
// }
|
||
// }
|
||
//}
|
||
}
|
||
|
||
// 汇总玩家该次游戏总产生的税收
|
||
// 数据用途: 平台和推广间分账用,确保数据计算无误,
|
||
// 注意:该税收不包含俱乐部的抽水
|
||
// tax:游戏税收
|
||
func (this *Player) AddServiceFee(tax int64) {
|
||
if this.scene == nil || this.scene.Testing || this.scene.IsMatchScene() { //测试场不统计
|
||
return
|
||
}
|
||
if tax > 0 && !this.IsRob {
|
||
this.serviceFee += tax
|
||
}
|
||
}
|
||
|
||
func (this *Player) GetStaticsData(gameDiff string) (winCoin int64, lostCoin int64) {
|
||
if this.PlayerData.GDatas != nil {
|
||
if data, ok := this.PlayerData.GDatas[gameDiff]; ok {
|
||
winCoin, lostCoin = data.Statics.TotalOut, data.Statics.TotalIn
|
||
return
|
||
}
|
||
}
|
||
return
|
||
}
|
||
func (this *Player) SaveReportForm(showId, sceneMode int, keyGameId string, profitCoin, flow int64, validBet int64) {
|
||
//个人报表统计
|
||
if this.TotalGameData == nil {
|
||
this.TotalGameData = make(map[int][]*model.PlayerGameTotal)
|
||
}
|
||
if this.TotalGameData[showId] == nil {
|
||
this.TotalGameData[showId] = []*model.PlayerGameTotal{new(model.PlayerGameTotal)}
|
||
}
|
||
td := this.TotalGameData[showId][len(this.TotalGameData[showId])-1]
|
||
td.ProfitCoin += profitCoin
|
||
td.BetCoin += validBet
|
||
td.FlowCoin += flow
|
||
///////////////最多盈利
|
||
if pgs, exist := this.GDatas[keyGameId]; exist {
|
||
if pgs.Statics.MaxSysOut < profitCoin {
|
||
pgs.Statics.MaxSysOut = profitCoin
|
||
}
|
||
} else {
|
||
gs := model.NewPlayerGameStatics()
|
||
gs.MaxSysOut = profitCoin
|
||
this.GDatas[keyGameId] = &model.PlayerGameInfo{FirstTime: time.Now(), Statics: *gs}
|
||
}
|
||
}
|
||
|
||
// Statics 弃用,使用 Scene.Statistics 方法
|
||
// 个人投入产出汇总,以游戏id为key存储
|
||
// 数据用途:计算玩家赔率用,数据确保计算无误,否则可能影响玩家手牌的调控
|
||
// key: 游戏ID对应的字符串,牛牛目前用的是同一个ID,这块有待优化
|
||
// gain:输赢额,注意如果是[正值]这里一定要用税前数据,否则玩家会有数值调控优势
|
||
// 如果需要汇总gameid today的数据,可以使用game scene的GetTotalTodayDaliyGameData
|
||
// Deprecated: Use Scene.Statistics instead.
|
||
func (this *Player) Statics(keyGameId string, keyGameFreeId string, gain int64, isAddNum bool) {
|
||
//if this.scene == nil || this.scene.Testing { //测试场|自建房和机器人不统计
|
||
// return
|
||
//}
|
||
//
|
||
//if this.IsRob && !this.scene.IsRobFightGame() {
|
||
// return
|
||
//}
|
||
//
|
||
//if this.TodayGameData == nil {
|
||
// this.TodayGameData = &model.PlayerGameCtrlData{}
|
||
//}
|
||
//if this.TodayGameData.CtrlData == nil {
|
||
// this.TodayGameData.CtrlData = make(map[string]*model.PlayerGameStatics)
|
||
//}
|
||
//
|
||
//var totalIn int64
|
||
//var totalOut int64
|
||
//if gain > 0 {
|
||
// totalOut = gain
|
||
//} else {
|
||
// totalIn = -gain
|
||
//}
|
||
//
|
||
//statics := make([]*model.PlayerGameStatics, 0, 4)
|
||
////当天数据统计
|
||
////按场次分
|
||
//if data, ok := this.TodayGameData.CtrlData[keyGameFreeId]; ok {
|
||
// statics = append(statics, data)
|
||
//} else {
|
||
// gs := &model.PlayerGameStatics{}
|
||
// this.TodayGameData.CtrlData[keyGameFreeId] = gs
|
||
// statics = append(statics, gs)
|
||
//}
|
||
////按游戏分
|
||
//if data, ok := this.TodayGameData.CtrlData[keyGameId]; ok {
|
||
// statics = append(statics, data)
|
||
//} else {
|
||
// data = &model.PlayerGameStatics{}
|
||
// this.TodayGameData.CtrlData[keyGameId] = data
|
||
// statics = append(statics, data)
|
||
//}
|
||
//
|
||
////按游戏场次进行的统计
|
||
//if data, ok := this.GDatas[keyGameFreeId]; ok {
|
||
// statics = append(statics, &data.Statics)
|
||
//} else {
|
||
// data = &model.PlayerGameInfo{FirstTime: time.Now(), Statics: model.PlayerGameStatics{}}
|
||
// this.GDatas[keyGameFreeId] = data
|
||
// statics = append(statics, &data.Statics)
|
||
//}
|
||
//if data, ok := this.GDatas[keyGameId]; ok {
|
||
// statics = append(statics, &data.Statics)
|
||
//} else {
|
||
// data = &model.PlayerGameInfo{FirstTime: time.Now(), Statics: model.PlayerGameStatics{}}
|
||
// this.GDatas[keyGameId] = data
|
||
// statics = append(statics, &data.Statics)
|
||
//}
|
||
//
|
||
////if !this.scene.IsPrivateScene() {
|
||
//// //增加黑白名单、GM过滤,因为黑白名单过后,会导致玩家体验急剧变化
|
||
//// needStatic := this.WhiteLevel == 0 && this.WhiteFlag == 0 && this.BlackLevel == 0 && this.GMLevel == 0
|
||
//// //增加黑白名单过滤,因为黑白名单后,会导致数据出现补偿
|
||
//// if needStatic {
|
||
//for _, data := range statics {
|
||
// if data != nil {
|
||
// data.TotalIn += totalIn
|
||
// data.TotalOut += totalOut
|
||
// if isAddNum {
|
||
// data.GameTimes++
|
||
// if gain > 0 {
|
||
// data.WinGameTimes++
|
||
// data.WinGameTimesNum++
|
||
// data.LoseGameTimesNum = 0
|
||
// } else if gain < 0 {
|
||
// data.LoseGameTimes++
|
||
// data.LoseGameTimesNum++
|
||
// data.WinGameTimesNum = 0
|
||
// } else {
|
||
// data.DrawGameTimes++
|
||
// data.WinGameTimesNum = 0
|
||
// data.LoseGameTimesNum = 0
|
||
// }
|
||
// }
|
||
// }
|
||
//}
|
||
//
|
||
//// 黑白名单,新手,不统计到个人赔率
|
||
//
|
||
////玩家身上元数据
|
||
//this.GameTimes++
|
||
//if gain > 0 {
|
||
// this.winTimes++
|
||
// this.WinTimes++
|
||
// this.WinCoin += totalOut
|
||
//} else if gain < 0 {
|
||
// this.lostTimes++
|
||
// this.FailTimes++
|
||
// this.FailCoin += totalIn
|
||
//} else {
|
||
// this.DrawTimes++
|
||
//}
|
||
//// }
|
||
////}
|
||
}
|
||
|
||
// 拉霸游戏 一局一条
|
||
func (this *Player) StaticsLaba(keyGameId string, keyGameFreeId string, totalIn, totalOut int64) {
|
||
if this.scene == nil || this.scene.Testing { //测试场|自建房和机器人不统计
|
||
return
|
||
}
|
||
if totalIn < 0 || totalOut < 0 {
|
||
return
|
||
}
|
||
|
||
if this.IsRob && !this.scene.IsRobFightGame() {
|
||
return
|
||
}
|
||
|
||
if this.TodayGameData == nil {
|
||
this.TodayGameData = &model.PlayerGameCtrlData{}
|
||
}
|
||
if this.TodayGameData.CtrlData == nil {
|
||
this.TodayGameData.CtrlData = make(map[string]*model.PlayerGameStatics)
|
||
}
|
||
|
||
statics := make([]*model.PlayerGameStatics, 0, 4)
|
||
//当天数据统计
|
||
//按场次分
|
||
if data, ok := this.TodayGameData.CtrlData[keyGameFreeId]; ok {
|
||
statics = append(statics, data)
|
||
} else {
|
||
gs := model.NewPlayerGameStatics()
|
||
this.TodayGameData.CtrlData[keyGameFreeId] = gs
|
||
statics = append(statics, gs)
|
||
}
|
||
//按游戏分
|
||
if data, ok := this.TodayGameData.CtrlData[keyGameId]; ok {
|
||
statics = append(statics, data)
|
||
} else {
|
||
data = model.NewPlayerGameStatics()
|
||
this.TodayGameData.CtrlData[keyGameId] = data
|
||
statics = append(statics, data)
|
||
}
|
||
|
||
//按游戏场次进行的统计
|
||
if data, ok := this.GDatas[keyGameFreeId]; ok {
|
||
statics = append(statics, &data.Statics)
|
||
} else {
|
||
data = &model.PlayerGameInfo{FirstTime: time.Now(), Statics: *model.NewPlayerGameStatics()}
|
||
this.GDatas[keyGameFreeId] = data
|
||
statics = append(statics, &data.Statics)
|
||
}
|
||
if data, ok := this.GDatas[keyGameId]; ok {
|
||
statics = append(statics, &data.Statics)
|
||
} else {
|
||
data = &model.PlayerGameInfo{FirstTime: time.Now(), Statics: *model.NewPlayerGameStatics()}
|
||
this.GDatas[keyGameId] = data
|
||
statics = append(statics, &data.Statics)
|
||
}
|
||
gain := totalOut - totalIn
|
||
for _, data := range statics {
|
||
if data != nil {
|
||
data.TotalIn += totalIn
|
||
data.TotalOut += totalOut
|
||
data.GameTimes++
|
||
if gain > 0 {
|
||
data.WinGameTimes++
|
||
} else if gain < 0 {
|
||
data.LoseGameTimes++
|
||
} else {
|
||
data.DrawGameTimes++
|
||
}
|
||
}
|
||
}
|
||
//玩家身上元数据
|
||
this.GameTimes++
|
||
if gain > 0 {
|
||
this.winTimes++
|
||
this.WinTimes++
|
||
} else if gain < 0 {
|
||
this.lostTimes++
|
||
this.FailTimes++
|
||
} else {
|
||
this.DrawTimes++
|
||
}
|
||
}
|
||
|
||
//func (this *Player) CheckType(gamefreeId, gameId int32) *server.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]
|
||
// 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) LoseRate(gamefreeId, gameId int32) (rate float64) {
|
||
rate = -1
|
||
if this.GDatas != nil {
|
||
if d, exist := this.GDatas[strconv.Itoa(int(gameId))]; exist {
|
||
rate = float64(float64(d.Statics.TotalOut+1) / float64(d.Statics.TotalIn+1))
|
||
return rate
|
||
}
|
||
}
|
||
|
||
return rate
|
||
}
|
||
|
||
// 计算玩家赔率 产出/投入
|
||
func (this *Player) LoseRateKeyGameid(gameKeyId string) (rate float64) {
|
||
rate = -1
|
||
var pgs *model.PlayerGameStatics
|
||
if this.GDatas != nil {
|
||
if d, exist := this.GDatas[gameKeyId]; exist {
|
||
pgs = &d.Statics
|
||
}
|
||
}
|
||
|
||
rate = float64(float64(pgs.TotalOut+1) / float64(pgs.TotalIn+1))
|
||
return
|
||
}
|
||
|
||
// 是否是新手判定
|
||
//
|
||
// func (this *Player) IsFoolPlayerBy(gameId string) {
|
||
// if this.IsRob || this.GDatas == nil {
|
||
// return
|
||
// }
|
||
// if this.GDatas[gameId] == nil {
|
||
// return
|
||
// }
|
||
// if this.IsFoolPlayer == nil {
|
||
// this.IsFoolPlayer = make(map[string]bool)
|
||
// }
|
||
// if model.GameParamData.BirdPlayerFlag == false {
|
||
// this.IsFoolPlayer[gameId] = false
|
||
// return
|
||
// }
|
||
// playerDate := this.GDatas[gameId]
|
||
// //金花游戏局数小于10局并且总产出<100000并且总产出/(总投入+10000)<=2的玩家定义为新手玩家
|
||
// if playerDate.Statics.GameTimes < 10 && playerDate.Statics.TotalOut < 100000 &&
|
||
// playerDate.Statics.TotalOut/(playerDate.Statics.TotalIn+10000) <= 2 {
|
||
// this.IsFoolPlayer[gameId] = true
|
||
// } else {
|
||
// this.IsFoolPlayer[gameId] = false
|
||
// }
|
||
// }
|
||
|
||
//func (this *Player) PlayerGameNewCheck(gameDiff string) bool {
|
||
// if this.IsRob {
|
||
// return false
|
||
// }
|
||
// if this.GDatas == nil {
|
||
// return true
|
||
// }
|
||
// gameId := gameDiff
|
||
// if this.GDatas[gameId] == nil {
|
||
// return true
|
||
// }
|
||
// playerDate := this.GDatas[gameId]
|
||
// if playerDate.Statics.GameTimes > int64(model.GameParamData.GamePlayerCheckNum) {
|
||
// return true
|
||
// } else {
|
||
// return false
|
||
// }
|
||
//}
|
||
|
||
func (this *Player) SendTrusteeshipTips() {
|
||
pack := &player.SCTrusteeshipTips{
|
||
Trusteeship: proto.Int32(this.Trusteeship),
|
||
TotalNum: proto.Int32(model.GameParamData.PlayerWatchNum),
|
||
}
|
||
proto.SetDefaults(pack)
|
||
logger.Logger.Trace("SCTrusteeshipTips: ", pack)
|
||
this.SendToClient(int(player.PlayerPacketID_PACKET_SC_TRUSTEESHIPTIPS), pack)
|
||
}
|
||
|
||
func (this *Player) MarshalIParam() []*server.PlayerIParam {
|
||
var params []*server.PlayerIParam
|
||
for i, v := range this.Iparams {
|
||
params = append(params, &server.PlayerIParam{
|
||
ParamId: proto.Int(i),
|
||
IntVal: proto.Int64(v),
|
||
})
|
||
}
|
||
return params
|
||
}
|
||
|
||
func (this *Player) UnmarshalIParam(params []*server.PlayerIParam) {
|
||
for _, p := range params {
|
||
this.Iparams[int(p.GetParamId())] = p.GetIntVal()
|
||
}
|
||
}
|
||
|
||
func (this *Player) MarshalSParam() []*server.PlayerSParam {
|
||
var params []*server.PlayerSParam
|
||
for i, v := range this.sparams {
|
||
params = append(params, &server.PlayerSParam{
|
||
ParamId: proto.Int(i),
|
||
StrVal: proto.String(v),
|
||
})
|
||
}
|
||
return params
|
||
}
|
||
|
||
func (this *Player) UnmarshalSParam(params []*server.PlayerSParam) {
|
||
for _, p := range params {
|
||
this.sparams[int(p.GetParamId())] = p.GetStrVal()
|
||
}
|
||
}
|
||
|
||
func (this *Player) MarshalCParam() []*server.PlayerCParam {
|
||
var params []*server.PlayerCParam
|
||
for k, v := range this.cparams {
|
||
params = append(params, &server.PlayerCParam{
|
||
StrKey: proto.String(k),
|
||
StrVal: proto.String(v),
|
||
})
|
||
}
|
||
return params
|
||
}
|
||
|
||
func (this *Player) UnmarshalCParam(params []*server.PlayerCParam) {
|
||
for _, p := range params {
|
||
this.cparams[p.GetStrKey()] = p.GetStrVal()
|
||
}
|
||
logger.Logger.Trace("(this *Player) UnmarshalCParam ", this.cparams)
|
||
}
|
||
|
||
func (this *Player) GetIParam(k int) int64 {
|
||
if v, exist := this.Iparams[k]; exist {
|
||
return v
|
||
}
|
||
return 0
|
||
}
|
||
|
||
func (this *Player) SetIParam(k int, v int64) {
|
||
this.Iparams[k] = v
|
||
}
|
||
|
||
func (this *Player) GetSParam(k int) string {
|
||
if v, exist := this.sparams[k]; exist {
|
||
return v
|
||
}
|
||
return ""
|
||
}
|
||
|
||
func (this *Player) SetSParam(k int, v string) {
|
||
this.sparams[k] = v
|
||
}
|
||
|
||
func (this *Player) GetCoin() int64 {
|
||
return this.Coin
|
||
}
|
||
func (this *Player) SetCoin(coin int64) {
|
||
this.Coin = coin
|
||
}
|
||
|
||
func (this *Player) GetRankScore(rankType int32) int64 {
|
||
return this.RankScore[rankType]
|
||
}
|
||
|
||
func (this *Player) SetRankScore(rankType int32, score int64) {
|
||
this.RankScore[rankType] = score
|
||
}
|
||
|
||
// func (this *Player) GetStartCoin() int64 {
|
||
// return this.StartCoin
|
||
// }
|
||
//
|
||
// func (this *Player) SetStartCoin(startCoin int64) {
|
||
// this.StartCoin = startCoin
|
||
// }
|
||
func (this *Player) GetExtraData() interface{} {
|
||
return this.ExtraData
|
||
}
|
||
func (this *Player) SetExtraData(data interface{}) {
|
||
this.ExtraData = data
|
||
}
|
||
func (this *Player) GetLastOPTimer() time.Time {
|
||
return this.LastOPTimer
|
||
}
|
||
func (this *Player) SetLastOPTimer(lastOPTimer time.Time) {
|
||
this.LastOPTimer = lastOPTimer
|
||
}
|
||
func (this *Player) GetPos() int {
|
||
return this.Pos
|
||
}
|
||
func (this *Player) SetPos(pos int) {
|
||
this.Pos = pos
|
||
}
|
||
func (this *Player) GetGameTimes() int32 {
|
||
return this.GameTimes
|
||
}
|
||
func (this *Player) SetGameTimes(gameTimes int32) {
|
||
this.GameTimes = gameTimes
|
||
}
|
||
func (this *Player) GetWinTimes() int {
|
||
return this.winTimes
|
||
}
|
||
func (this *Player) SetWinTimes(winTimes int) {
|
||
this.winTimes = winTimes
|
||
}
|
||
func (this *Player) GetLostTimes() int {
|
||
return this.lostTimes
|
||
}
|
||
func (this *Player) SetLostTimes(lostTimes int) {
|
||
this.lostTimes = lostTimes
|
||
}
|
||
func (this *Player) GetTotalBet() int64 {
|
||
return this.TotalBet
|
||
}
|
||
func (this *Player) SetTotalBet(totalBet int64) {
|
||
this.TotalBet = totalBet
|
||
}
|
||
func (this *Player) GetCurrentBet() int64 {
|
||
return this.CurrentBet
|
||
}
|
||
func (this *Player) SetCurrentBet(currentBet int64) {
|
||
this.CurrentBet = currentBet
|
||
}
|
||
func (this *Player) GetCurrentTax() int64 {
|
||
return this.CurrentTax
|
||
}
|
||
func (this *Player) SetCurrentTax(currentTax int64) {
|
||
this.CurrentTax = currentTax
|
||
}
|
||
func (this *Player) GetSid() int64 {
|
||
return this.sid
|
||
}
|
||
func (this *Player) SetSid(sid int64) {
|
||
this.sid = sid
|
||
}
|
||
func (this *Player) GetScene() *Scene {
|
||
return this.scene
|
||
}
|
||
func (this *Player) GetGateSess() *netlib.Session {
|
||
return this.gateSess
|
||
}
|
||
func (this *Player) SetGateSess(gateSess *netlib.Session) {
|
||
this.gateSess = gateSess
|
||
}
|
||
func (this *Player) GetWorldSess() *netlib.Session {
|
||
return this.worldSess
|
||
}
|
||
func (this *Player) SetWorldSess(worldSess *netlib.Session) {
|
||
this.worldSess = worldSess
|
||
}
|
||
func (this *Player) GetCurrentCoin() int64 {
|
||
return this.currentCoin
|
||
}
|
||
func (this *Player) SetCurrentCoin(currentCoin int64) {
|
||
this.currentCoin = currentCoin
|
||
}
|
||
func (this *Player) GetTakeCoin() int64 {
|
||
return this.takeCoin
|
||
}
|
||
func (this *Player) SetTakeCoin(takeCoin int64) {
|
||
this.takeCoin = takeCoin
|
||
}
|
||
func (this *Player) GetFlag() int {
|
||
return this.flag
|
||
}
|
||
func (this *Player) SetFlag(flag int) {
|
||
this.flag = flag
|
||
}
|
||
func (this *Player) GetCity() string {
|
||
return this.city
|
||
}
|
||
func (this *Player) SetCity(city string) {
|
||
this.city = city
|
||
}
|
||
|
||
// 附加ai
|
||
func (this *Player) AttachAI(ai AI) {
|
||
this.ai = ai
|
||
ai.SetOwner(this)
|
||
ai.OnStart()
|
||
}
|
||
|
||
// 解除ai
|
||
func (this *Player) UnattachAI() {
|
||
ai := this.ai
|
||
this.ai = nil
|
||
ai.SetOwner(nil)
|
||
ai.OnStop()
|
||
}
|
||
|
||
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) 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
|
||
}
|
||
}
|
||
|
||
// BlackWhiteOdds 黑白名单调控概率
|
||
func (this *Player) BlackWhiteOdds(gameId int) (int32, bool) {
|
||
if this.WBLevel == 0 {
|
||
return 0, false
|
||
}
|
||
data := srvdata.PBDB_BlackWhiteMgr.GetData(int32(gameId))
|
||
if data == nil {
|
||
return 0, false
|
||
}
|
||
var odds int32
|
||
var b bool
|
||
if this.WBLevel > 0 && len(data.GetWhiteOdds()) > 0 {
|
||
if int(this.WBLevel) > len(data.GetWhiteOdds()) {
|
||
odds = data.GetWhiteOdds()[len(data.GetWhiteOdds())-1]
|
||
b = true
|
||
} else if this.WBLevel-1 >= 0 {
|
||
odds = data.GetWhiteOdds()[this.WBLevel-1]
|
||
b = true
|
||
}
|
||
}
|
||
if this.WBLevel < 0 && len(data.GetBlackOdds()) > 0 {
|
||
if int(-this.WBLevel) > len(data.GetBlackOdds()) {
|
||
odds = data.GetBlackOdds()[len(data.GetBlackOdds())-1]
|
||
b = true
|
||
} else if -this.WBLevel-1 >= 0 {
|
||
odds = data.GetBlackOdds()[-this.WBLevel-1]
|
||
b = true
|
||
}
|
||
}
|
||
//logger.Logger.Tracef("TienLenSceneData snid(%v) 黑白名单调控 是否启用:%v WBLevel:%v config:%v 概率:%v", this.SnId, b, this.WBLevel, data, odds)
|
||
this.TestLog = append(this.TestLog, fmt.Sprintf("黑白名单调控 是否启用:%v WBTotalOut:%v WBTotalIn:%v WBCoinLimit:%v WBLevel:%v config:%v 概率:%v", b, this.WBCoinTotalOut, this.WBCoinTotalIn, this.WBCoinLimit, this.WBLevel, data, odds))
|
||
return odds, b
|
||
}
|
||
|
||
// NoviceOdds 新手补偿概率
|
||
func (this *Player) NoviceOdds(gameId int) (int32, bool) {
|
||
data := srvdata.PBDB_NewPlayerMgr.GetData(int32(gameId))
|
||
if data == nil {
|
||
return 0, false
|
||
}
|
||
|
||
if model.GameParamData.CloseNovice || common.InSliceInt(model.GameParamData.CloseNoviceGame, gameId) {
|
||
return 0, false
|
||
}
|
||
|
||
keyNoviceGameId := common.GetKeyNoviceGameId(gameId)
|
||
|
||
var b1, b2 bool
|
||
var times, targetTimes int64
|
||
var winCoin, targetWinCoin int64
|
||
switch data.GetCondition1() {
|
||
case 1: // 游戏次数
|
||
m := this.GDatas[keyNoviceGameId]
|
||
if m == nil {
|
||
b1 = true
|
||
} else {
|
||
b1 = m.Statics.GameTimes < data.GetConditionValue1()
|
||
times = m.Statics.GameTimes
|
||
}
|
||
targetTimes = data.GetConditionValue1()
|
||
case 2: // gameId输赢金额
|
||
m := this.GDatas[keyNoviceGameId]
|
||
if m == nil {
|
||
b1 = true
|
||
} else {
|
||
b1 = m.Statics.TotalOut-m.Statics.Tax-m.Statics.TotalIn < data.GetConditionValue1()
|
||
winCoin = m.Statics.TotalOut - m.Statics.TotalIn
|
||
}
|
||
targetWinCoin = data.GetConditionValue1()
|
||
}
|
||
|
||
switch data.GetCondition2() {
|
||
case 1: // 游戏次数
|
||
m := this.GDatas[keyNoviceGameId]
|
||
if m == nil {
|
||
b2 = true
|
||
} else {
|
||
b2 = m.Statics.GameTimes < data.GetConditionValue2()
|
||
times = m.Statics.GameTimes
|
||
}
|
||
targetTimes = data.GetConditionValue2()
|
||
case 2: // gameId输赢金额
|
||
m := this.GDatas[keyNoviceGameId]
|
||
if m == nil {
|
||
b2 = true
|
||
} else {
|
||
b2 = m.Statics.TotalOut-m.Statics.Tax-m.Statics.TotalIn < data.GetConditionValue2()
|
||
winCoin = m.Statics.TotalOut - m.Statics.TotalIn
|
||
}
|
||
targetWinCoin = data.GetConditionValue2()
|
||
}
|
||
|
||
switch data.GetBond() {
|
||
case 1: // or
|
||
b1 = b1 || b2
|
||
case 2: // and
|
||
b1 = b1 && b2
|
||
}
|
||
|
||
var odds int
|
||
if b1 {
|
||
switch data.GetAddType() {
|
||
case 1: // 游戏次数
|
||
odds = common.SliceMaxValue([]int{int(data.GetAddMin()),
|
||
int(data.GetAddMax() - int64(float64(times)/float64(targetTimes)*float64(data.GetAddMax()-data.GetAddMin())))})
|
||
case 2: // gameId输赢金额
|
||
odds = common.SliceMaxValue([]int{int(data.GetAddMin()),
|
||
int(data.GetAddMax() - int64(float64(winCoin)/float64(targetWinCoin)*float64(data.GetAddMax()-data.GetAddMin())))})
|
||
}
|
||
odds = common.SliceMinValue([]int{int(data.GetAddMax()), odds})
|
||
}
|
||
//logger.Logger.Tracef("TienLenSceneData snid(%v) 新手调控 是否启用:%v times:%v winCoin:%v config:%v 概率:%v", this.SnId, b1, times, winCoin, data, odds)
|
||
this.TestLog = append(this.TestLog, fmt.Sprintf("新手调控 是否启用:%v times:%v winCoin:%v config:%v 概率:%v", b1, times, winCoin, data, odds))
|
||
return int32(odds), b1
|
||
}
|
||
|
||
/*// 设置玩家捕鱼等级
|
||
func (this *Player) SetFishLevel(level int64) {
|
||
data := srvdata.PBDB_PlayerExpMgr.GetData(int32(level))
|
||
if data == nil {
|
||
logger.Logger.Errorf("设置玩家等级错误!snid = %v, lvel = %v", this.SnId, level)
|
||
return
|
||
}
|
||
this.FishLevel = level
|
||
this.FishExp = int64(data.Exp)
|
||
}*/
|
||
|
||
// 增加捕鱼经验
|
||
func (this *Player) AddPlayerExp(exp int64) bool {
|
||
this.FishExp += exp
|
||
if this.FishExp >= int64(math.MaxInt64) {
|
||
this.FishExp = int64(math.MaxInt64)
|
||
}
|
||
maxExp := srvdata.PBDB_PlayerExpMgr.Datas.Arr[len(srvdata.PBDB_PlayerExpMgr.Datas.Arr)-1].Exp
|
||
if this.FishExp > int64(maxExp) {
|
||
this.FishExp = int64(maxExp)
|
||
}
|
||
|
||
oldLevel := this.FishLevel
|
||
//获取等级
|
||
for _, playerExp := range srvdata.PBDB_PlayerExpMgr.Datas.Arr {
|
||
if this.FishExp >= int64(playerExp.Exp) {
|
||
this.FishLevel = int64(playerExp.Id)
|
||
} else {
|
||
break
|
||
}
|
||
}
|
||
//升级
|
||
if this.FishLevel != oldLevel {
|
||
////通知客户端
|
||
pack := &player.SCPlayerUpLevel{
|
||
Level: this.FishLevel,
|
||
Exp: this.FishExp,
|
||
}
|
||
//通知客户端玩家提升等级
|
||
this.SendToClient(int(player.PlayerPacketID_PACKET_SC_PlayerUpLevel), pack)
|
||
return true
|
||
}
|
||
return false
|
||
}
|
||
|
||
// 解锁炮倍
|
||
func (this *Player) UnPlayerPowerEx(power int64) {
|
||
logger.Logger.Tracef("解锁炮倍 当前最大解锁炮倍:%v,要解锁的炮倍:%v", this.UnMaxPower, power)
|
||
if this.UnPlayerPower(power) {
|
||
pack := &player.SCPlayerUnPower{
|
||
UnMaxpower: power,
|
||
}
|
||
this.UnMaxPower = power
|
||
this.SendToClient(int(player.PlayerPacketID_PACKET_SC_PlayerUnPower), pack)
|
||
logger.Logger.Tracef("通知客户端解锁最大炮倍,snid = %v,power = %v", this.SnId, power)
|
||
}
|
||
}
|
||
|
||
// 解锁炮台
|
||
func (this *Player) UnPlayerPowerListEx(powerId int32) {
|
||
data := srvdata.PBDB_ArtillerySkinMgr.GetData(powerId)
|
||
if data == nil {
|
||
return
|
||
}
|
||
if this.UnPlayerPowerList(powerId) {
|
||
//通知客户端解锁炮台
|
||
pack := &player.SCPlayerUnPowerList{
|
||
UnPowerList: powerId,
|
||
}
|
||
this.SendToClient(int(player.PlayerPacketID_PACKET_SC_PlayerUnPowerList), pack)
|
||
logger.Logger.Trace("通知客户端解锁炮台 snid = %v,解锁的炮台:%v,当前已有的炮台 = %v", this.SnId, powerId, this.PowerList)
|
||
}
|
||
return
|
||
}
|