game_sync/gamesrv/caishen/scenepolicy_caishen.go

1094 lines
41 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 caishen
import (
"fmt"
"math"
"math/rand"
"os"
"strconv"
"sync"
"time"
"mongo.games.com/goserver/core"
"mongo.games.com/goserver/core/basic"
"mongo.games.com/goserver/core/logger"
"mongo.games.com/goserver/core/task"
"mongo.games.com/goserver/core/timer"
"mongo.games.com/game/common"
rule "mongo.games.com/game/gamerule/caishen"
"mongo.games.com/game/gamesrv/base"
"mongo.games.com/game/model"
"mongo.games.com/game/proto"
"mongo.games.com/game/protocol/caishen"
"mongo.games.com/game/protocol/server"
)
////////////////////////////////////////////////////////////////////////////////
//财神
////////////////////////////////////////////////////////////////////////////////
// 房间内主要逻辑
var ScenePolicyCaiShenSington = &ScenePolicyCaiShen{}
type ScenePolicyCaiShen struct {
base.BaseScenePolicy
states [CaiShenSceneStateMax]base.SceneState
}
// 创建场景扩展数据
func (this *ScenePolicyCaiShen) CreateSceneExData(s *base.Scene) interface{} {
sceneEx := NewCaiShenSceneData(s)
if sceneEx != nil {
if sceneEx.init() {
s.ExtraData = sceneEx
}
}
return sceneEx
}
// 创建玩家扩展数据
func (this *ScenePolicyCaiShen) CreatePlayerExData(s *base.Scene, p *base.Player) interface{} {
playerEx := &CaiShenPlayerData{Player: p}
if playerEx != nil {
p.ExtraData = playerEx
}
return playerEx
}
// 场景开启事件
func (this *ScenePolicyCaiShen) OnStart(s *base.Scene) {
logger.Logger.Trace("(this *ScenePolicyCaiShen) OnStart, SceneId=", s.SceneId)
sceneEx := NewCaiShenSceneData(s)
if sceneEx != nil {
if sceneEx.init() {
s.ExtraData = sceneEx
s.ChangeSceneState(CaiShenSceneStateStart) //改变当前的玩家状态
}
}
}
// 场景关闭事件
func (this *ScenePolicyCaiShen) OnStop(s *base.Scene) {
logger.Logger.Trace("(this *ScenePolicyCaiShen) OnStop , SceneId=", s.SceneId)
if sceneEx, ok := s.ExtraData.(*CaiShenSceneData); ok {
sceneEx.SaveData(true)
}
}
// 场景心跳事件
func (this *ScenePolicyCaiShen) OnTick(s *base.Scene) {
if s == nil {
return
}
if s.SceneState != nil {
s.SceneState.OnTick(s)
}
}
// 玩家进入事件
func (this *ScenePolicyCaiShen) OnPlayerEnter(s *base.Scene, p *base.Player) {
if s == nil || p == nil {
return
}
logger.Logger.Trace("(this *ScenePolicyCaiShen) OnPlayerEnter, SceneId=", s.SceneId, " player=", p.SnId)
if sceneEx, ok := s.ExtraData.(*CaiShenSceneData); ok {
playerEx := &CaiShenPlayerData{Player: p}
playerEx.init(s) // 玩家当前信息初始化
playerEx.score = sceneEx.GetDBGameFree().GetBaseScore() // 底注
sceneEx.players[p.SnId] = playerEx
p.ExtraData = playerEx
CaiShenSendRoomInfo(s, p, sceneEx, playerEx, nil)
s.FirePlayerEvent(p, base.PlayerEventEnter, nil) //回调会调取 onPlayerEvent事件
}
}
// 玩家离开事件
func (this *ScenePolicyCaiShen) OnPlayerLeave(s *base.Scene, p *base.Player, reason int) {
if s == nil || p == nil {
return
}
logger.Logger.Trace("(this *ScenePolicyCaiShen) OnPlayerLeave, SceneId=", s.SceneId, " player=", p.SnId)
if sceneEx, ok := s.ExtraData.(*CaiShenSceneData); ok {
if this.CanChangeCoinScene(s, p) {
if playerEx, ok := p.ExtraData.(*CaiShenPlayerData); ok {
playerEx.SavePlayerGameData(s.KeyGamefreeId)
}
sceneEx.OnPlayerLeave(p, reason)
s.FirePlayerEvent(p, base.PlayerEventLeave, []int64{int64(reason)})
}
}
}
// 玩家掉线
func (this *ScenePolicyCaiShen) OnPlayerDropLine(s *base.Scene, p *base.Player) {
if s == nil || p == nil {
return
}
logger.Logger.Trace("(this *ScenePolicyCaiShen) OnPlayerDropLine, SceneId=", s.SceneId, " player=", p.SnId)
s.FirePlayerEvent(p, base.PlayerEventDropLine, nil)
if sceneEx, ok := s.ExtraData.(*CaiShenSceneData); ok {
if sceneEx.Gaming {
return
}
}
}
// 玩家重连
func (this *ScenePolicyCaiShen) OnPlayerRehold(s *base.Scene, p *base.Player) {
if s == nil || p == nil {
return
}
logger.Logger.Trace("(this *ScenePolicyCaiShen) OnPlayerRehold, SceneId=", s.SceneId, " player=", p.Name)
//if sceneEx, ok := s.ExtraData.(*CaiShenSceneData); ok {
// if playerEx, ok := p.ExtraData.(*CaiShenPlayerData); ok {
//发送房间信息给自己
//CaiShenSendRoomInfo(s, p, sceneEx, playerEx)
s.FirePlayerEvent(p, base.PlayerEventRehold, nil)
// }
//}
}
// 玩家返回房间
func (this *ScenePolicyCaiShen) OnPlayerReturn(s *base.Scene, p *base.Player) {
if s == nil || p == nil {
return
}
logger.Logger.Trace("(this *ScenePolicyCaiShen) OnPlayerReturn, SceneId=", s.SceneId, " player=", p.Name)
if sceneEx, ok := s.ExtraData.(*CaiShenSceneData); ok {
if playerEx, ok := p.ExtraData.(*CaiShenPlayerData); ok {
//发送房间信息给自己
CaiShenSendRoomInfo(s, p, sceneEx, playerEx, playerEx.billedData)
s.FirePlayerEvent(p, base.PlayerEventReturn, nil)
}
}
}
// 玩家操作
func (this *ScenePolicyCaiShen) OnPlayerOp(s *base.Scene, p *base.Player, opcode int, params []int64) bool {
if s == nil || p == nil {
return false
}
if s.SceneState != nil {
return s.SceneState.OnPlayerOp(s, p, opcode, params)
}
return true
}
// 玩家事件
func (this *ScenePolicyCaiShen) OnPlayerEvent(s *base.Scene, p *base.Player, evtcode int, params []int64) {
if s == nil || p == nil {
return
}
if s.SceneState != nil {
s.SceneState.OnPlayerEvent(s, p, evtcode, params)
}
}
// 是否完成了整个牌局
func (this *ScenePolicyCaiShen) IsCompleted(s *base.Scene) bool { return false }
// 是否可以强制开始
func (this *ScenePolicyCaiShen) IsCanForceStart(s *base.Scene) bool { return true }
// 当前状态能否换桌
func (this *ScenePolicyCaiShen) CanChangeCoinScene(s *base.Scene, p *base.Player) bool {
if s == nil || p == nil {
return true
}
if s.SceneState != nil {
return s.SceneState.CanChangeCoinScene(s, p)
}
return true
}
func (this *ScenePolicyCaiShen) RegisteSceneState(state base.SceneState) {
if state == nil {
return
}
stateid := state.GetState()
if stateid < 0 || stateid >= CaiShenSceneStateMax {
return
}
this.states[stateid] = state
}
func (this *ScenePolicyCaiShen) GetSceneState(s *base.Scene, stateid int) base.SceneState {
if stateid >= 0 && stateid < CaiShenSceneStateMax {
return ScenePolicyCaiShenSington.states[stateid]
}
return nil
}
func (this *ScenePolicyCaiShen) GetJackPotVal(s *base.Scene) int64 {
if sceneEx, ok := s.ExtraData.(*CaiShenSceneData); ok {
if sceneEx.lastJackpotValue != sceneEx.jackpot.VirtualJK {
return sceneEx.jackpot.VirtualJK
}
}
return 0
}
func CaiShenSendRoomInfo(s *base.Scene, p *base.Player, sceneEx *CaiShenSceneData, playerEx *CaiShenPlayerData, data *caishen.GameBilledData) {
logger.Logger.Trace("-------------------发送房间消息 ", s.RoomId, p.SnId)
pack := &caishen.SCCaiShenRoomInfo{
RoomId: s.SceneId,
Creator: proto.Int32(s.Creator),
GameId: s.GameId,
RoomMode: s.GameMode,
Params: common.CopySliceInt64ToInt32(s.Params),
State: proto.Int(s.SceneState.GetState()),
Jackpot: proto.Int64(sceneEx.jackpot.VirtualJK),
GameFreeId: proto.Int32(s.GetDBGameFree().Id),
BilledData: data,
}
if playerEx != nil {
pd := &caishen.CaiShenPlayerData{
SnId: proto.Int32(playerEx.SnId),
Name: proto.String(playerEx.Name),
Head: proto.Int32(playerEx.Head),
Sex: proto.Int32(playerEx.Sex),
Coin: proto.Int64(playerEx.Coin),
HeadOutLine: proto.Int32(playerEx.HeadOutLine),
VIP: proto.Int32(playerEx.VIP),
}
pack.Players = append(pack.Players, pd)
//for _, value := range playerEx.cards {
// pack.Cards = append(pack.Cards, int32(value))
//}
pack.BetLines = playerEx.betLines
pack.FreeTimes = proto.Int32(playerEx.freeTimes)
pack.Chip = proto.Int32(s.GetDBGameFree().BaseScore)
pack.SpinID = proto.Int64(playerEx.spinID)
if playerEx.totalPriceBonus > 0 {
switch playerEx.bonusStage {
case 0:
pack.ParamsEx = append(pack.ParamsEx, playerEx.bonusStage)
case 1:
if time.Now().Unix()-playerEx.bonusStartTime >= CaiShenBonusGameStageTimeout*2 {
playerEx.CleanBonus()
} else if time.Now().Unix()-playerEx.bonusStartTime >= CaiShenBonusGameStageTimeout {
playerEx.bonusStage = 2
playerEx.bonusStartTime += CaiShenBonusGameStageTimeout
pack.ParamsEx = append(pack.ParamsEx, playerEx.bonusStage)
leftTime := playerEx.bonusStartTime + CaiShenBonusGameStageTimeout + 2 - time.Now().Unix()
pack.ParamsEx = append(pack.ParamsEx, int32(leftTime))
} else {
pack.ParamsEx = append(pack.ParamsEx, playerEx.bonusStage)
leftTime := playerEx.bonusStartTime + CaiShenBonusGameStageTimeout + 2 - time.Now().Unix()
pack.ParamsEx = append(pack.ParamsEx, int32(leftTime))
pack.ParamsEx = append(pack.ParamsEx, playerEx.bonusGameIconData...)
pack.ParamsEx = append(pack.ParamsEx, playerEx.bonusOpRecord...)
}
case 2:
if time.Now().Unix()-playerEx.bonusStartTime >= CaiShenBonusGameStageTimeout {
playerEx.CleanBonus()
} else {
pack.ParamsEx = append(pack.ParamsEx, playerEx.bonusStage)
leftTime := playerEx.bonusStartTime + CaiShenBonusGameStageTimeout + 2 - time.Now().Unix()
pack.ParamsEx = append(pack.ParamsEx, int32(leftTime))
}
}
}
if playerEx.totalPriceBonus > 0 {
pack.TotalPriceBonus = proto.Int64(playerEx.totalPriceBonus)
pack.BonusGame = playerEx.bonusGame
pack.BonusX = playerEx.bonusX
}
}
proto.SetDefaults(pack)
p.SendToClient(int(caishen.CaiShenPacketID_PACKET_SC_CAISHEN_ROOMINFO), pack)
}
type SceneStateCaiShenStart struct {
}
// 获取当前场景状态
func (this *SceneStateCaiShenStart) GetState() int { return CaiShenSceneStateStart }
// 是否可以切换状态到
func (this *SceneStateCaiShenStart) CanChangeTo(s base.SceneState) bool { return true }
// 当前状态能否换桌
func (this *SceneStateCaiShenStart) CanChangeCoinScene(s *base.Scene, p *base.Player) bool {
if _, ok := p.ExtraData.(*CaiShenPlayerData); ok {
return true
}
return true
}
func (this *SceneStateCaiShenStart) GetTimeout(s *base.Scene) int { return 0 }
func (this *SceneStateCaiShenStart) OnEnter(s *base.Scene) {
if sceneEx, ok := s.ExtraData.(*CaiShenSceneData); ok {
logger.Logger.Tracef("(this *Scene) [%v] 场景状态进入 %v", s.SceneId, len(sceneEx.players))
sceneEx.StateStartTime = time.Now()
pack := &caishen.SCCaiShenRoomState{
State: proto.Int(this.GetState()),
}
proto.SetDefaults(pack)
s.Broadcast(int(caishen.CaiShenPacketID_PACKET_SC_CAISHEN_ROOMSTATE), pack, 0)
}
}
func (this *SceneStateCaiShenStart) OnLeave(s *base.Scene) {}
func (this *SceneStateCaiShenStart) OnTick(s *base.Scene) {
if sceneEx, ok := s.ExtraData.(*CaiShenSceneData); ok {
sceneEx.AIAddJackPot()
sceneEx.AIBurstJackPot()
sceneEx.KickPlayerByTime()
}
}
func (this *SceneStateCaiShenStart) OnPlayerOp(s *base.Scene, p *base.Player, opcode int, params []int64) bool {
playerEx, ok := p.ExtraData.(*CaiShenPlayerData)
if !ok {
return false
}
sceneEx, ok := s.ExtraData.(*CaiShenSceneData)
if !ok {
return false
}
if sceneEx.CheckNeedDestroy() && playerEx.freeTimes <= 0 {
//离开有统计
sceneEx.PlayerLeave(playerEx.Player, common.PlayerLeaveReason_OnDestroy, true)
return false
}
switch opcode {
case CaiShenPlayerOpStart: //开始
//if !caiShenBenchTest {
// caiShenBenchTest = true
// //for i := 0; i < 10; i++ {
// // //this.BenchTest(s, p)
// // this.WinTargetBenchTest(s, p)
// //}
// this.MultiplayerBenchTest(s)
// return true
//}
//参数是否合法
//params 参数0底注后面跟客户端选择的线n条线(1<=n<=25)客户端线是从1开始算起1~25条线
if len(params) < 2 || len(params) > rule.LINENUM+1 {
this.OnPlayerSToCOp(s, p, playerEx.Pos, opcode, caishen.OpResultCode_OPRC_Error, params)
return false
}
//先做底注校验
if sceneEx.GetDBGameFree().GetBaseScore() != int32(params[0]) {
this.OnPlayerSToCOp(s, p, playerEx.Pos, opcode, caishen.OpResultCode_OPRC_Error, params)
return false
}
playerEx.score = int32(params[0]) // 单线押注数
// 小游戏未结束 不能进行下一次旋转
if playerEx.totalPriceBonus > 0 {
this.OnPlayerSToCOp(s, p, playerEx.Pos, opcode, caishen.OpResultCode_OPRC_Error, params)
return false
}
//判断线条是否重复,是否合法
lineFlag := make(map[int64]bool)
lineParams := make([]int64, 0)
for i := 1; i < len(params); i++ {
lineNum := params[i]
if lineNum >= 1 && lineNum <= int64(rule.LINENUM) && !lineFlag[lineNum] {
lineParams = append(lineParams, lineNum)
lineFlag[lineNum] = true
} else {
this.OnPlayerSToCOp(s, p, playerEx.Pos, opcode, caishen.OpResultCode_OPRC_Error, params)
return false
}
}
//没有选线参数
if len(lineParams) == 0 {
this.OnPlayerSToCOp(s, p, playerEx.Pos, opcode, caishen.OpResultCode_OPRC_Error, params)
return false
}
//获取总投注金额(所有线的总投注) | 校验玩家余额是否足够
totalBetValue := (int64(len(lineParams))) * params[0]
if playerEx.freeTimes <= 0 && totalBetValue > playerEx.Coin {
this.OnPlayerSToCOp(s, p, playerEx.Pos, opcode, caishen.OpResultCode_OPRC_CoinNotEnough, params)
return false
} else if playerEx.freeTimes <= 0 && int64(sceneEx.GetDBGameFree().GetBetLimit()) > playerEx.Coin { //押注限制
this.OnPlayerSToCOp(s, p, playerEx.Pos, opcode, caishen.OpResultCode_OPRC_CoinNotEnough, params)
return false
}
p.LastOPTimer = time.Now()
sceneEx.GameNowTime = time.Now()
sceneEx.NumOfGames++
p.GameTimes++
//playerEx.StartCoin = playerEx.Coin
//获取当前水池的上下文环境
sceneEx.CpCtx = base.CoinPoolMgr.GetCoinPoolCtx(sceneEx.Platform, sceneEx.GetGameFreeId(), sceneEx.GroupId)
//税收比例
taxRate := sceneEx.GetDBGameFree().GetTaxRate()
if taxRate < 0 || taxRate > 10000 {
logger.Logger.Tracef("CaiShenErrorTaxRate [%v][%v][%v][%v]", sceneEx.GetGameFreeId(), playerEx.SnId, playerEx.spinID, taxRate)
taxRate = 500
}
//水池设置
coinPoolSetting := base.CoinPoolMgr.GetCoinPoolSetting(sceneEx.Platform, sceneEx.GetGameFreeId(), sceneEx.GroupId)
//baseRate := coinPoolSetting.GetBaseRate() //基础赔率
ctroRate := coinPoolSetting.GetCtrlRate() //调节赔率 暗税系数
jackpotRate := ctroRate //奖池系数
logger.Logger.Tracef("CaiShenRates [%v][%v][%v][%v][%v]", sceneEx.GetGameFreeId(), playerEx.SnId, playerEx.spinID, taxRate, ctroRate)
playerEx.IsFNovice(sceneEx.KeyGameId)
isFoolPlayer := playerEx.IsFoolPlayer[sceneEx.KeyGameId]
var gamePoolCoin int64
if isFoolPlayer {
gamePoolCoin = base.CoinPoolMgr.GetNoviceCoin(sceneEx.GetGameFreeId(), sceneEx.Platform, sceneEx.GroupId) // 当前水池金额
} else {
gamePoolCoin = base.CoinPoolMgr.GetCoin(sceneEx.GetGameFreeId(), sceneEx.Platform, sceneEx.GroupId) // 当前水池金额
}
prizeFund := gamePoolCoin - sceneEx.jackpot.VirtualJK // 除去奖池的水池剩余金额
// 奖池参数
var jackpotParam = sceneEx.GetDBGameFree().GetJackpot()
var jackpotInit = int64(jackpotParam[rule.CAISHEN_JACKPOT_InitJackpot]) * int64(sceneEx.GetDBGameFree().GetBaseScore()) //奖池初始值
var jackpotFundAdd, prizeFundAdd int64
if playerEx.freeTimes <= 0 { //正常模式才能记录用户的押注变化,免费模式不能改变押注
playerEx.betLines = lineParams // 选线记录
jackpotFundAdd = int64(math.Floor(float64(totalBetValue) * (float64(jackpotRate) / 10000.0))) //奖池要增加的金额
prizeFundAdd = totalBetValue - jackpotFundAdd
playerEx.TotalBet += totalBetValue //总下注额(从进房间开始,包含多局游戏的下注)
//扣除投注金币
p.AddCoin(-totalBetValue, common.GainWay_HundredSceneLost, base.SyncFlag_ToClient, "system", s.GetSceneName())
//p.Statics(sceneEx.KeyGameId, sceneEx.KeyGamefreeId, -totalBetValue, true)
if !p.IsRob && !sceneEx.Testing {
// 推送金币
sceneEx.PushCoinPool(prizeFundAdd, isFoolPlayer)
//base.CoinPoolMgr.PushCoin(sceneEx.GetGameFreeId(), sceneEx.GroupId, sceneEx.Platform, int64(float64(totalBetValue)*(float64(10000-ctroRate)/10000.0)))
}
////统计参与游戏次数
//if !sceneEx.Testing && !playerEx.IsRob {
// pack := &server.GWSceneEnd{
// GameFreeId: proto.Int32(sceneEx.GetDBGameFree().GetId()),
// Players: []*server.PlayerCtx{&server.PlayerCtx{SnId: proto.Int32(playerEx.SnId), Coin: proto.Int64(playerEx.Coin)}},
// }
// proto.SetDefaults(pack)
// sceneEx.SendToWorld(int(server.SSPacketID_PACKET_GW_SCENEEND), pack)
//}
} else { //免费次数时,不能改线改选线
totalBetValue = 0
}
writeBlackTryTimes := 0
WriteBlack:
slotData := make([]int, 0)
var spinRes CaiShenSpinResult
var slotDataIsOk bool
for {
var symbolType rule.Symbol
if gamePoolCoin < coinPoolSetting.GetLowerLimit() { // userInfo.prizeFund < limit * roomId
symbolType = rule.SYMBOL1
} else {
symbolType = rule.SYMBOL2
}
slotData, _ = rule.GenerateSlotsData_v2(symbolType)
spinRes = sceneEx.CalcLinePrize(slotData, playerEx.betLines, params[0])
// 免费次数时 不允许爆奖
if playerEx.freeTimes > 0 && spinRes.IsJackpot {
break
}
if spinRes.JackpotCnt > 1 {
break
}
if spinRes.IsJackpot {
if sceneEx.jackpot.Small < sceneEx.jackpot.VirtualJK {
break
}
}
spinCondition := prizeFund + prizeFundAdd - (spinRes.TotalPrizeLine + spinRes.BonusGame.GetTotalPrizeValue() + spinRes.TotalPrizeJackpot)
spinCondition += jackpotFundAdd + sceneEx.jackpot.VirtualJK - jackpotInit
win := spinRes.TotalPrizeLine + spinRes.BonusGame.GetTotalPrizeValue() + spinRes.TotalPrizeJackpot
// 现金池不足时 重新发牌
if spinCondition < 0 && win > totalBetValue {
if !spinRes.IsJackpot { // 非爆奖 水池不足 不再进行黑白名单调控
writeBlackTryTimes = 999
}
break
}
// 非爆奖时 不允许赢取太大的奖励
var limitBigWin int64 = 50
if spinCondition < int64(coinPoolSetting.GetLowerLimit()) { //现金池不足时
limitBigWin = int64(jackpotParam[rule.CAISHEN_JACKPOT_LIMITWIN_PRIZELOW])
} else {
limitBigWin = int64(jackpotParam[rule.CAISHEN_JACKPOT_LIMITWIN_PRIZEHIGH])
}
if totalBetValue > 0 && !spinRes.IsJackpot && spinRes.TotalPrizeLine+spinRes.BonusGame.GetTotalPrizeValue() > totalBetValue*limitBigWin {
break
}
// 小游戏次数限制
// 爆奖次数限制
slotDataIsOk = true
break
}
if !slotDataIsOk {
slotData = rule.MissData[rand.Intn(len(rule.MissData))]
spinRes = sceneEx.CalcLinePrize(slotData, playerEx.betLines, params[0])
}
// 黑白名单调控 防止异常循环,添加上限次数
if writeBlackTryTimes < 100 && playerEx.CheckBlackWriteList(spinRes.TotalPrizeLine+spinRes.TotalPrizeJackpot+spinRes.BonusGame.GetTotalPrizeValue() > totalBetValue) {
writeBlackTryTimes++
goto WriteBlack
} else if writeBlackTryTimes >= 100 && writeBlackTryTimes != 999 {
logger.Logger.Warnf("CaiShenWriteBlackTryTimesOver [%v][%v][%v][%v]", sceneEx.GetGameFreeId(), playerEx.SnId, gamePoolCoin, playerEx.WBLevel)
}
// 奖池水池处理
if spinRes.IsJackpot {
sceneEx.jackpot.Small -= sceneEx.jackpot.VirtualJK
if sceneEx.jackpot.Small < 0 {
sceneEx.jackpot.Small = 0
}
sceneEx.jackpot.VirtualJK = jackpotInit
} else {
sceneEx.jackpot.Small += jackpotFundAdd
sceneEx.jackpot.VirtualJK += jackpotFundAdd
}
// 玩家赢钱
totalWinScore := spinRes.TotalPrizeLine + spinRes.TotalPrizeJackpot
if totalWinScore > 0 || len(spinRes.BonusX) > 0 {
p.AddCoin(totalWinScore+spinRes.BonusGame.GetTotalPrizeValue(), common.GainWay_HundredSceneWin, 0, "system", s.GetSceneName())
//p.Statics(sceneEx.KeyGameId, sceneEx.KeyGamefreeId, totalWinScore+spinRes.BonusGame.GetTotalPrizeValue()+spinRes.TotalTaxScore, true)
if !p.IsRob && !sceneEx.Testing {
sceneEx.PopCoinPool(totalWinScore+spinRes.BonusGame.GetTotalPrizeValue()+spinRes.TotalTaxScore, isFoolPlayer)
//base.CoinPoolMgr.PopCoin(sceneEx.GetGameFreeId(), sceneEx.GroupId, sceneEx.Platform, totalWinScore+spinRes.BonusGame.GetTotalPrizeValue()+spinRes.TotalTaxScore)
}
playerEx.taxCoin = spinRes.TotalTaxScore
playerEx.AddServiceFee(playerEx.taxCoin)
}
sceneEx.StaticsLaba(&base.StaticLabaParam{
SnId: playerEx.SnId,
Gain: totalWinScore + spinRes.BonusGame.GetTotalPrizeValue() - totalBetValue,
GainTax: spinRes.TotalTaxScore,
IsAddTimes: true,
})
this.OnPlayerSToCOp(s, p, playerEx.Pos, opcode, caishen.OpResultCode_OPRC_Sucess, append(params[:1], playerEx.betLines...))
//免费次数
var isFreeFlag bool
if playerEx.freeTimes > 0 {
playerEx.freeTimes--
isFreeFlag = true
}
playerEx.freeTimes += spinRes.AddFreeTimes
rule.SpinID++
playerEx.spinID = rule.SpinID
playerEx.cards = spinRes.SlotsData
playerEx.winCoin = spinRes.TotalPrizeLine + spinRes.TotalPrizeJackpot + spinRes.BonusGame.GetTotalPrizeValue() + playerEx.taxCoin
playerEx.linesWinCoin = spinRes.TotalPrizeLine
playerEx.jackpotWinCoin = spinRes.TotalPrizeJackpot
playerEx.smallGameWinCoin = spinRes.BonusGame.GetTotalPrizeValue()
playerEx.CurrentBet = totalBetValue
playerEx.CurrentTax = playerEx.taxCoin
// 小游戏超时处理
if len(spinRes.BonusX) > 0 {
playerEx.totalPriceBonus = spinRes.BonusGame.GetTotalPrizeValue()
playerEx.bonusGame = &spinRes.BonusGame
playerEx.bonusX = spinRes.BonusX
logger.Logger.Tracef("BonusGame Start [%v][%v][%v][%v]", sceneEx.GetGameFreeId(), playerEx.SnId, playerEx.spinID, playerEx.totalPriceBonus)
// playerEx.bonusTimerHandle, _ = timer.StartTimer(timer.TimerActionWrapper(func(h timer.TimerHandle, ud interface{}) bool {
// this.OnPlayerOp(s, p, CaiShenBonusGame, []int64{playerEx.spinID})
// return true
// }), nil, CaiShenBonusGameTimeout, 1)
}
playerEx.billedData = &caishen.GameBilledData{
SpinID: proto.Int64(playerEx.spinID),
SlotsData: spinRes.SlotsData,
AddFreeSpin: proto.Int32(spinRes.AddFreeTimes),
IsJackpot: proto.Bool(spinRes.IsJackpot),
PrizeLines: spinRes.LinesInfo,
TotalPrizeValue: proto.Int64(totalWinScore),
TotalPaylinePrizeValue: proto.Int64(spinRes.TotalPrizeLine),
TotalJackpotValue: proto.Int64(spinRes.TotalPrizeJackpot),
Balance: proto.Int64(playerEx.Coin - spinRes.BonusGame.GetTotalPrizeValue()),
FreeSpins: proto.Int32(playerEx.freeTimes),
Jackpot: proto.Int64(sceneEx.jackpot.VirtualJK),
BonusX: spinRes.BonusX,
BonusGame: &spinRes.BonusGame,
}
pack := &caishen.SCCaiShenGameBilled{
BilledData: playerEx.billedData,
}
proto.SetDefaults(pack)
logger.Logger.Infof("CaiShenPlayerOpStart %v", pack)
p.SendToClient(int(caishen.CaiShenPacketID_PACKET_SC_CAISHEN_GAMEBILLED), pack)
// 记录本次操作
playerEx.RollGameType.BaseResult.WinTotal = pack.BilledData.GetTotalPrizeValue() + pack.BilledData.GetBonusGame().GetTotalPrizeValue()
playerEx.RollGameType.BaseResult.IsFree = isFreeFlag
playerEx.RollGameType.BaseResult.AllWinNum = int32(len(pack.BilledData.PrizeLines))
playerEx.RollGameType.BaseResult.WinRate = spinRes.TotalWinRate
playerEx.RollGameType.BaseResult.Cards = pack.BilledData.GetSlotsData()
playerEx.RollGameType.WinLines = spinRes.WinLines
playerEx.RollGameType.BaseResult.WinLineScore = pack.BilledData.TotalPaylinePrizeValue
playerEx.RollGameType.BaseResult.WinJackpot = pack.BilledData.GetTotalJackpotValue()
playerEx.RollGameType.BaseResult.WinSmallGame = pack.BilledData.GetBonusGame().GetTotalPrizeValue()
playerEx.RollGameType.BaseResult.IsFoolPlayer = isFoolPlayer
CaiShenCheckAndSaveLog(sceneEx, playerEx)
// 广播奖池
if totalBetValue == 0 && !spinRes.IsJackpot { // 没改变奖池
return true
}
// 添加进开奖记录里面
if spinRes.IsJackpot {
sceneEx.RecordBurstLog(playerEx.Name, pack.BilledData.GetTotalJackpotValue(), playerEx.CurrentBet)
}
logger.Logger.Tracef("---caishen---当前奖池:真人[%v] 虚拟[%v]", sceneEx.jackpot.Small, sceneEx.jackpot.VirtualJK)
case CaiShenBurstHistory:
sceneEx.BurstHistory(playerEx)
case CaiShenPlayerHistory:
task.New(nil, task.CallableWrapper(func(o *basic.Object) interface{} {
spinid := strconv.FormatInt(int64(playerEx.SnId), 10)
gpl := model.GetPlayerListByHallEx(p.SnId, p.Platform, 0, 80, 0, 0, 0, s.GetDBGameFree().GetGameClass(), int(s.GameId))
pack := &caishen.SCCaiShenPlayerHistory{}
for _, v := range gpl.Data {
//if v.GameDetailedLogId == "" {
// logger.Logger.Error("CaiShenPlayerHistory GameDetailedLogId is nil")
// break
//}
//gdl := model.GetPlayerHistory(p.Platform, v.GameDetailedLogId)
//if gdl == nil {
// logger.Logger.Error("CaiShenPlayerHistory gdl is nil")
// continue
//}
//data, err := UnMarshalCaiShenGameNote(gdl.GameDetailedNote)
//if err != nil {
// logger.Logger.Errorf("UnMarshalCaiShenGameNote error:%v", err)
//}
//gnd := data.(*GameResultLog)
player := &caishen.CaiShenPlayerHistoryInfo{
SpinID: proto.String(spinid),
CreatedTime: proto.Int64(int64(v.Ts)),
TotalBetValue: proto.Int64(v.BetAmount),
TotalPriceValue: proto.Int64(v.WinTotal),
IsFree: proto.Bool(v.IsFree),
TotalBonusValue: proto.Int64(v.WinSmallGame),
}
pack.PlayerHistory = append(pack.PlayerHistory, player)
}
proto.SetDefaults(pack)
logger.Logger.Info("CaiShenPlayerHistory: ", pack)
return pack
}), task.CompleteNotifyWrapper(func(data interface{}, t task.Task) {
if data == nil {
logger.Logger.Error("CaiShenPlayerHistory data is nil")
return
}
p.SendToClient(int(caishen.CaiShenPacketID_PACKET_SC_CAISHEN_PLAYERHISTORY), data)
}), "CSGetCaiShenPlayerHistoryHandler").Start()
case CaiShenBonusGame:
//params 参数0 spinID
//参数是否合法
if len(params) < 1 {
this.OnPlayerSToCOp(s, p, playerEx.Pos, opcode, caishen.OpResultCode_OPRC_Error, params)
return false
}
if playerEx.spinID != params[0] || playerEx.totalPriceBonus <= 0 {
this.OnPlayerSToCOp(s, p, playerEx.Pos, opcode, caishen.OpResultCode_OPRC_Error, params)
return false
}
if playerEx.bonusTimerHandle != timer.TimerHandle(0) {
timer.StopTimer(playerEx.bonusTimerHandle)
playerEx.bonusTimerHandle = timer.TimerHandle(0)
}
logger.Logger.Tracef("BonusGame Start [%v][%v][%v][%v]", sceneEx.GetGameFreeId(), playerEx.SnId, playerEx.spinID, playerEx.totalPriceBonus)
this.OnPlayerSToCOp(s, p, playerEx.Pos, opcode, caishen.OpResultCode_OPRC_Sucess, []int64{playerEx.totalPriceBonus, playerEx.Coin})
playerEx.CleanBonus()
case CaiShenBonusGameRecord:
// params[0] 小游戏阶段: 0 小游戏动画开始 1 小游戏界面1 2 切换小游戏界面2
// params[1] 小游戏界面1时选择奖项的界面位置信息
if len(params) < 1 || params[0] < 0 || params[0] > 2 || playerEx.totalPriceBonus <= 0 || (params[0] == 1 && len(params) < 2) {
this.OnPlayerSToCOp(s, p, playerEx.Pos, opcode, caishen.OpResultCode_OPRC_Error, params)
return false
}
if params[0] == 0 {
if playerEx.bonusStage > 0 || len(params) < 13 {
this.OnPlayerSToCOp(s, p, playerEx.Pos, opcode, caishen.OpResultCode_OPRC_Error, params)
return false
}
playerEx.bonusStage = 1
playerEx.bonusStartTime = time.Now().Unix()
for i := 1; i < len(params); i++ {
playerEx.bonusGameIconData = append(playerEx.bonusGameIconData, int32(params[i]))
}
} else if params[0] == 2 {
if playerEx.bonusStage != 1 {
this.OnPlayerSToCOp(s, p, playerEx.Pos, opcode, caishen.OpResultCode_OPRC_Error, params)
return false
}
playerEx.bonusStage = 2
playerEx.bonusStartTime = time.Now().Unix()
} else if params[0] == 1 {
if params[1] < 0 {
this.OnPlayerSToCOp(s, p, playerEx.Pos, opcode, caishen.OpResultCode_OPRC_Error, params)
return false
} else if playerEx.bonusGame != nil && len(playerEx.bonusOpRecord) >= len(playerEx.bonusGame.BonusData) {
this.OnPlayerSToCOp(s, p, playerEx.Pos, opcode, caishen.OpResultCode_OPRC_Error, params)
return false
}
playerEx.bonusOpRecord = append(playerEx.bonusOpRecord, int32(params[1]))
}
this.OnPlayerSToCOp(s, p, playerEx.Pos, opcode, caishen.OpResultCode_OPRC_Sucess, params)
}
return true
}
func (this *SceneStateCaiShenStart) OnPlayerEvent(s *base.Scene, p *base.Player, evtcode int, params []int64) {
}
// 发送玩家操作情况
func (this *SceneStateCaiShenStart) OnPlayerSToCOp(s *base.Scene, p *base.Player, pos int, opcode int,
opRetCode caishen.OpResultCode, params []int64) {
pack := &caishen.SCCaiShenOp{
SnId: proto.Int32(p.SnId),
OpCode: proto.Int(opcode),
OpRetCode: opRetCode,
Params: params,
}
proto.SetDefaults(pack)
p.SendToClient(int(caishen.CaiShenPacketID_PACKET_SC_CAISHEN_PLAYEROP), pack)
}
var caiShenBenchTest bool
var caiShenBenchTestTimes int
func (this *SceneStateCaiShenStart) BenchTest(s *base.Scene, p *base.Player) {
const BENCH_CNT = 10000
setting := base.CoinPoolMgr.GetCoinPoolSetting(s.Platform, s.GetGameFreeId(), s.GroupId)
oldPoolCoin := base.CoinPoolMgr.GetCoin(s.GetGameFreeId(), s.Platform, s.GroupId)
if caiShenBenchTestTimes == 0 {
defaultVal := int64(setting.GetLowerLimit())
if oldPoolCoin != defaultVal {
base.CoinPoolMgr.PushCoin(s.GetGameFreeId(), s.GroupId, s.Platform, defaultVal-oldPoolCoin)
}
}
caiShenBenchTestTimes++
fileName := fmt.Sprintf("caishen-%v-%d.csv", p.SnId, caiShenBenchTestTimes)
file, err := os.OpenFile(fileName, os.O_RDWR|os.O_CREATE|os.O_APPEND, os.ModePerm)
defer file.Close()
if err != nil {
file, err = os.Create(fileName)
if err != nil {
return
}
}
file.WriteString("玩家id,当前水位,之前余额,之后余额,投入,产出,税收,小游戏,中线倍数,中线数,剩余免费次数\r\n")
oldCoin := p.Coin
p.Coin = 10000000
if playerEx, ok := p.ExtraData.(*CaiShenPlayerData); ok {
for i := 0; i < BENCH_CNT; i++ {
StartCoin := p.Coin
freeTimes := playerEx.freeTimes
poolCoin := base.CoinPoolMgr.GetCoin(s.GetGameFreeId(), s.Platform, s.GroupId)
playerEx.UnmarkFlag(base.PlayerState_GameBreak)
suc := this.OnPlayerOp(s, p, CaiShenPlayerOpStart, append([]int64{int64(playerEx.score)}, rule.AllBetLines...))
inCoin := int64(playerEx.RollGameType.BaseResult.TotalBet)
outCoin := playerEx.RollGameType.BaseResult.ChangeCoin + inCoin
taxCoin := playerEx.RollGameType.BaseResult.Tax
str := fmt.Sprintf("%v,%v,%v,%v,%v,%v,%v,%v,%v,%v,%v\r\n", p.SnId, poolCoin, StartCoin, p.Coin, inCoin, outCoin, taxCoin,
playerEx.RollGameType.BaseResult.WinSmallGame, playerEx.RollGameType.BaseResult.WinRate, playerEx.RollGameType.BaseResult.AllWinNum, freeTimes)
file.WriteString(str)
if !suc {
break
}
if playerEx.totalPriceBonus > 0 {
this.OnPlayerOp(s, p, CaiShenBonusGame, []int64{playerEx.spinID})
}
}
}
p.Coin = oldCoin
}
func (this *SceneStateCaiShenStart) WinTargetBenchTest(s *base.Scene, p *base.Player) {
const BENCH_CNT = 10000
var once = sync.Once{}
once.Do(func() {
setting := base.CoinPoolMgr.GetCoinPoolSetting(s.Platform, s.GetGameFreeId(), s.GroupId)
oldPoolCoin := base.CoinPoolMgr.GetCoin(s.GetGameFreeId(), s.Platform, s.GroupId)
if caiShenBenchTestTimes == 0 {
defaultVal := int64(setting.GetLowerLimit())
if oldPoolCoin != defaultVal {
base.CoinPoolMgr.PushCoin(s.GetGameFreeId(), s.GroupId, s.Platform, defaultVal-oldPoolCoin)
}
}
})
caiShenBenchTestTimes++
fileName := fmt.Sprintf("caishen-win-%v-%d.csv", p.SnId, caiShenBenchTestTimes)
file, err := os.OpenFile(fileName, os.O_RDWR|os.O_CREATE|os.O_APPEND, os.ModePerm)
defer file.Close()
if err != nil {
file, err = os.Create(fileName)
if err != nil {
return
}
}
file.WriteString("玩家id,当前水位,之前余额,之后余额,投入,产出,税收,小游戏,中线倍数,中线数,剩余免费次数\r\n")
oldCoin := p.Coin
switch s.GetDBGameFree().GetSceneType() {
case 1:
p.Coin = 100000
case 2:
p.Coin = 500000
case 3:
p.Coin = 1000000
case 4:
p.Coin = 10000000
default:
p.Coin = 100000
}
var targetCoin = p.Coin + p.Coin/10
if playerEx, ok := p.ExtraData.(*CaiShenPlayerData); ok {
for i := 0; p.Coin < targetCoin; i++ {
StartCoin := p.Coin
freeTimes := playerEx.freeTimes
poolCoin := base.CoinPoolMgr.GetCoin(s.GetGameFreeId(), s.Platform, s.GroupId)
playerEx.UnmarkFlag(base.PlayerState_GameBreak)
suc := this.OnPlayerOp(s, p, CaiShenPlayerOpStart, append([]int64{int64(playerEx.score)}, rule.AllBetLines...))
inCoin := int64(playerEx.RollGameType.BaseResult.TotalBet)
outCoin := playerEx.RollGameType.BaseResult.ChangeCoin + inCoin
taxCoin := playerEx.RollGameType.BaseResult.Tax
str := fmt.Sprintf("%v,%v,%v,%v,%v,%v,%v,%v,%v,%v,%v\r\n", p.SnId, poolCoin, StartCoin, p.Coin, inCoin, outCoin, taxCoin,
playerEx.RollGameType.BaseResult.WinSmallGame, playerEx.RollGameType.BaseResult.WinRate, playerEx.RollGameType.BaseResult.AllWinNum, freeTimes)
file.WriteString(str)
if !suc {
break
}
if playerEx.totalPriceBonus > 0 {
this.OnPlayerOp(s, p, CaiShenBonusGame, []int64{playerEx.spinID})
}
if i > BENCH_CNT {
break
}
}
}
p.Coin = oldCoin
}
// MultiplayerBenchTest 多人同时测试 模拟正常环境
func (this *SceneStateCaiShenStart) MultiplayerBenchTest(s *base.Scene) {
const BENCH_CNT = 10000
var once = sync.Once{}
once.Do(func() {
setting := base.CoinPoolMgr.GetCoinPoolSetting(s.Platform, s.GetGameFreeId(), s.GroupId)
oldPoolCoin := base.CoinPoolMgr.GetCoin(s.GetGameFreeId(), s.Platform, s.GroupId)
if caiShenBenchTestTimes == 0 {
defaultVal := int64(setting.GetLowerLimit())
if oldPoolCoin != defaultVal {
base.CoinPoolMgr.PushCoin(s.GetGameFreeId(), s.GroupId, s.Platform, defaultVal-oldPoolCoin)
}
}
})
caiShenBenchTestTimes++
fileName := fmt.Sprintf("caishen-total-%v-%d.csv", s.GetDBGameFree().GetSceneType(), caiShenBenchTestTimes)
file, err := os.OpenFile(fileName, os.O_RDWR|os.O_CREATE|os.O_APPEND, os.ModePerm)
defer file.Close()
if err != nil {
file, err = os.Create(fileName)
if err != nil {
return
}
}
file.WriteString("玩家id,当前水位,之前余额,之后余额,投入,产出,税收,小游戏,爆奖,中线倍数,中线数,剩余免费次数\r\n")
playersFile := make(map[int32]*os.File)
oldCoins := make(map[int32]int64)
hasCoin := 1000 * int64(s.GetDBGameFree().GetBaseScore())
robots := make(map[int32]bool)
testPlayers := make(map[int32]*base.Player)
for _, p := range s.Players {
if p.IsRob {
p.IsRob = false
robots[p.SnId] = true
}
fileName := fmt.Sprintf("caishen-player%v-%v-%d.csv", p.SnId, s.GetDBGameFree().GetSceneType(), caiShenBenchTestTimes)
file, err := os.OpenFile(fileName, os.O_RDWR|os.O_CREATE|os.O_APPEND, os.ModePerm)
if err != nil {
file, err = os.Create(fileName)
if err != nil {
return
}
}
file.WriteString("玩家id,当前水位,之前余额,之后余额,投入,产出,税收,小游戏,爆奖,中线倍数,中线数,剩余免费次数\r\n")
playersFile[p.SnId] = file
oldCoins[p.SnId] = p.Coin
p.Coin = hasCoin
hasCoin = int64(float64(hasCoin) * 1.6)
testPlayers[p.SnId] = p
}
defer func() {
for _, file := range playersFile {
file.Close()
}
for snid, Coin := range oldCoins {
if player := s.GetPlayer(snid); player != nil {
player.Coin = Coin
if robots[player.SnId] {
player.IsRob = true
}
}
}
}()
totalBet := int64(s.GetDBGameFree().GetBaseScore()) * int64(len(rule.AllBetLines))
for i := 0; i < BENCH_CNT; i++ {
for snid, p := range testPlayers {
if playerEx, ok := p.ExtraData.(*CaiShenPlayerData); ok {
StartCoin := p.Coin
if StartCoin < totalBet {
continue
}
freeTimes := playerEx.freeTimes
poolCoin := base.CoinPoolMgr.GetCoin(s.GetGameFreeId(), s.Platform, s.GroupId)
playerEx.UnmarkFlag(base.PlayerState_GameBreak)
suc := this.OnPlayerOp(s, p, CaiShenPlayerOpStart, append([]int64{int64(playerEx.score)}, rule.AllBetLines...))
inCoin := int64(playerEx.RollGameType.BaseResult.TotalBet)
outCoin := playerEx.RollGameType.BaseResult.ChangeCoin + inCoin
taxCoin := playerEx.RollGameType.BaseResult.Tax
lineScore := float64(playerEx.RollGameType.BaseResult.WinRate*s.GetDBGameFree().GetBaseScore()) * float64(10000.0-s.GetDBGameFree().GetTaxRate()) / 10000.0
jackpotScore := outCoin - playerEx.RollGameType.BaseResult.WinSmallGame - int64(lineScore+0.00001)
str := fmt.Sprintf("%v,%v,%v,%v,%v,%v,%v,%v,%v,%v,%v,%v\r\n", p.SnId, poolCoin, StartCoin, p.Coin, inCoin, outCoin, taxCoin,
playerEx.RollGameType.BaseResult.WinSmallGame, jackpotScore, playerEx.RollGameType.BaseResult.WinRate, playerEx.RollGameType.BaseResult.AllWinNum, freeTimes)
file.WriteString(str)
if pFile := playersFile[snid]; pFile != nil {
pFile.WriteString(str)
}
if !suc {
continue
}
if playerEx.totalPriceBonus > 0 {
this.OnPlayerOp(s, p, CaiShenBonusGame, []int64{playerEx.spinID})
}
}
}
}
}
func CaiShenCheckAndSaveLog(sceneEx *CaiShenSceneData, playerEx *CaiShenPlayerData) {
//统计金币变动
//log1
logger.Logger.Trace("CaiShenCheckAndSaveLog Save ", playerEx.SnId)
//changeCoin := playerEx.Coin - playerEx.StartCoin
changeCoin := playerEx.winCoin - playerEx.taxCoin - playerEx.CurrentBet
startCoin := playerEx.Coin - changeCoin
//playerEx.SaveSceneCoinLog(startCoin, changeCoin,
// playerEx.Coin, playerEx.CurrentBet, playerEx.taxCoin, playerEx.winCoin, playerEx.jackpotWinCoin, playerEx.smallGameWinCoin)
//log2
playerEx.RollGameType.BaseResult.ChangeCoin = changeCoin
playerEx.RollGameType.BaseResult.BasicBet = sceneEx.GetDBGameFree().GetBaseScore()
playerEx.RollGameType.BaseResult.RoomId = int32(sceneEx.SceneId)
playerEx.RollGameType.BaseResult.AfterCoin = playerEx.Coin
playerEx.RollGameType.BaseResult.BeforeCoin = startCoin
playerEx.RollGameType.BaseResult.IsFirst = sceneEx.IsPlayerFirst(playerEx.Player)
playerEx.RollGameType.BaseResult.PlayerSnid = playerEx.SnId
playerEx.RollGameType.BaseResult.TotalBet = int32(playerEx.CurrentBet)
playerEx.RollGameType.AllLine = int32(len(playerEx.betLines))
playerEx.RollGameType.BaseResult.FreeTimes = playerEx.freeTimes
playerEx.RollGameType.UserName = playerEx.Name
playerEx.RollGameType.BetLines = playerEx.betLines
playerEx.RollGameType.BaseResult.Tax = playerEx.taxCoin
playerEx.RollGameType.BaseResult.WBLevel = sceneEx.players[playerEx.SnId].WBLevel
if playerEx.score > 0 {
if !playerEx.IsRob {
info, err := model.MarshalGameNoteByROLL(playerEx.RollGameType)
if err == nil {
logid, _ := model.AutoIncGameLogId()
playerEx.currentLogId = logid
sceneEx.SaveGameDetailedLog(logid, info, &base.GameDetailedParam{})
totalin := int64(playerEx.RollGameType.BaseResult.TotalBet)
totalout := playerEx.RollGameType.BaseResult.ChangeCoin + playerEx.taxCoin + totalin
validFlow := totalin + totalout
validBet := common.AbsI64(totalin - totalout)
logParam := &base.SaveGamePlayerListLogParam{
Platform: playerEx.Platform,
Channel: playerEx.Channel,
Promoter: playerEx.BeUnderAgentCode,
PackageTag: playerEx.PackageID,
InviterId: playerEx.InviterId,
LogId: logid,
TotalIn: totalin,
TotalOut: totalout,
TaxCoin: playerEx.taxCoin,
BetAmount: int64(playerEx.RollGameType.BaseResult.TotalBet),
WinAmountNoAnyTax: playerEx.RollGameType.BaseResult.ChangeCoin,
ValidBet: validBet,
ValidFlow: validFlow,
IsFirstGame: sceneEx.IsPlayerFirst(playerEx.Player),
IsFree: playerEx.RollGameType.BaseResult.IsFree,
WinSmallGame: playerEx.RollGameType.BaseResult.WinSmallGame,
WinTotal: playerEx.RollGameType.BaseResult.WinTotal,
}
sceneEx.SaveGamePlayerListLog(playerEx.SnId, logParam)
}
}
}
//统计输下注金币数
if !sceneEx.Testing && !playerEx.IsRob {
playerBet := &server.PlayerData{
SnId: proto.Int32(playerEx.SnId),
Bet: proto.Int64(playerEx.CurrentBet),
Gain: proto.Int64(playerEx.RollGameType.BaseResult.ChangeCoin),
Tax: proto.Int64(playerEx.taxCoin),
Coin: proto.Int64(playerEx.GetCoin()),
GameCoinTs: proto.Int64(playerEx.GameCoinTs),
}
gwPlayerBet := &server.GWPlayerData{
SceneId: sceneEx.SceneId,
GameFreeId: proto.Int32(sceneEx.GetDBGameFree().GetId()),
}
gwPlayerBet.Datas = append(gwPlayerBet.Datas, playerBet)
sceneEx.SyncPlayerDatas(&base.PlayerDataParam{
HasRobotGaming: false,
Data: gwPlayerBet,
})
}
playerEx.taxCoin = 0
playerEx.winCoin = 0
playerEx.linesWinCoin = 0
playerEx.jackpotWinCoin = 0
playerEx.smallGameWinCoin = 0
if sceneEx.CheckNeedDestroy() && playerEx.freeTimes <= 0 {
sceneEx.PlayerLeave(playerEx.Player, common.PlayerLeaveReason_OnDestroy, true)
}
}
func init() {
ScenePolicyCaiShenSington.RegisteSceneState(&SceneStateCaiShenStart{})
core.RegisteHook(core.HOOK_BEFORE_START, func() error {
base.RegisteScenePolicy(common.GameId_CaiShen, 0, ScenePolicyCaiShenSington)
return nil
})
}