From 758af0443fa9dfd2fc9c473bd533018c036d248f Mon Sep 17 00:00:00 2001 From: liuxiaobo <1224730913@qq.com> Date: Sun, 8 Jun 2025 22:29:01 +0800 Subject: [PATCH] =?UTF-8?q?=E9=87=8D=E5=86=99=E6=B6=88=E6=81=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- common/config/game/color.go | 26 +- common/pb/colorgame.proto | 745 +++------ server/colorgame/room/alive.go | 945 +++++------ server/colorgame/room/c2s.go | 417 ++--- server/colorgame/room/colorRoom.go | 812 +++++----- server/colorgame/room/helper.go | 2355 ++++++++++++++-------------- server/colorgame/room/process.go | 231 +-- server/colorgame/room/s2c.go | 1404 ++++++++--------- 8 files changed, 3223 insertions(+), 3712 deletions(-) diff --git a/common/config/game/color.go b/common/config/game/color.go index 12e6dfb..5f11a4d 100644 --- a/common/config/game/color.go +++ b/common/config/game/color.go @@ -24,26 +24,12 @@ type ColorRoomConfig struct { JpYRate int `json:"jp_y_rate"` // jp池追加比例 JpXYRate int `json:"jp_xy_rate"` // 系统池为正时jackpot追加比例 - AreaBetLimit int64 `json:"area_bet_limit"` // 下注区域自己的下注限制 - - NoBetCountMax int `json:"no_bet_count_max"` // 未操作回合踢出房间 - BetList [][]int64 `json:"bet_list"` // 筹码 - BetLevel []int64 `json:"bet_level"` // 筹码等级 - OneCreateMin int32 `json:"one_create_min"` // 一次创建机器最少数 - OneCreateMax int32 `json:"one_create_max"` // 一次创建机器人最大数 - UserAddRobotNum int32 `json:"user_add_robot_num"` // 真人+机器人最小数 - UserAddRobotNumMax int32 `json:"user_add_robot_num_max"` // 真人+机器人最大数 - OneDeleteNum int32 `json:"one_delete_num"` // 一次删除机器人数量 - BalanceMin int64 `json:"balance_min"` // 机器人生成最小金币 - BalanceMax int64 `json:"balance_max"` // 机器人生成最大金币 - BalanceMinDelete int64 `json:"balance_min_delete"` // 机器人低于多少金币删除 - RobotCreateTime int32 `json:"robot_create_time"` // 多少时间创建机器人 - RobotDeleteTime int32 `json:"robot_delete_time"` // 多少时间删除机器人 - RobotBetNumMin int32 `json:"robot_bet_num_min"` // 机器人每轮下注最少次数 - RobotBetNumMax int32 `json:"robot_bet_num_max"` // 机器人每轮下注最大次数 - OpenRobot bool `json:"open_robot"` // 机器人开关 - BetMap map[int64][]int32 - TotalBetLimit int64 `json:"total_bet_limit"` + AreaBetLimit int64 `json:"area_bet_limit"` // 下注区域自己的下注限制 + NoBetCountMax int `json:"no_bet_count_max"` // 未操作回合踢出房间 + BetList [][]int64 `json:"bet_list"` // 筹码 + BetLevel []int64 `json:"bet_level"` // 筹码等级 + BetMap map[int64][]int32 + TotalBetLimit int64 `json:"total_bet_limit"` } type ColorGameTiming struct { diff --git a/common/pb/colorgame.proto b/common/pb/colorgame.proto index 647cf62..868a18f 100644 --- a/common/pb/colorgame.proto +++ b/common/pb/colorgame.proto @@ -2,579 +2,270 @@ syntax = "proto3"; package pb; option go_package = "common/proto/pb"; +import "code.proto"; + +// 奖励档位 +enum ColorPrizeArea +{ + CPA_Single_0 = 0; // 单色投注区域开出单色 + CPA_Single_1 = 1; // 单色投注区域开出双色 + CPA_Single_2 = 2; // 单色投注区域开出三色 + CPA_Double = 3; // 双色投注区域 + CPA_Three = 4; // 三色投注区域 +} + +// 投注区域赔率范围配置信息 +message ColorPrizeAreaRange +{ + ColorPrizeArea pos = 1; // 下注区域为单色区0-2时,该值表明是单色还是双色,三色不同的赔率 + int64 minMul = 2; + int64 maxMul = 3; +} // color玩法配置信息 -message ColorRoomInfo +message ColorRoomConfig { - + repeated int64 betList = 3; // 下注档位 + repeated ColorPrizeAreaRange mulRangeConfig = 5; // 赔率显示 } - - //骰子颜色类型 -enum ColorPinoyLiveDiceColorType { - ColorPinoyLiveType_Void = 0; - ColorPinoyLiveType_YELLOW = 1; //黄色 - ColorPinoyLiveType_WHITE = 2; //白色 - ColorPinoyLiveType_PINK = 3; //粉色 - ColorPinoyLiveType_BLUE = 4; //蓝色 - ColorPinoyLiveType_RED = 5; //红色 - ColorPinoyLiveType_GREEN = 6; //绿色 - +enum ColorType +{ + CT_Yellow = 0; // 黄色 + CT_White = 1; // 白色 + CT_Pink = 2; // 粉色 + CT_Blue = 3; // 蓝色 + CT_Red = 4; // 红色 + CT_Green = 5; // 绿色 } -// 带jackpot版本的押注类型 -enum ColorPinoyLiveBetTypeJP { - CLJ_Yellow = 0; // 黄色 - CLJ_White = 1; // 白色 - CLJ_Pink = 2; // 粉色 - CLJ_Blue = 3; // 蓝色 - CLJ_Red = 4; // 红色 - CLJ_Green = 5; // 绿色 +// 押注区域 +enum ColorBetArea +{ + CBA_Yellow = 0; // 黄色 + CBA_White = 1; // 白色 + CBA_Pink = 2; // 粉色 + CBA_Blue = 3; // 蓝色 + CBA_Red = 4; // 红色 + CBA_Green = 5; // 绿色 - CLJ_Double_Yellow = 6; // 双黄色 - CLJ_Double_White = 7; // 双白色 - CLJ_Double_Pink = 8; // 双粉色 - CLJ_Double_Blue = 9; // 双蓝色 - CLJ_Double_Red = 10; // 双红色 - CLJ_Double_Green = 11; // 双绿色 + CBA_Yellow2 = 6; // 双黄色 + CBA_White2 = 7; // 双白色 + CBA_Pink2 = 8; // 双粉色 + CBA_Blue2 = 9; // 双蓝色 + CBA_Red2 = 10; // 双红色 + CBA_Green2 = 11; // 双绿色 - CLJ_Three_Yellow = 12; // 双黄色 - CLJ_Three_White = 13; // 双白色 - CLJ_Three_Pink = 14; // 双粉色 - CLJ_Three_Blue = 15; // 双蓝色 - CLJ_Three_Red = 16; // 双红色 - CLJ_Three_Green = 17; // 双绿色 + CBA_Yellow3 = 12; // 三黄色 + CBA_White3 = 13; // 三白色 + CBA_Pink3 = 14; // 三粉色 + CBA_Blue3 = 15; // 三蓝色 + CBA_Red3 = 16; // 三红色 + CBA_Green3 = 17; // 三绿色 } //游戏阶段 -enum ColorPinoyLiveGameStatus{ - ColorPinoyLiveStartUnReady = 0; - ColorPinoyLiveStartReady = 1; //开始321 - ColorPinoyLiveStartMovie = 2; //开始动画 - ColorPinoyLiveBetStatus = 3; //下注阶段 - ColorPinoyLiveEndBetMovie = 4; //结束下注动画 - // ColorPinoyLiveOpenLuckyDice = 5; //开lucky dice - ColorPinoyLiveOpenThreeDice = 6; //开3个 dice - ColorPinoyLiveSettleStatus = 7; //结算阶段 - ColorPinoyLiveRankStatus = 8; //排行阶段 +enum ColorGameStatus +{ + CGS_WaitStart = 0; // 等待准备 + CGS_Start = 1; // 开始 + CGS_Betting = 2; // 下注 + CGS_BetEnd = 3; // 下注结束 + CGS_OpenThreeDice = 4; // 开三色 + CGS_Settle = 5; // 结算 } -enum ColorPinoyLiveLeaveReason { - ColorPinoyLiveLeaveReason_void = 0; - ColorPinoyLiveLeaveReason_PLAYER_QUIT_ROOM=2; // 玩家离开游戏 - ColorPinoyLiveLeaveReason_Maintaince=20; //维护公告 - ColorPinoyLiveLeaveReason_Server_Update=21; //服务器更新 - ColorPinoyLiveLeaveReason_Ban=22; //封禁 +// 等待状态下房间显示信息 +message ColorRoomWaitStart +{ + NotifyColorTrend Trends = 1; // 路途显示 +} + +// 开始房间显示信息 +message ColorRoomStart +{ + NotifyColorTrend Trends = 1; // 路途显示 +} + +// 下注显示信息 +message ColorRoomBetting +{ + NotifyColorBetAreaInfo betAreaInfo = 1; // 每个投注区域的下注人数,下注金额显示 +} + +// 结束下注显示信息 +message ColorRoomEndBet +{ + NotifyColorEndBetting areaMul = 1; // 结束下注后,更新每个投注区域的赔率 + NotifyColorBetAreaInfo betAreaInfo = 2; // 每个投注区域的下注人数,下注金额显示 + NotifyColorBigUser bigUser = 3; // 大客数据 +} + +// 开骰子显示信息 +message ColorRoomOpenThreeDice +{ + NotifyColorOpenThreeDice dices = 1; +} + +// 结算信息 +message ColorRoomSettle +{ + NotifyColorSettle settle = 1; +} + +// 进房间发送房间当前所有信息及状态 +message NotifyColorRoomInfo +{ + ColorGameStatus status = 1; + int64 endTime = 2; // 该状态结束时间 + ColorRoomConfig config = 101; // 房间配置 + ColorUser user = 100; + ColorRoomWaitStart waitStart = 3; // 等待状态房间数据 + ColorRoomStart start = 4; + ColorRoomBetting betting = 5; + ColorRoomEndBet endBet = 6; + ColorRoomOpenThreeDice openThreeDice = 7; + ColorRoomSettle settle = 8; } -message ColorPinoyLiveStatusMessage{ - int32 Status = 1; //状态 - int32 StatusTime = 2; //状态的总时间 - int32 StatusRemainTime = 3; // 状态还剩多久结束时间 - int64 jackpot = 4; +message NotifyColorGameStart +{ + int64 endTime = 1; // 倒计时3秒后游戏开始,endTime = statusTime+3秒 +} + +message NotifyColorBetting +{ + int64 endTime = 1; // 结束时间 +} + +message ReqColorBetting +{ + ColorBetArea area = 1; + int64 bet = 2; +} + +message RspColorBetting +{ + ErrCode code = 1; + ColorBetArea area = 2; + int64 bet = 3; + int64 gold = 4; // 玩家一共有多少金币 +} + +// 更新投注区域信息 +message NotifyColorBetAreaInfo +{ + message BetAreaInfo + { + ColorBetArea area = 1; // 投注区域 + int64 totalGold = 2; // 所有玩家总投注金额 + int32 playerNum = 3; // 投注该区域人数 + int64 myBet = 4; // 我的投注金额 + } + repeated BetAreaInfo areaInfos = 1; +} + +// 奖励类型 +enum ColorPrizeType +{ + CPT_Normal = 0; // 普通奖励 + CPT_Big = 1; // 爆奖 + CPT_Jackpot = 2; // jackpot奖 +} + +// 投注区域实际赔率,奖励类型 +message ColorBetAreaMul +{ + ColorBetArea area = 1; // 区域位置 + ColorPrizeArea prizeArea = 2; // 奖励档位 + ColorPrizeType prizeType = 3; // 奖励类型 + int64 mul = 4; // 赔率 +} + +// 结束投注 +message NotifyColorEndBetting +{ + int64 endTime = 1; // 结束时间 + repeated ColorBetAreaMul areaMul = 2; // 更新区域实际赔率 + int64 jackpot = 3; // 下注结束,更新jackpot值 +} + +message NotifyColorOpenThreeDice +{ + repeated ColorType color = 1; // 骰子开出颜色 3个 + int32 aniRouteIndex = 3; // 动画路径 + repeated ColorBetAreaMul winBetArea = 5; // 中奖区域高亮 } -message ColorPinoyLiveGameOpenThreeDice{ - int32 Status = 1; //游戏状态 - repeated ColorPinoyLiveDiceColorType color = 2; //骰子颜色 3个 - int32 aniRouteIndex = 3; // 动画路径 +// 玩家结算信息 +message NotifyColorSettle +{ + message UserBetAreaMul + { + ColorBetAreaMul areaMul = 1; + int64 bet = 2; // 玩家在该区域投注金额 + int64 win = 3; // 该区域赢钱 + } + repeated UserBetAreaMul userAreaWin = 1; // 每个投注区域的下注及输赢 + + repeated ColorType threeDice = 2; // 骰子开出颜色 + int64 totalWin = 3; // 总输赢 + int64 totalBet = 4; // 总投注 + int64 tax = 5; // 税 } -message ColorPinoyLiveBetReq { - ColorPinoyLiveBetTypeJP BetType = 1;//下注区域 - int32 BetLevel = 2;//筹码级别 - int32 BetIndex = 3;//下注的下标 - int64 BetAmount = 4;//下注cash -} -// 服务器收到的押注信息 -message ColorPinoyLiveBetReqs { - repeated ColorPinoyLiveBetReq info = 1; // 下注区域数组 -} - -message ColorPinoyLiveBetResp { - int32 code = 1; - string msg = 2; -} //游戏中几个玩家的数据 -message ColorPinoyLiveSeatUser { +message ColorUser { string Nick = 1; // 用户昵称 string Head = 2; // 头像 int64 Score = 3; // 分数 int32 SeatId = 4; //在场景中的座位id int64 UserID = 5; //用户ID } -// 发送在线人数 -message ColorPinoyLiveS2COnlinePlayerNum{ - int64 Num = 1; // -} + // 结束下注,更新大客投注信息 -message ColorPinoyLivePlayerBigWinner +message NotifyColorBigUser { - repeated ColorPinoyLiveBigWinner bigBet = 34; // 大客投注 - int64 jackpot = 1; // 下注结束,更新jackpot值 + repeated ColorBigUser bigUser = 34; // 大客投注 } -message ColorPinoyLiveSceneBetInfo{ - int64 UserBetTotal = 1;//玩家总下注 - repeated int64 TotalBets = 2;//总各区域下注 - repeated int64 UserBets = 3;//用户各区域下注 - ColorPinoyLiveUserInfo UserInfo = 4;//用户信息 -} -message ColorPinoyLiveBetArr{ - repeated int64 betArr = 3; //下注数组 -} - -// 房间下注规则 -message ColorPinoyLiveRoomBetRuleMsg{ - int32 userBetLimit = 1; - int64 betMinLimit = 2;//最低携带金币限制 - repeated ColorPinoyLiveBetArr betLevels = 3;//下注级别 - repeated int64 level = 4;//等级 - repeated BetAreaMulRangeConfig mulRangeConfig = 5; // 赔率显示 -} - -message ColorPinoyLiveTrendGroup{ - ColorPinoyLiveDiceColorType luckyDice = 1; // 幸运骰子 - repeated ColorPinoyLiveDiceColorType threeDice = 2; // 3个普通骰子 -} - -message ColorPinoyLiveTrend{ - repeated ColorPinoyLiveTrendGroup listTrendGroup = 1; - repeated int32 luckStarRate = 2; // 数组索引号为颜色从0-5(ColorPinoyLiveDiceColorType-1) -} - -// 腾讯云实时音视频房间参数 -message TRTCRoomArgs { - int32 appId = 1; - string strRoomId = 2; - string userId = 3; - string userSig = 4; -} - -// 赢钱最多的6个玩家 -message ColorPinoyLiveBigWinner +// 路途展示 +message NotifyColorTrend { - string nickName = 5;//名字 + message ColorRate + { + ColorType color = 1; + int32 rate = 2; + } + repeated ColorRate colorRate = 1; // 最近30局各颜色中奖概率 +} + + +// 赢钱或下注最多的6个玩家 +message ColorBigUser +{ + string nickName = 5; //名字 string avatar = 2; - int64 winChips = 1; // 赢取金币 + int64 winChips = 1; // 赢取金币 repeated int64 areaId = 3; // 赢钱区域(前6个) } -// 投注区域赔率范围配置信息 -message BetAreaMulRangeConfig { - ColorPinoyLiveBigBetAreaPos pos = 1; // 下注区域为单色区0-2时,该值表明是单色还是双色,三色不同的赔率 - int64 minMul = 2; - int64 maxMul = 3; -} - -// 发送场景数据 -message SceneMessage{ - int32 roomID = 1; - ColorPinoyLiveStatusMessage gameStatus = 2; // 游戏状态 - int32 statusTime = 3; // 游戏状态剩余时间(下注倒计时会有 其余时间为 零) - int32 onlineNum = 4; // 在线人数 - ColorPinoyLiveTrend trendList = 5; // 走势图 - ColorPinoyLiveDiceColorType luckyDice = 6; // 幸运骰子 - repeated ColorPinoyLiveDiceColorType threeDice = 7; // 3个普通骰子 - repeated ColorPinoyLiveGameBetAreaInfo betAreaInfo = 8; // 下注信息 - ColorPinoyLiveRoomBetRuleMsg betRule = 9; // 下注规则 - // repeated SeatUser userData = 10; // 在坐玩家 - int32 aniLuckyDiceRouteIndex = 10; // 幸运骰子 掉落路径 - int32 aniThreeDiceRouteIndex = 11; // 3个骰子 掉落路径 - int32 onlineNums = 12; // 在线人数 - repeated ColorPinoyLiveBetReqs lastTimeBet = 13; // 上局下注 - repeated ColorPinoyLivePlayerData rankList = 14; // 玩家数据 - int32 bonus = 15; // 幸运骰子加成 - string artcUrl = 16; // 阿里云拉流地址 - TRTCRoomArgs trtcRoomArgs = 17; // 腾讯云房间参数 - int64 balance = 18; // 用户余额 - repeated ColorPinoyLiveBigWinner bigWinner = 19; // 大客数据 - repeated string dealerName = 20; // 主播名字 - int64 jackpot = 21; // jackpot值 - repeated BetAreaMulRangeConfig mulRangeConfig = 22; // 赔率显示 -} - -message ColorPinoyLiveUserSitDown{ - int32 ChairNo = 1;//座位号 -} - -message ColorPinoyLiveUserSitDownFail{ - string FailReaSon = 1;//坐下失败 -} - -message ColorPinoyLiveBetAreaOdd{ - ColorPinoyLiveBetTypeJP betArea = 1; // 投注区域 - int64 odd = 4; // 实际中奖赔率 - int64 viewOdd = 9; // 投注面板显示的赔率,比如单黄区域爆奖显示x10赔率,开出黄白红,则实际中奖赔率是基础赔率而不是爆奖赔率 - bool isBigOdd = 5; // true:爆奖 - ColorPinoyLiveBigBetAreaPos bigSingleColorOddPos = 6; // 下注区域为单色区0-2时,该值表明是单色还是双色,三色不同的赔率 - bool isWin = 7; // 该区域是否中奖 - bool isJackpot = 8; // true:jackpot位置 -} - -//扑克消息 -message ColorPinoyLivePokerMsg{ - repeated ColorPinoyLiveBetAreaOdd winBetArea = 5; // 中奖区域 -} - - - -message ColorPinoyLiveUserInfo{ - string NikeName = 1;//昵称 - int64 UserGlod = 2;//玩家金币 - int64 BetGold = 3;//近20局赢取的金币 - int32 WinCount = 4;//赢的次数 - string Head = 5; // 头像 - int64 UserID = 6;//用户id -} - -//用户列表 -message ColorPinoyLiveUserList{ - repeated ColorPinoyLiveUserInfo UserList = 1; -} - - -//个人 结算消息 -message ColorPinoyLiveUserSettleMsg{ - int64 TotalWinBaseBet = 1; //赢区的投注总和 - int64 UserScore = 2; //用户当前的分数 - int64 TotalWin = 3; //扣税以后总赢钱 - repeated int64 UserBets = 4; //用户各区域下注 - repeated int64 TotalBets = 5; //总各区域下注 - repeated int64 UserWins = 6; //用户各区域赢钱 - repeated int64 UserRealWins = 7;//用户各区域赢钱扣税后 - int64 Tax = 9; //税 - repeated int64 oddsWins = 10; // // 老版 用户各区域的赢区的结算倍率 todo - repeated int64 userBetsCount = 11; // 用户各区域下注次数 - repeated ColorPinoyLiveBetAreaOdd winAreaOdd = 12; // 中奖区域及中奖赔率 - int64 jackpotWin = 13; // jackpot奖励 - repeated string jackpotUserName = 14; // 中jackpot 玩家名单 -} - -message ColorPinoyLiveGameBetAreaUserInfo{ - int64 userID = 1; - int64 betChips = 2; -} - -// 爆奖区域位置 -enum ColorPinoyLiveBigBetAreaPos { - BBA_Single_0 = 0; // 单色投注区域开出单色 - BBA_Single_1 = 1; // 单色投注区域开出双色 - BBA_Single_2 = 2; // 单色投注区域开出三色 - BBA_Double = 3; // 双色投注区域 - BBA_Three = 4; // 三色投注区域 -} - -message ColorPinoyLiveGameBetAreaInfo{ - ColorPinoyLiveBetTypeJP betType = 1;// 下注区域 - repeated ColorPinoyLiveGameBetAreaUserInfo betChipsInfo = 2;//该下注区的玩家下注情况 - int32 isWin = 3; //这个区域是否中奖 - repeated int64 odd = 4; // 赔率 单色投注区域有三个赔率 其它投注区域只有一个赔率 - bool isBigOdd = 5; // true:爆奖 - ColorPinoyLiveBigBetAreaPos bigSingleColorOddPos = 6; // 下注区域为单色区0-2时,该值表明是单色还是双色,三色不同的赔率 - bool isJackpot = 7; // 该区域是否jackpot -} - -message ColorPinoyLiveSceneUserInfo{ - int64 UserID = 1; - int32 SceneSeatID = 2; - int64 UserScore = 3; //当前分数 - int64 TotalWin = 4; //扣税以后总赢钱 - int64 jackpotWin = 5; // jackpot赢钱 - int64 normalWin = 6; // 非jackpot赢钱 -} - -//场景上的玩家结算信息 -message ColorPinoyLiveSceneSettleMsg{ - repeated ColorPinoyLiveGameBetAreaInfo betAreaInfo = 1; // 下注区域信息 - // repeated SceneUserInfo UserList = 2; // 有座玩家下注信息 - int64 noChairTotalWin = 2; - int64 sysDealerAreaInfo = 3; // 系统庄是否有赢 - ColorPinoyLiveSceneUserInfo selfWinInfo = 4; // 自己的输赢 - ColorPinoyLiveDiceColorType luckyDice = 5; // 幸运骰子 - repeated ColorPinoyLiveDiceColorType threeDice = 6; // 3个普通骰子 - ColorPinoyLiveTrendGroup trendGroup = 7; - repeated ColorPinoyLiveBetReqs lastTimeBet = 8; // 上局下注 - ColorPinoyLiveTrend trendGroupEx = 9; - repeated ColorPinoyLiveBigWinner bigWinner = 10; // 大客数据 - int64 jackpot = 11; // jackpot池 - repeated string jackpotUserName = 12; // 中jackpot 玩家名单 -} - -//message ExitFail{ -// string FailReason = 1;//失败的原因 -//} - -message ColorPinoyLiveKickOutUserMsg{ - string KickOutReason = 1;//踢出玩家发送原因 - int32 reason = 2; //1没操作 2服务器维护 -} - -//次消息一秒一次 -message ColorPinoyLiveUpdateRoomInfoMsg{ - int64 OnlineNum = 1; //在线人数 -} - -//测试 -message ColorPinoyLivetempCardMsg{ - bytes LongPoker = 1; - bytes HuPoker = 2; -} - -// 押注成功时发送的消息 -message ColorPinoyLiveBetSuccessMessage { - int32 SeatId = 1;//座位号,场景中的座位号 - int32 BetLevel = 2;//下注的下标 - int32 BetIndex = 3;//下注的下标 - ColorPinoyLiveBetTypeJP BetType = 4;//下注区域 - int64 UserBet = 5; //该玩家本次下注 - int64 UserBets = 6; //该玩家各区域总下注 - int64 TotalBets = 7;//所有玩家总各区域下注 - -} - -// 押注成功返回 -message ColorPinoyLiveS2CRepetBet { - - repeated ColorPinoyLiveBetSuccessMessage betInfo = 1; - int64 UserScore = 2; //用户当前的分数 - int64 uid = 3; - -} - -message ColorPinoyLiveS2CNoChairRepetBet { - repeated ColorPinoyLiveBetSuccessMessage betInfo = 1; - repeated int64 UserBets = 2;//用户各区域下注 - repeated int64 TotalBets = 3;//总各区域下注 - int64 UserScore = 4; //用户当前的分数 - int64 uid = 5; -} - -// 押注翻倍 -message ColorPinoyLiveC2SBetDouble { - -} -//撤回类型 -enum ColorPinoyLiveUndoType{ - ColorPinoyLiveUndoVoid = 0; - ColorPinoyLiveUndoOne = 1;//撤回一次 - ColorPinoyLiveUndoAll = 2; //撤回所有 -} -// 撤回 -message ColorPinoyLiveC2SUndoBet { - ColorPinoyLiveUndoType undoType = 1; -} -//撤回返回 -message S2CUndoBet { - ColorPinoyLiveUndoType undoType = 1; - repeated ColorPinoyLiveBetSuccessMessage betInfo = 2; - int64 UserScore = 3; //用户当前的分数 - int64 uid = 4; -} - -// 广播爆奖 -message ColorPinoyLiveNtfBigOddBetArea +message NotifyColorKickOutUser { - repeated ColorPinoyLiveGameBetAreaInfo betAreas = 1; // 下注结束后,每个区域更新是否爆奖 + ErrCode code = 1; // 踢出原因 } -message ColorPinoyLiveMainteNtf { - ColorPinoyLiveUserInfo userInfo = 1; - string maintMsg = 2;//维护消息 - int64 returnGold = 3;//返回金币 -} - -message ColorPinoyLiveS2CBetEndFailResult{ // 停止下注和平台扣钱 失败返回 - int32 code = 1; - repeated ColorPinoyLiveS2CRepetBet players = 2; -} - -message ColorPinoyLiveApplyPropsReq{ - int64 userId = 1;//使用者 uid - int64 acceptUserId = 2;//接受者uid - string propsId = 3;//道具id -} - -message ColorPinoyLivePlayerPropsResp{ - int64 applyUserId = 1;//发送者 - int64 acceptUserId = 2;//接受者 - string propsId = 3;//道具id - int64 chips = 4;//发送者使用道具后金币 -} - -message ColorPinoyLiveLeaveResp{ - int32 code = 1; // 0能离开 其他不能离开 - string msg = 2; -} - -// 广播主播名字 -message ColorPinoyLiveDealerName +// 系统维护或流局 +message NotifyColorMaintain { - repeated string dealerName = 1; // 主播名字 -} - - -//================================================================================================================================ - -message ColorPinoyLivePlayerData { - int64 uid = 1; - repeated int64 totalBets = 2; // 各区域投注 - int64 totalBet = 3; // 总投注 - int64 score = 4; // 总分 - int64 profit = 5; // 实际总盈利(需按照以小博大&破产逻辑计算并抽水) - int64 tax = 6; // 抽水 - int64 balance = 7; // 余额 - int64 wait_time = 8; // 等待开局时间 - int64 pre_balance = 9; // 开局余额 - repeated int64 userWins = 10; // 用户各区域赢钱 - repeated int64 userRealWins = 11; // 用户各区域真实赢钱 - int64 start_time = 12; - string nickname = 13; // 用户冗余数据,生产方不需要填入,由API查询写入 - string avatar = 14; // 用户冗余数据,生产方不需要填入,由API查询写入 - int64 trans_bet = 15; // 流水投注 - int64 trans_win = 16; // 流水获利 - int32 dev_mode = 17; // 用户属性 - repeated int64 odds = 18; // // 老版 投注区域倍率 todo - repeated int64 userBetsCount = 19; // 用户各区域下注次数 - int32 isDiscard = 20; // 是否废弃 0正常 1废弃 - repeated ColorPinoyLiveBetAreaOdd areaOdds = 21; // 投注区域倍率 -} -message ColorPinoyLiveDetail { - repeated int64 winDoubleColorMul = 1; // // 老版 胜利双色奖励倍率 todo - repeated int64 winSingleColorMul = 2; // // 老版 胜利单色奖励倍率 todo - int64 bonus = 3; // 幸运骰子加成 - repeated ColorPinoyLiveDiceColorType threeDice = 4; // 3个普通骰子 - ColorPinoyLiveDiceColorType luckyDice = 5; // // 老版 幸运骰子 todo - repeated ColorPinoyLiveDiceColorType startDice = 6; // 初始位置摆放的骰子 - repeated string resultImg = 7; // 结果图片 - repeated string dealerName = 8; // 主播名字 - repeated ColorPinoyLiveBetAreaOdd betAreaMul = 9; // 新版各区域的赔率 - int64 jackpotFunding = 10; // 本局jackpot系统垫资多少,没有垫资为0 - int64 jackpotX = 11; // 赎回比例(反应系统盈亏) - int64 jackpotY = 12; // 追加进jackpot池子比例 -} -// 对局详情 (游戏生产) -message ColorPinoyLiveEnd { - string game_no = 1; // 编号 - int64 start_time = 2; // 开始时间 - int64 end_time = 3; // 结束时间 - int32 level = 4; // 场次 - int64 base_bet = 5; // 底注 - repeated ColorPinoyLivePlayerData player_data = 6; // 玩家数据 - int64 tax_rate = 7; // 抽水比例 - int64 totalBet = 8; //投注总量 - repeated int64 totalBets = 9; //各区域投注总量 - int64 realSystemWin = 10; //系统输赢 - repeated int64 realSystemWins = 11; //各区域系统输赢 - int64 tax = 12; //抽水流水 - repeated ColorPinoyLiveBetTypeJP wins = 13; // 中奖区域 - string op_token = 14; // 平台 - ColorPinoyLiveDetail detail = 15; // 数据详情 - int32 isDiscard = 16; // 是否废弃 0正常 1废弃 -} - -//================================================================================================================================ -//游戏转态 ColorPinoyLiveGameStatus 客户端 0未开始 1准备 2开始 3下注 4结束下注 5开幸运骰子 6开三个骰子 7结算 8排行 -// 对后台 2,3 合并为一个阶段 3 下注阶段, 0忽略 最终 1准备 3 下注 4结束下注 5 开幸运骰子 6 开三个骰子 7 结算 8 排行 - -enum ColorPinoyLiveProcessCmd{ - ColorPinoyLiveVoid = 0; - ColorPinoyLiveMSGGameGetStatus = 300;//获取游戏状态 ColorPinoyLiveGetStatus - ColorPinoyLiveMSGReady = 301;//准备 空 - ColorPinoyLiveMSGBetting = 302;//开始下注 空 - ColorPinoyLiveMSGLucky = 303;//幸运星 ColorPinoyLiveLucky - ColorPinoyLiveMSGResult = 304;//游戏结果 ColorPinoyLiveResult - ColorPinoyLiveMSGSettle = 305;//结算 空 - ColorPinoyLiveMSGRank = 306;//排行榜 空 - ColorPinoyLiveMSGMMainteSet = 307;//维护状态 设置 ColorPinoyLiveMainte -> ColorPinoyLiveCommResp - ColorPinoyLiveMSGMDiscard = 308;//废弃 ColorPinoyLiveMainte -> ColorPinoyLiveCommResp - ColorPinoyLiveMSGMRankList = 309;//排行榜列表 空 ->ColorPinoyLiveRankList - ColorPinoyLiveMSGMEndBet = 310;//结束下注 空 - ColorPinoyLiveMSGMStartDice = 311;//初始位置摆放的骰子 - ColorPinoyLiveMSGMResultImg = 312;//结果图片 - ColorPinoyLiveMSGMSyncNotify = 400;//状态同步通知 - ColorPinoyLiveMSGMChat = 401; //聊天数据推送 - ColorPinoyLiveMSGLiveConfig = 402; //直播配置推送 - ColorPinoyLiveMSGSetDealer = 403; // 设置主播名 -} - -enum ColorPinoyLiveCmd{ - ColorPinoyLiveCmdMSGMRandomNext = 0; // 只用于控制点击NEXT按钮推进流程 -} - -enum ColorPinoyLiveProcessError{ - ColorPinoyLiveProcessErrorVoid =0; - ColorPinoyLiveProcessErrorGameSatus = 1;//游戏状态错误 - ColorPinoyLiveProcessErrorMainteStatus = 2;//维护状态错误 - ColorPinoyLiveProcessErrorDice = 3;//骰子错误 -} - -//通用返回 -message ColorPinoyLiveCommResp{ - int32 code = 1; - string msg = 2; - int32 gameId = 3; - int32 gameStatus = 4; // 当前游戏状态 - int64 countdown = 5; // 进入下一个阶段的毫秒时间戳 - int64 countdown2 = 6; // 进入下一个阶段的毫秒时间戳 - int32 maintainStatus = 7; // 维护状态 0 正常 1 维护 - string maintainMsg = 8; //维护消息 - ColorPinoyLiveDiceColorType luckyStar = 9; // 幸运星 - repeated ColorPinoyLiveDiceColorType drawResult = 10; // 开奖结果 - repeated int64 times = 11; - ColorPinoyLiveRankList rankList = 12; // 排行榜列表 - repeated ColorPinoyLiveDiceColorType startDice = 13; // 初始位置摆放的骰子 - repeated string resultImg = 14; // 结果图片 - bool randomNext = 15; // randomNext - string gameNo = 16; // 对局编号 - repeated string dealerName = 19; // 当前主播名字 - repeated ColorPinoyLiveGameBetAreaInfo betAreaMul = 20; // 新版各区域的赔率 - int64 jackpot = 30; // jackpot金额 -} -//GameGetStatus -message ColorPinoyLiveGetStatus{ - int32 gameId = 1; -} -//幸运星 -message ColorPinoyLiveLucky{ - ColorPinoyLiveDiceColorType Color = 1; -} -//游戏结果 -message ColorPinoyLiveResult{ - repeated ColorPinoyLiveDiceColorType Color = 1; -} -//初始位置摆放的骰子 -message ColorPinoyLiveStartDice{ - repeated ColorPinoyLiveDiceColorType startDice = 1; // 初始位置摆放的骰子 -} -//结果图片 -message ColorPinoyLiveResultImg{ - repeated string resultImg = 1; // 结果图片 - int32 stage = 2; // 控制台使用 1: random 2: lottery -} -// 维护状态设置 -message ColorPinoyLiveMaintain{ - int32 targetStatus = 1;// 维护状态 0 正常 1 维护 - string msg = 2;//维护消息 -} - -//排行榜列表 -message ColorPinoyLiveRankList{ - repeated ColorPinoyLivePlayerData player_data = 1; // 玩家数据 - string game_no = 2; // 编号 - int64 start_time = 3; // 开始时间 - int64 end_time = 4; // 结束时间 -} - -// 设置主播名字 -message ColorPinoyLiveSetDealer{ - repeated string dealerName = 1; // 主播名字 + string msg = 2; // 维护消息 + int64 gold = 3; // 玩家金币重置为该值 } diff --git a/server/colorgame/room/alive.go b/server/colorgame/room/alive.go index 04c8855..13bb3ce 100644 --- a/server/colorgame/room/alive.go +++ b/server/colorgame/room/alive.go @@ -1,518 +1,441 @@ package room -import ( - "encoding/json" - "game/common/proto/pb" - "github.com/fox/fox/log" -) +//import ( +// "encoding/json" +// "game/common/proto/pb" +// "github.com/fox/fox/log" +//) -// const ( -// LiveProcessInit = iota -// LiveProcessStart -// LiveProcessWait -// LiveProcessWaitDone -// LiveProcessFuncStart -// LiveProcessFuncDone -// ) // -// var LiveProcessStatusName = map[int]string{ -// LiveProcessInit: "LiveProcessInit", -// LiveProcessStart: "LiveProcessStart", -// LiveProcessWait: "LiveProcessWait", -// LiveProcessWaitDone: "LiveProcessWaitDone", -// LiveProcessFuncStart: "LiveProcessFuncStart", -// LiveProcessFuncDone: "LiveProcessFuncDone", -// } - -type LiveMgr struct { - // LiveWg *sync.WaitGroup - // Count int // 当前数量 - // Mu *sync.Mutex - MaintenanceStatus int32 // 维护状态 0 正常 1 维护 - // ProcessStatus int // 进程状态 - Restting bool // 重置状态 - MainteMsg string - DiscardMsg string - DiscardStatus int - DiscardRestting bool // 重置状态 - RankList *pb.ColorPinoyLiveRankList - HasMainte bool -} - -func NewLiveMgr() *LiveMgr { - return &LiveMgr{ - // LiveWg: new(sync.WaitGroup), - // Mu: new(sync.Mutex), - RankList: new(pb.ColorPinoyLiveRankList), - } -} - -func (lm *LiveMgr) Reset() { - lm.Restting = false - lm.DiscardRestting = false - lm.DiscardStatus = 0 -} - -// func (lm *LiveMgr) IsAdd() bool { -// lm.Mu.Lock() -// defer lm.Mu.Unlock() -// return lm.Count > 0 -// } // -// func (lm *LiveMgr) Add() { -// log.Debug("LiveMgr add") -// lm.Mu.Lock() -// defer lm.Mu.Unlock() -// lm.LiveWg.Add(1) -// lm.Count++ -// } +//type LiveMgr struct { +// // LiveWg *sync.WaitGroup +// // Count int // 当前数量 +// // Mu *sync.Mutex +// MaintenanceStatus int32 // 维护状态 0 正常 1 维护 +// // ProcessStatus int // 进程状态 +// Restting bool // 重置状态 +// MainteMsg string +// DiscardMsg string +// DiscardStatus int +// DiscardRestting bool // 重置状态 +// RankList *pb.ColorPinoyLiveRankList +// HasMainte bool +//} // -// func (lm *LiveMgr) Done() { -// log.Debug("LiveMgr Done") -// lm.Mu.Lock() -// defer lm.Mu.Unlock() -// if lm.Count == 0 { -// return -// } -// lm.LiveWg.Done() -// lm.Count-- -// } +//func NewLiveMgr() *LiveMgr { +// return &LiveMgr{ +// // LiveWg: new(sync.WaitGroup), +// // Mu: new(sync.Mutex), +// RankList: new(pb.ColorPinoyLiveRankList), +// } +//} // -// func (lm *LiveMgr) Wait() { -// log.Debug("LiveMgr Wait") -// lm.LiveWg.Wait() -// } - -func (lm *LiveMgr) NeedMaintenance() bool { - return !lm.HasMainte && (lm.MaintenanceStatus == 1 || lm.DiscardStatus == 1) -} - -func (rm *ColorRoom) LiveDelayUpdate() error { - event := &events.ServCmdKafka{ - ServCmd: common.ServCmd_sc_live_delay_update, - } - data := &common.ServLiveDelayUpdate{ - GameId: gconfig.GConfig.GRoomConfig.GameId, - MainteStatus: rm.LiveMgr.MaintenanceStatus, - MainteMsg: rm.LiveMgr.MainteMsg, - } - event.Data, _ = proto.Marshal(data) - err := gconfig.Produce(context.Background(), define.TopicSysServerCmd, event) - if err != nil { - log.Error(rm.Log("fail to Produce Event(%+v), err: %v", event, err)) - return err - } - return nil -} - -func (rm *ColorRoom) NotifyLiveDelayUpdate() { - if !gconfig.DelayUpdateServer { - return - } - if rm.LiveDelayUpdate() != nil { - return - } - gconfig.DelayUpdateServer = false -} - -func (rm *ColorRoom) ServerMaintenanceKickPlayer() { - rm.Traverse(func(u *model.User) bool { - kMsg := new(pb.ColorPinoyLiveKickOutUserMsg) - kMsg.Reason = int32(pb.ColorPinoyLiveLeaveReason_ColorPinoyLiveLeaveReason_Server_Update) - u.SendMsg(int32(pb.ColorPinoyLiveSendToClientMessageType_ColorPinoyLiveNoticeKickOutUser), kMsg) - rm.KickOutUser(u) - return true - }) -} - -func (rm *ColorRoom) SyncServerMaintenance(st int32, ss string) { - _ = st - _ = ss - rm.LoadDealerNames() - // 可能即将变为 normal - if gconfig.GConfig.GServConfig.Status != define.GameStatusNoraml { - rm.LiveMgr.MaintenanceStatus = 0 - rm.LiveMgr.MainteMsg = "" - return - } - ssv := redisf.RSC.LiveMainteGet(gconfig.GConfig.GDataConfig.VersionMode, gconfig.GConfig.GRoomConfig.GameId) - resp := new(pb.ColorPinoyLiveCommResp) - _ = json.Unmarshal([]byte(ssv), resp) - rm.LiveMgr.MaintenanceStatus = resp.MaintainStatus - rm.LiveMgr.MainteMsg = resp.MaintainMsg - -} - -func (rm *ColorRoom) OnLiveGameMessage(subCmd int32, buffer []byte) ([]byte, error) { - // log.Debug("收到后台消息:", subCmd) - var result proto.Message - _, err := rm.Table.RunAndWait(func() any { - switch subCmd { - case int32(pb.ColorPinoyLiveProcessCmd_ColorPinoyLiveMSGGameGetStatus): - result = rm.LiveGetGameStatus(buffer) - case int32(pb.ColorPinoyLiveProcessCmd_ColorPinoyLiveMSGReady): - result = rm.LiveGameReady(buffer) // 点击finish - case int32(pb.ColorPinoyLiveProcessCmd_ColorPinoyLiveMSGBetting): - result = rm.LiveGameBetting(buffer) // 点击start - case int32(pb.ColorPinoyLiveProcessCmd_ColorPinoyLiveMSGMStartDice): - result = rm.LiveGameStartDice(buffer) - case int32(pb.ColorPinoyLiveProcessCmd_ColorPinoyLiveMSGMResultImg): - result = rm.LiveGameResultImg(buffer) - // case int32(pb.ColorPinoyLiveProcessCmd_ColorPinoyLiveMSGLucky): - // result = rm.LiveGameLucky(buffer) - case int32(pb.ColorPinoyLiveProcessCmd_ColorPinoyLiveMSGResult): - result = rm.LiveGameResult(buffer) - case int32(pb.ColorPinoyLiveProcessCmd_ColorPinoyLiveMSGMMainteSet): - result = rm.LiveGameMainte(buffer) - case int32(pb.ColorPinoyLiveProcessCmd_ColorPinoyLiveMSGMDiscard): - result = rm.LiveGameDiscard(buffer) - case int32(pb.ColorPinoyLiveProcessCmd_ColorPinoyLiveMSGMRankList): - result = rm.LiveGameRankList(buffer) - case int32(pb.ColorPinoyLiveProcessCmd_ColorPinoyLiveMSGSetDealer): - result = rm.LiveGameSetDealerName(buffer) - default: - log.Error(rm.Log("no protocol")) - return nil - } - return result - }) - if err == nil && result != nil { - b, _ := proto.Marshal(result) - canLog := true - if subCmd == int32(pb.ColorPinoyLiveProcessCmd_ColorPinoyLiveMSGGameGetStatus) { - if rd := rand.RandInt(0, 100); rd < 90 { - canLog = false - } - } - if canLog { - j, _ := json.Marshal(result) - log.Debug(rm.Log("返回后台消息 subCmd:%d, msg:%s", subCmd, string(j))) - } - return b, nil - } - return nil, err -} - -func (rm *ColorRoom) getStatus() (int32, int64) { - switch rm.Status { - case pb.ColorPinoyLiveGameStatus_ColorPinoyLiveStartUnReady: - return int32(rm.Status), rm.StatusTime + int64(rm.RoomCfg.TimeConf.Readymove) - case pb.ColorPinoyLiveGameStatus_ColorPinoyLiveStartReady: - return int32(rm.Status), rm.StatusTime + int64(rm.RoomCfg.TimeConf.Startmove) - case pb.ColorPinoyLiveGameStatus_ColorPinoyLiveStartMovie: - return int32(pb.ColorPinoyLiveGameStatus_ColorPinoyLiveBetStatus), rm.StatusTime + int64(rm.RoomCfg.TimeConf.Startbet) - case pb.ColorPinoyLiveGameStatus_ColorPinoyLiveBetStatus: - return int32(rm.Status), rm.StatusTime + int64(rm.RoomCfg.TimeConf.Startbet) - case pb.ColorPinoyLiveGameStatus_ColorPinoyLiveEndBetMovie: - return int32(rm.Status), rm.StatusTime + int64(rm.RoomCfg.TimeConf.Endmove) - case pb.ColorPinoyLiveGameStatus_ColorPinoyLiveOpenThreeDice: - return int32(rm.Status), rm.StatusTime + int64(rm.RoomCfg.TimeConf.OpenThreeDice) - case pb.ColorPinoyLiveGameStatus_ColorPinoyLiveSettleStatus: - return int32(rm.Status), rm.StatusTime + int64(rm.RoomCfg.TimeConf.Endpay) - case pb.ColorPinoyLiveGameStatus_ColorPinoyLiveRankStatus: - return int32(rm.Status), rm.StatusTime + int64(rm.RoomCfg.TimeConf.Rank) - default: - return int32(rm.Status), rm.StatusTime - } -} - -func (rm *ColorRoom) LiveStatus() *pb.ColorPinoyLiveCommResp { - resp := &pb.ColorPinoyLiveCommResp{ - GameId: gconfig.GConfig.GRoomConfig.GameId, - MaintainStatus: rm.LiveMgr.MaintenanceStatus, - MaintainMsg: rm.LiveMgr.MainteMsg, - Times: rm.RoomCfg.TimeConf.Get(), - GameNo: rm.Table.GetGameRoundId(), - DealerName: rm.dealerName, - Jackpot: rm.jackpotMgr.GetJackpotCopy(), - } - resp.GameStatus, resp.Countdown = rm.getStatus() - resp.BetAreaMul = rm.betEndBetAreasOdds - for _, dice := range rm.StartDices { - resp.StartDice = append(resp.StartDice, pb.ColorPinoyLiveDiceColorType(model.GetColor(dice))) - } - resp.ResultImg = rm.ResultImgs - switch rm.Status { - case pb.ColorPinoyLiveGameStatus_ColorPinoyLiveOpenThreeDice: - resp.LuckyStar = pb.ColorPinoyLiveDiceColorType(model.GetColor(rm.LuckyDice)) - for _, dice := range rm.NormalDices { - resp.DrawResult = append(resp.DrawResult, pb.ColorPinoyLiveDiceColorType(model.GetColor(dice))) - } - case pb.ColorPinoyLiveGameStatus_ColorPinoyLiveSettleStatus, pb.ColorPinoyLiveGameStatus_ColorPinoyLiveRankStatus: - resp.LuckyStar = pb.ColorPinoyLiveDiceColorType(model.GetColor(rm.LuckyDice)) - for _, dice := range rm.NormalDices { - resp.DrawResult = append(resp.DrawResult, pb.ColorPinoyLiveDiceColorType(model.GetColor(dice))) - } - resp.RankList = rm.LiveMgr.RankList - default: - } - // 结束下注后,后台可看到更新爆奖后的投注面板 - if rm.Status > pb.ColorPinoyLiveGameStatus_ColorPinoyLiveBetStatus { - resp.BetAreaMul = rm.betEndBetAreasOdds - } - return resp -} - -func (rm *ColorRoom) LiveGetGameStatus(buffer []byte) proto.Message { - _ = buffer - return rm.LiveStatus() -} - -func (rm *ColorRoom) LiveGameReady(buffer []byte) proto.Message { - _ = buffer - log.Debug(rm.Log("LiveGameReady")) - // rm.MutexStatus.Lock() - // defer rm.MutexStatus.Unlock() - resp := rm.LiveStatus() - if rm.LiveMgr.MaintenanceStatus == 1 { - resp.Code = int32(pb.ColorPinoyLiveProcessError_ColorPinoyLiveProcessErrorMainteStatus) - return resp - } - if rm.Status != pb.ColorPinoyLiveGameStatus_ColorPinoyLiveRankStatus { - resp.Code = int32(pb.ColorPinoyLiveProcessError_ColorPinoyLiveProcessErrorGameSatus) - return resp - } - rm.Ready() - resp.GameStatus, resp.Countdown = rm.getStatus() - return resp -} - -func (rm *ColorRoom) LiveGameBetting(buffer []byte) proto.Message { - _ = buffer - log.Debug(rm.Log("LiveGameBetting")) - // rm.MutexStatus.Lock() - // defer rm.MutexStatus.Unlock() - resp := rm.LiveStatus() - if rm.LiveMgr.MaintenanceStatus == 1 { - resp.Code = int32(pb.ColorPinoyLiveProcessError_ColorPinoyLiveProcessErrorMainteStatus) - return resp - } - if rm.Status != pb.ColorPinoyLiveGameStatus_ColorPinoyLiveStartReady { - resp.Code = int32(pb.ColorPinoyLiveProcessError_ColorPinoyLiveProcessErrorGameSatus) - return resp - } - - rm.StartBet() - return resp -} - -func (rm *ColorRoom) LiveGameStartDice(buffer []byte) proto.Message { - log.Debug(rm.Log("LiveGameStartDice")) - resp := rm.LiveStatus() - if rm.LiveMgr.MaintenanceStatus == 1 { - resp.Code = int32(pb.ColorPinoyLiveProcessError_ColorPinoyLiveProcessErrorMainteStatus) - return resp - } - if rm.Status != pb.ColorPinoyLiveGameStatus_ColorPinoyLiveEndBetMovie { - resp.Code = int32(pb.ColorPinoyLiveProcessError_ColorPinoyLiveProcessErrorGameSatus) - return resp - } - req := new(pb.ColorPinoyLiveStartDice) - _ = proto.Unmarshal(buffer, req) - if len(req.GetStartDice()) != 3 { - resp.Code = int32(pb.ColorPinoyLiveProcessError_ColorPinoyLiveProcessErrorDice) - return resp - } - for i := 0; i < len(req.GetStartDice()); i++ { - rm.StartDices[i] = byte(req.GetStartDice()[i]) - } - log.Debug(rm.Log("req:", req.GetStartDice(), ",StartDice:", rm.StartDices)) - resp.StartDice = make([]pb.ColorPinoyLiveDiceColorType, 0) - for _, dice := range rm.StartDices { - resp.StartDice = append(resp.StartDice, pb.ColorPinoyLiveDiceColorType(model.GetColor(dice))) - } - resp.ResultImg = rm.ResultImgs - return resp -} - -func (rm *ColorRoom) LiveGameResultImg(buffer []byte) proto.Message { - resp := rm.LiveStatus() - if rm.LiveMgr.MaintenanceStatus == 1 { - resp.Code = int32(pb.ColorPinoyLiveProcessError_ColorPinoyLiveProcessErrorMainteStatus) - return resp - } - req := new(pb.ColorPinoyLiveResultImg) - _ = proto.Unmarshal(buffer, req) - rm.ResultImgs = append(rm.ResultImgs, req.GetResultImg()...) - log.Debug(rm.Log("req:", req.GetResultImg(), ",ResultImg:", rm.ResultImgs)) - resp.StartDice = make([]pb.ColorPinoyLiveDiceColorType, 0) - for _, dice := range rm.StartDices { - resp.StartDice = append(resp.StartDice, pb.ColorPinoyLiveDiceColorType(model.GetColor(dice))) - } - resp.ResultImg = rm.ResultImgs - return resp -} - -func (rm *ColorRoom) LiveGameResult(buffer []byte) proto.Message { - // rm.MutexStatus.Lock() - // defer rm.MutexStatus.Unlock() - log.Debug(rm.Log("LiveGameResult")) - resp := rm.LiveStatus() - if rm.LiveMgr.MaintenanceStatus == 1 { - resp.Code = int32(pb.ColorPinoyLiveProcessError_ColorPinoyLiveProcessErrorMainteStatus) - return resp - } - log.Debug(rm.Log("LiveGameResult status:%v ", rm.Status)) - if rm.Status != pb.ColorPinoyLiveGameStatus_ColorPinoyLiveEndBetMovie { - resp.Code = int32(pb.ColorPinoyLiveProcessError_ColorPinoyLiveProcessErrorGameSatus) - return resp - } - req := new(pb.ColorPinoyLiveResult) - _ = proto.Unmarshal(buffer, req) - if len(req.GetColor()) != 3 { - resp.Code = int32(pb.ColorPinoyLiveProcessError_ColorPinoyLiveProcessErrorDice) - return resp - } else { - for i := 0; i < len(req.GetColor()); i++ { - if !model.IsLogic(int32(req.GetColor()[i])) { - resp.Code = int32(pb.ColorPinoyLiveProcessError_ColorPinoyLiveProcessErrorDice) - return resp - } - rm.NormalDices[i] = byte(req.GetColor()[i]) - } - } - log.Debug(rm.Log("LiveGameResult req:%v NormalDices:%v", req.GetColor(), rm.NormalDices)) - - rm.Table.Run(rm.openThreeDice) - return resp -} - -func (rm *ColorRoom) LiveGameMainte(buffer []byte) proto.Message { - req := new(pb.ColorPinoyLiveMaintain) - _ = proto.Unmarshal(buffer, req) - b, _ := json.Marshal(req) - log.Debug(rm.Log("LiveGameMainte:%v", string(b))) - resp := rm.LiveStatus() - if rm.LiveMgr.Restting { - resp.Code = int32(pb.ColorPinoyLiveProcessError_ColorPinoyLiveProcessErrorMainteStatus) - resp.Msg = "Restting" - return resp - } - if req.TargetStatus == rm.LiveMgr.MaintenanceStatus { - resp.Code = int32(pb.ColorPinoyLiveProcessError_ColorPinoyLiveProcessErrorMainteStatus) - return resp - } - if rm.GetGameStatus() == pb.ColorPinoyLiveGameStatus_ColorPinoyLiveSettleStatus { - resp.Code = int32(pb.ColorPinoyLiveProcessError_ColorPinoyLiveProcessErrorGameSatus) - resp.Msg = "SettleStatus" - return resp - } - defer func() { - _ = pushGate.NotifyConfigUpdated(msg.ConfigUpdateType_ConfigUpdateTypeLiveConfig) - rm.SetLiveGameStatus() - }() - if req.TargetStatus == 0 { - rm.LiveMgr.MaintenanceStatus = 0 - rm.LiveMgr.MainteMsg = "" - rm.LiveMgr.HasMainte = false - } else { - rm.LiveMgr.MaintenanceStatus = req.TargetStatus - rm.LiveMgr.MainteMsg = req.GetMsg() - rm.LiveMainteCnt() - } - resp.MaintainStatus = rm.LiveMgr.MaintenanceStatus - resp.MaintainMsg = rm.LiveMgr.MainteMsg - resp.GameStatus, resp.Countdown = rm.getStatus() - br, _ := json.Marshal(resp) - redisf.RSC.LiveMainteSet(gconfig.GConfig.GDataConfig.VersionMode, gconfig.GConfig.GRoomConfig.GameId, string(br)) - redisf.RSC.LiveMainteLobbySet(gconfig.GConfig.GDataConfig.VersionMode, gconfig.GConfig.GRoomConfig.GameId, rm.LiveMgr.MaintenanceStatus, rm.LiveMgr.MainteMsg) - return resp -} - -func (rm *ColorRoom) LiveMainteCnt() { - rm.LiveMainte() -} - -func (rm *ColorRoom) LiveMainte() { - if rm.LiveMgr.MaintenanceStatus == 1 { - rm.LiveMgr.HasMainte = true - rm.LiveMgr.Restting = true - } - if rm.LiveMgr.DiscardStatus == 1 { - rm.LiveMgr.DiscardRestting = true - } - rm.GameDiscard() - // rm.LiveMgr.SetProcessStatus(LiveProcessInit) - if rm.LiveMgr.MaintenanceStatus == 1 { - rm.LiveMgr.Restting = false - } - if rm.LiveMgr.DiscardStatus == 1 { - rm.LiveMgr.DiscardRestting = false - rm.LiveMgr.DiscardStatus = 0 - } -} - -func (rm *ColorRoom) LiveGameDiscard(_ []byte) proto.Message { - log.Debug(rm.Log("LiveGameDiscard")) - resp := rm.LiveStatus() - if rm.LiveMgr.MaintenanceStatus == 1 { - log.Error(rm.Log("rm.LiveMgr.MaintenanceStatus")) - resp.Code = int32(pb.ColorPinoyLiveProcessError_ColorPinoyLiveProcessErrorMainteStatus) - return resp - } - if rm.LiveMgr.DiscardRestting { - resp.Code = int32(pb.ColorPinoyLiveProcessError_ColorPinoyLiveProcessErrorMainteStatus) - resp.Msg = "DiscardRestting" - return resp - } - // if rm.GetGameStatus() == pb.ColorPinoyLiveGameStatus_ColorPinoyLiveSettleStatus { - // resp.Code = int32(pb.ColorPinoyLiveProcessError_ColorPinoyLiveProcessErrorGameSatus) - // resp.Msg = "SettleStatus" - // return resp - // } - rm.LiveMgr.DiscardStatus = 1 - rm.LiveMgr.DiscardMsg = "" - rm.LiveMainteCnt() - resp.GameStatus, resp.Countdown = rm.getStatus() - return resp -} -func (rm *ColorRoom) LiveGameRankList(buffer []byte) proto.Message { - _ = buffer - return rm.LiveMgr.RankList -} - -func (rm *ColorRoom) LiveGameSetDealerName(buffer []byte) proto.Message { - resp := rm.LiveStatus() - if rm.LiveMgr.MaintenanceStatus == 1 { - resp.Code = int32(pb.ColorPinoyLiveProcessError_ColorPinoyLiveProcessErrorMainteStatus) - return resp - } - req := new(pb.ColorPinoyLiveSetDealer) - _ = proto.Unmarshal(buffer, req) - rm.UpdateDealerName(req.DealerName) - log.Debug(rm.Log("set dealer:", req.DealerName)) - resp.DealerName = rm.dealerName - return resp -} - -// 长度0 维护, 长度1 设置状态 , 长度2 设置排行榜 -func (rm *ColorRoom) SetLiveGameStatus(pushRank ...int) { - lScene := &lws.CPLScene{ - Status: int32(rm.Status), - RankList: nil, - MaintainStatus: rm.LiveMgr.MaintenanceStatus, - } - if rm.LiveMgr.RankList != nil && - (rm.Status == pb.ColorPinoyLiveGameStatus_ColorPinoyLiveSettleStatus || rm.Status == pb.ColorPinoyLiveGameStatus_ColorPinoyLiveRankStatus) { - lScene.RankList = &lws.CPLRankList{ - PlayerData: nil, - GameNo: rm.LiveMgr.RankList.GameNo, - } - for _, dd := range rm.LiveMgr.RankList.PlayerData { - lScene.RankList.PlayerData = append(lScene.RankList.PlayerData, &lws.CPLPlayerData{ - Uid: dd.Uid, - Profit: dd.Profit, - Nickname: dd.Nickname, - Avatar: dd.Avatar, - }) - } - } - if len(pushRank) == 0 { - live.PushScene(lScene) - } else if len(pushRank) == 1 { - live.PushStatus(&lws.CPLStatus{Status: lScene.Status}) - } else if len(pushRank) == 2 { - live.PushColorRank(lScene.RankList) - } - go redisf.RSC.SetLiveGameStatus(lScene, gconfig.GConfig.GRoomConfig.GameId, gconfig.GConfig.GDataConfig.VersionMode) -} +//func (lm *LiveMgr) Reset() { +// lm.Restting = false +// lm.DiscardRestting = false +// lm.DiscardStatus = 0 +//} +// +// +//func (lm *LiveMgr) NeedMaintenance() bool { +// return !lm.HasMainte && (lm.MaintenanceStatus == 1 || lm.DiscardStatus == 1) +//} +// +//func (rm *ColorRoom) LiveDelayUpdate() error { +// event := &events.ServCmdKafka{ +// ServCmd: common.ServCmd_sc_live_delay_update, +// } +// data := &common.ServLiveDelayUpdate{ +// GameId: gconfig.GConfig.GRoomConfig.GameId, +// MainteStatus: rm.LiveMgr.MaintenanceStatus, +// MainteMsg: rm.LiveMgr.MainteMsg, +// } +// event.Data, _ = proto.Marshal(data) +// err := gconfig.Produce(context.Background(), define.TopicSysServerCmd, event) +// if err != nil { +// log.Error(rm.Log("fail to Produce Event(%+v), err: %v", event, err)) +// return err +// } +// return nil +//} +// +//func (rm *ColorRoom) NotifyLiveDelayUpdate() { +// if !gconfig.DelayUpdateServer { +// return +// } +// if rm.LiveDelayUpdate() != nil { +// return +// } +// gconfig.DelayUpdateServer = false +//} +// +//func (rm *ColorRoom) ServerMaintenanceKickPlayer() { +// rm.Traverse(func(u *model.User) bool { +// kMsg := new(pb.ColorPinoyLiveKickOutUserMsg) +// kMsg.Reason = int32(pb.ColorPinoyLiveLeaveReason_ColorPinoyLiveLeaveReason_Server_Update) +// u.SendMsg(int32(pb.ColorPinoyLiveSendToClientMessageType_ColorPinoyLiveNoticeKickOutUser), kMsg) +// rm.KickOutUser(u) +// return true +// }) +//} +// +//func (rm *ColorRoom) SyncServerMaintenance(st int32, ss string) { +// _ = st +// _ = ss +// rm.LoadDealerNames() +// // 可能即将变为 normal +// if gconfig.GConfig.GServConfig.Status != define.GameStatusNoraml { +// rm.LiveMgr.MaintenanceStatus = 0 +// rm.LiveMgr.MainteMsg = "" +// return +// } +// ssv := redisf.RSC.LiveMainteGet(gconfig.GConfig.GDataConfig.VersionMode, gconfig.GConfig.GRoomConfig.GameId) +// resp := new(pb.ColorPinoyLiveCommResp) +// _ = json.Unmarshal([]byte(ssv), resp) +// rm.LiveMgr.MaintenanceStatus = resp.MaintainStatus +// rm.LiveMgr.MainteMsg = resp.MaintainMsg +// +//} +// +//func (rm *ColorRoom) OnLiveGameMessage(subCmd int32, buffer []byte) ([]byte, error) { +// // log.Debug("收到后台消息:", subCmd) +// var result proto.Message +// _, err := rm.Table.RunAndWait(func() any { +// switch subCmd { +// case int32(pb.ColorPinoyLiveProcessCmd_ColorPinoyLiveMSGGameGetStatus): +// result = rm.LiveGetGameStatus(buffer) +// case int32(pb.ColorPinoyLiveProcessCmd_ColorPinoyLiveMSGReady): +// result = rm.LiveGameReady(buffer) // 点击finish +// case int32(pb.ColorPinoyLiveProcessCmd_ColorPinoyLiveMSGBetting): +// result = rm.LiveGameBetting(buffer) // 点击start +// case int32(pb.ColorPinoyLiveProcessCmd_ColorPinoyLiveMSGMStartDice): +// result = rm.LiveGameStartDice(buffer) +// case int32(pb.ColorPinoyLiveProcessCmd_ColorPinoyLiveMSGMResultImg): +// result = rm.LiveGameResultImg(buffer) +// // case int32(pb.ColorPinoyLiveProcessCmd_ColorPinoyLiveMSGLucky): +// // result = rm.LiveGameLucky(buffer) +// case int32(pb.ColorPinoyLiveProcessCmd_ColorPinoyLiveMSGResult): +// result = rm.LiveGameResult(buffer) +// case int32(pb.ColorPinoyLiveProcessCmd_ColorPinoyLiveMSGMMainteSet): +// result = rm.LiveGameMainte(buffer) +// case int32(pb.ColorPinoyLiveProcessCmd_ColorPinoyLiveMSGMDiscard): +// result = rm.LiveGameDiscard(buffer) +// case int32(pb.ColorPinoyLiveProcessCmd_ColorPinoyLiveMSGMRankList): +// result = rm.LiveGameRankList(buffer) +// case int32(pb.ColorPinoyLiveProcessCmd_ColorPinoyLiveMSGSetDealer): +// result = rm.LiveGameSetDealerName(buffer) +// default: +// log.Error(rm.Log("no protocol")) +// return nil +// } +// return result +// }) +// if err == nil && result != nil { +// b, _ := proto.Marshal(result) +// canLog := true +// if subCmd == int32(pb.ColorPinoyLiveProcessCmd_ColorPinoyLiveMSGGameGetStatus) { +// if rd := rand.RandInt(0, 100); rd < 90 { +// canLog = false +// } +// } +// if canLog { +// j, _ := json.Marshal(result) +// log.Debug(rm.Log("返回后台消息 subCmd:%d, msg:%s", subCmd, string(j))) +// } +// return b, nil +// } +// return nil, err +//} +// +//func (rm *ColorRoom) getStatus() (int32, int64) { +// switch rm.Status { +// case pb.ColorPinoyLiveGameStatus_ColorPinoyLiveStartUnReady: +// return int32(rm.Status), rm.StatusTime + int64(rm.RoomCfg.TimeConf.Readymove) +// case pb.ColorPinoyLiveGameStatus_ColorPinoyLiveStartReady: +// return int32(rm.Status), rm.StatusTime + int64(rm.RoomCfg.TimeConf.Startmove) +// case pb.ColorPinoyLiveGameStatus_ColorPinoyLiveStartMovie: +// return int32(pb.ColorPinoyLiveGameStatus_ColorPinoyLiveBetStatus), rm.StatusTime + int64(rm.RoomCfg.TimeConf.Startbet) +// case pb.ColorPinoyLiveGameStatus_ColorPinoyLiveBetStatus: +// return int32(rm.Status), rm.StatusTime + int64(rm.RoomCfg.TimeConf.Startbet) +// case pb.ColorPinoyLiveGameStatus_ColorPinoyLiveEndBetMovie: +// return int32(rm.Status), rm.StatusTime + int64(rm.RoomCfg.TimeConf.Endmove) +// case pb.ColorPinoyLiveGameStatus_ColorPinoyLiveOpenThreeDice: +// return int32(rm.Status), rm.StatusTime + int64(rm.RoomCfg.TimeConf.OpenThreeDice) +// case pb.ColorPinoyLiveGameStatus_ColorPinoyLiveSettleStatus: +// return int32(rm.Status), rm.StatusTime + int64(rm.RoomCfg.TimeConf.Endpay) +// case pb.ColorPinoyLiveGameStatus_ColorPinoyLiveRankStatus: +// return int32(rm.Status), rm.StatusTime + int64(rm.RoomCfg.TimeConf.Rank) +// default: +// return int32(rm.Status), rm.StatusTime +// } +//} +// +//func (rm *ColorRoom) LiveStatus() *pb.ColorPinoyLiveCommResp { +// resp := &pb.ColorPinoyLiveCommResp{ +// GameId: gconfig.GConfig.GRoomConfig.GameId, +// MaintainStatus: rm.LiveMgr.MaintenanceStatus, +// MaintainMsg: rm.LiveMgr.MainteMsg, +// Times: rm.RoomCfg.TimeConf.Get(), +// GameNo: rm.Table.GetGameRoundId(), +// DealerName: rm.dealerName, +// Jackpot: rm.jackpotMgr.GetJackpotCopy(), +// } +// resp.GameStatus, resp.Countdown = rm.getStatus() +// resp.BetAreaMul = rm.betEndBetAreasOdds +// for _, dice := range rm.StartDices { +// resp.StartDice = append(resp.StartDice, pb.ColorPinoyLiveDiceColorType(model.GetColor(dice))) +// } +// resp.ResultImg = rm.ResultImgs +// switch rm.Status { +// case pb.ColorPinoyLiveGameStatus_ColorPinoyLiveOpenThreeDice: +// resp.LuckyStar = pb.ColorPinoyLiveDiceColorType(model.GetColor(rm.LuckyDice)) +// for _, dice := range rm.NormalDices { +// resp.DrawResult = append(resp.DrawResult, pb.ColorPinoyLiveDiceColorType(model.GetColor(dice))) +// } +// case pb.ColorPinoyLiveGameStatus_ColorPinoyLiveSettleStatus, pb.ColorPinoyLiveGameStatus_ColorPinoyLiveRankStatus: +// resp.LuckyStar = pb.ColorPinoyLiveDiceColorType(model.GetColor(rm.LuckyDice)) +// for _, dice := range rm.NormalDices { +// resp.DrawResult = append(resp.DrawResult, pb.ColorPinoyLiveDiceColorType(model.GetColor(dice))) +// } +// resp.RankList = rm.LiveMgr.RankList +// default: +// } +// // 结束下注后,后台可看到更新爆奖后的投注面板 +// if rm.Status > pb.ColorPinoyLiveGameStatus_ColorPinoyLiveBetStatus { +// resp.BetAreaMul = rm.betEndBetAreasOdds +// } +// return resp +//} +// +//func (rm *ColorRoom) LiveGetGameStatus(buffer []byte) proto.Message { +// _ = buffer +// return rm.LiveStatus() +//} +// +//func (rm *ColorRoom) LiveGameReady(buffer []byte) proto.Message { +// _ = buffer +// log.Debug(rm.Log("LiveGameReady")) +// // rm.MutexStatus.Lock() +// // defer rm.MutexStatus.Unlock() +// resp := rm.LiveStatus() +// if rm.LiveMgr.MaintenanceStatus == 1 { +// resp.Code = int32(pb.ColorPinoyLiveProcessError_ColorPinoyLiveProcessErrorMainteStatus) +// return resp +// } +// if rm.Status != pb.ColorPinoyLiveGameStatus_ColorPinoyLiveRankStatus { +// resp.Code = int32(pb.ColorPinoyLiveProcessError_ColorPinoyLiveProcessErrorGameSatus) +// return resp +// } +// rm.Ready() +// resp.GameStatus, resp.Countdown = rm.getStatus() +// return resp +//} +// +//func (rm *ColorRoom) LiveGameBetting(buffer []byte) proto.Message { +// _ = buffer +// log.Debug(rm.Log("LiveGameBetting")) +// // rm.MutexStatus.Lock() +// // defer rm.MutexStatus.Unlock() +// resp := rm.LiveStatus() +// if rm.LiveMgr.MaintenanceStatus == 1 { +// resp.Code = int32(pb.ColorPinoyLiveProcessError_ColorPinoyLiveProcessErrorMainteStatus) +// return resp +// } +// if rm.Status != pb.ColorPinoyLiveGameStatus_ColorPinoyLiveStartReady { +// resp.Code = int32(pb.ColorPinoyLiveProcessError_ColorPinoyLiveProcessErrorGameSatus) +// return resp +// } +// +// rm.StartBet() +// return resp +//} +// +//func (rm *ColorRoom) LiveGameStartDice(buffer []byte) proto.Message { +// log.Debug(rm.Log("LiveGameStartDice")) +// resp := rm.LiveStatus() +// if rm.LiveMgr.MaintenanceStatus == 1 { +// resp.Code = int32(pb.ColorPinoyLiveProcessError_ColorPinoyLiveProcessErrorMainteStatus) +// return resp +// } +// if rm.Status != pb.ColorPinoyLiveGameStatus_ColorPinoyLiveEndBetMovie { +// resp.Code = int32(pb.ColorPinoyLiveProcessError_ColorPinoyLiveProcessErrorGameSatus) +// return resp +// } +// req := new(pb.ColorPinoyLiveStartDice) +// _ = proto.Unmarshal(buffer, req) +// if len(req.GetStartDice()) != 3 { +// resp.Code = int32(pb.ColorPinoyLiveProcessError_ColorPinoyLiveProcessErrorDice) +// return resp +// } +// for i := 0; i < len(req.GetStartDice()); i++ { +// rm.StartDices[i] = byte(req.GetStartDice()[i]) +// } +// log.Debug(rm.Log("req:", req.GetStartDice(), ",StartDice:", rm.StartDices)) +// resp.StartDice = make([]pb.ColorPinoyLiveDiceColorType, 0) +// for _, dice := range rm.StartDices { +// resp.StartDice = append(resp.StartDice, pb.ColorPinoyLiveDiceColorType(model.GetColor(dice))) +// } +// resp.ResultImg = rm.ResultImgs +// return resp +//} +// +//func (rm *ColorRoom) LiveGameResultImg(buffer []byte) proto.Message { +// resp := rm.LiveStatus() +// if rm.LiveMgr.MaintenanceStatus == 1 { +// resp.Code = int32(pb.ColorPinoyLiveProcessError_ColorPinoyLiveProcessErrorMainteStatus) +// return resp +// } +// req := new(pb.ColorPinoyLiveResultImg) +// _ = proto.Unmarshal(buffer, req) +// rm.ResultImgs = append(rm.ResultImgs, req.GetResultImg()...) +// log.Debug(rm.Log("req:", req.GetResultImg(), ",ResultImg:", rm.ResultImgs)) +// resp.StartDice = make([]pb.ColorPinoyLiveDiceColorType, 0) +// for _, dice := range rm.StartDices { +// resp.StartDice = append(resp.StartDice, pb.ColorPinoyLiveDiceColorType(model.GetColor(dice))) +// } +// resp.ResultImg = rm.ResultImgs +// return resp +//} +// +//func (rm *ColorRoom) LiveGameResult(buffer []byte) proto.Message { +// // rm.MutexStatus.Lock() +// // defer rm.MutexStatus.Unlock() +// log.Debug(rm.Log("LiveGameResult")) +// resp := rm.LiveStatus() +// if rm.LiveMgr.MaintenanceStatus == 1 { +// resp.Code = int32(pb.ColorPinoyLiveProcessError_ColorPinoyLiveProcessErrorMainteStatus) +// return resp +// } +// log.Debug(rm.Log("LiveGameResult status:%v ", rm.Status)) +// if rm.Status != pb.ColorPinoyLiveGameStatus_ColorPinoyLiveEndBetMovie { +// resp.Code = int32(pb.ColorPinoyLiveProcessError_ColorPinoyLiveProcessErrorGameSatus) +// return resp +// } +// req := new(pb.ColorPinoyLiveResult) +// _ = proto.Unmarshal(buffer, req) +// if len(req.GetColor()) != 3 { +// resp.Code = int32(pb.ColorPinoyLiveProcessError_ColorPinoyLiveProcessErrorDice) +// return resp +// } else { +// for i := 0; i < len(req.GetColor()); i++ { +// if !model.IsLogic(int32(req.GetColor()[i])) { +// resp.Code = int32(pb.ColorPinoyLiveProcessError_ColorPinoyLiveProcessErrorDice) +// return resp +// } +// rm.NormalDices[i] = byte(req.GetColor()[i]) +// } +// } +// log.Debug(rm.Log("LiveGameResult req:%v NormalDices:%v", req.GetColor(), rm.NormalDices)) +// +// rm.Table.Run(rm.openThreeDice) +// return resp +//} +// +//func (rm *ColorRoom) LiveGameMainte(buffer []byte) proto.Message { +// req := new(pb.ColorPinoyLiveMaintain) +// _ = proto.Unmarshal(buffer, req) +// b, _ := json.Marshal(req) +// log.Debug(rm.Log("LiveGameMainte:%v", string(b))) +// resp := rm.LiveStatus() +// if rm.LiveMgr.Restting { +// resp.Code = int32(pb.ColorPinoyLiveProcessError_ColorPinoyLiveProcessErrorMainteStatus) +// resp.Msg = "Restting" +// return resp +// } +// if req.TargetStatus == rm.LiveMgr.MaintenanceStatus { +// resp.Code = int32(pb.ColorPinoyLiveProcessError_ColorPinoyLiveProcessErrorMainteStatus) +// return resp +// } +// if rm.GetGameStatus() == pb.ColorPinoyLiveGameStatus_ColorPinoyLiveSettleStatus { +// resp.Code = int32(pb.ColorPinoyLiveProcessError_ColorPinoyLiveProcessErrorGameSatus) +// resp.Msg = "SettleStatus" +// return resp +// } +// defer func() { +// _ = pushGate.NotifyConfigUpdated(msg.ConfigUpdateType_ConfigUpdateTypeLiveConfig) +// rm.SetLiveGameStatus() +// }() +// if req.TargetStatus == 0 { +// rm.LiveMgr.MaintenanceStatus = 0 +// rm.LiveMgr.MainteMsg = "" +// rm.LiveMgr.HasMainte = false +// } else { +// rm.LiveMgr.MaintenanceStatus = req.TargetStatus +// rm.LiveMgr.MainteMsg = req.GetMsg() +// rm.LiveMainteCnt() +// } +// resp.MaintainStatus = rm.LiveMgr.MaintenanceStatus +// resp.MaintainMsg = rm.LiveMgr.MainteMsg +// resp.GameStatus, resp.Countdown = rm.getStatus() +// br, _ := json.Marshal(resp) +// redisf.RSC.LiveMainteSet(gconfig.GConfig.GDataConfig.VersionMode, gconfig.GConfig.GRoomConfig.GameId, string(br)) +// redisf.RSC.LiveMainteLobbySet(gconfig.GConfig.GDataConfig.VersionMode, gconfig.GConfig.GRoomConfig.GameId, rm.LiveMgr.MaintenanceStatus, rm.LiveMgr.MainteMsg) +// return resp +//} +// +//func (rm *ColorRoom) LiveMainteCnt() { +// rm.LiveMainte() +//} +// +//func (rm *ColorRoom) LiveMainte() { +// if rm.LiveMgr.MaintenanceStatus == 1 { +// rm.LiveMgr.HasMainte = true +// rm.LiveMgr.Restting = true +// } +// if rm.LiveMgr.DiscardStatus == 1 { +// rm.LiveMgr.DiscardRestting = true +// } +// rm.GameDiscard() +// // rm.LiveMgr.SetProcessStatus(LiveProcessInit) +// if rm.LiveMgr.MaintenanceStatus == 1 { +// rm.LiveMgr.Restting = false +// } +// if rm.LiveMgr.DiscardStatus == 1 { +// rm.LiveMgr.DiscardRestting = false +// rm.LiveMgr.DiscardStatus = 0 +// } +//} +// +//func (rm *ColorRoom) LiveGameDiscard(_ []byte) proto.Message { +// log.Debug(rm.Log("LiveGameDiscard")) +// resp := rm.LiveStatus() +// if rm.LiveMgr.MaintenanceStatus == 1 { +// log.Error(rm.Log("rm.LiveMgr.MaintenanceStatus")) +// resp.Code = int32(pb.ColorPinoyLiveProcessError_ColorPinoyLiveProcessErrorMainteStatus) +// return resp +// } +// if rm.LiveMgr.DiscardRestting { +// resp.Code = int32(pb.ColorPinoyLiveProcessError_ColorPinoyLiveProcessErrorMainteStatus) +// resp.Msg = "DiscardRestting" +// return resp +// } +// // if rm.GetGameStatus() == pb.ColorPinoyLiveGameStatus_ColorPinoyLiveSettleStatus { +// // resp.Code = int32(pb.ColorPinoyLiveProcessError_ColorPinoyLiveProcessErrorGameSatus) +// // resp.Msg = "SettleStatus" +// // return resp +// // } +// rm.LiveMgr.DiscardStatus = 1 +// rm.LiveMgr.DiscardMsg = "" +// rm.LiveMainteCnt() +// resp.GameStatus, resp.Countdown = rm.getStatus() +// return resp +//} +//func (rm *ColorRoom) LiveGameRankList(buffer []byte) proto.Message { +// _ = buffer +// return rm.LiveMgr.RankList +//} +// +//func (rm *ColorRoom) LiveGameSetDealerName(buffer []byte) proto.Message { +// resp := rm.LiveStatus() +// if rm.LiveMgr.MaintenanceStatus == 1 { +// resp.Code = int32(pb.ColorPinoyLiveProcessError_ColorPinoyLiveProcessErrorMainteStatus) +// return resp +// } +// req := new(pb.ColorPinoyLiveSetDealer) +// _ = proto.Unmarshal(buffer, req) +// rm.UpdateDealerName(req.DealerName) +// log.Debug(rm.Log("set dealer:", req.DealerName)) +// resp.DealerName = rm.dealerName +// return resp +//} diff --git a/server/colorgame/room/c2s.go b/server/colorgame/room/c2s.go index 65c51e9..d882601 100644 --- a/server/colorgame/room/c2s.go +++ b/server/colorgame/room/c2s.go @@ -3,7 +3,6 @@ package room import ( "game/common/proto/pb" "github.com/fox/fox/ipb" - "github.com/fox/fox/log" ) func (rm *ColorRoom) checkEnterRoom(user *ColorPlayer, iMsg *ipb.InternalMsg, req *pb.C2SMatchRoom) { @@ -16,210 +15,212 @@ func (rm *ColorRoom) OnEnterRoom(user *ColorPlayer, iMsg *ipb.InternalMsg, req * return } -func (rm *ColorRoom) ApplyLeave(buffer []byte, user inter.UserInetr) { - _ = buffer - resp := new(pb.ColorPinoyLiveLeaveResp) - u := rm.GetPlayer(user.GetId()) - if u == nil { - rm.Table.KickOut(user) - return - } - // 有下注时不让玩家离开 - if u.TotalBet != 0 { - resp.Code = 1 - _ = user.SendMsg(int32(pb.ColorPinoyLiveReceiveFromClientMessageType_ColorPinoyLiveApplyLeave), resp) - return - } - rm.KickOutUser(u) - _ = user.SendMsg(int32(pb.ColorPinoyLiveReceiveFromClientMessageType_ColorPinoyLiveApplyLeave), resp) - return -} - -func (rm *ColorRoom) checkNoBet() bool { - return rm.GetGameStatus() != pb.ColorPinoyLiveGameStatus_ColorPinoyLiveBetStatus || - rm.LiveMgr.MaintenanceStatus == 1 || - rm.LiveMgr.DiscardRestting -} - -func (rm *ColorRoom) Bet(buffer []byte, user inter.UserInetr) { - u := rm.getUser(user) - u.MutexBet.Lock() - defer u.MutexBet.Unlock() - if rm.checkNoBet() { - log.Error(rm.Log("game bet status err:%v", rm.GetGameStatus())) - model.SendBetFailMessageInetr(model.StatusError, user) - return - } - // 用户下注 - BetPb := &pb.ColorPinoyLiveBetReqs{} - err := proto.Unmarshal(buffer, BetPb) - if err != nil { - log.Error(rm.Log("proto.Unmarshal err:%v", err)) - model.SendBetFailMessageInetr(model.DataErr, user) - return - } - log.Debug(rm.Log("Bet pb = ", BetPb)) - var bets []*pb.ColorPinoyLiveBetReq - - for _, bet := range BetPb.Info { - req := &pb.ColorPinoyLiveBetReq{ - BetType: bet.BetType, - BetLevel: bet.BetLevel, - BetIndex: bet.BetIndex, - BetAmount: bet.BetAmount, - } - bets = append(bets, req) - } - - // log.Debug("Bet bets =", bets) - rm.CheckAndBet(u, bets) -} - -func (rm *ColorRoom) UserSitDown(buffer []byte, user inter.UserInetr) { - us := &pb.ColorPinoyLiveUserSitDown{} - _ = proto.Unmarshal(buffer, us) - // u, ok := rm.AllUserList[user.GetId()] - u := rm.GetPlayer(user.GetId()) - if u != nil { - if rm.SceneInfo.SitScene(u, int(us.ChairNo)) { - u.SceneChairId = int(us.ChairNo) - rm.Traverse(func(v *model.User) bool { - // rm.SendSceneMsg(v) - return true - }) - } - } -} - -func (rm *ColorRoom) SendUserListInfo(user inter.UserInetr) { - msg := new(pb.ColorPinoyLiveUserList) - for _, u := range rm.OnlineUserList { - userinfo := new(pb.ColorPinoyLiveUserInfo) - userinfo.NikeName = u.UserInetr.GetNike() - userinfo.UserGlod = u.Balance - userinfo.Head = u.UserInetr.GetHead() - userinfo.UserID = u.UserID - msg.UserList = append(msg.UserList, userinfo) - } - // log.Debug("SendUserListInfo", msg) - _ = user.SendMsg(int32(pb.ColorPinoyLiveReceiveFromClientMessageType_ColorPinoyLiveApplyGetUserListInfo), msg) -} - -func (rm *ColorRoom) SendTrend(u inter.UserInetr) { - // log.Debug("发送走势图") - msg := new(pb.ColorPinoyLiveTrend) - msg.ListTrendGroup = rm.GameTrend.ListTrendGroup - msg.LuckStarRate = rm.GetGameTrend() - _ = u.SendMsg(int32(pb.ColorPinoyLiveSendToClientMessageType_ColorPinoyLiveNoticeGameTrendInfo), msg) -} - -func (rm *ColorRoom) OnUserStanUp(user *model.User) { - rm.SceneInfo.UserStandUp(user.UserInetr) - user.Mn.Lock() - user.SceneChairId = 0 - user.Mn.Unlock() - if rm.GetGameStatus() < pb.ColorPinoyLiveGameStatus_ColorPinoyLiveOpenThreeDice { - rm.SelectUserListBalanceTopSitDownChair() - } else { - // rm.Traverse(func(v *model.User) bool { - // rm.SendSceneMsg(v) - // return true - // }) - } -} - -func (rm *ColorRoom) AgainBet(user inter.UserInetr) { - u := rm.getUser(user) - u.MutexBet.Lock() - defer u.MutexBet.Unlock() - if rm.checkNoBet() { - log.Error(rm.Log("game bet status err ", rm.GetGameStatus())) - model.SendBetFailMessageInetr(model.StatusError, user) - return - } - // u := rm.getUser(user) - var bets []*pb.ColorPinoyLiveBetReq - if u.TempLastTimeBet != nil { - for _, bet := range u.TempLastTimeBet { - bets = append(bets, bet...) - } - } - rm.CheckAndBet(u, bets) -} - -func (rm *ColorRoom) BetDouble(user inter.UserInetr) { - u := rm.getUser(user) - u.MutexBet.Lock() - defer u.MutexBet.Unlock() - if rm.checkNoBet() { - log.Error(rm.Log("game bet status err ", rm.GetGameStatus())) - model.SendBetFailMessageInetr(model.StatusError, user) - return - } - // u := rm.getUser(user) - var bets []*pb.ColorPinoyLiveBetReq - if u.LastTimeBet != nil { - for _, bet := range u.LastTimeBet { - bets = append(bets, bet...) - } - // log.Debug("BetDouble 上次下注:", u.LastTimeBet, "bets:", bets) - } - if len(bets) > 1000 { - log.Error(rm.Log("game bet status err ", rm.GetGameStatus())) - model.SendBetFailMessageInetr(12, user) - return - } - - rm.CheckAndBet(u, bets) -} - -func (rm *ColorRoom) OnUndoBet(buffer []byte, user inter.UserInetr) { - u := rm.getUser(user) - u.MutexBet.Lock() - defer u.MutexBet.Unlock() - if rm.checkNoBet() { - log.Error(rm.Log("game bet status err:%v", rm.GetGameStatus())) - model.SendBetFailMessageInetr(model.StatusError, user) - return - } - reqInfo := &pb.ColorPinoyLiveC2SUndoBet{} - err := proto.Unmarshal(buffer, reqInfo) - if err != nil { - log.Error(rm.Log("proto.Unmarshal err:%v", err)) - model.SendBetFailMessageInetr(model.DataErr, user) - return - } - rm.UndoBet(u, reqInfo.UndoType) -} - -// ApplyUseProps todo -func (rm *ColorRoom) ApplyUseProps(buffer []byte, userInter inter.UserInetr) { - applyInfo := new(pb.ColorPinoyLiveApplyPropsReq) - err := proto.Unmarshal(buffer, applyInfo) - user := rm.getUser(userInter) - if err != nil { - log.Error(rm.Log("proto.Unmarshal err:%v", err)) - model.SendBetFailMessage(model.DataErr, user) - return - } - AcceptUser := rm.GetPlayer(applyInfo.AcceptUserId) - if AcceptUser == nil { - log.Error(rm.Log("AcceptUser is null")) - model.SendBetFailMessage(model.UserNull, user) - return - } - _, err = user.GetPropsReal(rm.RoomCfg.Prop, rm.Table, rm.RoomCfg) - if err != nil { - log.Error(rm.Log("GetPropsReal err", err)) - model.SendBetFailMessage(model.ScoreLess, user) - return - } - leftCoins := user.Balance - propsResp := &pb.ColorPinoyLivePlayerPropsResp{ - ApplyUserId: user.UserID, - AcceptUserId: AcceptUser.UserID, - PropsId: applyInfo.PropsId, - Chips: leftCoins, - } - rm.Table.Broadcast(int32(pb.ColorPinoyLiveSendToClientMessageType_ColorPinoyLiveNoticePlayerUseProps), propsResp) -} +//--------------------------------------------------------------------------------------------------------------------- +// +//func (rm *ColorRoom) ApplyLeave(buffer []byte, user inter.UserInetr) { +// _ = buffer +// resp := new(pb.ColorPinoyLiveLeaveResp) +// u := rm.GetPlayer(user.GetId()) +// if u == nil { +// rm.Table.KickOut(user) +// return +// } +// // 有下注时不让玩家离开 +// if u.TotalBet != 0 { +// resp.Code = 1 +// _ = user.SendMsg(int32(pb.ColorPinoyLiveReceiveFromClientMessageType_ColorPinoyLiveApplyLeave), resp) +// return +// } +// rm.KickOutUser(u) +// _ = user.SendMsg(int32(pb.ColorPinoyLiveReceiveFromClientMessageType_ColorPinoyLiveApplyLeave), resp) +// return +//} +// +//func (rm *ColorRoom) checkNoBet() bool { +// return rm.GetGameStatus() != pb.ColorPinoyLiveGameStatus_ColorPinoyLiveBetStatus || +// rm.LiveMgr.MaintenanceStatus == 1 || +// rm.LiveMgr.DiscardRestting +//} +// +//func (rm *ColorRoom) Bet(buffer []byte, user inter.UserInetr) { +// u := rm.getUser(user) +// u.MutexBet.Lock() +// defer u.MutexBet.Unlock() +// if rm.checkNoBet() { +// log.Error(rm.Log("game bet status err:%v", rm.GetGameStatus())) +// model.SendBetFailMessageInetr(model.StatusError, user) +// return +// } +// // 用户下注 +// BetPb := &pb.ColorPinoyLiveBetReqs{} +// err := proto.Unmarshal(buffer, BetPb) +// if err != nil { +// log.Error(rm.Log("proto.Unmarshal err:%v", err)) +// model.SendBetFailMessageInetr(model.DataErr, user) +// return +// } +// log.Debug(rm.Log("Bet pb = ", BetPb)) +// var bets []*pb.ColorPinoyLiveBetReq +// +// for _, bet := range BetPb.Info { +// req := &pb.ColorPinoyLiveBetReq{ +// BetType: bet.BetType, +// BetLevel: bet.BetLevel, +// BetIndex: bet.BetIndex, +// BetAmount: bet.BetAmount, +// } +// bets = append(bets, req) +// } +// +// // log.Debug("Bet bets =", bets) +// rm.CheckAndBet(u, bets) +//} +// +//func (rm *ColorRoom) UserSitDown(buffer []byte, user inter.UserInetr) { +// us := &pb.ColorPinoyLiveUserSitDown{} +// _ = proto.Unmarshal(buffer, us) +// // u, ok := rm.AllUserList[user.GetId()] +// u := rm.GetPlayer(user.GetId()) +// if u != nil { +// if rm.SceneInfo.SitScene(u, int(us.ChairNo)) { +// u.SceneChairId = int(us.ChairNo) +// rm.Traverse(func(v *model.User) bool { +// // rm.SendSceneMsg(v) +// return true +// }) +// } +// } +//} +// +//func (rm *ColorRoom) SendUserListInfo(user inter.UserInetr) { +// msg := new(pb.ColorPinoyLiveUserList) +// for _, u := range rm.OnlineUserList { +// userinfo := new(pb.ColorPinoyLiveUserInfo) +// userinfo.NikeName = u.UserInetr.GetNike() +// userinfo.UserGlod = u.Balance +// userinfo.Head = u.UserInetr.GetHead() +// userinfo.UserID = u.UserID +// msg.UserList = append(msg.UserList, userinfo) +// } +// // log.Debug("SendUserListInfo", msg) +// _ = user.SendMsg(int32(pb.ColorPinoyLiveReceiveFromClientMessageType_ColorPinoyLiveApplyGetUserListInfo), msg) +//} +// +//func (rm *ColorRoom) SendTrend(u inter.UserInetr) { +// // log.Debug("发送走势图") +// msg := new(pb.ColorPinoyLiveTrend) +// msg.ListTrendGroup = rm.GameTrend.ListTrendGroup +// msg.LuckStarRate = rm.GetGameTrend() +// _ = u.SendMsg(int32(pb.ColorPinoyLiveSendToClientMessageType_ColorPinoyLiveNoticeGameTrendInfo), msg) +//} +// +//func (rm *ColorRoom) OnUserStanUp(user *model.User) { +// rm.SceneInfo.UserStandUp(user.UserInetr) +// user.Mn.Lock() +// user.SceneChairId = 0 +// user.Mn.Unlock() +// if rm.GetGameStatus() < pb.ColorPinoyLiveGameStatus_ColorPinoyLiveOpenThreeDice { +// rm.SelectUserListBalanceTopSitDownChair() +// } else { +// // rm.Traverse(func(v *model.User) bool { +// // rm.SendSceneMsg(v) +// // return true +// // }) +// } +//} +// +//func (rm *ColorRoom) AgainBet(user inter.UserInetr) { +// u := rm.getUser(user) +// u.MutexBet.Lock() +// defer u.MutexBet.Unlock() +// if rm.checkNoBet() { +// log.Error(rm.Log("game bet status err ", rm.GetGameStatus())) +// model.SendBetFailMessageInetr(model.StatusError, user) +// return +// } +// // u := rm.getUser(user) +// var bets []*pb.ColorPinoyLiveBetReq +// if u.TempLastTimeBet != nil { +// for _, bet := range u.TempLastTimeBet { +// bets = append(bets, bet...) +// } +// } +// rm.CheckAndBet(u, bets) +//} +// +//func (rm *ColorRoom) BetDouble(user inter.UserInetr) { +// u := rm.getUser(user) +// u.MutexBet.Lock() +// defer u.MutexBet.Unlock() +// if rm.checkNoBet() { +// log.Error(rm.Log("game bet status err ", rm.GetGameStatus())) +// model.SendBetFailMessageInetr(model.StatusError, user) +// return +// } +// // u := rm.getUser(user) +// var bets []*pb.ColorPinoyLiveBetReq +// if u.LastTimeBet != nil { +// for _, bet := range u.LastTimeBet { +// bets = append(bets, bet...) +// } +// // log.Debug("BetDouble 上次下注:", u.LastTimeBet, "bets:", bets) +// } +// if len(bets) > 1000 { +// log.Error(rm.Log("game bet status err ", rm.GetGameStatus())) +// model.SendBetFailMessageInetr(12, user) +// return +// } +// +// rm.CheckAndBet(u, bets) +//} +// +//func (rm *ColorRoom) OnUndoBet(buffer []byte, user inter.UserInetr) { +// u := rm.getUser(user) +// u.MutexBet.Lock() +// defer u.MutexBet.Unlock() +// if rm.checkNoBet() { +// log.Error(rm.Log("game bet status err:%v", rm.GetGameStatus())) +// model.SendBetFailMessageInetr(model.StatusError, user) +// return +// } +// reqInfo := &pb.ColorPinoyLiveC2SUndoBet{} +// err := proto.Unmarshal(buffer, reqInfo) +// if err != nil { +// log.Error(rm.Log("proto.Unmarshal err:%v", err)) +// model.SendBetFailMessageInetr(model.DataErr, user) +// return +// } +// rm.UndoBet(u, reqInfo.UndoType) +//} +// +//// ApplyUseProps todo +//func (rm *ColorRoom) ApplyUseProps(buffer []byte, userInter inter.UserInetr) { +// applyInfo := new(pb.ColorPinoyLiveApplyPropsReq) +// err := proto.Unmarshal(buffer, applyInfo) +// user := rm.getUser(userInter) +// if err != nil { +// log.Error(rm.Log("proto.Unmarshal err:%v", err)) +// model.SendBetFailMessage(model.DataErr, user) +// return +// } +// AcceptUser := rm.GetPlayer(applyInfo.AcceptUserId) +// if AcceptUser == nil { +// log.Error(rm.Log("AcceptUser is null")) +// model.SendBetFailMessage(model.UserNull, user) +// return +// } +// _, err = user.GetPropsReal(rm.RoomCfg.Prop, rm.Table, rm.RoomCfg) +// if err != nil { +// log.Error(rm.Log("GetPropsReal err", err)) +// model.SendBetFailMessage(model.ScoreLess, user) +// return +// } +// leftCoins := user.Balance +// propsResp := &pb.ColorPinoyLivePlayerPropsResp{ +// ApplyUserId: user.UserID, +// AcceptUserId: AcceptUser.UserID, +// PropsId: applyInfo.PropsId, +// Chips: leftCoins, +// } +// rm.Table.Broadcast(int32(pb.ColorPinoyLiveSendToClientMessageType_ColorPinoyLiveNoticePlayerUseProps), propsResp) +//} diff --git a/server/colorgame/room/colorRoom.go b/server/colorgame/room/colorRoom.go index f4d765b..177b40e 100644 --- a/server/colorgame/room/colorRoom.go +++ b/server/colorgame/room/colorRoom.go @@ -1,68 +1,53 @@ package room import ( - "fmt" "game/common/baseroom" "game/common/proto/pb" "github.com/fox/fox/log" "github.com/fox/fox/processor" "github.com/fox/fox/service" - "sync" - "time" +) + +const ( + BET_TYPE_NUM = 18 ) type ColorRoom struct { *baseroom.BaseRoom[ColorSeat] //--------------------------------- - Status pb.ColorPinoyLiveGameStatus // 房间状态1 表示 - StatusTime int64 // 切换状态时的时间戳 + //Status pb.ColorPinoyLiveGameStatus // 房间状态1 表示 + //StatusTime int64 // 切换状态时的时间戳 + // + //NormalDices []byte // 普通骰子 3个 + //StartDices []byte // 初始位置摆放的骰子 3个 + // + //// DefaultLuckyDice byte // 幸运骰子 1个 每局开始 放在拉杆上的骰子 + //// DefaultNormalDices []byte // 普通骰子 3个 每局开始 放在拉杆上的骰子 + // + //TotalBets [BET_TYPE_NUM]int64 // 各区域的下注统计 + //TotalBet int64 // 下注统计 + ////SceneInfo model.SceneInfo // 下注的玩家列表 + // + //GameTrend *pb.ColorPinoyLiveTrend // 走势图 + ////OnlineUserList []*model.User // 所有的玩家列表 用于排序 + //PokerMsg *pb.ColorPinoyLivePokerMsg // 扑克消息 + //RoomCfg game.ColorRoomConfig // 房间配置 + //GameTiming game.ColorGameTiming // 时间配置 + //startAt int64 + //endAt int64 + // + //ServerStatus int32 + //wd *sync.WaitGroup + //TrendRedisKey string + //_aniLuckyDiceRouteIndex int32 // 幸运骰子动画路径 + //_aniThreeDiceRouteIndex int32 // 3个骰子动画路径 + //BigWinner []*pb.ColorPinoyLiveBigWinner + //LiveMgr *LiveMgr + //dealerName []string // 主播名字 + //betEndBetAreasOdds []*pb.ColorPinoyLiveGameBetAreaInfo // 下注结束后,每个区域更新是否爆奖 + //afterBetAreaOdds []*pb.ColorPinoyLiveBetAreaOdd // 开奖后,更新每个区域的赔率(主要是单色投注区开奖后,三个赔率变为1个赔率) - LuckyDice byte // 幸运骰子 1个 - NormalDices []byte // 普通骰子 3个 - StartDices []byte // 初始位置摆放的骰子 3个 - ResultImgs []string // 结果图片 - - // DefaultLuckyDice byte // 幸运骰子 1个 每局开始 放在拉杆上的骰子 - // DefaultNormalDices []byte // 普通骰子 3个 每局开始 放在拉杆上的骰子 - - TotalBets [config.BET_TYPE_NUM]int64 // 各区域的下注统计 - TotalBet int64 // 下注统计 - SceneInfo model.SceneInfo // 下注的玩家列表 - GamePoker *model.GameDice // 管理一副牌 - TimerJob *clock.Job // job - RobotCreateJob *clock.Job // job - RobotDeleteJob *clock.Job // job - // LuckyBetType int32 // 幸运区域 - // LuckyMul int32 // 幸运倍率 - // RobotTimerJob *clock.Job // 机器人job - // LastMasterBetType int32 // 最近一次神算子下注的类型 - GameTrend *pb.ColorPinoyLiveTrend // 走势图 - OnlineUserList []*model.User // 所有的玩家列表 用于排序 - PokerMsg *pb.ColorPinoyLivePokerMsg // 扑克消息 - RoomCfg *config.RoomConfig // 房间配置 - Cfg *config.ColorPinoyLiveConfig // 房间配置 - startAt int64 - endAt int64 - MutexData *sync.RWMutex - MutexStatus *sync.RWMutex - MutexUserList *sync.RWMutex - ServerStatus int32 - wd *sync.WaitGroup - TrendRedisKey string - _aniLuckyDiceRouteIndex int32 // 幸运骰子动画路径 - _aniThreeDiceRouteIndex int32 // 3个骰子动画路径 - BigWinner []*pb.ColorPinoyLiveBigWinner - LiveMgr *LiveMgr - dealerName []string // 主播名字 - betEndBetAreasOdds []*pb.ColorPinoyLiveGameBetAreaInfo // 下注结束后,每个区域更新是否爆奖 - afterBetAreaOdds []*pb.ColorPinoyLiveBetAreaOdd // 开奖后,更新每个区域的赔率(主要是单色投注区开奖后,三个赔率变为1个赔率) - jackpotMgr *jackpot.JackPotMgr - jackpotFunding int64 // 本局垫资 - jackpotX int64 // 赎回比例 - jackpotY int64 // 追加进 - costJackpot int64 // 本局发下去的jackpot奖励,回滚用 - jackpotUser map[int64]int64 // 本局中jackpot的玩家,用于kafka发送消息 } func newColorRoom(id, roomType int, srv service.IService) (baseroom.IRoom, pb.ErrCode) { @@ -100,406 +85,327 @@ func (rm *ColorRoom) AddGold(user *ColorPlayer, add int64) (int64, bool) { } // --------------------------------------------------------------------------------------------------- - -const ( - BigWinnerCount = 6 - GameName = "ColorPinoyLive" -) - -func (rm *ColorRoom) SetGameStatus(status pb.ColorPinoyLiveGameStatus) { - rm.Status = status - rm.StatusTime = time.Now().UnixMilli() - log.Debug("设置房间状态:", status) - rm.SetLiveGameStatus([]int{1}...) -} -func (rm *ColorRoom) GetGameStatus() pb.ColorPinoyLiveGameStatus { - return rm.Status -} -func (rm *ColorRoom) UserOffline(user inter.UserInetr) { - _ = user -} - -// 客户端显示赔率范围 -func (rm *ColorRoom) MulRangeConfig() []*pb.BetAreaMulRangeConfig { - var mulRangeCfg []*pb.BetAreaMulRangeConfig - for pos, mul := range rm.Cfg.WinSingleColorMul { - if len(mul) > 0 { - mulRangeCfg = append(mulRangeCfg, &pb.BetAreaMulRangeConfig{ - Pos: pb.ColorPinoyLiveBigBetAreaPos(pos), - MinMul: mul[0].Mul, - MaxMul: mul[len(mul)-1].Mul, - }) - } - } - if len(rm.Cfg.WinDoubleColorMul) > 0 { - mul := rm.Cfg.WinDoubleColorMul - mulRangeCfg = append(mulRangeCfg, &pb.BetAreaMulRangeConfig{ - Pos: pb.ColorPinoyLiveBigBetAreaPos_BBA_Double, - MinMul: mul[0].Mul, - MaxMul: mul[0].Mul, - }) - } - if len(rm.Cfg.WinThreeColorMul) > 0 { - mul := rm.Cfg.WinThreeColorMul - mulRangeCfg = append(mulRangeCfg, &pb.BetAreaMulRangeConfig{ - Pos: pb.ColorPinoyLiveBigBetAreaPos_BBA_Three, - MinMul: mul[0].Mul, - MaxMul: mul[0].Mul, - }) - } - if len(mulRangeCfg) != len(pb.ColorPinoyLiveBigBetAreaPos_name) { - log.Error(rm.Log(("配置错误"))) - return nil - } - for pos, v := range mulRangeCfg { - log.Debug(rm.Log("pos:%v 赔率区间:%v-%v", pos, v.MinMul, v.MaxMul)) - } - return mulRangeCfg -} - -func (rm *ColorRoom) InitBigOddsBetAreas() { - if len(rm.betEndBetAreasOdds) == 0 { - rm.betEndBetAreasOdds = make([]*pb.ColorPinoyLiveGameBetAreaInfo, 0, len(pb.ColorPinoyLiveBetTypeJP_name)) - } - rm.betEndBetAreasOdds = rm.betEndBetAreasOdds[0:0] - for betType := 0; betType < config.BET_TYPE_NUM; betType++ { - rm.betEndBetAreasOdds = append(rm.betEndBetAreasOdds, &pb.ColorPinoyLiveGameBetAreaInfo{ - BetType: pb.ColorPinoyLiveBetTypeJP(betType), - BetChipsInfo: nil, - IsWin: 0, - Odd: nil, - IsBigOdd: false, - BigSingleColorOddPos: 0, - }) - } - for pos, betArea := range rm.betEndBetAreasOdds { - betArea.IsBigOdd = false - index := pos / int(pb.ColorPinoyLiveDiceColorType_ColorPinoyLiveType_GREEN) - if index == 0 { - betArea.BigSingleColorOddPos = pb.ColorPinoyLiveBigBetAreaPos_BBA_Single_0 - var mulRangeW []*MulRangeW - begin := 0 - for _, mul := range rm.Cfg.WinSingleColorMul[0] { - mulRangeW = append(mulRangeW, &MulRangeW{MulRate: mul, ColorPos: pb.ColorPinoyLiveBigBetAreaPos(pos), MinW: begin, MaxW: begin + mul.Rate}) - begin += mul.Rate - } - rdv := rand.RandInt(mulRangeW[0].MinW, mulRangeW[len(mulRangeW)-1].MaxW) - singleMul := rm.Cfg.WinSingleColorMul[0][0].Mul - for _, mul := range mulRangeW { - if rdv < mul.MinW || rdv >= mul.MaxW { - continue - } - singleMul = mul.Mul - break - } - log.Debug(rm.Log("单色区域基础权重区间:[%v,%v],随机数:%v 基础赔率:%v", mulRangeW[0].MinW, mulRangeW[len(mulRangeW)-1].MaxW, rdv, singleMul)) - betArea.Odd = append(betArea.Odd, singleMul) - betArea.Odd = append(betArea.Odd, rm.Cfg.WinSingleColorMul[1][0].Mul) - betArea.Odd = append(betArea.Odd, rm.Cfg.WinSingleColorMul[2][0].Mul) - } else if index == 1 { - betArea.BigSingleColorOddPos = pb.ColorPinoyLiveBigBetAreaPos_BBA_Double - betArea.Odd = append(betArea.Odd, rm.Cfg.WinDoubleColorMul[0].Mul) - } else { - betArea.BigSingleColorOddPos = pb.ColorPinoyLiveBigBetAreaPos_BBA_Three - betArea.Odd = append(betArea.Odd, rm.Cfg.WinThreeColorMul[0].Mul) - } - } - for _, betArea := range rm.betEndBetAreasOdds { - log.Debug(rm.Log("初始化投注区域:%v 倍率:%v 是否爆奖:%v 是否jackpot:%v", betArea.BetType, betArea.Odd, betArea.IsBigOdd, betArea.IsJackpot)) - } -} - -func (rm *ColorRoom) Log(format string, args ...any) string { - s := fmt.Sprintf(format, args...) - head := fmt.Sprintf("gameno:%v ", rm.Table.GetGameRoundId()) - return head + s -} - -func (rm *ColorRoom) LogEx(user *model.User, format string, args ...any) string { - s := fmt.Sprintf(format, args...) - head := fmt.Sprintf("gameno:%v user:%v", rm.Table.GetGameRoundId(), user.UserID) - return head + s -} - -func (rm *ColorRoom) InitTableFrameSink(table inter.TableInter) inter.LiveRoomInter { - room := new(ColorPinoyLiveGame) - room.Table = table - room.OnlineUserList = make([]*model.User, 0) - room.SceneInfo.Init() - room.PokerMsg = new(pb.ColorPinoyLivePokerMsg) - // room.PokerMsg.LongPoker = make([]int32, 1) - // room.PokerMsg.HuPoker = make([]int32, 1) - room.MutexData = new(sync.RWMutex) - room.MutexStatus = new(sync.RWMutex) - room.MutexUserList = new(sync.RWMutex) - room.GamePoker = new(model.GameDice) - room.wd = new(sync.WaitGroup) - room.GamePoker.InitPoker() - room.NormalDices = make([]byte, 3) - // room.DefaultNormalDices = make([]byte, 3) - room.GameTrend = new(pb.ColorPinoyLiveTrend) - room.GameTrend.ListTrendGroup = []*pb.ColorPinoyLiveTrendGroup{} - room.GameRoundStart() - room.InitWinTrend() - room.LiveMgr = NewLiveMgr() - room.InitBigOddsBetAreas() - room.jackpotMgr = jackpot.NewJackPotMgr() - // room.jackpotMgr.Load(room.RoomCfg.ColorPinoyLiveConfig.InitJackpot) - - table.BindGame(room) - return room -} -func (rm *ColorRoom) ResetConfigPrivate() bool { - rm.RoomCfg = config.ResetConfigPrivate() - rm.Cfg = &rm.RoomCfg.ColorPinoyLiveConfig - return true -} -func (rm *ColorRoom) GetPlayer(userid int64) *model.User { - user, ok := rm.AllUserList.Load(userid) - if !ok { - return nil - } - player, ok := user.(*model.User) - if !ok { - return nil - } - return player -} -func (rm *ColorRoom) AddPlayer(player *model.User) { - rm.AllUserList.Store(player.UserInetr.GetId(), player) - rm.MutexUserList.Lock() - rm.OnlineUserList = append(rm.OnlineUserList, player) - rm.MutexUserList.Unlock() -} - -type TraverseFunc func(v *model.User) bool - -func (rm *ColorRoom) Traverse(f TraverseFunc) { - function := func(key, value interface{}) bool { - if value != nil { - us, ok := value.(*model.User) - if !ok { - log.Warn("user is not *UserInetr") - } else { - return f(us) - } - } - return true - } - rm.AllUserList.Range(function) -} -func (rm *ColorRoom) TraverseRobotNum(num int, f TraverseFunc) { - curNum := 0 - function := func(key, value interface{}) bool { - if value != nil { - us, ok := value.(*model.User) - if !ok { - log.Warn("user is not *UserInetr") - } else if us.IsRobot { - curNum++ - f(us) - } - } - if num > 0 && curNum == num { - return false - } - return true - } - rm.AllUserList.Range(function) -} - -func (rm *ColorRoom) DeletePlayer(uid int64) { - p := rm.GetPlayer(uid) - if p != nil { - rm.AllUserList.Delete(uid) - rm.DeleteExitUserFromOnlineUserListSlice(p) - } -} -func (rm *ColorRoom) getUserLen() int64 { - len1 := int64(0) - rm.Traverse(func(v *model.User) bool { - len1++ - return true - }) - return len1 -} -func (rm *ColorRoom) getUserAndRobotLen() (userNum, robotNum int64) { - rm.Traverse(func(v *model.User) bool { - if v.IsRobot { - robotNum++ - } else { - userNum++ - } - return true - }) - return -} - -func (rm *ColorRoom) UserReady(user inter.UserInetr) bool { - _ = user - return true -} - -// 用户坐下 -func (rm *ColorRoom) OnActionUserSitDown(user inter.UserInetr, chairId int, config string) int { - _ = chairId - _ = config - u := rm.getUser(user) - // log.Debug("玩家坐下...OnActionUserSitDown:", u, chairId, config) - go rm.SceneUserSitDown(u) - return 1 // business.OnActionUserSitDownHandler() -} - -func (rm *ColorRoom) UserExit(user inter.UserInetr) bool { - u := rm.getUser(user) - // 有下注时不让玩家离开 - if u.TotalBet != 0 { - return false - } - rm.KickOutUser(u) - return true -} -func (rm *ColorRoom) LeaveGame(user inter.UserInetr) bool { - u := rm.getUser(user) - if u.TotalBet != 0 { - // msg := new(pb.KickOutUserMsg) - // msg.KickOutReason = "游戏中不能退出!" - // u.SendMsg(int32(pb.SendToClientMessageType_NoticeExitRet), msg) - return false - } - - rm.KickOutUser(u) - return true -} - -// 游戏消息 -func (rm *ColorRoom) OnGameMessage(subCmd int32, buffer []byte, user inter.UserInetr) { - // log.Debug("收到客户端消息:", subCmd) - switch pb.ColorPinoyLiveReceiveFromClientMessageType(subCmd) { - case pb.ColorPinoyLiveReceiveFromClientMessageType_ColorPinoyLiveApplyRefresh: - rm.GameSync(user) - case pb.ColorPinoyLiveReceiveFromClientMessageType_ColorPinoyLiveApplyBetChips: - monitor.GoSafe(rm.Bet, buffer, user) - case pb.ColorPinoyLiveReceiveFromClientMessageType_ColorPinoyLiveApplyGetUserListInfo: - monitor.GoSafe(rm.SendUserListInfo, user) - case pb.ColorPinoyLiveReceiveFromClientMessageType_ColorPinoyLiveApplyGetTrend: - monitor.GoSafe(rm.SendTrend, user) - case pb.ColorPinoyLiveReceiveFromClientMessageType_ColorPinoyLiveApplyBetAgain: - // go rm.AgainBet(user) - monitor.GoSafe(rm.AgainBet, user) - case pb.ColorPinoyLiveReceiveFromClientMessageType_ColorPinoyLiveApplyBetDouble: - monitor.GoSafe(rm.BetDouble, user) - case pb.ColorPinoyLiveReceiveFromClientMessageType_ColorPinoyLiveApplyUndoBet: - monitor.GoSafe(rm.OnUndoBet, buffer, user) - case pb.ColorPinoyLiveReceiveFromClientMessageType_ColorPinoyLiveApplyUseProps: - monitor.GoSafe(rm.ApplyUseProps, buffer, user) - case pb.ColorPinoyLiveReceiveFromClientMessageType_ColorPinoyLiveApplyLeave: - monitor.GoSafe(rm.ApplyLeave, buffer, user) - } -} - -func (rm *ColorRoom) initDefaultDiceGameRoundReady() { - // rm.DefaultLuckyDice = rm.GamePoker.ShuffleDices(1)[0] - // - // rm.DefaultNormalDices[0] = rm.GamePoker.ShuffleDices(1)[0] - // rm.DefaultNormalDices[1] = rm.GamePoker.ShuffleDices(1)[0] - // rm.DefaultNormalDices[2] = rm.GamePoker.ShuffleDices(1)[0] -} - -// 开lucky dice -func (rm *ColorRoom) OpenLuckyDice() { - - dealDice := rm.GetPairDice(1, 0, 1) - - if dealDice == nil || len(dealDice) < 1 { - rm.LuckyDice = rm.GamePoker.ShuffleDices(1)[0] - } else { - deck := model.GetInitialDeck() - rm.LuckyDice = deck[dealDice[0]-1] - } -} - -// 开3个普通 dice -func (rm *ColorRoom) OpenThreeDice() { - - dealDice := rm.GetPairDice(3, 1, 4) - if dealDice == nil || len(dealDice) < 3 { - rm.NormalDices[0] = rm.GamePoker.ShuffleDices(1)[0] - rm.NormalDices[1] = rm.GamePoker.ShuffleDices(1)[0] - rm.NormalDices[2] = rm.GamePoker.ShuffleDices(1)[0] - } else { - deck := model.GetInitialDeck() - rm.NormalDices[0] = deck[dealDice[0]-1] - rm.NormalDices[1] = deck[dealDice[1]-1] - rm.NormalDices[2] = deck[dealDice[2]-1] - } -} - -func (rm *ColorRoom) getUser(user inter.UserInetr) *model.User { - // u, ok := rm.AllUserList[user.GetId()] - u := rm.GetPlayer(user.GetId()) - if u == nil { - u = new(model.User) - u.UserID = user.GetId() - u.UserInetr = user - u.Balance = user.GetScore() - u.Carry = user.GetCarry() - u.Time = time.Now().UnixNano() / 1e6 - u.UserInetr = user - rm.AddPlayer(u) - u.ResetUserData() - } - - return u -} - -func (rm *ColorRoom) getRobotUser(user inter.UserInetr) *model.User { - // u, ok := rm.AllUserList[user.GetId()] - u := rm.GetPlayer(user.GetId()) - if u == nil { - u = new(model.User) - u.UserID = user.GetId() - u.UserInetr = user - u.Balance = user.GetScore() - u.Carry = user.GetCarry() - u.Time = time.Now().UnixNano() / 1e6 - u.UserInetr = user - u.IsRobot = true - rm.AddPlayer(u) - u.ResetUserData() - } - - return u -} - -// 游戏开始入口..... -func (rm *ColorRoom) GameStart() bool { - if rm.GetGameStatus() == 0 { - rm.Ready() - rm.SyncServerMaintenance(0, "") - _ = rm.LiveDelayUpdate() - // 防止卡房间 - rm.Table.AddTimerRepeat(60, 0, func() { - if rm.LiveMgr.MaintenanceStatus == 1 { - rm.Table.EndGame() - } - }) - } else if rm.TimerJob != nil { - } - - return true -} - -func (rm *ColorRoom) GameRoundStart() { - rm.RoomCfg = config.ResetConfig() - rm.Cfg = &rm.RoomCfg.ColorPinoyLiveConfig - rm.ServerStatus = gconfig.GConfig.GServConfig.Status -} - -func (rm *ColorRoom) ResetTable() { - rm.SetGameStatus(0) -} - -// 关闭桌子 -func (rm *ColorRoom) CloseTable() { -} +// +//const ( +// BigWinnerCount = 6 +// GameName = "ColorPinoyLive" +//) +// +//func (rm *ColorRoom) SetGameStatus(status pb.ColorPinoyLiveGameStatus) { +// rm.Status = status +// rm.StatusTime = time.Now().UnixMilli() +// log.DebugF(rm.Log("设置房间状态:%v", status)) +//} +//func (rm *ColorRoom) GetGameStatus() pb.ColorPinoyLiveGameStatus { +// return rm.Status +//} +// +//// 客户端显示赔率范围 +//func (rm *ColorRoom) MulRangeConfig() []*pb.BetAreaMulRangeConfig { +// var mulRangeCfg []*pb.BetAreaMulRangeConfig +// for pos, mul := range rm.RoomCfg.WinSingleColorMul { +// if len(mul) > 0 { +// mulRangeCfg = append(mulRangeCfg, &pb.BetAreaMulRangeConfig{ +// Pos: pb.ColorPinoyLiveBigBetAreaPos(pos), +// MinMul: mul[0].Mul, +// MaxMul: mul[len(mul)-1].Mul, +// }) +// } +// } +// if len(rm.RoomCfg.WinDoubleColorMul) > 0 { +// mul := rm.RoomCfg.WinDoubleColorMul +// mulRangeCfg = append(mulRangeCfg, &pb.BetAreaMulRangeConfig{ +// Pos: pb.ColorPinoyLiveBigBetAreaPos_BBA_Double, +// MinMul: mul[0].Mul, +// MaxMul: mul[0].Mul, +// }) +// } +// if len(rm.RoomCfg.WinThreeColorMul) > 0 { +// mul := rm.RoomCfg.WinThreeColorMul +// mulRangeCfg = append(mulRangeCfg, &pb.BetAreaMulRangeConfig{ +// Pos: pb.ColorPinoyLiveBigBetAreaPos_BBA_Three, +// MinMul: mul[0].Mul, +// MaxMul: mul[0].Mul, +// }) +// } +// if len(mulRangeCfg) != len(pb.ColorPinoyLiveBigBetAreaPos_name) { +// log.Error(rm.Log(("配置错误"))) +// return nil +// } +// for pos, v := range mulRangeCfg { +// log.Debug(rm.Log("pos:%v 赔率区间:%v-%v", pos, v.MinMul, v.MaxMul)) +// } +// return mulRangeCfg +//} +// +//func (rm *ColorRoom) InitBigOddsBetAreas() { +// if len(rm.betEndBetAreasOdds) == 0 { +// rm.betEndBetAreasOdds = make([]*pb.ColorPinoyLiveGameBetAreaInfo, 0, len(pb.ColorPinoyLiveBetTypeJP_name)) +// } +// rm.betEndBetAreasOdds = rm.betEndBetAreasOdds[0:0] +// for betType := 0; betType < BET_TYPE_NUM; betType++ { +// rm.betEndBetAreasOdds = append(rm.betEndBetAreasOdds, &pb.ColorPinoyLiveGameBetAreaInfo{ +// BetType: pb.ColorPinoyLiveBetTypeJP(betType), +// BetChipsInfo: nil, +// IsWin: 0, +// Odd: nil, +// IsBigOdd: false, +// BigSingleColorOddPos: 0, +// }) +// } +// for pos, betArea := range rm.betEndBetAreasOdds { +// betArea.IsBigOdd = false +// index := pos / int(pb.ColorPinoyLiveDiceColorType_ColorPinoyLiveType_GREEN) +// if index == 0 { +// betArea.BigSingleColorOddPos = pb.ColorPinoyLiveBigBetAreaPos_BBA_Single_0 +// var mulRangeW []*MulRangeW +// begin := 0 +// for _, mul := range rm.RoomCfg.WinSingleColorMul[0] { +// mulRangeW = append(mulRangeW, &MulRangeW{MulRate: mul, ColorPos: pb.ColorPinoyLiveBigBetAreaPos(pos), MinW: begin, MaxW: begin + mul.Rate}) +// begin += mul.Rate +// } +// rdv := xrand.RandRange[int](mulRangeW[0].MinW, mulRangeW[len(mulRangeW)-1].MaxW) +// singleMul := rm.Cfg.WinSingleColorMul[0][0].Mul +// for _, mul := range mulRangeW { +// if rdv < mul.MinW || rdv >= mul.MaxW { +// continue +// } +// singleMul = mul.Mul +// break +// } +// log.Debug(rm.Log("单色区域基础权重区间:[%v,%v],随机数:%v 基础赔率:%v", mulRangeW[0].MinW, mulRangeW[len(mulRangeW)-1].MaxW, rdv, singleMul)) +// betArea.Odd = append(betArea.Odd, singleMul) +// betArea.Odd = append(betArea.Odd, rm.Cfg.WinSingleColorMul[1][0].Mul) +// betArea.Odd = append(betArea.Odd, rm.Cfg.WinSingleColorMul[2][0].Mul) +// } else if index == 1 { +// betArea.BigSingleColorOddPos = pb.ColorPinoyLiveBigBetAreaPos_BBA_Double +// betArea.Odd = append(betArea.Odd, rm.Cfg.WinDoubleColorMul[0].Mul) +// } else { +// betArea.BigSingleColorOddPos = pb.ColorPinoyLiveBigBetAreaPos_BBA_Three +// betArea.Odd = append(betArea.Odd, rm.Cfg.WinThreeColorMul[0].Mul) +// } +// } +// for _, betArea := range rm.betEndBetAreasOdds { +// log.Debug(rm.Log("初始化投注区域:%v 倍率:%v 是否爆奖:%v 是否jackpot:%v", betArea.BetType, betArea.Odd, betArea.IsBigOdd, betArea.IsJackpot)) +// } +//} +// +//func (rm *ColorRoom) Log(format string, args ...any) string { +// s := fmt.Sprintf(format, args...) +// head := fmt.Sprintf("gameno:%v ", rm.Table.GetGameRoundId()) +// return head + s +//} +// +//func (rm *ColorRoom) LogEx(user *model.User, format string, args ...any) string { +// s := fmt.Sprintf(format, args...) +// head := fmt.Sprintf("gameno:%v user:%v", rm.Table.GetGameRoundId(), user.UserID) +// return head + s +//} +// +// +//func (rm *ColorRoom) ResetConfigPrivate() bool { +// rm.RoomCfg = config.ResetConfigPrivate() +// rm.Cfg = &rm.RoomCfg.ColorPinoyLiveConfig +// return true +//} +//func (rm *ColorRoom) GetPlayer(userid int64) *model.User { +// user, ok := rm.AllUserList.Load(userid) +// if !ok { +// return nil +// } +// player, ok := user.(*model.User) +// if !ok { +// return nil +// } +// return player +//} +//func (rm *ColorRoom) AddPlayer(player *model.User) { +// rm.AllUserList.Store(player.UserInetr.GetId(), player) +// rm.MutexUserList.Lock() +// rm.OnlineUserList = append(rm.OnlineUserList, player) +// rm.MutexUserList.Unlock() +//} +// +//type TraverseFunc func(v *model.User) bool +// +//func (rm *ColorRoom) Traverse(f TraverseFunc) { +// function := func(key, value interface{}) bool { +// if value != nil { +// us, ok := value.(*model.User) +// if !ok { +// log.Warn("user is not *UserInetr") +// } else { +// return f(us) +// } +// } +// return true +// } +// rm.AllUserList.Range(function) +//} +// +// +//func (rm *ColorRoom) DeletePlayer(uid int64) { +// p := rm.GetPlayer(uid) +// if p != nil { +// rm.AllUserList.Delete(uid) +// rm.DeleteExitUserFromOnlineUserListSlice(p) +// } +//} +// +// +// +// +// +//func (rm *ColorRoom) UserExit(user inter.UserInetr) bool { +// u := rm.getUser(user) +// // 有下注时不让玩家离开 +// if u.TotalBet != 0 { +// return false +// } +// rm.KickOutUser(u) +// return true +//} +//func (rm *ColorRoom) LeaveGame(user inter.UserInetr) bool { +// u := rm.getUser(user) +// if u.TotalBet != 0 { +// // msg := new(pb.KickOutUserMsg) +// // msg.KickOutReason = "游戏中不能退出!" +// // u.SendMsg(int32(pb.SendToClientMessageType_NoticeExitRet), msg) +// return false +// } +// +// rm.KickOutUser(u) +// return true +//} +// +//// 游戏消息 +//func (rm *ColorRoom) OnGameMessage(subCmd int32, buffer []byte, user inter.UserInetr) { +// // log.Debug("收到客户端消息:", subCmd) +// switch pb.ColorPinoyLiveReceiveFromClientMessageType(subCmd) { +// case pb.ColorPinoyLiveReceiveFromClientMessageType_ColorPinoyLiveApplyRefresh: +// rm.GameSync(user) +// case pb.ColorPinoyLiveReceiveFromClientMessageType_ColorPinoyLiveApplyBetChips: +// monitor.GoSafe(rm.Bet, buffer, user) +// case pb.ColorPinoyLiveReceiveFromClientMessageType_ColorPinoyLiveApplyGetUserListInfo: +// monitor.GoSafe(rm.SendUserListInfo, user) +// case pb.ColorPinoyLiveReceiveFromClientMessageType_ColorPinoyLiveApplyGetTrend: +// monitor.GoSafe(rm.SendTrend, user) +// case pb.ColorPinoyLiveReceiveFromClientMessageType_ColorPinoyLiveApplyBetAgain: +// // go rm.AgainBet(user) +// monitor.GoSafe(rm.AgainBet, user) +// case pb.ColorPinoyLiveReceiveFromClientMessageType_ColorPinoyLiveApplyBetDouble: +// monitor.GoSafe(rm.BetDouble, user) +// case pb.ColorPinoyLiveReceiveFromClientMessageType_ColorPinoyLiveApplyUndoBet: +// monitor.GoSafe(rm.OnUndoBet, buffer, user) +// case pb.ColorPinoyLiveReceiveFromClientMessageType_ColorPinoyLiveApplyUseProps: +// monitor.GoSafe(rm.ApplyUseProps, buffer, user) +// case pb.ColorPinoyLiveReceiveFromClientMessageType_ColorPinoyLiveApplyLeave: +// monitor.GoSafe(rm.ApplyLeave, buffer, user) +// } +//} +// +//func (rm *ColorRoom) initDefaultDiceGameRoundReady() { +// // rm.DefaultLuckyDice = rm.GamePoker.ShuffleDices(1)[0] +// // +// // rm.DefaultNormalDices[0] = rm.GamePoker.ShuffleDices(1)[0] +// // rm.DefaultNormalDices[1] = rm.GamePoker.ShuffleDices(1)[0] +// // rm.DefaultNormalDices[2] = rm.GamePoker.ShuffleDices(1)[0] +//} +// +//// 开lucky dice +//func (rm *ColorRoom) OpenLuckyDice() { +// +// dealDice := rm.GetPairDice(1, 0, 1) +// +// if dealDice == nil || len(dealDice) < 1 { +// rm.LuckyDice = rm.GamePoker.ShuffleDices(1)[0] +// } else { +// deck := model.GetInitialDeck() +// rm.LuckyDice = deck[dealDice[0]-1] +// } +//} +// +//// 开3个普通 dice +//func (rm *ColorRoom) OpenThreeDice() { +// +// dealDice := rm.GetPairDice(3, 1, 4) +// if dealDice == nil || len(dealDice) < 3 { +// rm.NormalDices[0] = rm.GamePoker.ShuffleDices(1)[0] +// rm.NormalDices[1] = rm.GamePoker.ShuffleDices(1)[0] +// rm.NormalDices[2] = rm.GamePoker.ShuffleDices(1)[0] +// } else { +// deck := model.GetInitialDeck() +// rm.NormalDices[0] = deck[dealDice[0]-1] +// rm.NormalDices[1] = deck[dealDice[1]-1] +// rm.NormalDices[2] = deck[dealDice[2]-1] +// } +//} +// +//func (rm *ColorRoom) getUser(user inter.UserInetr) *model.User { +// // u, ok := rm.AllUserList[user.GetId()] +// u := rm.GetPlayer(user.GetId()) +// if u == nil { +// u = new(model.User) +// u.UserID = user.GetId() +// u.UserInetr = user +// u.Balance = user.GetScore() +// u.Carry = user.GetCarry() +// u.Time = time.Now().UnixNano() / 1e6 +// u.UserInetr = user +// rm.AddPlayer(u) +// u.ResetUserData() +// } +// +// return u +//} +// +//func (rm *ColorRoom) getRobotUser(user inter.UserInetr) *model.User { +// // u, ok := rm.AllUserList[user.GetId()] +// u := rm.GetPlayer(user.GetId()) +// if u == nil { +// u = new(model.User) +// u.UserID = user.GetId() +// u.UserInetr = user +// u.Balance = user.GetScore() +// u.Carry = user.GetCarry() +// u.Time = time.Now().UnixNano() / 1e6 +// u.UserInetr = user +// u.IsRobot = true +// rm.AddPlayer(u) +// u.ResetUserData() +// } +// +// return u +//} +// +//// 游戏开始入口..... +//func (rm *ColorRoom) GameStart() bool { +// if rm.GetGameStatus() == 0 { +// rm.Ready() +// rm.SyncServerMaintenance(0, "") +// _ = rm.LiveDelayUpdate() +// // 防止卡房间 +// rm.Table.AddTimerRepeat(60, 0, func() { +// if rm.LiveMgr.MaintenanceStatus == 1 { +// rm.Table.EndGame() +// } +// }) +// } else if rm.TimerJob != nil { +// } +// +// return true +//} +// +//func (rm *ColorRoom) GameRoundStart() { +// rm.RoomCfg = config.ResetConfig() +// rm.Cfg = &rm.RoomCfg.ColorPinoyLiveConfig +// rm.ServerStatus = gconfig.GConfig.GServConfig.Status +//} +// +//func (rm *ColorRoom) ResetTable() { +// rm.SetGameStatus(0) +//} +// +//// 关闭桌子 +//func (rm *ColorRoom) CloseTable() { +//} diff --git a/server/colorgame/room/helper.go b/server/colorgame/room/helper.go index aeb08b1..4de596f 100644 --- a/server/colorgame/room/helper.go +++ b/server/colorgame/room/helper.go @@ -1,1179 +1,1180 @@ package room -import ( - "encoding/json" - "fmt" - "game/common/proto/pb" - "github.com/fox/fox/ipb" - "github.com/fox/fox/log" - "sort" - "sync" - "time" -) - -func (rm *ColorRoom) SceneUserSitDown(user *model.User) { - _ = user - rm.SendOnlinePlayerNum() -} - -// CheckAndBet 检查并下注 -func (rm *ColorRoom) CheckAndBet(user *model.User, bets []*pb.ColorPinoyLiveBetReq) { - if len(bets) == 0 { - log.Error(rm.Log("玩家(%d) bets data err :%v ", bets)) - model.SendBetFailMessage(model.DataErr, user) - return - } - - betInfos := [config.BET_TYPE_NUM]int64{} - betCountInfos := [config.BET_TYPE_NUM]int64{} - totalBetAmount := int64(0) - oneBetMessage := &pb.ColorPinoyLiveS2CRepetBet{} - oneBetMessage.Uid = user.UserID - oneBetMessage.BetInfo = []*pb.ColorPinoyLiveBetSuccessMessage{} - - if rm.GetGameStatus() != pb.ColorPinoyLiveGameStatus_ColorPinoyLiveBetStatus { - log.Error(rm.Log("玩家(%d) UndoBet data err GetGameStatus:%v,LastTimeBet:%v ", user.UserID, rm.GetGameStatus(), user.LastTimeBet)) - model.SendBetFailMessage(model.StatusError, user) - return - } - - for _, bet := range bets { - // 判断下注下标和下注区域下标是否超出列表 - if _, ok := pb.ColorPinoyLiveBetTypeJP_name[int32(bet.BetType)]; !ok || - bet.BetLevel < 0 || bet.BetLevel >= int32(len(rm.RoomCfg.ColorPinoyLiveConfig.BetList)) || - bet.BetIndex < 0 || bet.BetIndex >= int32(len(rm.RoomCfg.ColorPinoyLiveConfig.BetList[bet.BetLevel])) { - log.Error(rm.Log("玩家(%d) bets data err BetLevel:%d BetIndex:%d ", bet.BetLevel, bet.BetIndex)) - model.SendBetFailMessage(model.DataErr, user) - return - } - // 下注总金额 - betAmountCount := rm.RoomCfg.ColorPinoyLiveConfig.BetList[bet.BetLevel][bet.BetIndex] - bet.BetAmount = betAmountCount - - if betAmountCount > user.Balance-totalBetAmount { - log.Debug(rm.Log("用户余额为:%v 总押注%d 押注%d", user.Balance, totalBetAmount, betAmountCount)) - model.SendBetFailMessage(model.ScoreLess, user) - return - } else { - totalBetAmount += betAmountCount - betInfos[bet.BetType%config.BET_TYPE_NUM] += betAmountCount - betCountInfos[bet.BetType%config.BET_TYPE_NUM] += 1 - } - } - - if totalBetAmount <= 0 || totalBetAmount+user.TotalBet > rm.RoomCfg.ColorPinoyLiveConfig.TotalBetLimit { - log.Error(rm.Log("DataErr totalBetAmount:%d err ", totalBetAmount)) - model.SendBetFailMessage(model.PlayerEarTopScore, user) - return - } - log.Debug(rm.LogEx(user, "下注区域最大金额:%v", rm.Cfg.AreaBetLimit)) - for i, num := range betInfos { - // 投注大于下注区域限制 - if (user.TotalBets[i] + num) > rm.Cfg.AreaBetLimit { - // log.Debug("PlayerEarTopScore totalBetAmount:%d err ", totalBetAmount) - model.SendBetFailMessage(model.PlayerEarTopScore, user) - return - } - } - - user.AddBalance(-totalBetAmount) - - if user.LastTimeBet == nil { - user.LastTimeBet = make([][]*pb.ColorPinoyLiveBetReq, 0) - } - user.LastTimeBet = append(user.LastTimeBet, bets) - user.TotalBet += totalBetAmount - // log.Debug("上次下注:", user.LastTimeBet) - rm.MutexData.Lock() - for i, num := range betInfos { - if num > 0 { - user.TotalBets[i] += num - rm.TotalBets[i] += num - - SendSuccessMessage := new(pb.ColorPinoyLiveBetSuccessMessage) - SendSuccessMessage.BetType = pb.ColorPinoyLiveBetTypeJP(i) - SendSuccessMessage.UserBet = num - SendSuccessMessage.UserBets = user.TotalBets[i] + num - SendSuccessMessage.TotalBets = rm.TotalBets[i] + num - oneBetMessage.BetInfo = append(oneBetMessage.BetInfo, SendSuccessMessage) - } - } - // 统计个区域投注次数 - // user.TotalBetsCount = make([]int64, config.BET_TYPE_NUM) - for i, count := range betCountInfos { - if count > 0 { - user.TotalBetsCount[i] += count - } - } - user.AllBet += totalBetAmount - user.NoBetCount = 0 - oneBetMessage.UserScore = user.Balance - // oneBetMessage.UserBets = user.TotalBets[:] - - rm.TotalBet += totalBetAmount - rm.MutexData.Unlock() - - rm.Table.Broadcast(int32(pb.ColorPinoyLiveSendToClientMessageType_ColorPinoyLiveNoticeGameSeatUserBet), oneBetMessage) - live.PushColorBet(&lws.CPLBet{ - Uid: user.UserID, - Nickname: user.UserInetr.GetNike(), - Bet: totalBetAmount, - Avatar: user.UserInetr.GetHead(), - }) -} - -func (rm *ColorRoom) UndoBet(user *model.User, undoType pb.ColorPinoyLiveUndoType) { - - betInfos := [config.BET_TYPE_NUM]int64{} - betCountInfos := [config.BET_TYPE_NUM]int64{} - totalBetAmount := int64(0) - undoBetMessage := &pb.S2CUndoBet{} - undoBetMessage.Uid = user.UserID - undoBetMessage.BetInfo = []*pb.ColorPinoyLiveBetSuccessMessage{} - undoBetMessage.UndoType = undoType - - if rm.GetGameStatus() != pb.ColorPinoyLiveGameStatus_ColorPinoyLiveBetStatus { - log.Error(rm.Log("玩家(%d) UndoBet data err GetGameStatus:%v,LastTimeBet:%v ", user.UserID, rm.GetGameStatus(), user.LastTimeBet)) - model.SendBetFailMessage(model.StatusError, user) - return - } - if len(user.LastTimeBet) == 0 { - log.Error(rm.Log("玩家(%d) LastTimeBet null err:%v ", user.UserID, user.LastTimeBet)) - model.SendBetFailMessage(model.LastBetNull, user) - return - } - var bets []*pb.ColorPinoyLiveBetReq - if undoType == pb.ColorPinoyLiveUndoType_ColorPinoyLiveUndoOne { - bets = user.LastTimeBet[len(user.LastTimeBet)-1] - } else if undoType == pb.ColorPinoyLiveUndoType_ColorPinoyLiveUndoAll { - for _, bet := range user.LastTimeBet { - bets = append(bets, bet...) - } - } else { - log.Error(rm.Log("玩家(%d) undoType err %v,", user.UserID, undoType)) - model.SendBetFailMessage(model.DataErr, user) - return - } - if len(bets) == 0 { - log.Error(rm.Log("玩家(%d) bets err %v,", user.UserID, bets)) - model.SendBetFailMessage(model.LastBetNull, user) - return - } - for _, bet := range bets { - // 判断下注下标和下注区域下标是否超出列表 - if _, ok := pb.ColorPinoyLiveBetTypeJP_name[int32(bet.BetType)]; !ok { - log.Error(rm.Log("玩家(%d) bet err %v,", bet)) - model.SendBetFailMessage(model.DataErr, user) - return - } - totalBetAmount += bet.BetAmount - betInfos[bet.BetType%config.BET_TYPE_NUM] += bet.BetAmount - betCountInfos[bet.BetType%config.BET_TYPE_NUM] += 1 - } - - if totalBetAmount > 0 { - user.AddBalance(totalBetAmount) - } - - if user.LastTimeBet != nil && len(user.LastTimeBet) > 0 { - if undoType == pb.ColorPinoyLiveUndoType_ColorPinoyLiveUndoOne { - user.LastTimeBet = user.LastTimeBet[:len(user.LastTimeBet)-1] - } else { - user.LastTimeBet = nil - } - } - - rm.MutexData.Lock() - for i, num := range betInfos { - user.TotalBets[i] -= num - rm.TotalBets[i] -= num - } - // 统计个区域投注次数 - for i, count := range betCountInfos { - if count > 0 { - user.TotalBetsCount[i] -= count - } - if user.TotalBetsCount[i] < 0 { - user.TotalBetsCount[i] = 0 - } - } - rm.TotalBet -= totalBetAmount - - user.TotalBet -= totalBetAmount - user.AllBet -= totalBetAmount - user.NoBetCount = 0 - - for i, num := range betInfos { - - SendSuccessMessage := new(pb.ColorPinoyLiveBetSuccessMessage) - SendSuccessMessage.SeatId = int32(user.SceneChairId) - SendSuccessMessage.BetType = pb.ColorPinoyLiveBetTypeJP(i) - SendSuccessMessage.UserBet = num - SendSuccessMessage.UserBets = user.TotalBets[i] - SendSuccessMessage.TotalBets = rm.TotalBets[i] - - undoBetMessage.BetInfo = append(undoBetMessage.BetInfo, SendSuccessMessage) - } - rm.MutexData.Unlock() - // 玩家当前分数 - undoBetMessage.UserScore = user.Balance - - // log.Debug("undoBetMessage %v", undoBetMessage) - rm.Table.Broadcast(int32(pb.ColorPinoyLiveSendToClientMessageType_ColorPinoyLiveNoticeUndoBet), undoBetMessage) - -} -func (rm *ColorRoom) KickOutUser(u *model.User) { - // delete(rm.AllUserList, k) - rm.DeletePlayer(u.UserID) - if u.SceneChairId != 0 { - rm.OnUserStanUp(u) - } - role := "机器人" - // rm.DeleteExitUserFromOnlineUserListSlice(u) - if !u.IsRobot { - rm.Table.KickOut(u.UserInetr) - role = "玩家" - } - log.Debug(rm.Log("删除(%s)(%d) 金额:%d 输赢:%d", role, u.UserID, u.Balance, u.Balance-u.UserInetr.GetScore())) - rm.SendOnlinePlayerNum() -} -func (rm *ColorRoom) TransInoutGameBet(user *model.User, bet int64) error { - if config.CHIPS_DEBUG { - user.Balance -= bet - return nil - } - user.Mn.Lock() - defer user.Mn.Unlock() - transferInOutResp, err := rm.Table.TransInoutGameCarryAdd(user.UserInetr, rm.Table.GetLevel(), bet, "") - if err != nil { - return err - } - user.Balance = transferInOutResp.Balance - user.Carry = transferInOutResp.Carry - user.UserInetr.SetPreserve(transferInOutResp.Preserve) - // time.Sleep(10 * time.Second) - return nil -} -func (rm *ColorRoom) TransInoutGameEnd(user *model.User, bet int64, amountWin int64, tax int64) (int64, error) { - if config.CHIPS_DEBUG || user.IsRobot { - user.Balance += amountWin - return amountWin, nil - } - transferInOutResp, err := rm.Table.TransInoutGameEnd(user.UserInetr, rm.Table.GetLevel(), bet+tax, amountWin+tax, "") - if err != nil { - return 0, err - } - user.Balance = transferInOutResp.GetBalance() - if transferInOutResp.GetRealTransfer() == 0 { - return 0, errors.New("error") - } - user.TransBet += bet - user.TransWin += amountWin - // time.Sleep(10 * time.Second) - return transferInOutResp.RealTransfer, nil -} - -func (rm *ColorRoom) ResetUserBet(user *model.User) { - rm.MutexData.Lock() - for i, bet := range user.TotalBets { - rm.TotalBets[i] -= bet - // rm.BetNumber[i] -= user.BetNumber[i] - } - rm.TotalBet -= user.TotalBet - rm.MutexData.Unlock() - user.TotalBet = 0 - user.TotalBets = [config.BET_TYPE_NUM]int64{} - // user.BetNumber = [config.BET_TYPE_NUM]int64{} - -} - -func (rm *ColorRoom) StartTransInoutBet() { - wg := new(sync.WaitGroup) - var failUser []*model.User - failMutx := &sync.Mutex{} - rm.Traverse(func(u *model.User) bool { - wg.Add(1) - go func(user *model.User) { - defer wg.Done() - user.Mn.Lock() - defer user.Mn.Unlock() - if user.TotalBet > 0 { - _, err := rm.TransInoutGameEnd(user, user.TotalBet, 0, 0) - if err != nil { - func() { - failMutx.Lock() - defer failMutx.Unlock() - failUser = append(failUser, user) - }() - } - } - }(u) - return true - }) - wg.Wait() - // 异步扣款完成后,处理部分扣款失败回滚操作 - if len(failUser) > 0 { - pbMsg := &pb.ColorPinoyLiveS2CBetEndFailResult{ - Code: 1, - } - for _, user := range failUser { - rm.ResetUserBet(user) - player := &pb.ColorPinoyLiveS2CRepetBet{} - player.UserScore = user.Balance - player.Uid = user.UserID - - var bets []*pb.ColorPinoyLiveBetReq - for _, bet := range user.LastTimeBet { - bets = append(bets, bet...) - } - for _, bet := range bets { - // 判断下注下标和下注区域下标是否超出列表 - if _, ok := pb.ColorPinoyLiveBetTypeJP_name[int32(bet.BetType)]; !ok { - log.Error(rm.Log("玩家(%d) bet err %v,", bet)) - model.SendBetFailMessage(model.DataErr, user) - return - } - SendSuccessMessage := new(pb.ColorPinoyLiveBetSuccessMessage) - SendSuccessMessage.BetIndex = bet.BetIndex - SendSuccessMessage.BetLevel = bet.BetLevel - SendSuccessMessage.BetType = bet.BetType - SendSuccessMessage.SeatId = int32(user.SceneChairId) - SendSuccessMessage.UserBet = bet.BetAmount - SendSuccessMessage.TotalBets = rm.TotalBets[bet.BetType] - - player.BetInfo = append(player.BetInfo, SendSuccessMessage) - } - pbMsg.Players = append(pbMsg.Players, player) - } - // log.Debug("玩家停止下注后 扣钱失败: %v", pbMsg) - rm.Table.Broadcast(int32(pb.ColorPinoyLiveSendToClientMessageType_ColorPinoyLiveNoticePlayerBetEndResultFailed), pbMsg) - } - // 大客投注 - var allWinner []*pb.ColorPinoyLiveBigWinner - rm.Traverse(func(user *model.User) bool { - if user.TotalBet > 0 { - allWinner = append(allWinner, &pb.ColorPinoyLiveBigWinner{NickName: user.UserInetr.GetNike(), Avatar: user.UserInetr.GetHead(), WinChips: user.TotalBet, AreaId: user.TotalBets[:]}) - } - return true - }) - rm.updateBigWinner(allWinner) - bigMsg := &pb.ColorPinoyLivePlayerBigWinner{BigBet: allWinner, Jackpot: rm.jackpotMgr.GetJackpot()} - rm.Table.Broadcast(int32(pb.ColorPinoyLiveSendToClientMessageType_ColorPinoyLiveNoticeGameBigWinner), bigMsg) - - rm.TimerJob, _ = rm.Table.AddTimer(time.Duration(rm.RoomCfg.TimeConf.Endmove), func() { - rm.NotifyBigBetAreaMul() - }) - allUserTotalBet := int64(0) // 所有玩家投注未中奖的总金额,用于计算jackpot池 - rm.Traverse(func(user *model.User) bool { - if user.TotalBet < 1 { - return true - } - allUserTotalBet += user.TotalBet - return true - }) - log.Debug(rm.Log("本局总投注金额为:%v 赎回比例:%v 追加比例:%v 满额追加比例:%v", allUserTotalBet, rm.Cfg.JpXRate, rm.Cfg.JpYRate, rm.Cfg.JpXYRate)) - rm.jackpotX, rm.jackpotY = rm.jackpotMgr.AddJp(allUserTotalBet, int64(rm.Cfg.JpXRate), int64(rm.Cfg.JpYRate), int64(rm.Cfg.JpXYRate)) - if rm.jackpotX > 0 || rm.jackpotY > 0 { - rm.kafkaJackpotUserRepaid(rm.jackpotX, rm.jackpotY) - } -} - -// 计算 下注区域中奖得分,返回是否有jp奖,jp奖位置,中奖人数 -func (rm *ColorRoom) CalculateJackpotScore() (pb.ColorPinoyLiveBetTypeJP, map[int64]int64) { - jackpotArea := pb.ColorPinoyLiveBetTypeJP(-1) - for _, winArea := range rm.PokerMsg.WinBetArea { - if !winArea.IsJackpot || !winArea.IsWin { - continue - } - color := getColorByBetArea(winArea.BetArea) - colorCount := getColorCount(rm.NormalDices, color) - if colorCount != 3 { - continue - } - jackpotArea = winArea.BetArea - rm.Traverse(func(user *model.User) bool { - if user.TotalBets[winArea.BetArea] <= 0 { - return true - } - rm.jackpotMgr.AddJpUser(user.UserID, user.TotalBets[winArea.BetArea]) - return true - }) - } - rm.jackpotUser, rm.costJackpot = rm.jackpotMgr.WinJackpot() - if rm.costJackpot > 0 { - rm.kafkaHitJackpot(rm.costJackpot, rm.jackpotUser) - } - log.Debug(rm.Log("本局是否中jackpot奖:%v, 玩家一起分走jackpot:%v, 当前jackpot值:%v", rm.costJackpot > 0, rm.costJackpot, rm.jackpotMgr.GetJackpot())) - return jackpotArea, rm.jackpotUser -} - -// 计算 所有玩家的下注区域中奖得分 -func (rm *ColorRoom) CalculateAllUserScore() { - // 赢钱会清空jackpot池 - jpArea, userJackPot := rm.CalculateJackpotScore() - var jackpotUserName []string - rm.Traverse(func(user *model.User) bool { - msg := new(pb.ColorPinoyLiveUserSettleMsg) - msg.WinAreaOdd = rm.PokerMsg.WinBetArea - msg.UserBets = rm.CopyArr(user.TotalBets) - msg.UserRealWins = make([]int64, config.BET_TYPE_NUM) - msg.UserWins = make([]int64, config.BET_TYPE_NUM) - - if user.TotalBet > 0 { - // 算分 - jpScore := userJackPot[user.UserID] - rm.CalculateScore(user, jpArea, jpScore, msg) - if jpScore > 0 { - jackpotUserName = append(jackpotUserName, user.UserInetr.GetNike()) - rm.BroadHitJackpot(user, jpScore) - } - } - // 统计玩家信息 - if msg.TotalWin > user.TotalBet { - user.UserCount(true, msg.TotalWin) - } else { - user.UserCount(false, 0) - } - user.Balance += msg.TotalWin - msg.UserScore = user.Balance - user.SettleMsg = msg - return true - }) - rm.Traverse(func(user *model.User) bool { - user.SettleMsg.JackpotUserName = jackpotUserName - return true - }) -} - -// 计算 下注区域中奖得分 -func (rm *ColorRoom) CalculateScore(user *model.User, jpArea pb.ColorPinoyLiveBetTypeJP, jpScore int64, msg *pb.ColorPinoyLiveUserSettleMsg) { - for _, winArea := range msg.WinAreaOdd { - if msg.UserBets[winArea.BetArea] <= 0 { - continue - } - if jpArea != winArea.BetArea { - odds := winArea.Odd - // 奖金计算公式 Payouts =( Odds * Bet ) * ( 1 + Bonus) + Bet odds 是倍率 Bonus是猜中幸运骰子 的加成 - // 本区域赢未扣税 倍率是百分值所以计算时要除以100 - win2 := (odds * msg.UserBets[winArea.BetArea]) / 100 - // 本区域赢扣税 - Gold := win2 * (100 - rm.RoomCfg.Rate) / 100 - // 算税() - msg.Tax += win2 - Gold - // 加回投注本金 - Gold += msg.UserBets[winArea.BetArea] - msg.TotalWin += Gold - // 统计赢区的下注总额 - msg.TotalWinBaseBet += msg.UserBets[winArea.BetArea] - - msg.UserWins[winArea.BetArea] += win2 - msg.UserRealWins[winArea.BetArea] += Gold - log.Debug(rm.LogEx(user, "算分 odds:%v 投注区:%v win2:%v Gold:%v", odds, winArea.BetArea, win2, Gold)) - } else { - win2 := jpScore - // 本区域赢扣税 - Gold := jpScore * (100 - rm.RoomCfg.Rate) / 100 - // 算税() - msg.Tax += win2 - Gold - // 加回投注本金 - Gold += msg.UserBets[winArea.BetArea] - msg.TotalWin += Gold - // 统计赢区的下注总额 - msg.TotalWinBaseBet += msg.UserBets[winArea.BetArea] - - msg.UserWins[winArea.BetArea] += win2 - msg.UserRealWins[winArea.BetArea] += Gold - msg.JackpotWin = Gold - log.Debug(rm.LogEx(user, "算分 jackpot 投注区:%v win2:%v Gold:%v", winArea.BetArea, win2, Gold)) - } - } - -} - -type areaWin struct { - areaId int64 - win int64 -} - -// 更新大赢家 -func (rm *ColorRoom) updateBigWinner(allWinner []*pb.ColorPinoyLiveBigWinner) { - // log.Debug(fmt.Sprintf("allWinner:%+v", allWinner)) - rm.BigWinner = rm.BigWinner[:0] - sort.Slice(allWinner, func(i, j int) bool { - return allWinner[i].WinChips > allWinner[j].WinChips - }) - if len(allWinner) > BigWinnerCount { - allWinner = allWinner[:BigWinnerCount] - } - for _, winner := range allWinner { - var areaWins []*areaWin - for areaId, win := range winner.AreaId { - if win > 0 { - areaWins = append(areaWins, &areaWin{areaId: int64(areaId), win: win}) - } - } - sort.Slice(areaWins, func(i, j int) bool { - return areaWins[i].win > areaWins[j].win - }) - if len(areaWins) > BigWinnerCount { - areaWins = areaWins[:BigWinnerCount] - } - winner.AreaId = make([]int64, 0, BigWinnerCount) - for _, area := range areaWins { - winner.AreaId = append(winner.AreaId, area.areaId) - } - } - rm.BigWinner = allWinner -} - -// 和平台做结算 -func (rm *ColorRoom) SetUserSettleMsg() { - var allWinner []*pb.ColorPinoyLiveBigWinner - rm.CalculateAllUserScore() - wg := new(sync.WaitGroup) - rm.Traverse(func(uu *model.User) bool { - wg.Add(1) - go func(u *model.User) { - defer wg.Done() - if u.TotalBet > 0 { - // 和平台做赢钱结算 - // if msg.TotalWin > 0 { - _, err := rm.TransInoutGameEnd(u, 0, u.SettleMsg.TotalWin, u.SettleMsg.Tax) - if err != nil { - log.Error(rm.Log(err.Error())) - // model.SendBetFailMessage(model.BalanceError, u) - } - // } - } - }(uu) - return true - }) - wg.Wait() - // 异步加钱完成后再执行后续的结算操作 - rm.Traverse(func(u *model.User) bool { - msg := u.SettleMsg - if msg == nil || msg.TotalWin < 1 { - return true - } - winner := &pb.ColorPinoyLiveBigWinner{ - NickName: u.UserInetr.GetNike(), - Avatar: u.UserInetr.GetHead(), - WinChips: msg.TotalWin, - AreaId: msg.UserRealWins, - } - allWinner = append(allWinner, winner) - log.Debug(rm.LogEx(u, "赢钱:%v", winner.WinChips)) - return true - }) - rm.updateBigWinner(allWinner) - - rm.SetGameTrend() - rm.sendSettleMsg2Client() - // log.Debug(time.Now().Unix() - rm.endAt) - rm.Table.EndGame() - rm.NotifyLiveDelayUpdate() // 通知延迟更新服务器配置,切换维护状态 - rm.TimerJob, _ = rm.Table.AddTimer(time.Duration(rm.RoomCfg.TimeConf.Endpay), func() { - rm.Rank() - }) -} - -func (rm *ColorRoom) CountUser(u *model.User) { - u.Icon = 0 - // rm.OnlineUserList = append(rm.OnlineUserList, u) -} -func (rm *ColorRoom) ResetData(all bool) { - rm.TotalBets = [config.BET_TYPE_NUM]int64{} - rm.TotalBet = 0 - rm.LuckyDice = 0 - rm.NormalDices = make([]byte, 3) - rm.StartDices = make([]byte, 3) - rm.ResultImgs = make([]string, 0) - rm.InitBigOddsBetAreas() - - if all { - rm.LiveMgr.Reset() - rm.Traverse(func(u *model.User) bool { - u.ResetUserData() - u.RetrunGold = 0 - return true - }) - } -} -func (rm *ColorRoom) GetPairDice(count int, startIndex int, endIndex int) []byte { - if gconfig.GConfig.IsProd() { - return nil - } - // PokerCard 表示一张扑克牌 - type Dice struct { - Color int // 花色 - Point int // 点数 - } - type PairDice struct { - Cards []Dice - } - key := fmt.Sprintf("preset-cards:0:color:%d", rm.Table.GetId()) - log.Debug(rm.Log("获取配牌配置 key:", key)) - str := redisf.RSC.GetPairCard(key) - if str == "" { - return nil - } - pairCard := new(PairDice) - err := json.Unmarshal([]byte(str), pairCard) - if err != nil { - log.Debug(rm.Log("getPairCard:%v", err)) - return nil - } - if len(pairCard.Cards) < 2 { - log.Error(rm.Log("getPairCard ", pairCard)) - return nil - } - log.Debug(rm.Log("getPairCard pairCard:%v", pairCard)) - var res []byte - for index, card := range pairCard.Cards { - if index >= startIndex && index < endIndex { - res = append(res, byte(card.Point)) - if (len(res)) == count { - break - } - } - } - return res -} - -func (rm *ColorRoom) GetGameTrend() (luckyRates []int32) { - // var mapLuckyRate = map[pb.ColorPinoyLiveDiceColorType]int32{} - // for _, trend := range rm.GameTrend.ListTrendGroup { - // mapLuckyRate[trend.LuckyDice]++ - // } - // for i := pb.ColorPinoyLiveDiceColorType_ColorPinoyLiveType_YELLOW; i <= pb.ColorPinoyLiveDiceColorType_ColorPinoyLiveType_GREEN; i++ { - // luckyRates = append(luckyRates, 0) - // } - // if len(mapLuckyRate) > 0 { - // for k, v := range mapLuckyRate { - // // log.Debug(fmt.Sprintf("颜色:%v 数量:%v 总数量:%v 配置:%v", k, v, len(rm.GameTrend.ListTrendGroup), config.WinTrendNum)) - // if int(k-1) < len(luckyRates) { - // luckyRates[k-1] = v * 10000 / int32(len(rm.GameTrend.ListTrendGroup)) - // } - // } - // } - - return luckyRates - -} - -func (rm *ColorRoom) SetGameTrend() { - - trendGroup := new(pb.ColorPinoyLiveTrendGroup) - trendGroup.LuckyDice = pb.ColorPinoyLiveDiceColorType(model.GetColor(rm.LuckyDice)) - for _, dice := range rm.NormalDices { - trendGroup.ThreeDice = append(trendGroup.ThreeDice, pb.ColorPinoyLiveDiceColorType(model.GetColor(dice))) - } - - rm.GameTrend.ListTrendGroup = append(rm.GameTrend.ListTrendGroup, trendGroup) - - // log.Debug("走势图 rm.GameTrend.ListTrendGroup: ", rm.GameTrend.ListTrendGroup) - winlen := len(rm.GameTrend.ListTrendGroup) - if winlen > config.WinTrendNum { - rm.GameTrend.ListTrendGroup = rm.GameTrend.ListTrendGroup[(winlen - config.WinTrendNum):] - } - - if rm.ServerStatus == define.GameStatusNoraml { - str, err := json.Marshal(rm.GameTrend.ListTrendGroup) - if err != nil { - return - } - redisf.RSC.SetColorGameTrend(rm.TrendRedisKey, str) - // log.Debug("SetGameTrend 保存走势图到redis :", str) - - } -} - -// 获取投注区域的颜色 -func getColorByBetArea(area pb.ColorPinoyLiveBetTypeJP) pb.ColorPinoyLiveDiceColorType { - switch area { - case pb.ColorPinoyLiveBetTypeJP_CLJ_Yellow, pb.ColorPinoyLiveBetTypeJP_CLJ_Double_Yellow, pb.ColorPinoyLiveBetTypeJP_CLJ_Three_Yellow: - return pb.ColorPinoyLiveDiceColorType_ColorPinoyLiveType_YELLOW - case pb.ColorPinoyLiveBetTypeJP_CLJ_White, pb.ColorPinoyLiveBetTypeJP_CLJ_Double_White, pb.ColorPinoyLiveBetTypeJP_CLJ_Three_White: - return pb.ColorPinoyLiveDiceColorType_ColorPinoyLiveType_WHITE - case pb.ColorPinoyLiveBetTypeJP_CLJ_Pink, pb.ColorPinoyLiveBetTypeJP_CLJ_Double_Pink, pb.ColorPinoyLiveBetTypeJP_CLJ_Three_Pink: - return pb.ColorPinoyLiveDiceColorType_ColorPinoyLiveType_PINK - case pb.ColorPinoyLiveBetTypeJP_CLJ_Blue, pb.ColorPinoyLiveBetTypeJP_CLJ_Double_Blue, pb.ColorPinoyLiveBetTypeJP_CLJ_Three_Blue: - return pb.ColorPinoyLiveDiceColorType_ColorPinoyLiveType_BLUE - case pb.ColorPinoyLiveBetTypeJP_CLJ_Red, pb.ColorPinoyLiveBetTypeJP_CLJ_Double_Red, pb.ColorPinoyLiveBetTypeJP_CLJ_Three_Red: - return pb.ColorPinoyLiveDiceColorType_ColorPinoyLiveType_RED - case pb.ColorPinoyLiveBetTypeJP_CLJ_Green, pb.ColorPinoyLiveBetTypeJP_CLJ_Double_Green, pb.ColorPinoyLiveBetTypeJP_CLJ_Three_Green: - return pb.ColorPinoyLiveDiceColorType_ColorPinoyLiveType_GREEN - } - return pb.ColorPinoyLiveDiceColorType_ColorPinoyLiveType_Void -} - -func getColorCount(result []byte, color pb.ColorPinoyLiveDiceColorType) int { - count := 0 - for _, c := range result { - if model.GetColor(c) == int32(color) { - count++ - } - } - return count -} - -func stringDices(result []byte) string { - s := "" - for _, c := range result { - s += fmt.Sprintf("%v", pb.ColorPinoyLiveDiceColorType(model.GetColor(c))) - } - return s -} - -// 检查投掷结果是否匹配某个下注区域 -func isWinningArea(result []byte, area pb.ColorPinoyLiveBetTypeJP) (win bool, bigPos pb.ColorPinoyLiveBigBetAreaPos, colorCount int) { - color := getColorByBetArea(area) - colorCount = getColorCount(result, color) - if colorCount == 0 { - return false, 0, colorCount - } - // 单色投注区,查看开出几个该颜色 - if area < pb.ColorPinoyLiveBetTypeJP_CLJ_Double_Yellow { - if colorCount == 1 { - return true, pb.ColorPinoyLiveBigBetAreaPos_BBA_Single_0, colorCount - } else if colorCount == 2 { - return true, pb.ColorPinoyLiveBigBetAreaPos_BBA_Single_1, colorCount - } else { - return true, pb.ColorPinoyLiveBigBetAreaPos_BBA_Single_2, colorCount - } - } else if area < pb.ColorPinoyLiveBetTypeJP_CLJ_Three_Yellow { - if colorCount > 1 { - return true, pb.ColorPinoyLiveBigBetAreaPos_BBA_Double, colorCount - } - } else { - if colorCount > 2 { - return true, pb.ColorPinoyLiveBigBetAreaPos_BBA_Three, colorCount - } - } - return false, 0, colorCount -} - -// 计算开奖结果 -func (rm *ColorRoom) CompareDiceResult() { - var wins []*pb.ColorPinoyLiveBetAreaOdd - // // 存储中奖区域 - result := rm.NormalDices - log.Debug(rm.Log("开奖结果:%v", stringDices(result))) - rm.afterBetAreaOdds = rm.afterBetAreaOdds[0:0] - // 检查所有下注区域是否中奖 - for pos, area := range rm.betEndBetAreasOdds { - betAreaOdd := &pb.ColorPinoyLiveBetAreaOdd{ - BetArea: area.BetType, - Odd: area.Odd[0], - ViewOdd: 0, - IsBigOdd: area.IsBigOdd, - BigSingleColorOddPos: area.BigSingleColorOddPos, - IsWin: false, - IsJackpot: area.IsJackpot, - } - if pos/6 == 0 { - // 第一行投注区域,赔率是多个赔率中的一个 - betAreaOdd.Odd = area.Odd[area.BigSingleColorOddPos] - } else { - betAreaOdd.Odd = area.Odd[0] - } - betAreaOdd.ViewOdd = betAreaOdd.Odd - // 更新实际赔率 - isWin, winOddPos, colorCount := isWinningArea(result, area.BetType) - betAreaOdd.IsWin = isWin - if betAreaOdd.IsWin { - if betAreaOdd.IsJackpot && colorCount == 3 { - betAreaOdd.Odd = 0 - } else { - if winOddPos == pb.ColorPinoyLiveBigBetAreaPos_BBA_Single_0 { - betAreaOdd.Odd = area.Odd[0] - } else if winOddPos == pb.ColorPinoyLiveBigBetAreaPos_BBA_Single_1 { - betAreaOdd.Odd = area.Odd[1] - } else if winOddPos == pb.ColorPinoyLiveBigBetAreaPos_BBA_Single_2 { - betAreaOdd.Odd = area.Odd[2] - } - // 爆奖需要修正 - if betAreaOdd.IsBigOdd && winOddPos > betAreaOdd.BigSingleColorOddPos { - betAreaOdd.Odd = area.Odd[area.BigSingleColorOddPos] - } - } - wins = append(wins, betAreaOdd) - } - - // 修正牌局记录倍率 - tmpAreaOdd := &pb.ColorPinoyLiveBetAreaOdd{ - BetArea: betAreaOdd.BetArea, - Odd: betAreaOdd.Odd, - ViewOdd: betAreaOdd.ViewOdd, - IsBigOdd: betAreaOdd.IsBigOdd, - BigSingleColorOddPos: betAreaOdd.BigSingleColorOddPos, - IsWin: betAreaOdd.IsWin, - IsJackpot: betAreaOdd.IsJackpot, - } - if !tmpAreaOdd.IsWin && pos/6 == 0 && - (betAreaOdd.BigSingleColorOddPos == pb.ColorPinoyLiveBigBetAreaPos_BBA_Single_1 || - betAreaOdd.BigSingleColorOddPos == pb.ColorPinoyLiveBigBetAreaPos_BBA_Single_2) { - tmpAreaOdd.Odd = area.Odd[0] - if !tmpAreaOdd.IsBigOdd { - tmpAreaOdd.ViewOdd = tmpAreaOdd.Odd - } - } - if !tmpAreaOdd.IsWin && pos/6 == 1 && tmpAreaOdd.IsBigOdd { - tmpAreaOdd.Odd = rm.RoomCfg.ColorPinoyLiveConfig.WinDoubleColorMul[0].Mul - } - if !tmpAreaOdd.IsWin && pos/6 == 2 && tmpAreaOdd.IsBigOdd { - tmpAreaOdd.Odd = rm.RoomCfg.ColorPinoyLiveConfig.WinThreeColorMul[0].Mul - } - - rm.afterBetAreaOdds = append(rm.afterBetAreaOdds, tmpAreaOdd) - log.Debug(rm.Log("开奖,区域:%v 是否中奖:%v 实际赔率:%v 显示赔率:%v 是否爆奖:%v 爆奖位置:%v", betAreaOdd.BetArea, betAreaOdd.IsWin, betAreaOdd.Odd, - betAreaOdd.ViewOdd, betAreaOdd.IsBigOdd, betAreaOdd.BigSingleColorOddPos)) - } - rm.PokerMsg.WinBetArea = wins -} - -// 检查用户是否被踢掉 -func (rm *ColorRoom) checkUserBet() { - kickMsg, isKick := redisf.RSC.IsGameMaintenance(gconfig.GConfig.GRoomConfig.ChannelId, gconfig.GConfig.GServConfig.GameId) - rm.Traverse(func(u *model.User) bool { - u.NoBetCount++ - if isKick { - msg := new(pb.ColorPinoyLiveKickOutUserMsg) - // msg.KickOutReason = fmt.Sprintf("you did not bet %d games", rm.RoomCfg.LongHuConfig.NoBetCountMax) - msg.Reason = int32(pb.ColorPinoyLiveLeaveReason_ColorPinoyLiveLeaveReason_Maintaince) - msg.KickOutReason = kickMsg - u.SendMsg(int32(pb.ColorPinoyLiveSendToClientMessageType_ColorPinoyLiveNoticeKickOutUser), msg) - u.NoBetCount = 0 - rm.KickOutUser(u) - return true - } - if rm.ServerStatus != define.GameStatusNoraml || u.UserInetr.NeedKickout() { - msg := new(pb.ColorPinoyLiveKickOutUserMsg) - // msg.KickOutReason = fmt.Sprintf("game server maintenance ") - msg.Reason = int32(pb.ColorPinoyLiveLeaveReason_ColorPinoyLiveLeaveReason_PLAYER_QUIT_ROOM) - u.SendMsg(int32(pb.ColorPinoyLiveSendToClientMessageType_ColorPinoyLiveNoticeKickOutUser), msg) - rm.KickOutUser(u) - return true - } - if redisf.RSC.IsUserLiveBan(u.UserInetr.GetOpToken(), int64(gconfig.GConfig.GRoomConfig.GameId), u.UserID) { - msg := new(pb.ColorPinoyLiveKickOutUserMsg) - msg.Reason = int32(pb.ColorPinoyLiveLeaveReason_ColorPinoyLiveLeaveReason_Ban) - u.SendMsg(int32(pb.ColorPinoyLiveSendToClientMessageType_ColorPinoyLiveNoticeKickOutUser), msg) - rm.KickOutUser(u) - return true - } - // if u.NoBetCount >= (rm.RoomCfg.ColorPinoyLiveConfig.NoBetCountMax + 1) { - // msg := new(pb.ColorPinoyLiveKickOutUserMsg) - // // msg.KickOutReason = fmt.Sprintf("you did not bet %d games", rm.RoomCfg.LongHuConfig.NoBetCountMax) - // msg.Reason = 1 - // u.SendMsg(int32(pb.ColorPinoyLiveSendToClientMessageType_ColorPinoyLiveNoticeKickOutUser), msg) - // // 踢掉用户 - // u.NoBetCount = 0 - // rm.KickOutUser(u) - // return true - // } - - return true - }) -} - -// 初始走势图 -func (rm *ColorRoom) InitWinTrend() { - rm.TrendRedisKey = fmt.Sprintf("pb.:%d:%d:trend", gconfig.GConfig.GDataConfig.VersionMode, rm.RoomCfg.Level) - if rm.ServerStatus == define.GameStatusNoraml { - winTrend := redisf.RSC.GetColorGameTrend(rm.TrendRedisKey) - if winTrend != "" { - rm.GameTrend = new(pb.ColorPinoyLiveTrend) - rm.GameTrend.ListTrendGroup = []*pb.ColorPinoyLiveTrendGroup{} - err := json.Unmarshal([]byte(winTrend), &rm.GameTrend.ListTrendGroup) - winlen := len(rm.GameTrend.ListTrendGroup) - // log.Debug("初始化走势图1:", len(rm.GameTrend.ListTrendGroup)) - if winlen > config.WinTrendNum { - rm.GameTrend.ListTrendGroup = rm.GameTrend.ListTrendGroup[(winlen - config.WinTrendNum):] - // log.Debug("初始化走势图2:", len(rm.GameTrend.ListTrendGroup)) - } - // log.Debug("初始化走势图:", rm.GameTrend.ListTrendGroup) - if err != nil { - log.Error(rm.Log("初始化走势图:%v", err)) - } - } - - } - -} - -func (rm *ColorRoom) DeleteExitUserFromOnlineUserListSlice(user *model.User) { - rm.MutexUserList.Lock() - defer rm.MutexUserList.Unlock() - for k, v := range rm.OnlineUserList { - if user == v { - rm.OnlineUserList = append(rm.OnlineUserList[:k], rm.OnlineUserList[k+1:]...) - break - } - } -} - -func (rm *ColorRoom) SelectUserListBalanceTopSitDownChair() { - rm.MutexUserList.Lock() - rm.SceneInfo.ClearSceneChairId() - rm.SceneInfo.Init() - index := len(rm.OnlineUserList) - if index >= config.SEAT_NUM { - index = config.SEAT_NUM - } - cou := model.Usercount{} - cou = rm.OnlineUserList - sort.Sort(cou) - for i := 0; i < index; i++ { - u := rm.OnlineUserList[i] - ChairId := i + 1 - if rm.SceneInfo.SitScene(u, ChairId) { - u.SceneChairId = ChairId - } - } - rm.MutexUserList.Unlock() - -} - -func (rm *ColorRoom) CopyArr(arr [config.BET_TYPE_NUM]int64) []int64 { - slice := make([]int64, len(arr)) - copy(slice, arr[:]) - return slice -} - -func (rm *ColorRoom) GameDiscard() { - rm.TimerJob.Cancel() - rm.GameUserDiscard() - // rm.TimerJob, _ = rm.Table.AddTimer(1000, func() { - // rm.LiveCnt(rm.Ready, false, true, []bool{true}...) - // }) - rm.ResetData(false) - rm.Traverse(func(user *model.User) bool { - if rm.LiveMgr.MaintenanceStatus == 1 { - rm.sendUserMainte(user, int32(pb.ColorPinoyLiveSendToClientMessageType_ColorPinoyLiveNoticeGameMainte)) - } - if rm.LiveMgr.DiscardStatus == 1 { - rm.sendUserMainte(user, int32(pb.ColorPinoyLiveSendToClientMessageType_ColorPinoyLiveNoticeDiscard)) - } - return true - }) - rm.Ready() -} - -func (rm *ColorRoom) sendUserMainte(user *model.User, cmd int32) { - userinfo := new(pb.ColorPinoyLiveUserInfo) - userinfo.NikeName = user.UserInetr.GetNike() - userinfo.UserGlod = user.Balance - userinfo.Head = user.UserInetr.GetHead() - userinfo.UserID = user.UserID - _ = user.UserInetr.SendMsg(cmd, &pb.ColorPinoyLiveMainteNtf{ - UserInfo: userinfo, - MaintMsg: rm.LiveMgr.MainteMsg, - ReturnGold: user.RetrunGold, - }) -} - -func (rm *ColorRoom) GameUserDiscard() { - rm.MutexStatus.RLock() - defer rm.MutexStatus.RUnlock() - log.Debug(rm.Log("流局,状态:%v,分出去的jackpot:%v", rm.GetGameStatus(), rm.costJackpot)) - // 回退 - if rm.GetGameStatus() >= pb.ColorPinoyLiveGameStatus_ColorPinoyLiveEndBetMovie && rm.GetGameStatus() < pb.ColorPinoyLiveGameStatus_ColorPinoyLiveSettleStatus { - rm.jackpotMgr.RollBackJpXAndJpY(0, 0, rm.jackpotX, rm.jackpotY) - rm.kafkaBackJackpot(0, rm.jackpotX, rm.jackpotY, rm.jackpotUser) - } else if rm.GetGameStatus() >= pb.ColorPinoyLiveGameStatus_ColorPinoyLiveSettleStatus { - rm.jackpotMgr.RollBackJpXAndJpY(rm.costJackpot, rm.jackpotFunding, rm.jackpotX, rm.jackpotY) - rm.kafkaBackJackpot(rm.costJackpot, rm.jackpotX, rm.jackpotY, rm.jackpotUser) - } - - var betCount int64 - GameTotalBets := make([]int64, config.BET_TYPE_NUM) - var PlayerData []*pb.ColorPinoyLivePlayerData - copyBetAreaMul := rm.copyBetAreaOdds() - wg := new(sync.WaitGroup) - playerDataMu := new(sync.Mutex) - rm.Traverse(func(v *model.User) bool { - wg.Add(1) - monitor.GoSafe(func(u *model.User) { - defer wg.Done() - u.RetrunGold = u.TotalBet - msg := new(pb.ColorPinoyLiveUserSettleMsg) - msg.UserBets = rm.CopyArr(u.TotalBets) - msg.UserRealWins = make([]int64, config.BET_TYPE_NUM) - msg.UserWins = make([]int64, config.BET_TYPE_NUM) - msg.WinAreaOdd = rm.PokerMsg.WinBetArea - msg.UserScore = u.Balance - u.SettleMsg = msg - // 写入数据库统计信息 - if u.TotalBet > 0 { - for i, bet := range u.TotalBets { - betCount += bet - GameTotalBets[i] += bet - } - // 玩家下注区域统计 - u.SettleMsg.UserBetsCount = make([]int64, config.BET_TYPE_NUM) - for i, count := range u.TotalBetsCount { - u.SettleMsg.UserBetsCount[i] = count - } - if rm.GetGameStatus() < pb.ColorPinoyLiveGameStatus_ColorPinoyLiveEndBetMovie { - u.AddBalance(u.TotalBet) - } else if rm.GetGameStatus() < pb.ColorPinoyLiveGameStatus_ColorPinoyLiveSettleStatus { - _, err := rm.TransInoutGameEnd(u, u.TransWin, u.TransBet, 0) - if err != nil { - log.Error(rm.Log("discard error:%v, game_no:%s, uid:%d, TransWin:%d, TransBet:%d", err, rm.Table.GetGameRoundId(), u.UserID, u.TransWin, u.TransBet)) - } - } else { - if rm.LiveMgr.DiscardStatus == 1 { - _, err := rm.TransInoutGameEnd(u, u.TransWin, u.TransBet, 0) - if err != nil { - log.Error(rm.Log("discard error:%v, game_no:%s, uid:%d, TransWin:%d, TransBet:%d", err, rm.Table.GetGameRoundId(), u.UserID, u.TransWin, u.TransBet)) - } - } else { - return - } - } - func() { - playerDataMu.Lock() - defer playerDataMu.Unlock() - PlayerData = append(PlayerData, &pb.ColorPinoyLivePlayerData{ - Uid: u.UserID, - TotalBets: u.SettleMsg.UserBets, // 玩家各个区域的总下注额 - TotalBet: u.TotalBet, - Profit: u.SettleMsg.TotalWin, - Tax: u.SettleMsg.Tax, - Balance: u.Balance, - PreBalance: u.PreBalance, - UserWins: u.SettleMsg.UserWins, // 玩家赢取的下注区域总下注额 - UserRealWins: u.SettleMsg.UserRealWins, // 玩家赢取的下注区域总下注额 扣税后 - AreaOdds: copyBetAreaMul, // 投注区域倍率 - StartTime: u.StartAt, - TransBet: u.TransBet, - TransWin: u.TransWin, - DevMode: u.UserInetr.GetDevMode(), - UserBetsCount: u.SettleMsg.UserBetsCount, - IsDiscard: 1, - }) - }() - } - u.ResetUserData() - }, v) - return true - }) - wg.Wait() - // 发布事件 - if PlayerData == nil || len(PlayerData) == 0 { - return - } - // 开奖结果 - gameDetail := &pb.ColorPinoyLiveDetail{DealerName: rm.dealerName, ResultImg: rm.ResultImgs} - gameDetail.BetAreaMul = copyBetAreaMul - gameRecordData := &pb.ColorPinoyLiveEnd{ - GameNo: fmt.Sprintf("%d|%d|%d", gconfig.GConfig.GRoomConfig.GameId, rm.Table.GetId(), time.Now().UnixMilli()), - StartTime: rm.startAt, - EndTime: rm.endAt, - Level: gconfig.GConfig.GRoomConfig.Level, - BaseBet: rm.RoomCfg.BaseBet, - PlayerData: PlayerData, - TaxRate: rm.RoomCfg.Rate, - TotalBet: betCount, - TotalBets: GameTotalBets[:], - OpToken: gconfig.GConfig.GServConfig.ChannelId, - Detail: gameDetail, - IsDiscard: 1, - } - log.Debug("GameUserDiscard") - go func() { - err := gconfig.Produce(context.Background(), define.TopicColoLiveGameGameEnd, gameRecordData) - if err != nil { - log.Error(rm.Log("[%s] fail to Produce TongitsGameEndEvent(%+v), err: %v", gameRecordData.GameNo, gameRecordData, err)) - } - }() -} - -func (rm *ColorRoom) LoadDealerNames() { - ssv := redisf.RSC.DealerNameGet(gconfig.GConfig.GDataConfig.VersionMode, gconfig.GConfig.GRoomConfig.GameId, GameName) - var dealerNames []string - _ = json.Unmarshal([]byte(ssv), &dealerNames) - rm.dealerName = dealerNames - log.Debug(rm.Log("dealerNames:%v", rm.dealerName)) -} - -// 发送垫资kafka -func (rm *ColorRoom) kafkaJackpotFunding(funding int64) { - msg := &events.JackpotEvent{ - EventType: events.JackpotEvent_et_funding, - GameId: rm.RoomCfg.GameId, - Time: time.Now().UnixMilli(), - Funding: &events.JackpotEvent_Funding{Funding: funding}, - GameNo: rm.Table.GetGameRoundId(), - } - go func() { - err := gconfig.Produce(context.Background(), define.TopicJackpot, msg) - if err != nil { - log.Error(rm.Log("kafka JackpotEvent_et_funding err: %v", err)) - } - }() - log.Debug(rm.Log("kafka 垫资:%v", funding)) -} - -// 发送赎回及追加kafka -func (rm *ColorRoom) kafkaJackpotUserRepaid(jpx, jpy int64) { - msg := &events.JackpotEvent{ - EventType: events.JackpotEvent_et_user_repaid, - GameId: rm.RoomCfg.GameId, - Time: time.Now().UnixMilli(), - UserRepaid: &events.JackpotEvent_UserRepaid{JackpotX: jpx, JackpotY: jpy}, - GameNo: rm.Table.GetGameRoundId(), - } - go func() { - err := gconfig.Produce(context.Background(), define.TopicJackpot, msg) - if err != nil { - log.Error(rm.Log("kafka JackpotEvent_et_user_repaid err: %v", err)) - } - }() - log.Debug(rm.Log("kafka 赎回jpx:%v 追加jpy:%v", jpx, jpy)) -} - -// 中jackpot分奖 -func (rm *ColorRoom) kafkaHitJackpot(jackpot int64, userJp map[int64]int64) { - msg := &events.JackpotEvent{ - EventType: events.JackpotEvent_et_hit_jackpot, - GameId: rm.RoomCfg.GameId, - Time: time.Now().UnixMilli(), - HitJackpot: &events.JackpotEvent_HitJackpot{SumJackpot: jackpot, UserJackpot: userJp}, - GameNo: rm.Table.GetGameRoundId(), - } - go func() { - err := gconfig.Produce(context.Background(), define.TopicJackpot, msg) - if err != nil { - log.Error(rm.Log("kafka JackpotEvent_HitJackpot err: %v", err)) - } - }() - log.Debug(rm.Log("kafka 中jackpot:%v", jackpot)) -} - -func (rm *ColorRoom) kafkaBackJackpot(jackpot, jpx, jpy int64, userJp map[int64]int64) { - userJp2 := make(map[int64]int64) - for k, v := range userJp { - userJp2[k] = -v - } - msg := &events.JackpotEvent{ - EventType: events.JackpotEvent_et_game_discard, - GameId: rm.RoomCfg.GameId, - Time: time.Now().UnixMilli(), - GameDiscard: &events.JackpotEvent_GameDiscard{ - Jackpot: -jackpot, - JackpotX: -jpx, - JackpotY: -jpy, - UserJackpot: userJp2, - }, - GameNo: rm.Table.GetGameRoundId(), - } - go func() { - err := gconfig.Produce(context.Background(), define.TopicJackpot, msg) - if err != nil { - log.Error(rm.Log("kafka JackpotEvent_HitJackpot err: %v", err)) - } - }() - log.Debug(rm.Log("kafka 回退jackpot:%v jpx:%v jpy:%v", -jackpot, -jpx, -jpy)) -} +// +//import ( +// "encoding/json" +// "fmt" +// "game/common/proto/pb" +// "github.com/fox/fox/ipb" +// "github.com/fox/fox/log" +// "sort" +// "sync" +// "time" +//) +// +//func (rm *ColorRoom) SceneUserSitDown(user *model.User) { +// _ = user +// rm.SendOnlinePlayerNum() +//} +// +//// CheckAndBet 检查并下注 +//func (rm *ColorRoom) CheckAndBet(user *model.User, bets []*pb.ColorPinoyLiveBetReq) { +// if len(bets) == 0 { +// log.Error(rm.Log("玩家(%d) bets data err :%v ", bets)) +// model.SendBetFailMessage(model.DataErr, user) +// return +// } +// +// betInfos := [config.BET_TYPE_NUM]int64{} +// betCountInfos := [config.BET_TYPE_NUM]int64{} +// totalBetAmount := int64(0) +// oneBetMessage := &pb.ColorPinoyLiveS2CRepetBet{} +// oneBetMessage.Uid = user.UserID +// oneBetMessage.BetInfo = []*pb.ColorPinoyLiveBetSuccessMessage{} +// +// if rm.GetGameStatus() != pb.ColorPinoyLiveGameStatus_ColorPinoyLiveBetStatus { +// log.Error(rm.Log("玩家(%d) UndoBet data err GetGameStatus:%v,LastTimeBet:%v ", user.UserID, rm.GetGameStatus(), user.LastTimeBet)) +// model.SendBetFailMessage(model.StatusError, user) +// return +// } +// +// for _, bet := range bets { +// // 判断下注下标和下注区域下标是否超出列表 +// if _, ok := pb.ColorPinoyLiveBetTypeJP_name[int32(bet.BetType)]; !ok || +// bet.BetLevel < 0 || bet.BetLevel >= int32(len(rm.RoomCfg.ColorPinoyLiveConfig.BetList)) || +// bet.BetIndex < 0 || bet.BetIndex >= int32(len(rm.RoomCfg.ColorPinoyLiveConfig.BetList[bet.BetLevel])) { +// log.Error(rm.Log("玩家(%d) bets data err BetLevel:%d BetIndex:%d ", bet.BetLevel, bet.BetIndex)) +// model.SendBetFailMessage(model.DataErr, user) +// return +// } +// // 下注总金额 +// betAmountCount := rm.RoomCfg.ColorPinoyLiveConfig.BetList[bet.BetLevel][bet.BetIndex] +// bet.BetAmount = betAmountCount +// +// if betAmountCount > user.Balance-totalBetAmount { +// log.Debug(rm.Log("用户余额为:%v 总押注%d 押注%d", user.Balance, totalBetAmount, betAmountCount)) +// model.SendBetFailMessage(model.ScoreLess, user) +// return +// } else { +// totalBetAmount += betAmountCount +// betInfos[bet.BetType%config.BET_TYPE_NUM] += betAmountCount +// betCountInfos[bet.BetType%config.BET_TYPE_NUM] += 1 +// } +// } +// +// if totalBetAmount <= 0 || totalBetAmount+user.TotalBet > rm.RoomCfg.ColorPinoyLiveConfig.TotalBetLimit { +// log.Error(rm.Log("DataErr totalBetAmount:%d err ", totalBetAmount)) +// model.SendBetFailMessage(model.PlayerEarTopScore, user) +// return +// } +// log.Debug(rm.LogEx(user, "下注区域最大金额:%v", rm.Cfg.AreaBetLimit)) +// for i, num := range betInfos { +// // 投注大于下注区域限制 +// if (user.TotalBets[i] + num) > rm.Cfg.AreaBetLimit { +// // log.Debug("PlayerEarTopScore totalBetAmount:%d err ", totalBetAmount) +// model.SendBetFailMessage(model.PlayerEarTopScore, user) +// return +// } +// } +// +// user.AddBalance(-totalBetAmount) +// +// if user.LastTimeBet == nil { +// user.LastTimeBet = make([][]*pb.ColorPinoyLiveBetReq, 0) +// } +// user.LastTimeBet = append(user.LastTimeBet, bets) +// user.TotalBet += totalBetAmount +// // log.Debug("上次下注:", user.LastTimeBet) +// rm.MutexData.Lock() +// for i, num := range betInfos { +// if num > 0 { +// user.TotalBets[i] += num +// rm.TotalBets[i] += num +// +// SendSuccessMessage := new(pb.ColorPinoyLiveBetSuccessMessage) +// SendSuccessMessage.BetType = pb.ColorPinoyLiveBetTypeJP(i) +// SendSuccessMessage.UserBet = num +// SendSuccessMessage.UserBets = user.TotalBets[i] + num +// SendSuccessMessage.TotalBets = rm.TotalBets[i] + num +// oneBetMessage.BetInfo = append(oneBetMessage.BetInfo, SendSuccessMessage) +// } +// } +// // 统计个区域投注次数 +// // user.TotalBetsCount = make([]int64, config.BET_TYPE_NUM) +// for i, count := range betCountInfos { +// if count > 0 { +// user.TotalBetsCount[i] += count +// } +// } +// user.AllBet += totalBetAmount +// user.NoBetCount = 0 +// oneBetMessage.UserScore = user.Balance +// // oneBetMessage.UserBets = user.TotalBets[:] +// +// rm.TotalBet += totalBetAmount +// rm.MutexData.Unlock() +// +// rm.Table.Broadcast(int32(pb.ColorPinoyLiveSendToClientMessageType_ColorPinoyLiveNoticeGameSeatUserBet), oneBetMessage) +// live.PushColorBet(&lws.CPLBet{ +// Uid: user.UserID, +// Nickname: user.UserInetr.GetNike(), +// Bet: totalBetAmount, +// Avatar: user.UserInetr.GetHead(), +// }) +//} +// +//func (rm *ColorRoom) UndoBet(user *model.User, undoType pb.ColorPinoyLiveUndoType) { +// +// betInfos := [config.BET_TYPE_NUM]int64{} +// betCountInfos := [config.BET_TYPE_NUM]int64{} +// totalBetAmount := int64(0) +// undoBetMessage := &pb.S2CUndoBet{} +// undoBetMessage.Uid = user.UserID +// undoBetMessage.BetInfo = []*pb.ColorPinoyLiveBetSuccessMessage{} +// undoBetMessage.UndoType = undoType +// +// if rm.GetGameStatus() != pb.ColorPinoyLiveGameStatus_ColorPinoyLiveBetStatus { +// log.Error(rm.Log("玩家(%d) UndoBet data err GetGameStatus:%v,LastTimeBet:%v ", user.UserID, rm.GetGameStatus(), user.LastTimeBet)) +// model.SendBetFailMessage(model.StatusError, user) +// return +// } +// if len(user.LastTimeBet) == 0 { +// log.Error(rm.Log("玩家(%d) LastTimeBet null err:%v ", user.UserID, user.LastTimeBet)) +// model.SendBetFailMessage(model.LastBetNull, user) +// return +// } +// var bets []*pb.ColorPinoyLiveBetReq +// if undoType == pb.ColorPinoyLiveUndoType_ColorPinoyLiveUndoOne { +// bets = user.LastTimeBet[len(user.LastTimeBet)-1] +// } else if undoType == pb.ColorPinoyLiveUndoType_ColorPinoyLiveUndoAll { +// for _, bet := range user.LastTimeBet { +// bets = append(bets, bet...) +// } +// } else { +// log.Error(rm.Log("玩家(%d) undoType err %v,", user.UserID, undoType)) +// model.SendBetFailMessage(model.DataErr, user) +// return +// } +// if len(bets) == 0 { +// log.Error(rm.Log("玩家(%d) bets err %v,", user.UserID, bets)) +// model.SendBetFailMessage(model.LastBetNull, user) +// return +// } +// for _, bet := range bets { +// // 判断下注下标和下注区域下标是否超出列表 +// if _, ok := pb.ColorPinoyLiveBetTypeJP_name[int32(bet.BetType)]; !ok { +// log.Error(rm.Log("玩家(%d) bet err %v,", bet)) +// model.SendBetFailMessage(model.DataErr, user) +// return +// } +// totalBetAmount += bet.BetAmount +// betInfos[bet.BetType%config.BET_TYPE_NUM] += bet.BetAmount +// betCountInfos[bet.BetType%config.BET_TYPE_NUM] += 1 +// } +// +// if totalBetAmount > 0 { +// user.AddBalance(totalBetAmount) +// } +// +// if user.LastTimeBet != nil && len(user.LastTimeBet) > 0 { +// if undoType == pb.ColorPinoyLiveUndoType_ColorPinoyLiveUndoOne { +// user.LastTimeBet = user.LastTimeBet[:len(user.LastTimeBet)-1] +// } else { +// user.LastTimeBet = nil +// } +// } +// +// rm.MutexData.Lock() +// for i, num := range betInfos { +// user.TotalBets[i] -= num +// rm.TotalBets[i] -= num +// } +// // 统计个区域投注次数 +// for i, count := range betCountInfos { +// if count > 0 { +// user.TotalBetsCount[i] -= count +// } +// if user.TotalBetsCount[i] < 0 { +// user.TotalBetsCount[i] = 0 +// } +// } +// rm.TotalBet -= totalBetAmount +// +// user.TotalBet -= totalBetAmount +// user.AllBet -= totalBetAmount +// user.NoBetCount = 0 +// +// for i, num := range betInfos { +// +// SendSuccessMessage := new(pb.ColorPinoyLiveBetSuccessMessage) +// SendSuccessMessage.SeatId = int32(user.SceneChairId) +// SendSuccessMessage.BetType = pb.ColorPinoyLiveBetTypeJP(i) +// SendSuccessMessage.UserBet = num +// SendSuccessMessage.UserBets = user.TotalBets[i] +// SendSuccessMessage.TotalBets = rm.TotalBets[i] +// +// undoBetMessage.BetInfo = append(undoBetMessage.BetInfo, SendSuccessMessage) +// } +// rm.MutexData.Unlock() +// // 玩家当前分数 +// undoBetMessage.UserScore = user.Balance +// +// // log.Debug("undoBetMessage %v", undoBetMessage) +// rm.Table.Broadcast(int32(pb.ColorPinoyLiveSendToClientMessageType_ColorPinoyLiveNoticeUndoBet), undoBetMessage) +// +//} +//func (rm *ColorRoom) KickOutUser(u *model.User) { +// // delete(rm.AllUserList, k) +// rm.DeletePlayer(u.UserID) +// if u.SceneChairId != 0 { +// rm.OnUserStanUp(u) +// } +// role := "机器人" +// // rm.DeleteExitUserFromOnlineUserListSlice(u) +// if !u.IsRobot { +// rm.Table.KickOut(u.UserInetr) +// role = "玩家" +// } +// log.Debug(rm.Log("删除(%s)(%d) 金额:%d 输赢:%d", role, u.UserID, u.Balance, u.Balance-u.UserInetr.GetScore())) +// rm.SendOnlinePlayerNum() +//} +//func (rm *ColorRoom) TransInoutGameBet(user *model.User, bet int64) error { +// if config.CHIPS_DEBUG { +// user.Balance -= bet +// return nil +// } +// user.Mn.Lock() +// defer user.Mn.Unlock() +// transferInOutResp, err := rm.Table.TransInoutGameCarryAdd(user.UserInetr, rm.Table.GetLevel(), bet, "") +// if err != nil { +// return err +// } +// user.Balance = transferInOutResp.Balance +// user.Carry = transferInOutResp.Carry +// user.UserInetr.SetPreserve(transferInOutResp.Preserve) +// // time.Sleep(10 * time.Second) +// return nil +//} +//func (rm *ColorRoom) TransInoutGameEnd(user *model.User, bet int64, amountWin int64, tax int64) (int64, error) { +// if config.CHIPS_DEBUG || user.IsRobot { +// user.Balance += amountWin +// return amountWin, nil +// } +// transferInOutResp, err := rm.Table.TransInoutGameEnd(user.UserInetr, rm.Table.GetLevel(), bet+tax, amountWin+tax, "") +// if err != nil { +// return 0, err +// } +// user.Balance = transferInOutResp.GetBalance() +// if transferInOutResp.GetRealTransfer() == 0 { +// return 0, errors.New("error") +// } +// user.TransBet += bet +// user.TransWin += amountWin +// // time.Sleep(10 * time.Second) +// return transferInOutResp.RealTransfer, nil +//} +// +//func (rm *ColorRoom) ResetUserBet(user *model.User) { +// rm.MutexData.Lock() +// for i, bet := range user.TotalBets { +// rm.TotalBets[i] -= bet +// // rm.BetNumber[i] -= user.BetNumber[i] +// } +// rm.TotalBet -= user.TotalBet +// rm.MutexData.Unlock() +// user.TotalBet = 0 +// user.TotalBets = [config.BET_TYPE_NUM]int64{} +// // user.BetNumber = [config.BET_TYPE_NUM]int64{} +// +//} +// +//func (rm *ColorRoom) StartTransInoutBet() { +// wg := new(sync.WaitGroup) +// var failUser []*model.User +// failMutx := &sync.Mutex{} +// rm.Traverse(func(u *model.User) bool { +// wg.Add(1) +// go func(user *model.User) { +// defer wg.Done() +// user.Mn.Lock() +// defer user.Mn.Unlock() +// if user.TotalBet > 0 { +// _, err := rm.TransInoutGameEnd(user, user.TotalBet, 0, 0) +// if err != nil { +// func() { +// failMutx.Lock() +// defer failMutx.Unlock() +// failUser = append(failUser, user) +// }() +// } +// } +// }(u) +// return true +// }) +// wg.Wait() +// // 异步扣款完成后,处理部分扣款失败回滚操作 +// if len(failUser) > 0 { +// pbMsg := &pb.ColorPinoyLiveS2CBetEndFailResult{ +// Code: 1, +// } +// for _, user := range failUser { +// rm.ResetUserBet(user) +// player := &pb.ColorPinoyLiveS2CRepetBet{} +// player.UserScore = user.Balance +// player.Uid = user.UserID +// +// var bets []*pb.ColorPinoyLiveBetReq +// for _, bet := range user.LastTimeBet { +// bets = append(bets, bet...) +// } +// for _, bet := range bets { +// // 判断下注下标和下注区域下标是否超出列表 +// if _, ok := pb.ColorPinoyLiveBetTypeJP_name[int32(bet.BetType)]; !ok { +// log.Error(rm.Log("玩家(%d) bet err %v,", bet)) +// model.SendBetFailMessage(model.DataErr, user) +// return +// } +// SendSuccessMessage := new(pb.ColorPinoyLiveBetSuccessMessage) +// SendSuccessMessage.BetIndex = bet.BetIndex +// SendSuccessMessage.BetLevel = bet.BetLevel +// SendSuccessMessage.BetType = bet.BetType +// SendSuccessMessage.SeatId = int32(user.SceneChairId) +// SendSuccessMessage.UserBet = bet.BetAmount +// SendSuccessMessage.TotalBets = rm.TotalBets[bet.BetType] +// +// player.BetInfo = append(player.BetInfo, SendSuccessMessage) +// } +// pbMsg.Players = append(pbMsg.Players, player) +// } +// // log.Debug("玩家停止下注后 扣钱失败: %v", pbMsg) +// rm.Table.Broadcast(int32(pb.ColorPinoyLiveSendToClientMessageType_ColorPinoyLiveNoticePlayerBetEndResultFailed), pbMsg) +// } +// // 大客投注 +// var allWinner []*pb.ColorPinoyLiveBigWinner +// rm.Traverse(func(user *model.User) bool { +// if user.TotalBet > 0 { +// allWinner = append(allWinner, &pb.ColorPinoyLiveBigWinner{NickName: user.UserInetr.GetNike(), Avatar: user.UserInetr.GetHead(), WinChips: user.TotalBet, AreaId: user.TotalBets[:]}) +// } +// return true +// }) +// rm.updateBigWinner(allWinner) +// bigMsg := &pb.ColorPinoyLivePlayerBigWinner{BigBet: allWinner, Jackpot: rm.jackpotMgr.GetJackpot()} +// rm.Table.Broadcast(int32(pb.ColorPinoyLiveSendToClientMessageType_ColorPinoyLiveNoticeGameBigWinner), bigMsg) +// +// rm.TimerJob, _ = rm.Table.AddTimer(time.Duration(rm.RoomCfg.TimeConf.Endmove), func() { +// rm.NotifyBigBetAreaMul() +// }) +// allUserTotalBet := int64(0) // 所有玩家投注未中奖的总金额,用于计算jackpot池 +// rm.Traverse(func(user *model.User) bool { +// if user.TotalBet < 1 { +// return true +// } +// allUserTotalBet += user.TotalBet +// return true +// }) +// log.Debug(rm.Log("本局总投注金额为:%v 赎回比例:%v 追加比例:%v 满额追加比例:%v", allUserTotalBet, rm.Cfg.JpXRate, rm.Cfg.JpYRate, rm.Cfg.JpXYRate)) +// rm.jackpotX, rm.jackpotY = rm.jackpotMgr.AddJp(allUserTotalBet, int64(rm.Cfg.JpXRate), int64(rm.Cfg.JpYRate), int64(rm.Cfg.JpXYRate)) +// if rm.jackpotX > 0 || rm.jackpotY > 0 { +// rm.kafkaJackpotUserRepaid(rm.jackpotX, rm.jackpotY) +// } +//} +// +//// 计算 下注区域中奖得分,返回是否有jp奖,jp奖位置,中奖人数 +//func (rm *ColorRoom) CalculateJackpotScore() (pb.ColorPinoyLiveBetTypeJP, map[int64]int64) { +// jackpotArea := pb.ColorPinoyLiveBetTypeJP(-1) +// for _, winArea := range rm.PokerMsg.WinBetArea { +// if !winArea.IsJackpot || !winArea.IsWin { +// continue +// } +// color := getColorByBetArea(winArea.BetArea) +// colorCount := getColorCount(rm.NormalDices, color) +// if colorCount != 3 { +// continue +// } +// jackpotArea = winArea.BetArea +// rm.Traverse(func(user *model.User) bool { +// if user.TotalBets[winArea.BetArea] <= 0 { +// return true +// } +// rm.jackpotMgr.AddJpUser(user.UserID, user.TotalBets[winArea.BetArea]) +// return true +// }) +// } +// rm.jackpotUser, rm.costJackpot = rm.jackpotMgr.WinJackpot() +// if rm.costJackpot > 0 { +// rm.kafkaHitJackpot(rm.costJackpot, rm.jackpotUser) +// } +// log.Debug(rm.Log("本局是否中jackpot奖:%v, 玩家一起分走jackpot:%v, 当前jackpot值:%v", rm.costJackpot > 0, rm.costJackpot, rm.jackpotMgr.GetJackpot())) +// return jackpotArea, rm.jackpotUser +//} +// +//// 计算 所有玩家的下注区域中奖得分 +//func (rm *ColorRoom) CalculateAllUserScore() { +// // 赢钱会清空jackpot池 +// jpArea, userJackPot := rm.CalculateJackpotScore() +// var jackpotUserName []string +// rm.Traverse(func(user *model.User) bool { +// msg := new(pb.ColorPinoyLiveUserSettleMsg) +// msg.WinAreaOdd = rm.PokerMsg.WinBetArea +// msg.UserBets = rm.CopyArr(user.TotalBets) +// msg.UserRealWins = make([]int64, config.BET_TYPE_NUM) +// msg.UserWins = make([]int64, config.BET_TYPE_NUM) +// +// if user.TotalBet > 0 { +// // 算分 +// jpScore := userJackPot[user.UserID] +// rm.CalculateScore(user, jpArea, jpScore, msg) +// if jpScore > 0 { +// jackpotUserName = append(jackpotUserName, user.UserInetr.GetNike()) +// rm.BroadHitJackpot(user, jpScore) +// } +// } +// // 统计玩家信息 +// if msg.TotalWin > user.TotalBet { +// user.UserCount(true, msg.TotalWin) +// } else { +// user.UserCount(false, 0) +// } +// user.Balance += msg.TotalWin +// msg.UserScore = user.Balance +// user.SettleMsg = msg +// return true +// }) +// rm.Traverse(func(user *model.User) bool { +// user.SettleMsg.JackpotUserName = jackpotUserName +// return true +// }) +//} +// +//// 计算 下注区域中奖得分 +//func (rm *ColorRoom) CalculateScore(user *model.User, jpArea pb.ColorPinoyLiveBetTypeJP, jpScore int64, msg *pb.ColorPinoyLiveUserSettleMsg) { +// for _, winArea := range msg.WinAreaOdd { +// if msg.UserBets[winArea.BetArea] <= 0 { +// continue +// } +// if jpArea != winArea.BetArea { +// odds := winArea.Odd +// // 奖金计算公式 Payouts =( Odds * Bet ) * ( 1 + Bonus) + Bet odds 是倍率 Bonus是猜中幸运骰子 的加成 +// // 本区域赢未扣税 倍率是百分值所以计算时要除以100 +// win2 := (odds * msg.UserBets[winArea.BetArea]) / 100 +// // 本区域赢扣税 +// Gold := win2 * (100 - rm.RoomCfg.Rate) / 100 +// // 算税() +// msg.Tax += win2 - Gold +// // 加回投注本金 +// Gold += msg.UserBets[winArea.BetArea] +// msg.TotalWin += Gold +// // 统计赢区的下注总额 +// msg.TotalWinBaseBet += msg.UserBets[winArea.BetArea] +// +// msg.UserWins[winArea.BetArea] += win2 +// msg.UserRealWins[winArea.BetArea] += Gold +// log.Debug(rm.LogEx(user, "算分 odds:%v 投注区:%v win2:%v Gold:%v", odds, winArea.BetArea, win2, Gold)) +// } else { +// win2 := jpScore +// // 本区域赢扣税 +// Gold := jpScore * (100 - rm.RoomCfg.Rate) / 100 +// // 算税() +// msg.Tax += win2 - Gold +// // 加回投注本金 +// Gold += msg.UserBets[winArea.BetArea] +// msg.TotalWin += Gold +// // 统计赢区的下注总额 +// msg.TotalWinBaseBet += msg.UserBets[winArea.BetArea] +// +// msg.UserWins[winArea.BetArea] += win2 +// msg.UserRealWins[winArea.BetArea] += Gold +// msg.JackpotWin = Gold +// log.Debug(rm.LogEx(user, "算分 jackpot 投注区:%v win2:%v Gold:%v", winArea.BetArea, win2, Gold)) +// } +// } +// +//} +// +//type areaWin struct { +// areaId int64 +// win int64 +//} +// +//// 更新大赢家 +//func (rm *ColorRoom) updateBigWinner(allWinner []*pb.ColorPinoyLiveBigWinner) { +// // log.Debug(fmt.Sprintf("allWinner:%+v", allWinner)) +// rm.BigWinner = rm.BigWinner[:0] +// sort.Slice(allWinner, func(i, j int) bool { +// return allWinner[i].WinChips > allWinner[j].WinChips +// }) +// if len(allWinner) > BigWinnerCount { +// allWinner = allWinner[:BigWinnerCount] +// } +// for _, winner := range allWinner { +// var areaWins []*areaWin +// for areaId, win := range winner.AreaId { +// if win > 0 { +// areaWins = append(areaWins, &areaWin{areaId: int64(areaId), win: win}) +// } +// } +// sort.Slice(areaWins, func(i, j int) bool { +// return areaWins[i].win > areaWins[j].win +// }) +// if len(areaWins) > BigWinnerCount { +// areaWins = areaWins[:BigWinnerCount] +// } +// winner.AreaId = make([]int64, 0, BigWinnerCount) +// for _, area := range areaWins { +// winner.AreaId = append(winner.AreaId, area.areaId) +// } +// } +// rm.BigWinner = allWinner +//} +// +//// 和平台做结算 +//func (rm *ColorRoom) SetUserSettleMsg() { +// var allWinner []*pb.ColorPinoyLiveBigWinner +// rm.CalculateAllUserScore() +// wg := new(sync.WaitGroup) +// rm.Traverse(func(uu *model.User) bool { +// wg.Add(1) +// go func(u *model.User) { +// defer wg.Done() +// if u.TotalBet > 0 { +// // 和平台做赢钱结算 +// // if msg.TotalWin > 0 { +// _, err := rm.TransInoutGameEnd(u, 0, u.SettleMsg.TotalWin, u.SettleMsg.Tax) +// if err != nil { +// log.Error(rm.Log(err.Error())) +// // model.SendBetFailMessage(model.BalanceError, u) +// } +// // } +// } +// }(uu) +// return true +// }) +// wg.Wait() +// // 异步加钱完成后再执行后续的结算操作 +// rm.Traverse(func(u *model.User) bool { +// msg := u.SettleMsg +// if msg == nil || msg.TotalWin < 1 { +// return true +// } +// winner := &pb.ColorPinoyLiveBigWinner{ +// NickName: u.UserInetr.GetNike(), +// Avatar: u.UserInetr.GetHead(), +// WinChips: msg.TotalWin, +// AreaId: msg.UserRealWins, +// } +// allWinner = append(allWinner, winner) +// log.Debug(rm.LogEx(u, "赢钱:%v", winner.WinChips)) +// return true +// }) +// rm.updateBigWinner(allWinner) +// +// rm.SetGameTrend() +// rm.sendSettleMsg2Client() +// // log.Debug(time.Now().Unix() - rm.endAt) +// rm.Table.EndGame() +// rm.NotifyLiveDelayUpdate() // 通知延迟更新服务器配置,切换维护状态 +// rm.TimerJob, _ = rm.Table.AddTimer(time.Duration(rm.RoomCfg.TimeConf.Endpay), func() { +// rm.Rank() +// }) +//} +// +//func (rm *ColorRoom) CountUser(u *model.User) { +// u.Icon = 0 +// // rm.OnlineUserList = append(rm.OnlineUserList, u) +//} +//func (rm *ColorRoom) ResetData(all bool) { +// rm.TotalBets = [config.BET_TYPE_NUM]int64{} +// rm.TotalBet = 0 +// rm.LuckyDice = 0 +// rm.NormalDices = make([]byte, 3) +// rm.StartDices = make([]byte, 3) +// rm.ResultImgs = make([]string, 0) +// rm.InitBigOddsBetAreas() +// +// if all { +// rm.LiveMgr.Reset() +// rm.Traverse(func(u *model.User) bool { +// u.ResetUserData() +// u.RetrunGold = 0 +// return true +// }) +// } +//} +//func (rm *ColorRoom) GetPairDice(count int, startIndex int, endIndex int) []byte { +// if gconfig.GConfig.IsProd() { +// return nil +// } +// // PokerCard 表示一张扑克牌 +// type Dice struct { +// Color int // 花色 +// Point int // 点数 +// } +// type PairDice struct { +// Cards []Dice +// } +// key := fmt.Sprintf("preset-cards:0:color:%d", rm.Table.GetId()) +// log.Debug(rm.Log("获取配牌配置 key:", key)) +// str := redisf.RSC.GetPairCard(key) +// if str == "" { +// return nil +// } +// pairCard := new(PairDice) +// err := json.Unmarshal([]byte(str), pairCard) +// if err != nil { +// log.Debug(rm.Log("getPairCard:%v", err)) +// return nil +// } +// if len(pairCard.Cards) < 2 { +// log.Error(rm.Log("getPairCard ", pairCard)) +// return nil +// } +// log.Debug(rm.Log("getPairCard pairCard:%v", pairCard)) +// var res []byte +// for index, card := range pairCard.Cards { +// if index >= startIndex && index < endIndex { +// res = append(res, byte(card.Point)) +// if (len(res)) == count { +// break +// } +// } +// } +// return res +//} +// +//func (rm *ColorRoom) GetGameTrend() (luckyRates []int32) { +// // var mapLuckyRate = map[pb.ColorPinoyLiveDiceColorType]int32{} +// // for _, trend := range rm.GameTrend.ListTrendGroup { +// // mapLuckyRate[trend.LuckyDice]++ +// // } +// // for i := pb.ColorPinoyLiveDiceColorType_ColorPinoyLiveType_YELLOW; i <= pb.ColorPinoyLiveDiceColorType_ColorPinoyLiveType_GREEN; i++ { +// // luckyRates = append(luckyRates, 0) +// // } +// // if len(mapLuckyRate) > 0 { +// // for k, v := range mapLuckyRate { +// // // log.Debug(fmt.Sprintf("颜色:%v 数量:%v 总数量:%v 配置:%v", k, v, len(rm.GameTrend.ListTrendGroup), config.WinTrendNum)) +// // if int(k-1) < len(luckyRates) { +// // luckyRates[k-1] = v * 10000 / int32(len(rm.GameTrend.ListTrendGroup)) +// // } +// // } +// // } +// +// return luckyRates +// +//} +// +//func (rm *ColorRoom) SetGameTrend() { +// +// trendGroup := new(pb.ColorPinoyLiveTrendGroup) +// trendGroup.LuckyDice = pb.ColorPinoyLiveDiceColorType(model.GetColor(rm.LuckyDice)) +// for _, dice := range rm.NormalDices { +// trendGroup.ThreeDice = append(trendGroup.ThreeDice, pb.ColorPinoyLiveDiceColorType(model.GetColor(dice))) +// } +// +// rm.GameTrend.ListTrendGroup = append(rm.GameTrend.ListTrendGroup, trendGroup) +// +// // log.Debug("走势图 rm.GameTrend.ListTrendGroup: ", rm.GameTrend.ListTrendGroup) +// winlen := len(rm.GameTrend.ListTrendGroup) +// if winlen > config.WinTrendNum { +// rm.GameTrend.ListTrendGroup = rm.GameTrend.ListTrendGroup[(winlen - config.WinTrendNum):] +// } +// +// if rm.ServerStatus == define.GameStatusNoraml { +// str, err := json.Marshal(rm.GameTrend.ListTrendGroup) +// if err != nil { +// return +// } +// redisf.RSC.SetColorGameTrend(rm.TrendRedisKey, str) +// // log.Debug("SetGameTrend 保存走势图到redis :", str) +// +// } +//} +// +//// 获取投注区域的颜色 +//func getColorByBetArea(area pb.ColorPinoyLiveBetTypeJP) pb.ColorPinoyLiveDiceColorType { +// switch area { +// case pb.ColorPinoyLiveBetTypeJP_CLJ_Yellow, pb.ColorPinoyLiveBetTypeJP_CLJ_Double_Yellow, pb.ColorPinoyLiveBetTypeJP_CLJ_Three_Yellow: +// return pb.ColorPinoyLiveDiceColorType_ColorPinoyLiveType_YELLOW +// case pb.ColorPinoyLiveBetTypeJP_CLJ_White, pb.ColorPinoyLiveBetTypeJP_CLJ_Double_White, pb.ColorPinoyLiveBetTypeJP_CLJ_Three_White: +// return pb.ColorPinoyLiveDiceColorType_ColorPinoyLiveType_WHITE +// case pb.ColorPinoyLiveBetTypeJP_CLJ_Pink, pb.ColorPinoyLiveBetTypeJP_CLJ_Double_Pink, pb.ColorPinoyLiveBetTypeJP_CLJ_Three_Pink: +// return pb.ColorPinoyLiveDiceColorType_ColorPinoyLiveType_PINK +// case pb.ColorPinoyLiveBetTypeJP_CLJ_Blue, pb.ColorPinoyLiveBetTypeJP_CLJ_Double_Blue, pb.ColorPinoyLiveBetTypeJP_CLJ_Three_Blue: +// return pb.ColorPinoyLiveDiceColorType_ColorPinoyLiveType_BLUE +// case pb.ColorPinoyLiveBetTypeJP_CLJ_Red, pb.ColorPinoyLiveBetTypeJP_CLJ_Double_Red, pb.ColorPinoyLiveBetTypeJP_CLJ_Three_Red: +// return pb.ColorPinoyLiveDiceColorType_ColorPinoyLiveType_RED +// case pb.ColorPinoyLiveBetTypeJP_CLJ_Green, pb.ColorPinoyLiveBetTypeJP_CLJ_Double_Green, pb.ColorPinoyLiveBetTypeJP_CLJ_Three_Green: +// return pb.ColorPinoyLiveDiceColorType_ColorPinoyLiveType_GREEN +// } +// return pb.ColorPinoyLiveDiceColorType_ColorPinoyLiveType_Void +//} +// +//func getColorCount(result []byte, color pb.ColorPinoyLiveDiceColorType) int { +// count := 0 +// for _, c := range result { +// if model.GetColor(c) == int32(color) { +// count++ +// } +// } +// return count +//} +// +//func stringDices(result []byte) string { +// s := "" +// for _, c := range result { +// s += fmt.Sprintf("%v", pb.ColorPinoyLiveDiceColorType(model.GetColor(c))) +// } +// return s +//} +// +//// 检查投掷结果是否匹配某个下注区域 +//func isWinningArea(result []byte, area pb.ColorPinoyLiveBetTypeJP) (win bool, bigPos pb.ColorPinoyLiveBigBetAreaPos, colorCount int) { +// color := getColorByBetArea(area) +// colorCount = getColorCount(result, color) +// if colorCount == 0 { +// return false, 0, colorCount +// } +// // 单色投注区,查看开出几个该颜色 +// if area < pb.ColorPinoyLiveBetTypeJP_CLJ_Double_Yellow { +// if colorCount == 1 { +// return true, pb.ColorPinoyLiveBigBetAreaPos_BBA_Single_0, colorCount +// } else if colorCount == 2 { +// return true, pb.ColorPinoyLiveBigBetAreaPos_BBA_Single_1, colorCount +// } else { +// return true, pb.ColorPinoyLiveBigBetAreaPos_BBA_Single_2, colorCount +// } +// } else if area < pb.ColorPinoyLiveBetTypeJP_CLJ_Three_Yellow { +// if colorCount > 1 { +// return true, pb.ColorPinoyLiveBigBetAreaPos_BBA_Double, colorCount +// } +// } else { +// if colorCount > 2 { +// return true, pb.ColorPinoyLiveBigBetAreaPos_BBA_Three, colorCount +// } +// } +// return false, 0, colorCount +//} +// +//// 计算开奖结果 +//func (rm *ColorRoom) CompareDiceResult() { +// var wins []*pb.ColorPinoyLiveBetAreaOdd +// // // 存储中奖区域 +// result := rm.NormalDices +// log.Debug(rm.Log("开奖结果:%v", stringDices(result))) +// rm.afterBetAreaOdds = rm.afterBetAreaOdds[0:0] +// // 检查所有下注区域是否中奖 +// for pos, area := range rm.betEndBetAreasOdds { +// betAreaOdd := &pb.ColorPinoyLiveBetAreaOdd{ +// BetArea: area.BetType, +// Odd: area.Odd[0], +// ViewOdd: 0, +// IsBigOdd: area.IsBigOdd, +// BigSingleColorOddPos: area.BigSingleColorOddPos, +// IsWin: false, +// IsJackpot: area.IsJackpot, +// } +// if pos/6 == 0 { +// // 第一行投注区域,赔率是多个赔率中的一个 +// betAreaOdd.Odd = area.Odd[area.BigSingleColorOddPos] +// } else { +// betAreaOdd.Odd = area.Odd[0] +// } +// betAreaOdd.ViewOdd = betAreaOdd.Odd +// // 更新实际赔率 +// isWin, winOddPos, colorCount := isWinningArea(result, area.BetType) +// betAreaOdd.IsWin = isWin +// if betAreaOdd.IsWin { +// if betAreaOdd.IsJackpot && colorCount == 3 { +// betAreaOdd.Odd = 0 +// } else { +// if winOddPos == pb.ColorPinoyLiveBigBetAreaPos_BBA_Single_0 { +// betAreaOdd.Odd = area.Odd[0] +// } else if winOddPos == pb.ColorPinoyLiveBigBetAreaPos_BBA_Single_1 { +// betAreaOdd.Odd = area.Odd[1] +// } else if winOddPos == pb.ColorPinoyLiveBigBetAreaPos_BBA_Single_2 { +// betAreaOdd.Odd = area.Odd[2] +// } +// // 爆奖需要修正 +// if betAreaOdd.IsBigOdd && winOddPos > betAreaOdd.BigSingleColorOddPos { +// betAreaOdd.Odd = area.Odd[area.BigSingleColorOddPos] +// } +// } +// wins = append(wins, betAreaOdd) +// } +// +// // 修正牌局记录倍率 +// tmpAreaOdd := &pb.ColorPinoyLiveBetAreaOdd{ +// BetArea: betAreaOdd.BetArea, +// Odd: betAreaOdd.Odd, +// ViewOdd: betAreaOdd.ViewOdd, +// IsBigOdd: betAreaOdd.IsBigOdd, +// BigSingleColorOddPos: betAreaOdd.BigSingleColorOddPos, +// IsWin: betAreaOdd.IsWin, +// IsJackpot: betAreaOdd.IsJackpot, +// } +// if !tmpAreaOdd.IsWin && pos/6 == 0 && +// (betAreaOdd.BigSingleColorOddPos == pb.ColorPinoyLiveBigBetAreaPos_BBA_Single_1 || +// betAreaOdd.BigSingleColorOddPos == pb.ColorPinoyLiveBigBetAreaPos_BBA_Single_2) { +// tmpAreaOdd.Odd = area.Odd[0] +// if !tmpAreaOdd.IsBigOdd { +// tmpAreaOdd.ViewOdd = tmpAreaOdd.Odd +// } +// } +// if !tmpAreaOdd.IsWin && pos/6 == 1 && tmpAreaOdd.IsBigOdd { +// tmpAreaOdd.Odd = rm.RoomCfg.ColorPinoyLiveConfig.WinDoubleColorMul[0].Mul +// } +// if !tmpAreaOdd.IsWin && pos/6 == 2 && tmpAreaOdd.IsBigOdd { +// tmpAreaOdd.Odd = rm.RoomCfg.ColorPinoyLiveConfig.WinThreeColorMul[0].Mul +// } +// +// rm.afterBetAreaOdds = append(rm.afterBetAreaOdds, tmpAreaOdd) +// log.Debug(rm.Log("开奖,区域:%v 是否中奖:%v 实际赔率:%v 显示赔率:%v 是否爆奖:%v 爆奖位置:%v", betAreaOdd.BetArea, betAreaOdd.IsWin, betAreaOdd.Odd, +// betAreaOdd.ViewOdd, betAreaOdd.IsBigOdd, betAreaOdd.BigSingleColorOddPos)) +// } +// rm.PokerMsg.WinBetArea = wins +//} +// +//// 检查用户是否被踢掉 +//func (rm *ColorRoom) checkUserBet() { +// kickMsg, isKick := redisf.RSC.IsGameMaintenance(gconfig.GConfig.GRoomConfig.ChannelId, gconfig.GConfig.GServConfig.GameId) +// rm.Traverse(func(u *model.User) bool { +// u.NoBetCount++ +// if isKick { +// msg := new(pb.ColorPinoyLiveKickOutUserMsg) +// // msg.KickOutReason = fmt.Sprintf("you did not bet %d games", rm.RoomCfg.LongHuConfig.NoBetCountMax) +// msg.Reason = int32(pb.ColorPinoyLiveLeaveReason_ColorPinoyLiveLeaveReason_Maintaince) +// msg.KickOutReason = kickMsg +// u.SendMsg(int32(pb.ColorPinoyLiveSendToClientMessageType_ColorPinoyLiveNoticeKickOutUser), msg) +// u.NoBetCount = 0 +// rm.KickOutUser(u) +// return true +// } +// if rm.ServerStatus != define.GameStatusNoraml || u.UserInetr.NeedKickout() { +// msg := new(pb.ColorPinoyLiveKickOutUserMsg) +// // msg.KickOutReason = fmt.Sprintf("game server maintenance ") +// msg.Reason = int32(pb.ColorPinoyLiveLeaveReason_ColorPinoyLiveLeaveReason_PLAYER_QUIT_ROOM) +// u.SendMsg(int32(pb.ColorPinoyLiveSendToClientMessageType_ColorPinoyLiveNoticeKickOutUser), msg) +// rm.KickOutUser(u) +// return true +// } +// if redisf.RSC.IsUserLiveBan(u.UserInetr.GetOpToken(), int64(gconfig.GConfig.GRoomConfig.GameId), u.UserID) { +// msg := new(pb.ColorPinoyLiveKickOutUserMsg) +// msg.Reason = int32(pb.ColorPinoyLiveLeaveReason_ColorPinoyLiveLeaveReason_Ban) +// u.SendMsg(int32(pb.ColorPinoyLiveSendToClientMessageType_ColorPinoyLiveNoticeKickOutUser), msg) +// rm.KickOutUser(u) +// return true +// } +// // if u.NoBetCount >= (rm.RoomCfg.ColorPinoyLiveConfig.NoBetCountMax + 1) { +// // msg := new(pb.ColorPinoyLiveKickOutUserMsg) +// // // msg.KickOutReason = fmt.Sprintf("you did not bet %d games", rm.RoomCfg.LongHuConfig.NoBetCountMax) +// // msg.Reason = 1 +// // u.SendMsg(int32(pb.ColorPinoyLiveSendToClientMessageType_ColorPinoyLiveNoticeKickOutUser), msg) +// // // 踢掉用户 +// // u.NoBetCount = 0 +// // rm.KickOutUser(u) +// // return true +// // } +// +// return true +// }) +//} +// +//// 初始走势图 +//func (rm *ColorRoom) InitWinTrend() { +// rm.TrendRedisKey = fmt.Sprintf("pb.:%d:%d:trend", gconfig.GConfig.GDataConfig.VersionMode, rm.RoomCfg.Level) +// if rm.ServerStatus == define.GameStatusNoraml { +// winTrend := redisf.RSC.GetColorGameTrend(rm.TrendRedisKey) +// if winTrend != "" { +// rm.GameTrend = new(pb.ColorPinoyLiveTrend) +// rm.GameTrend.ListTrendGroup = []*pb.ColorPinoyLiveTrendGroup{} +// err := json.Unmarshal([]byte(winTrend), &rm.GameTrend.ListTrendGroup) +// winlen := len(rm.GameTrend.ListTrendGroup) +// // log.Debug("初始化走势图1:", len(rm.GameTrend.ListTrendGroup)) +// if winlen > config.WinTrendNum { +// rm.GameTrend.ListTrendGroup = rm.GameTrend.ListTrendGroup[(winlen - config.WinTrendNum):] +// // log.Debug("初始化走势图2:", len(rm.GameTrend.ListTrendGroup)) +// } +// // log.Debug("初始化走势图:", rm.GameTrend.ListTrendGroup) +// if err != nil { +// log.Error(rm.Log("初始化走势图:%v", err)) +// } +// } +// +// } +// +//} +// +//func (rm *ColorRoom) DeleteExitUserFromOnlineUserListSlice(user *model.User) { +// rm.MutexUserList.Lock() +// defer rm.MutexUserList.Unlock() +// for k, v := range rm.OnlineUserList { +// if user == v { +// rm.OnlineUserList = append(rm.OnlineUserList[:k], rm.OnlineUserList[k+1:]...) +// break +// } +// } +//} +// +//func (rm *ColorRoom) SelectUserListBalanceTopSitDownChair() { +// rm.MutexUserList.Lock() +// rm.SceneInfo.ClearSceneChairId() +// rm.SceneInfo.Init() +// index := len(rm.OnlineUserList) +// if index >= config.SEAT_NUM { +// index = config.SEAT_NUM +// } +// cou := model.Usercount{} +// cou = rm.OnlineUserList +// sort.Sort(cou) +// for i := 0; i < index; i++ { +// u := rm.OnlineUserList[i] +// ChairId := i + 1 +// if rm.SceneInfo.SitScene(u, ChairId) { +// u.SceneChairId = ChairId +// } +// } +// rm.MutexUserList.Unlock() +// +//} +// +//func (rm *ColorRoom) CopyArr(arr [config.BET_TYPE_NUM]int64) []int64 { +// slice := make([]int64, len(arr)) +// copy(slice, arr[:]) +// return slice +//} +// +//func (rm *ColorRoom) GameDiscard() { +// rm.TimerJob.Cancel() +// rm.GameUserDiscard() +// // rm.TimerJob, _ = rm.Table.AddTimer(1000, func() { +// // rm.LiveCnt(rm.Ready, false, true, []bool{true}...) +// // }) +// rm.ResetData(false) +// rm.Traverse(func(user *model.User) bool { +// if rm.LiveMgr.MaintenanceStatus == 1 { +// rm.sendUserMainte(user, int32(pb.ColorPinoyLiveSendToClientMessageType_ColorPinoyLiveNoticeGameMainte)) +// } +// if rm.LiveMgr.DiscardStatus == 1 { +// rm.sendUserMainte(user, int32(pb.ColorPinoyLiveSendToClientMessageType_ColorPinoyLiveNoticeDiscard)) +// } +// return true +// }) +// rm.Ready() +//} +// +//func (rm *ColorRoom) sendUserMainte(user *model.User, cmd int32) { +// userinfo := new(pb.ColorPinoyLiveUserInfo) +// userinfo.NikeName = user.UserInetr.GetNike() +// userinfo.UserGlod = user.Balance +// userinfo.Head = user.UserInetr.GetHead() +// userinfo.UserID = user.UserID +// _ = user.UserInetr.SendMsg(cmd, &pb.ColorPinoyLiveMainteNtf{ +// UserInfo: userinfo, +// MaintMsg: rm.LiveMgr.MainteMsg, +// ReturnGold: user.RetrunGold, +// }) +//} +// +//func (rm *ColorRoom) GameUserDiscard() { +// rm.MutexStatus.RLock() +// defer rm.MutexStatus.RUnlock() +// log.Debug(rm.Log("流局,状态:%v,分出去的jackpot:%v", rm.GetGameStatus(), rm.costJackpot)) +// // 回退 +// if rm.GetGameStatus() >= pb.ColorPinoyLiveGameStatus_ColorPinoyLiveEndBetMovie && rm.GetGameStatus() < pb.ColorPinoyLiveGameStatus_ColorPinoyLiveSettleStatus { +// rm.jackpotMgr.RollBackJpXAndJpY(0, 0, rm.jackpotX, rm.jackpotY) +// rm.kafkaBackJackpot(0, rm.jackpotX, rm.jackpotY, rm.jackpotUser) +// } else if rm.GetGameStatus() >= pb.ColorPinoyLiveGameStatus_ColorPinoyLiveSettleStatus { +// rm.jackpotMgr.RollBackJpXAndJpY(rm.costJackpot, rm.jackpotFunding, rm.jackpotX, rm.jackpotY) +// rm.kafkaBackJackpot(rm.costJackpot, rm.jackpotX, rm.jackpotY, rm.jackpotUser) +// } +// +// var betCount int64 +// GameTotalBets := make([]int64, config.BET_TYPE_NUM) +// var PlayerData []*pb.ColorPinoyLivePlayerData +// copyBetAreaMul := rm.copyBetAreaOdds() +// wg := new(sync.WaitGroup) +// playerDataMu := new(sync.Mutex) +// rm.Traverse(func(v *model.User) bool { +// wg.Add(1) +// monitor.GoSafe(func(u *model.User) { +// defer wg.Done() +// u.RetrunGold = u.TotalBet +// msg := new(pb.ColorPinoyLiveUserSettleMsg) +// msg.UserBets = rm.CopyArr(u.TotalBets) +// msg.UserRealWins = make([]int64, config.BET_TYPE_NUM) +// msg.UserWins = make([]int64, config.BET_TYPE_NUM) +// msg.WinAreaOdd = rm.PokerMsg.WinBetArea +// msg.UserScore = u.Balance +// u.SettleMsg = msg +// // 写入数据库统计信息 +// if u.TotalBet > 0 { +// for i, bet := range u.TotalBets { +// betCount += bet +// GameTotalBets[i] += bet +// } +// // 玩家下注区域统计 +// u.SettleMsg.UserBetsCount = make([]int64, config.BET_TYPE_NUM) +// for i, count := range u.TotalBetsCount { +// u.SettleMsg.UserBetsCount[i] = count +// } +// if rm.GetGameStatus() < pb.ColorPinoyLiveGameStatus_ColorPinoyLiveEndBetMovie { +// u.AddBalance(u.TotalBet) +// } else if rm.GetGameStatus() < pb.ColorPinoyLiveGameStatus_ColorPinoyLiveSettleStatus { +// _, err := rm.TransInoutGameEnd(u, u.TransWin, u.TransBet, 0) +// if err != nil { +// log.Error(rm.Log("discard error:%v, game_no:%s, uid:%d, TransWin:%d, TransBet:%d", err, rm.Table.GetGameRoundId(), u.UserID, u.TransWin, u.TransBet)) +// } +// } else { +// if rm.LiveMgr.DiscardStatus == 1 { +// _, err := rm.TransInoutGameEnd(u, u.TransWin, u.TransBet, 0) +// if err != nil { +// log.Error(rm.Log("discard error:%v, game_no:%s, uid:%d, TransWin:%d, TransBet:%d", err, rm.Table.GetGameRoundId(), u.UserID, u.TransWin, u.TransBet)) +// } +// } else { +// return +// } +// } +// func() { +// playerDataMu.Lock() +// defer playerDataMu.Unlock() +// PlayerData = append(PlayerData, &pb.ColorPinoyLivePlayerData{ +// Uid: u.UserID, +// TotalBets: u.SettleMsg.UserBets, // 玩家各个区域的总下注额 +// TotalBet: u.TotalBet, +// Profit: u.SettleMsg.TotalWin, +// Tax: u.SettleMsg.Tax, +// Balance: u.Balance, +// PreBalance: u.PreBalance, +// UserWins: u.SettleMsg.UserWins, // 玩家赢取的下注区域总下注额 +// UserRealWins: u.SettleMsg.UserRealWins, // 玩家赢取的下注区域总下注额 扣税后 +// AreaOdds: copyBetAreaMul, // 投注区域倍率 +// StartTime: u.StartAt, +// TransBet: u.TransBet, +// TransWin: u.TransWin, +// DevMode: u.UserInetr.GetDevMode(), +// UserBetsCount: u.SettleMsg.UserBetsCount, +// IsDiscard: 1, +// }) +// }() +// } +// u.ResetUserData() +// }, v) +// return true +// }) +// wg.Wait() +// // 发布事件 +// if PlayerData == nil || len(PlayerData) == 0 { +// return +// } +// // 开奖结果 +// gameDetail := &pb.ColorPinoyLiveDetail{DealerName: rm.dealerName, ResultImg: rm.ResultImgs} +// gameDetail.BetAreaMul = copyBetAreaMul +// gameRecordData := &pb.ColorPinoyLiveEnd{ +// GameNo: fmt.Sprintf("%d|%d|%d", gconfig.GConfig.GRoomConfig.GameId, rm.Table.GetId(), time.Now().UnixMilli()), +// StartTime: rm.startAt, +// EndTime: rm.endAt, +// Level: gconfig.GConfig.GRoomConfig.Level, +// BaseBet: rm.RoomCfg.BaseBet, +// PlayerData: PlayerData, +// TaxRate: rm.RoomCfg.Rate, +// TotalBet: betCount, +// TotalBets: GameTotalBets[:], +// OpToken: gconfig.GConfig.GServConfig.ChannelId, +// Detail: gameDetail, +// IsDiscard: 1, +// } +// log.Debug("GameUserDiscard") +// go func() { +// err := gconfig.Produce(context.Background(), define.TopicColoLiveGameGameEnd, gameRecordData) +// if err != nil { +// log.Error(rm.Log("[%s] fail to Produce TongitsGameEndEvent(%+v), err: %v", gameRecordData.GameNo, gameRecordData, err)) +// } +// }() +//} +// +//func (rm *ColorRoom) LoadDealerNames() { +// ssv := redisf.RSC.DealerNameGet(gconfig.GConfig.GDataConfig.VersionMode, gconfig.GConfig.GRoomConfig.GameId, GameName) +// var dealerNames []string +// _ = json.Unmarshal([]byte(ssv), &dealerNames) +// rm.dealerName = dealerNames +// log.Debug(rm.Log("dealerNames:%v", rm.dealerName)) +//} +// +//// 发送垫资kafka +//func (rm *ColorRoom) kafkaJackpotFunding(funding int64) { +// msg := &events.JackpotEvent{ +// EventType: events.JackpotEvent_et_funding, +// GameId: rm.RoomCfg.GameId, +// Time: time.Now().UnixMilli(), +// Funding: &events.JackpotEvent_Funding{Funding: funding}, +// GameNo: rm.Table.GetGameRoundId(), +// } +// go func() { +// err := gconfig.Produce(context.Background(), define.TopicJackpot, msg) +// if err != nil { +// log.Error(rm.Log("kafka JackpotEvent_et_funding err: %v", err)) +// } +// }() +// log.Debug(rm.Log("kafka 垫资:%v", funding)) +//} +// +//// 发送赎回及追加kafka +//func (rm *ColorRoom) kafkaJackpotUserRepaid(jpx, jpy int64) { +// msg := &events.JackpotEvent{ +// EventType: events.JackpotEvent_et_user_repaid, +// GameId: rm.RoomCfg.GameId, +// Time: time.Now().UnixMilli(), +// UserRepaid: &events.JackpotEvent_UserRepaid{JackpotX: jpx, JackpotY: jpy}, +// GameNo: rm.Table.GetGameRoundId(), +// } +// go func() { +// err := gconfig.Produce(context.Background(), define.TopicJackpot, msg) +// if err != nil { +// log.Error(rm.Log("kafka JackpotEvent_et_user_repaid err: %v", err)) +// } +// }() +// log.Debug(rm.Log("kafka 赎回jpx:%v 追加jpy:%v", jpx, jpy)) +//} +// +//// 中jackpot分奖 +//func (rm *ColorRoom) kafkaHitJackpot(jackpot int64, userJp map[int64]int64) { +// msg := &events.JackpotEvent{ +// EventType: events.JackpotEvent_et_hit_jackpot, +// GameId: rm.RoomCfg.GameId, +// Time: time.Now().UnixMilli(), +// HitJackpot: &events.JackpotEvent_HitJackpot{SumJackpot: jackpot, UserJackpot: userJp}, +// GameNo: rm.Table.GetGameRoundId(), +// } +// go func() { +// err := gconfig.Produce(context.Background(), define.TopicJackpot, msg) +// if err != nil { +// log.Error(rm.Log("kafka JackpotEvent_HitJackpot err: %v", err)) +// } +// }() +// log.Debug(rm.Log("kafka 中jackpot:%v", jackpot)) +//} +// +//func (rm *ColorRoom) kafkaBackJackpot(jackpot, jpx, jpy int64, userJp map[int64]int64) { +// userJp2 := make(map[int64]int64) +// for k, v := range userJp { +// userJp2[k] = -v +// } +// msg := &events.JackpotEvent{ +// EventType: events.JackpotEvent_et_game_discard, +// GameId: rm.RoomCfg.GameId, +// Time: time.Now().UnixMilli(), +// GameDiscard: &events.JackpotEvent_GameDiscard{ +// Jackpot: -jackpot, +// JackpotX: -jpx, +// JackpotY: -jpy, +// UserJackpot: userJp2, +// }, +// GameNo: rm.Table.GetGameRoundId(), +// } +// go func() { +// err := gconfig.Produce(context.Background(), define.TopicJackpot, msg) +// if err != nil { +// log.Error(rm.Log("kafka JackpotEvent_HitJackpot err: %v", err)) +// } +// }() +// log.Debug(rm.Log("kafka 回退jackpot:%v jpx:%v jpy:%v", -jackpot, -jpx, -jpy)) +//} diff --git a/server/colorgame/room/process.go b/server/colorgame/room/process.go index 937d408..c9e44a2 100644 --- a/server/colorgame/room/process.go +++ b/server/colorgame/room/process.go @@ -1,117 +1,118 @@ package room -import ( - "encoding/json" - "game/common/proto/pb" - "github.com/fox/fox/ipb" - "time" -) - -func (rm *ColorRoom) Ready() { - rm.Table.ResetGameRoundId() - rm.ResetData(true) - rm.Table.EndGame() - - if isFunding := rm.jackpotMgr.Load(rm.RoomCfg.ColorPinoyLiveConfig.InitJackpot); isFunding { - rm.kafkaJackpotFunding(rm.RoomCfg.ColorPinoyLiveConfig.InitJackpot) - rm.jackpotFunding = rm.RoomCfg.ColorPinoyLiveConfig.InitJackpot - log.Debugf(rm.Log("发生垫资:%v", rm.jackpotFunding)) - } else { - rm.jackpotFunding = 0 - log.Debugf(rm.Log("没有垫资")) - } - rm.jackpotUser = nil - rm.costJackpot = 0 - log.Debugf(rm.Log("游戏开始costJackpot重置为0")) - rm.SetGameStatus(pb.ColorPinoyLiveGameStatus_ColorPinoyLiveStartReady) - rm.TimerJob, _ = rm.Table.AddTimer(time.Duration(rm.RoomCfg.TimeConf.Readymove), func() { - rm.Start() - }) - - // 初始化默认骰子 - // rm.initDefaultDiceGameRoundReady() - // 开始动画消息 - msg := new(pb.ColorPinoyLiveStatusMessage) - msg.Status = int32(rm.GetGameStatus()) - msg.StatusTime = int32(rm.RoomCfg.TimeConf.Startmove) - msg.Jackpot = rm.jackpotMgr.GetJackpot() - rm.Table.Broadcast(int32(pb.ColorPinoyLiveSendToClientMessageType_ColorPinoyLiveNoticeGameReady), msg) -} - -func (rm *ColorRoom) Start() { - rm.GameRoundStart() - rm.InitBigOddsBetAreas() - // 推送房间筹码选择规则 - rm.SendRuleInfo() - rm.checkUserBet() - // 选择列表中前6个用户上座 - rm.SelectUserListBalanceTopSitDownChair() - rm.startAt = time.Now().Unix() - rm.Table.StartGame() - // 开始动画消息 - msg := new(pb.ColorPinoyLiveStatusMessage) - msg.Status = int32(rm.GetGameStatus()) - msg.StatusTime = int32(rm.RoomCfg.TimeConf.Startmove) - // rm.jackpotMgr.Load(rm.Cfg.InitJackpot) - msg.Jackpot = rm.jackpotMgr.GetJackpot() - rm.Table.Broadcast(int32(pb.ColorPinoyLiveSendToClientMessageType_ColorPinoyLiveNoticeGameStart), msg) -} - -func (rm *ColorRoom) StartBet() { - rm.SetGameStatus(pb.ColorPinoyLiveGameStatus_ColorPinoyLiveBetStatus) - rm.TimerJob, _ = rm.Table.AddTimer(time.Duration(rm.RoomCfg.TimeConf.Startbet), func() { - rm.EndBet() - }) - - // 发送开始下注消息 - msg := new(pb.ColorPinoyLiveStatusMessage) - msg.Status = int32(rm.GetGameStatus()) - msg.StatusTime = int32(rm.RoomCfg.TimeConf.Startbet) - msg.Jackpot = rm.jackpotMgr.GetJackpot() - rm.Table.Broadcast(int32(pb.ColorPinoyLiveSendToClientMessageType_ColorPinoyLiveNoticeGameStartBet), msg) - // log.Debug("pb. 开始下注.....StartBet()") -} - -func (rm *ColorRoom) EndBet() { - rm.SetGameStatus(pb.ColorPinoyLiveGameStatus_ColorPinoyLiveEndBetMovie) - // 停止下注就扣钱 - rm.StartTransInoutBet() - - // 发送停止下注消息 - msg := new(pb.ColorPinoyLiveStatusMessage) - msg.Status = int32(rm.GetGameStatus()) - msg.StatusTime = int32(rm.RoomCfg.TimeConf.Endmove) - msg.Jackpot = rm.jackpotMgr.GetJackpot() - rm.Table.Broadcast(int32(pb.ColorPinoyLiveSendToClientMessageType_ColorPinoyLiveNoticeGameEndBet), msg) - - // log.Debug("pb. 停止下注.....EndBet()") -} - -// 开3个 dice -func (rm *ColorRoom) openThreeDice() { - // log.Debug("aabb openThreeDice") - rm.SetGameStatus(pb.ColorPinoyLiveGameStatus_ColorPinoyLiveOpenThreeDice) - rm.Table.AddTimer(time.Duration(rm.RoomCfg.TimeConf.OpenThreeDice), func() { - // log.Debug("aabb settle") - rm.CompareDiceResult() - rm.Settle() - }) - // 发送开三个骰子消息 - rm._aniThreeDiceRouteIndex = int32(rand.RandIntM(0, 48)) - msg := new(pb.ColorPinoyLiveGameOpenThreeDice) - msg.Status = int32(rm.GetGameStatus()) - msg.AniRouteIndex = rm._aniThreeDiceRouteIndex // 掉落路径 - - for _, dice := range rm.NormalDices { - msg.Color = append(msg.Color, pb.ColorPinoyLiveDiceColorType(model.GetColor(dice))) - } - rm.Table.Broadcast(int32(pb.ColorPinoyLiveSendToClientMessageType_ColorPinoyLiveNoticeGameOpenThreeDice), msg) -} - -// 结算 -func (rm *ColorRoom) Settle() { - // log.Debug("aabb 结算") - rm.SetGameStatus(pb.ColorPinoyLiveGameStatus_ColorPinoyLiveSettleStatus) - rm.endAt = time.Now().Unix() - rm.SetUserSettleMsg() -} +// +//import ( +// "encoding/json" +// "game/common/proto/pb" +// "github.com/fox/fox/ipb" +// "time" +//) +// +//func (rm *ColorRoom) Ready() { +// rm.Table.ResetGameRoundId() +// rm.ResetData(true) +// rm.Table.EndGame() +// +// if isFunding := rm.jackpotMgr.Load(rm.RoomCfg.ColorPinoyLiveConfig.InitJackpot); isFunding { +// rm.kafkaJackpotFunding(rm.RoomCfg.ColorPinoyLiveConfig.InitJackpot) +// rm.jackpotFunding = rm.RoomCfg.ColorPinoyLiveConfig.InitJackpot +// log.Debugf(rm.Log("发生垫资:%v", rm.jackpotFunding)) +// } else { +// rm.jackpotFunding = 0 +// log.Debugf(rm.Log("没有垫资")) +// } +// rm.jackpotUser = nil +// rm.costJackpot = 0 +// log.Debugf(rm.Log("游戏开始costJackpot重置为0")) +// rm.SetGameStatus(pb.ColorPinoyLiveGameStatus_ColorPinoyLiveStartReady) +// rm.TimerJob, _ = rm.Table.AddTimer(time.Duration(rm.RoomCfg.TimeConf.Readymove), func() { +// rm.Start() +// }) +// +// // 初始化默认骰子 +// // rm.initDefaultDiceGameRoundReady() +// // 开始动画消息 +// msg := new(pb.ColorPinoyLiveStatusMessage) +// msg.Status = int32(rm.GetGameStatus()) +// msg.StatusTime = int32(rm.RoomCfg.TimeConf.Startmove) +// msg.Jackpot = rm.jackpotMgr.GetJackpot() +// rm.Table.Broadcast(int32(pb.ColorPinoyLiveSendToClientMessageType_ColorPinoyLiveNoticeGameReady), msg) +//} +// +//func (rm *ColorRoom) Start() { +// rm.GameRoundStart() +// rm.InitBigOddsBetAreas() +// // 推送房间筹码选择规则 +// rm.SendRuleInfo() +// rm.checkUserBet() +// // 选择列表中前6个用户上座 +// rm.SelectUserListBalanceTopSitDownChair() +// rm.startAt = time.Now().Unix() +// rm.Table.StartGame() +// // 开始动画消息 +// msg := new(pb.ColorPinoyLiveStatusMessage) +// msg.Status = int32(rm.GetGameStatus()) +// msg.StatusTime = int32(rm.RoomCfg.TimeConf.Startmove) +// // rm.jackpotMgr.Load(rm.Cfg.InitJackpot) +// msg.Jackpot = rm.jackpotMgr.GetJackpot() +// rm.Table.Broadcast(int32(pb.ColorPinoyLiveSendToClientMessageType_ColorPinoyLiveNoticeGameStart), msg) +//} +// +//func (rm *ColorRoom) StartBet() { +// rm.SetGameStatus(pb.ColorPinoyLiveGameStatus_ColorPinoyLiveBetStatus) +// rm.TimerJob, _ = rm.Table.AddTimer(time.Duration(rm.RoomCfg.TimeConf.Startbet), func() { +// rm.EndBet() +// }) +// +// // 发送开始下注消息 +// msg := new(pb.ColorPinoyLiveStatusMessage) +// msg.Status = int32(rm.GetGameStatus()) +// msg.StatusTime = int32(rm.RoomCfg.TimeConf.Startbet) +// msg.Jackpot = rm.jackpotMgr.GetJackpot() +// rm.Table.Broadcast(int32(pb.ColorPinoyLiveSendToClientMessageType_ColorPinoyLiveNoticeGameStartBet), msg) +// // log.Debug("pb. 开始下注.....StartBet()") +//} +// +//func (rm *ColorRoom) EndBet() { +// rm.SetGameStatus(pb.ColorPinoyLiveGameStatus_ColorPinoyLiveEndBetMovie) +// // 停止下注就扣钱 +// rm.StartTransInoutBet() +// +// // 发送停止下注消息 +// msg := new(pb.ColorPinoyLiveStatusMessage) +// msg.Status = int32(rm.GetGameStatus()) +// msg.StatusTime = int32(rm.RoomCfg.TimeConf.Endmove) +// msg.Jackpot = rm.jackpotMgr.GetJackpot() +// rm.Table.Broadcast(int32(pb.ColorPinoyLiveSendToClientMessageType_ColorPinoyLiveNoticeGameEndBet), msg) +// +// // log.Debug("pb. 停止下注.....EndBet()") +//} +// +//// 开3个 dice +//func (rm *ColorRoom) openThreeDice() { +// // log.Debug("aabb openThreeDice") +// rm.SetGameStatus(pb.ColorPinoyLiveGameStatus_ColorPinoyLiveOpenThreeDice) +// rm.Table.AddTimer(time.Duration(rm.RoomCfg.TimeConf.OpenThreeDice), func() { +// // log.Debug("aabb settle") +// rm.CompareDiceResult() +// rm.Settle() +// }) +// // 发送开三个骰子消息 +// rm._aniThreeDiceRouteIndex = int32(rand.RandIntM(0, 48)) +// msg := new(pb.ColorPinoyLiveGameOpenThreeDice) +// msg.Status = int32(rm.GetGameStatus()) +// msg.AniRouteIndex = rm._aniThreeDiceRouteIndex // 掉落路径 +// +// for _, dice := range rm.NormalDices { +// msg.Color = append(msg.Color, pb.ColorPinoyLiveDiceColorType(model.GetColor(dice))) +// } +// rm.Table.Broadcast(int32(pb.ColorPinoyLiveSendToClientMessageType_ColorPinoyLiveNoticeGameOpenThreeDice), msg) +//} +// +//// 结算 +//func (rm *ColorRoom) Settle() { +// // log.Debug("aabb 结算") +// rm.SetGameStatus(pb.ColorPinoyLiveGameStatus_ColorPinoyLiveSettleStatus) +// rm.endAt = time.Now().Unix() +// rm.SetUserSettleMsg() +//} diff --git a/server/colorgame/room/s2c.go b/server/colorgame/room/s2c.go index fb0019c..56a30a3 100644 --- a/server/colorgame/room/s2c.go +++ b/server/colorgame/room/s2c.go @@ -1,703 +1,705 @@ package room -import ( - "encoding/json" - "fmt" - "game/common/proto/pb" - "github.com/fox/fox/ipb" - "github.com/fox/fox/log" - "math" - "sort" - "time" -) - -// 发送场景消息 -func (rm *ColorRoom) SendSceneMsg(u *model.User) { - - rm.MutexUserList.RLock() - defer rm.MutexUserList.RUnlock() - - msg := new(pb.SceneMessage) - - msg.RoomID = int32(rm.Table.GetId()) - // 游戏状态信息 - msg.GameStatus = new(pb.ColorPinoyLiveStatusMessage) - msg.GameStatus.Status = int32(rm.GetGameStatus()) - msg.GameStatus.StatusTime = int32(rm.StatusTime / 1000) // 转成秒 - msg.GameStatus.StatusRemainTime = int32(math.Floor(float64(rm.TimerJob.GetTimeDifference() / 1000))) // 转成秒 - msg.GameStatus.Jackpot = rm.jackpotMgr.GetJackpot() - msg.Jackpot = msg.GameStatus.Jackpot - - // 玩家信息 和下注信息 - var betAreaInfo []*pb.ColorPinoyLiveGameBetAreaInfo - for _, betArea := range rm.betEndBetAreasOdds { - areaInfo := new(pb.ColorPinoyLiveGameBetAreaInfo) - areaInfo.BetType = betArea.BetType - areaInfo.Odd = betArea.Odd - areaInfo.IsBigOdd = betArea.IsBigOdd - areaInfo.IsJackpot = betArea.IsJackpot - areaInfo.BigSingleColorOddPos = betArea.BigSingleColorOddPos - - areaInfo.BetChipsInfo = []*pb.ColorPinoyLiveGameBetAreaUserInfo{} - betAreaInfo = append(betAreaInfo, areaInfo) - } - rm.Traverse(func(u *model.User) bool { - if u.TotalBet > 0 { - // 下注玩家下注区域信息 - for _, info := range betAreaInfo { - for betType, betChips := range u.TotalBets { - if pb.ColorPinoyLiveBetTypeJP(betType) == info.BetType && betChips != 0 { - var betAearUser = new(pb.ColorPinoyLiveGameBetAreaUserInfo) - betAearUser.UserID = u.UserID - betAearUser.BetChips = betChips - info.BetChipsInfo = append(info.BetChipsInfo, betAearUser) - } - } - } - } - return true - }) - msg.BetAreaInfo = betAreaInfo - msg.MulRangeConfig = rm.MulRangeConfig() - - if u != nil { - // 后台配置的下注档位信息 - roomBetRule := new(pb.ColorPinoyLiveRoomBetRuleMsg) - for _, v := range rm.RoomCfg.ColorPinoyLiveConfig.BetList { - betArr := new(pb.ColorPinoyLiveBetArr) - betArr.BetArr = v - roomBetRule.BetLevels = append(roomBetRule.BetLevels, betArr) - } - roomBetRule.BetMinLimit = rm.RoomCfg.BaseBet - roomBetRule.Level = rm.RoomCfg.ColorPinoyLiveConfig.BetLevel - msg.BetRule = roomBetRule - // 上局下注数据 - if u.TempLastTimeBet != nil { - msg.LastTimeBet = make([]*pb.ColorPinoyLiveBetReqs, 0) - for _, reqs := range u.TempLastTimeBet { - betreq := &pb.ColorPinoyLiveBetReqs{} - for _, req := range reqs { - betreq.Info = append(betreq.Info, req) - } - msg.LastTimeBet = append(msg.LastTimeBet, betreq) - } - } - } - - if rm.Status == pb.ColorPinoyLiveGameStatus_ColorPinoyLiveOpenThreeDice || rm.Status == pb.ColorPinoyLiveGameStatus_ColorPinoyLiveSettleStatus { - // 3个骰子 - // log.Debug("同步房间信息发送场景信息 rm.NormalDices:", rm.NormalDices) - msg.LuckyDice = pb.ColorPinoyLiveDiceColorType(model.GetColor(rm.LuckyDice)) - msg.ThreeDice = []pb.ColorPinoyLiveDiceColorType{} - for _, dice := range rm.NormalDices { - msg.ThreeDice = append(msg.ThreeDice, pb.ColorPinoyLiveDiceColorType(model.GetColor(dice))) - // log.Debug("同步房间信息发送场景信息 i:", i, "dice:", dice, "color:", pb.DiceColorType(model.GetColor(dice)), "msg.ThreeDice:", msg.ThreeDice) - } - msg.AniThreeDiceRouteIndex = rm._aniThreeDiceRouteIndex - } - // 走势图 - msg.TrendList = rm.GameTrend - if msg.TrendList != nil { - msg.TrendList.LuckStarRate = rm.GetGameTrend() - } - - // 在线人数 - msg.OnlineNums = int32(len(rm.OnlineUserList)) - if rm.LiveMgr.RankList != nil { - msg.RankList = rm.LiveMgr.RankList.PlayerData - } - // msg.Bonus = int32(rm.RoomCfg.ColorPinoyLiveConfig.Bonus) - - liveAuthDuration := time.Hour * 24 - //goland:noinspection GoDfaNilDereference - msg.ArtcUrl, _ = artc.GetAuthedUrl( - gconfig.LiveRtcConfig.Uri, - gconfig.LiveRtcConfig.Key, - u.UserInetr.GetId(), - liveAuthDuration, - ) - roomArgs, _ := trtc.GetRoomArgs( - gconfig.LiveTrtcConfig.AppId, - gconfig.LiveTrtcConfig.SecretKey, - int64(gconfig.LiveTrtcConfig.GameId), - u.UserInetr.GetId(), - liveAuthDuration, - gconfig.GConfig.GDataConfig.VersionMode, - ) - msg.TrtcRoomArgs = &pb.TRTCRoomArgs{ - AppId: roomArgs.AppId, - StrRoomId: roomArgs.StrRoomId, - UserId: roomArgs.UserId, - UserSig: roomArgs.UserSig, - } - msg.Balance = u.Balance - msg.BigWinner = rm.BigWinner - if rm.GetGameStatus() < pb.ColorPinoyLiveGameStatus_ColorPinoyLiveEndBetMovie { - msg.BigWinner = nil - } - msg.DealerName = rm.dealerName - // log.Debug("同步房间信息发送场景信息 msg:", msg) - // log.Debug(msg) - u.SendMsg(int32(pb.ColorPinoyLiveSendToClientMessageType_ColorPinoyLiveNoticeGameSync), msg) -} - -func (rm *ColorRoom) SendUserBet(u *model.User) { - msg := new(pb.ColorPinoyLiveSceneBetInfo) - msg.UserBets = u.TotalBets[:] - msg.TotalBets = rm.TotalBets[:] - msg.UserBetTotal = u.TotalBet - // msg.MasterBetType = rm.LastMasterBetType - msg.UserInfo = new(pb.ColorPinoyLiveUserInfo) - msg.UserInfo.UserID = u.UserID - msg.UserInfo.UserGlod = u.Balance - msg.UserInfo.NikeName = u.UserInetr.GetNike() - msg.UserInfo.Head = u.UserInetr.GetHead() - _ = u.UserInetr.SendMsg(int32(pb.ColorPinoyLiveSendToClientMessageType_ColorPinoyLiveNoticeGameUserBet), msg) -} - -func (rm *ColorRoom) SendRuleInfo() { - // 后台配置的下注档位信息 - msg := new(pb.ColorPinoyLiveRoomBetRuleMsg) - for _, v := range rm.RoomCfg.ColorPinoyLiveConfig.BetList { - betArr := new(pb.ColorPinoyLiveBetArr) - betArr.BetArr = v - msg.BetLevels = append(msg.BetLevels, betArr) - } - msg.BetMinLimit = rm.RoomCfg.BaseBet - msg.Level = rm.RoomCfg.ColorPinoyLiveConfig.BetLevel - msg.MulRangeConfig = rm.MulRangeConfig() - // log.Debug("发送规则 2222 BroadcastRuleInfo:", msg) - rm.Table.Broadcast(int32(pb.ColorPinoyLiveSendToClientMessageType_ColorPinoyLiveNoticeRoomBetRuleMsg), msg) -} - -func (rm *ColorRoom) SendScene(user inter.UserInetr) bool { - _ = user - return true -} - -func (rm *ColorRoom) copyBetAreaOdds() []*pb.ColorPinoyLiveBetAreaOdd { - var betAreaMul []*pb.ColorPinoyLiveBetAreaOdd - // 游戏下注区域倍率 - for _, areaOdds := range rm.afterBetAreaOdds { - area := &pb.ColorPinoyLiveBetAreaOdd{ - BetArea: areaOdds.BetArea, - Odd: areaOdds.Odd, - ViewOdd: areaOdds.ViewOdd, - IsBigOdd: areaOdds.IsBigOdd, - BigSingleColorOddPos: areaOdds.BigSingleColorOddPos, - IsWin: areaOdds.IsWin, - IsJackpot: areaOdds.IsJackpot, - } - betAreaMul = append(betAreaMul, area) - } - return betAreaMul -} - -func (rm *ColorRoom) GameSync(user inter.UserInetr) { - // 玩家加入 牌桌 - u := rm.getUser(user) - rm.SendSceneMsg(u) - rm.Table.AddTimer(100, func() { - if rm.LiveMgr.MaintenanceStatus == 1 { - rm.sendUserMainte(u, int32(pb.ColorPinoyLiveSendToClientMessageType_ColorPinoyLiveNoticeGameMainte)) - } - }) -} - -// 向客户端发送结算消息 -func (rm *ColorRoom) sendSettleMsg2Client() { - - MaxWinGold := int64(0) - MaxWinUserID := int64(0) - var RealSystemWins [config.BET_TYPE_NUM]int64 - var RealSystemWin int64 - var SystemTax int64 - var PlayerData []*pb.ColorPinoyLivePlayerData - betTypePlayerCount := [config.BET_TYPE_NUM]int64{} - wins := rm.PokerMsg.WinBetArea - - // 玩家各个下注区域的输赢情况 - var betAreaInfo []*pb.ColorPinoyLiveGameBetAreaInfo - for i := 0; i < config.BET_TYPE_NUM; i++ { - areaInfo := new(pb.ColorPinoyLiveGameBetAreaInfo) - areaInfo.BetType = pb.ColorPinoyLiveBetTypeJP(i) - for _, win := range wins { - if win.BetArea == areaInfo.BetType { - areaInfo.IsWin = 1 - } - } - areaInfo.BetChipsInfo = []*pb.ColorPinoyLiveGameBetAreaUserInfo{} - betAreaInfo = append(betAreaInfo, areaInfo) - } - - // 获取有座玩家下注情况 暂时没有有座玩家下注 - var betUserInfo []*pb.ColorPinoyLiveSceneUserInfo - noChairTotalWin := int64(0) - rm.Traverse(func(u *model.User) bool { - if u.TotalBet > 0 && u.SettleMsg != nil { - user := new(pb.ColorPinoyLiveSceneUserInfo) - user.UserID = u.UserID - user.TotalWin = u.SettleMsg.TotalWin - user.UserScore = u.SettleMsg.UserScore - - for _, info := range betAreaInfo { - for betType, betChips := range u.SettleMsg.UserBets { - if pb.ColorPinoyLiveBetTypeJP(betType) == info.BetType && betChips != 0 { - var betAearUser = new(pb.ColorPinoyLiveGameBetAreaUserInfo) - betAearUser.UserID = u.UserID - betAearUser.BetChips = betChips - info.BetChipsInfo = append(info.BetChipsInfo, betAearUser) - } - } - } - betUserInfo = append(betUserInfo, user) - noChairTotalWin += u.SettleMsg.TotalWin - - } - return true - }) - - // 单播每个玩家的结算信息 - copyBetAreaMul := rm.copyBetAreaOdds() - betCount := int64(0) - GameTotalBets := [config.BET_TYPE_NUM]int64{} - rm.Traverse(func(u *model.User) bool { - - SceneUserInfo := new(pb.ColorPinoyLiveSceneSettleMsg) - // 下注区域投注信息 - SceneUserInfo.BetAreaInfo = betAreaInfo - // 本局走势图数据 - trendGroup := new(pb.ColorPinoyLiveTrendGroup) - trendGroup.LuckyDice = pb.ColorPinoyLiveDiceColorType(model.GetColor(rm.LuckyDice)) - for _, dice := range rm.NormalDices { - trendGroup.ThreeDice = append(trendGroup.ThreeDice, pb.ColorPinoyLiveDiceColorType(model.GetColor(dice))) - } - SceneUserInfo.TrendGroup = trendGroup - // 有座玩家下注信息 暂时没有有座玩家 - // SceneUserInfo.UserList = betUserInfo - // 幸运骰子 - SceneUserInfo.LuckyDice = pb.ColorPinoyLiveDiceColorType(model.GetColor(rm.LuckyDice)) - // 3个骰子 - SceneUserInfo.ThreeDice = []pb.ColorPinoyLiveDiceColorType{} - for _, dice := range rm.NormalDices { - SceneUserInfo.ThreeDice = append(SceneUserInfo.ThreeDice, pb.ColorPinoyLiveDiceColorType(model.GetColor(dice))) - } - // 自己的投注信息 - if u.SettleMsg != nil { - SceneUserInfo.SelfWinInfo = new(pb.ColorPinoyLiveSceneUserInfo) - SceneUserInfo.SelfWinInfo.UserID = int64(u.UserInetr.GetId()) - SceneUserInfo.SelfWinInfo.SceneSeatID = int32(u.SceneChairId) - SceneUserInfo.SelfWinInfo.TotalWin = u.SettleMsg.TotalWin // 净利 + 投注本金 - SceneUserInfo.SelfWinInfo.UserScore = u.SettleMsg.UserScore - SceneUserInfo.SelfWinInfo.JackpotWin = u.SettleMsg.JackpotWin - SceneUserInfo.SelfWinInfo.NormalWin = u.SettleMsg.TotalWin - u.SettleMsg.JackpotWin - } - // 上局投注信息 - SceneUserInfo.LastTimeBet = make([]*pb.ColorPinoyLiveBetReqs, 0) - for _, reqs := range u.LastTimeBet { - betreq := &pb.ColorPinoyLiveBetReqs{} - for _, req := range reqs { - betreq.Info = append(betreq.Info, req) - } - SceneUserInfo.LastTimeBet = append(SceneUserInfo.LastTimeBet, betreq) - } - SceneUserInfo.TrendGroupEx = &pb.ColorPinoyLiveTrend{} - SceneUserInfo.TrendGroupEx.ListTrendGroup = rm.GameTrend.ListTrendGroup - SceneUserInfo.TrendGroupEx.LuckStarRate = rm.GetGameTrend() - SceneUserInfo.BigWinner = rm.BigWinner - SceneUserInfo.Jackpot = rm.jackpotMgr.GetJackpot() - SceneUserInfo.JackpotUserName = u.SettleMsg.JackpotUserName - // 单播玩家结算信息 - // log.Debug("发送结算信息 SceneUserInfo BetAreaInfo:", SceneUserInfo.BetAreaInfo) - // log.Debug("发送结算信息 SceneUserInfo UserList:", SceneUserInfo.UserList) - // log.Debug("发送结算信息 SceneUserInfo SelfWinInfo:", SceneUserInfo.SelfWinInfo) - u.SendMsg(int32(pb.ColorPinoyLiveSendToClientMessageType_ColorPinoyLiveNoticeGameUserSettle), SceneUserInfo) - - if !u.IsRobot && u.SettleMsg != nil { - RealSystemWin += u.TotalBet - RealSystemWin -= u.SettleMsg.TotalWin - betCount += u.TotalBet - SystemTax += u.SettleMsg.Tax - if MaxWinGold < u.SettleMsg.TotalWin-u.TotalBet { - MaxWinGold = u.SettleMsg.TotalWin - u.TotalBet - MaxWinUserID = u.UserInetr.GetId() - } - for i, bet := range u.TotalBets { - if bet > 0 { - RealSystemWins[i] += bet - betTypePlayerCount[i] += 1 - RealSystemWins[i] -= u.SettleMsg.UserRealWins[i] - GameTotalBets[i] += bet - } - } - // 写入数据库统计信息 - if u.TotalBet > 0 { - // 玩家下注区域统计 - u.SettleMsg.UserBetsCount = make([]int64, config.BET_TYPE_NUM) - for i, count := range u.TotalBetsCount { - u.SettleMsg.UserBetsCount[i] = count - } - PlayerData = append(PlayerData, &pb.ColorPinoyLivePlayerData{ - Uid: u.UserID, - TotalBets: u.SettleMsg.UserBets, // 玩家各个区域的总下注额 - TotalBet: u.TotalBet, - Profit: u.SettleMsg.TotalWin, - Tax: u.SettleMsg.Tax, - Balance: u.Balance, - PreBalance: u.PreBalance, - UserWins: u.SettleMsg.UserWins, // 玩家赢取的下注区域总下注额 - UserRealWins: u.SettleMsg.UserRealWins, // 玩家赢取的下注区域总下注额 扣税后 - AreaOdds: copyBetAreaMul, // 投注区域赔率 - StartTime: u.StartAt, - TransBet: u.TransBet, - TransWin: u.TransWin, - DevMode: u.UserInetr.GetDevMode(), - UserBetsCount: u.SettleMsg.UserBetsCount, - Nickname: u.UserInetr.GetNike(), - Avatar: u.UserInetr.GetHead(), - }) - } - // log.Debug("开奖倍率:", u.SettleMsg.OddsWins) - } - - // u.ResetUserData() - return true - }) - // rm.Table.GameBetInfo(gameBetInfos) - cou := model.Usercount{} - cou = rm.OnlineUserList - sort.Sort(cou) - - for key, v := range pb.ColorPinoyLiveBetTypeJP_value { - if rm.TotalBets[v] > 0 || betTypePlayerCount[v] > 0 || RealSystemWins[v] > 0 { - log.Debug(rm.Log("%v 区域:总:%v 真:%v 真人数量:%v 真输赢:%v", key, score.GetScoreStr(rm.TotalBets[v]), score.GetScoreStr(GameTotalBets[v]), betTypePlayerCount[v], score.GetScoreStr(rm.TotalBets[v]-RealSystemWins[v]))) - } - } - - str := fmt.Sprintf("开局结果 幸运骰子:%v :普通骰子:%v ,%v ,%v ,", - model.GetColorString(rm.LuckyDice), model.GetColorString(rm.NormalDices[0]), model.GetColorString(rm.NormalDices[1]), model.GetColorString(rm.NormalDices[2])) - - str += fmt.Sprintf("总押注:%v ", score.GetScoreStr(rm.TotalBet)) - - str += fmt.Sprintf("真人 总押注:%v , 系统输赢额度:%v ", - score.GetScoreStr(betCount), - score.GetScoreStr(RealSystemWin), - ) - - str += fmt.Sprintf("最高获利用户ID:%v 获得:%v", - MaxWinUserID, score.GetScoreStr(MaxWinGold)) - - log.Debug(rm.Log(str)) - log.Debug(rm.Log("各区域投注:%v", rm.TotalBets)) - log.Debug(rm.Log("真人各区域投注:%v", GameTotalBets)) - log.Debug(rm.Log("真人各区域中奖:%v", RealSystemWins)) - log.Debug(rm.Log("中奖区域:%v", wins)) - - // SceneSettleMsg.NoChairTotalWin = noChairTotalWin - // rm.Table.Broadcast(int32(pb.SendToClientMessageType_NoticeGameSettle), SceneSettleMsg) - rm.LiveMgr.RankList = &pb.ColorPinoyLiveRankList{ - PlayerData: nil, - GameNo: rm.Table.GetGameRoundId(), - StartTime: rm.startAt, - EndTime: rm.endAt, - } - - // 发布事件 - if PlayerData == nil || len(PlayerData) == 0 { - return - } - // 开奖结果 - var threeDice []pb.ColorPinoyLiveDiceColorType - for _, dice := range rm.NormalDices { - threeDice = append(threeDice, pb.ColorPinoyLiveDiceColorType(model.GetColor(dice))) - } - - var startDice []pb.ColorPinoyLiveDiceColorType - for _, dice := range rm.StartDices { - startDice = append(startDice, pb.ColorPinoyLiveDiceColorType(model.GetColor(dice))) - } - - gameDetail := &pb.ColorPinoyLiveDetail{ - // LuckyDice: pb.ColorPinoyLiveDiceColorType(model.GetColor(rm.LuckyDice)), - ThreeDice: threeDice, - // Bonus: rm.RoomCfg.ColorPinoyLiveConfig.Bonus, - StartDice: startDice, - ResultImg: rm.ResultImgs, - DealerName: rm.dealerName, - BetAreaMul: copyBetAreaMul, - JackpotFunding: rm.jackpotFunding, - JackpotX: rm.jackpotX, - JackpotY: rm.jackpotY, - } - - gameRecordData := &pb.ColorPinoyLiveEnd{ - GameNo: rm.Table.GetGameRoundId(), - StartTime: rm.startAt, - EndTime: rm.endAt, - Level: gconfig.GConfig.GRoomConfig.Level, - BaseBet: rm.RoomCfg.BaseBet, - PlayerData: PlayerData, - TaxRate: rm.RoomCfg.Rate, - TotalBet: betCount, - TotalBets: GameTotalBets[:], - RealSystemWin: RealSystemWin, - RealSystemWins: RealSystemWins[:], - Tax: SystemTax, - Wins: nil, - OpToken: gconfig.GConfig.GServConfig.ChannelId, - Detail: gameDetail, - } - for _, winArea := range rm.PokerMsg.WinBetArea { - gameRecordData.Wins = append(gameRecordData.Wins, winArea.BetArea) - } - - sort.Slice(PlayerData, func(i, j int) bool { - return PlayerData[i].Profit > PlayerData[j].Profit - }) - - for i := 0; i < 6 && i < len(PlayerData); i++ { - if PlayerData[i].TransWin == 0 { - continue - } - rm.LiveMgr.RankList.PlayerData = append(rm.LiveMgr.RankList.PlayerData, PlayerData[i]) - } - log.Debug(rm.Log("玩家数量:%v 赢家数量:%v", len(PlayerData), len(rm.LiveMgr.RankList.PlayerData))) - go func() { - // log.Debug("color game 游戏记录:", gameDetail) - // log.Debug("color game 游戏记录 Tax:", gameRecordData.Tax) - // log.Debug("color game 游戏记录 Wins:", gameRecordData.Wins) - // log.Debug("color game 游戏记录 PlayerData:", gameRecordData.PlayerData) - s, _ := json.Marshal(gameRecordData) - log.Debug(rm.Log("记录区域数据:%v", string(s))) - err := gconfig.Produce(context.Background(), define.TopicColoLiveGameGameEnd, gameRecordData) - if err != nil { - log.Error(rm.Log("[%s] fail to Produce TongitsGameEndEvent(%+v), err: %v", gameRecordData.GameNo, gameRecordData, err)) - } - }() - -} - -func (rm *ColorRoom) SendOnlinePlayerNum() { - msg := new(pb.ColorPinoyLiveS2COnlinePlayerNum) - msg.Num = int64(len(rm.OnlineUserList)) - rm.Table.Broadcast(int32(pb.ColorPinoyLiveSendToClientMessageType_ColorPinoyLiveNoticeOnlinePlayerNum), msg) -} - -func (rm *ColorRoom) SendRoomInfo() { - // if rm.GetGameStatus() == 0 { - // return - // } - // msg := new(pb.UpdateRoomInfoMsg) - // msg.OnlineNum = int64(len(rm.OnlineUserList)) - // rm.Table.Broadcast(int32(pb.SendToClientMessageType_NoticeUpdateRoomInfo), msg) -} - -// 广播主播名字 -func (rm *ColorRoom) NotifyDealerName() { - msg := new(pb.ColorPinoyLiveDealerName) - msg.DealerName = rm.dealerName - rm.Table.Broadcast(int32(pb.ColorPinoyLiveSendToClientMessageType_ColorPinoyLiveNoticeDealerName), msg) - log.Debug(rm.Log("NotifyDealerName:%v", msg)) -} - -type MulRangeW struct { - *config.MulRate - MinW int // 权重转换成数值区间 - MaxW int // 权重转换成数值区间 - ColorPos pb.ColorPinoyLiveBigBetAreaPos // 0:单色区域基础倍率 1:单色区域双色倍率 2:单色区域开三色倍率 3:双色区域 4:三色区域 -} - -// 带有权重信息的五行倍率数组(单色单,单色双,单色三,双色,三色倍率数组) -func (rm *ColorRoom) initMulRangeW() (mulRangeW [][]*MulRangeW) { - mulRangeW = make([][]*MulRangeW, 0, 5) - - for pos, mulWs := range rm.Cfg.WinSingleColorMul { - var single []*MulRangeW - for _, mul := range mulWs { - single = append(single, &MulRangeW{MulRate: mul, ColorPos: pb.ColorPinoyLiveBigBetAreaPos(pos)}) - } - mulRangeW = append(mulRangeW, single) - } - - var double []*MulRangeW - for _, mul := range rm.Cfg.WinDoubleColorMul { - double = append(double, &MulRangeW{MulRate: mul, ColorPos: pb.ColorPinoyLiveBigBetAreaPos_BBA_Double}) - } - mulRangeW = append(mulRangeW, double) - - var three []*MulRangeW - for _, mul := range rm.Cfg.WinThreeColorMul { - three = append(three, &MulRangeW{MulRate: mul, ColorPos: pb.ColorPinoyLiveBigBetAreaPos_BBA_Three}) - } - mulRangeW = append(mulRangeW, three) - - for _, mulRws := range mulRangeW { - begin := 0 - for _, v := range mulRws { - v.MinW = begin - v.MaxW = begin + v.Rate - begin += v.Rate - } - } - - return mulRangeW -} - -// 返回单色投注区爆奖的权重数组及是爆在双色还是三色位置 -func (rm *ColorRoom) randSingle(cfg *config.ColorPinoyLiveConfig) (singleMul []*MulRangeW, singlePos int) { - maxWeight := 0 - for _, w := range cfg.WinSingleColorWeight { - maxWeight += w - } - weight := rand.RandInt(0, maxWeight) - log.Debug(rm.Log("单色投注区获取爆奖在双色还是三色,随机值为:%v 最大值:%v", weight, maxWeight)) - for pos, w := range cfg.WinSingleColorWeight { - if weight > w { - weight -= w - continue - } - log.Debug(rm.Log("单色投注区获取爆奖根据权重随机出来的爆奖位置为:%v", pos)) - // 爆奖只会提高开出双色或三色的赔率,基础赔率区不会爆奖 - if pos == 0 { - log.Debug(rm.Log("单色投注区的基础赔率区不会爆奖")) - return nil, pos - } - for _, mul := range cfg.WinSingleColorMul[pos] { - singleMul = append(singleMul, &MulRangeW{MulRate: mul, ColorPos: pb.ColorPinoyLiveBigBetAreaPos(pos)}) - } - begin := 0 - for _, v := range singleMul { - v.MinW = begin - v.MaxW = begin + v.Rate - begin += v.Rate - } - return singleMul, pos - } - return nil, 0 -} - -// 更新 -func (rm *ColorRoom) updateBetEndBetAreasOdds(mulRangeWs [][]*MulRangeW) { - for pos, betArea := range rm.betEndBetAreasOdds { - log.Debug(rm.Log("区域:%v 随机前 爆奖状态:%v", pb.ColorPinoyLiveBetTypeJP(pos), betArea.IsBigOdd)) - betArea.IsBigOdd = false - // 区域位置 0-2分别为单色、双色、三色投注区域, - index := pos / 6 - singlePos := 0 - var mulRangeW []*MulRangeW - if index == 0 { - mulRangeW, singlePos = rm.randSingle(rm.Cfg) - } else { - mulRangeW = mulRangeWs[index+2] - } - if mulRangeW == nil { - log.Error(rm.Log("投注区域:%v 获取爆奖权重数组为nil", pos)) - continue - } - rdv := rand.RandInt(mulRangeW[0].MinW, mulRangeW[len(mulRangeW)-1].MaxW) - for mulPos, mul := range mulRangeW { - if rdv < mul.MinW || rdv >= mul.MaxW { - continue - } - if index == 0 { - betArea.Odd[singlePos] = mul.Mul - if singlePos != 0 && mulPos != 0 { - log.Debug(rm.Log("区域:%v 爆奖位置:%v", pb.ColorPinoyLiveBetTypeJP(pos), mul.ColorPos)) - betArea.IsBigOdd = true - } - } else { - betArea.Odd[0] = mul.Mul - if mulPos != 0 { - log.Debug(rm.Log("区域:%v 爆奖位置:%v", pb.ColorPinoyLiveBetTypeJP(pos), mul.ColorPos)) - betArea.IsBigOdd = true - } - } - betArea.BigSingleColorOddPos = mul.ColorPos - break - } - log.Debug(rm.Log("区域:%v 爆奖权重区间:[%v,%v],随机数:%v betArea:%+v", pb.ColorPinoyLiveBetTypeJP(pos), - mulRangeW[0].MinW, mulRangeW[len(mulRangeW)-1].MaxW, rdv, betArea)) - } - // 更新jackpot标记 - _ = rm.randJackpotArea() - return -} - -func (rm *ColorRoom) randJackpotArea() []pb.ColorPinoyLiveBetTypeJP { - betAreaInfo := make(map[int]*pb.ColorPinoyLiveGameBetAreaInfo) - for pos, betArea := range rm.betEndBetAreasOdds { - betAreaInfo[pos] = betArea - } - // 利用map的随机特性 - for pos, betArea := range betAreaInfo { - // 区域位置 0-2分别为单色、双色、三色投注区域, - index := pos / 6 - if index > 0 { - continue - } - _, singlePos := rm.randSingle(rm.Cfg) - // 在单色区域 命中三同色爆奖之后 再随jackpot概率 - // 只会有一个区域有jackpot标签 - if singlePos == 2 { - if rand.RandInt(0, 10000) < rm.Cfg.JackpotRate { - betArea.IsJackpot = true - return []pb.ColorPinoyLiveBetTypeJP{betArea.BetType} - } - } - } - return nil -} - -// 区域爆奖 -func (rm *ColorRoom) NotifyBigBetAreaMul() { - mulRangeW := rm.initMulRangeW() - rm.updateBetEndBetAreasOdds(mulRangeW) - - for _, betArea := range rm.betEndBetAreasOdds { - log.Debug(rm.Log("投注区域:%v 倍率:%v 是否爆奖:%v 是否jackpot:%v 倍率位置:%v", betArea.BetType, betArea.Odd, betArea.IsBigOdd, betArea.IsJackpot, betArea.BigSingleColorOddPos)) - } - - msg := new(pb.ColorPinoyLiveNtfBigOddBetArea) - msg.BetAreas = rm.betEndBetAreasOdds - rm.Table.Broadcast(int32(pb.ColorPinoyLiveSendToClientMessageType_ColorPinoyLiveNoticeBigOddBetArea), msg) - log.Debug(rm.Log("ColorPinoyLiveNtfBigOddBetArea:%v", msg)) -} - -func (rm *ColorRoom) formatScore(score int64) string { - s := float64(score / 100.0) - numStr := fmt.Sprintf("%.2f", s) - - // result := "" - // for i := len(numStr) - 1; i >= 0; i-- { - // result = string(numStr[i]) + result - // if (len(numStr)-i)%3 == 0 && i != 0 { - // result = "," + result - // } - // } - return numStr - // return result -} - -func (rm *ColorRoom) BroadHitJackpot(user *model.User, jpScore int64) { - go func() { - req := &fmsg.ChatReq{ - Uid: user.UserID, - GameId: rm.RoomCfg.GameId, - Content: fmt.Sprintf("%v WIN ₱ %v FROM JACKPOT", user.UserInetr.GetNike(), rm.formatScore(jpScore)), - Type: 0, - } - bReq, err := proto.Marshal(req) - if err != nil { - log.Error(rm.Log(err.Error())) - return - } - lobbyMsg := &events.SingleMsgToLobbyEvent{ - Module: events.SingleMsgToLobbyEvent_mtl_chat, - Data: bReq, - } - err = gconfig.Produce(context.Background(), define.TopicSingleMsgToLobby, lobbyMsg) - if err != nil { - log.Error(rm.Log("fail to Produce SingleMsgToLobbyEvent_mtl_chat, err: %v", err)) - } - }() -} +// +//import ( +// "encoding/json" +// "fmt" +// "game/common/config/game" +// "game/common/proto/pb" +// "github.com/fox/fox/ipb" +// "github.com/fox/fox/log" +// "math" +// "sort" +// "time" +//) +// +//// 发送场景消息 +//func (rm *ColorRoom) SendSceneMsg(u *model.User) { +// +// rm.MutexUserList.RLock() +// defer rm.MutexUserList.RUnlock() +// +// msg := new(pb.SceneMessage) +// +// msg.RoomID = int32(rm.Table.GetId()) +// // 游戏状态信息 +// msg.GameStatus = new(pb.ColorPinoyLiveStatusMessage) +// msg.GameStatus.Status = int32(rm.GetGameStatus()) +// msg.GameStatus.StatusTime = int32(rm.StatusTime / 1000) // 转成秒 +// msg.GameStatus.StatusRemainTime = int32(math.Floor(float64(rm.TimerJob.GetTimeDifference() / 1000))) // 转成秒 +// msg.GameStatus.Jackpot = rm.jackpotMgr.GetJackpot() +// msg.Jackpot = msg.GameStatus.Jackpot +// +// // 玩家信息 和下注信息 +// var betAreaInfo []*pb.ColorPinoyLiveGameBetAreaInfo +// for _, betArea := range rm.betEndBetAreasOdds { +// areaInfo := new(pb.ColorPinoyLiveGameBetAreaInfo) +// areaInfo.BetType = betArea.BetType +// areaInfo.Odd = betArea.Odd +// areaInfo.IsBigOdd = betArea.IsBigOdd +// areaInfo.IsJackpot = betArea.IsJackpot +// areaInfo.BigSingleColorOddPos = betArea.BigSingleColorOddPos +// +// areaInfo.BetChipsInfo = []*pb.ColorPinoyLiveGameBetAreaUserInfo{} +// betAreaInfo = append(betAreaInfo, areaInfo) +// } +// rm.Traverse(func(u *model.User) bool { +// if u.TotalBet > 0 { +// // 下注玩家下注区域信息 +// for _, info := range betAreaInfo { +// for betType, betChips := range u.TotalBets { +// if pb.ColorPinoyLiveBetTypeJP(betType) == info.BetType && betChips != 0 { +// var betAearUser = new(pb.ColorPinoyLiveGameBetAreaUserInfo) +// betAearUser.UserID = u.UserID +// betAearUser.BetChips = betChips +// info.BetChipsInfo = append(info.BetChipsInfo, betAearUser) +// } +// } +// } +// } +// return true +// }) +// msg.BetAreaInfo = betAreaInfo +// msg.MulRangeConfig = rm.MulRangeConfig() +// +// if u != nil { +// // 后台配置的下注档位信息 +// roomBetRule := new(pb.ColorPinoyLiveRoomBetRuleMsg) +// for _, v := range rm.RoomCfg.ColorPinoyLiveConfig.BetList { +// betArr := new(pb.ColorPinoyLiveBetArr) +// betArr.BetArr = v +// roomBetRule.BetLevels = append(roomBetRule.BetLevels, betArr) +// } +// roomBetRule.BetMinLimit = rm.RoomCfg.BaseBet +// roomBetRule.Level = rm.RoomCfg.ColorPinoyLiveConfig.BetLevel +// msg.BetRule = roomBetRule +// // 上局下注数据 +// if u.TempLastTimeBet != nil { +// msg.LastTimeBet = make([]*pb.ColorPinoyLiveBetReqs, 0) +// for _, reqs := range u.TempLastTimeBet { +// betreq := &pb.ColorPinoyLiveBetReqs{} +// for _, req := range reqs { +// betreq.Info = append(betreq.Info, req) +// } +// msg.LastTimeBet = append(msg.LastTimeBet, betreq) +// } +// } +// } +// +// if rm.Status == pb.ColorPinoyLiveGameStatus_ColorPinoyLiveOpenThreeDice || rm.Status == pb.ColorPinoyLiveGameStatus_ColorPinoyLiveSettleStatus { +// // 3个骰子 +// // log.Debug("同步房间信息发送场景信息 rm.NormalDices:", rm.NormalDices) +// msg.LuckyDice = pb.ColorPinoyLiveDiceColorType(model.GetColor(rm.LuckyDice)) +// msg.ThreeDice = []pb.ColorPinoyLiveDiceColorType{} +// for _, dice := range rm.NormalDices { +// msg.ThreeDice = append(msg.ThreeDice, pb.ColorPinoyLiveDiceColorType(model.GetColor(dice))) +// // log.Debug("同步房间信息发送场景信息 i:", i, "dice:", dice, "color:", pb.DiceColorType(model.GetColor(dice)), "msg.ThreeDice:", msg.ThreeDice) +// } +// msg.AniThreeDiceRouteIndex = rm._aniThreeDiceRouteIndex +// } +// // 走势图 +// msg.TrendList = rm.GameTrend +// if msg.TrendList != nil { +// msg.TrendList.LuckStarRate = rm.GetGameTrend() +// } +// +// // 在线人数 +// msg.OnlineNums = int32(len(rm.OnlineUserList)) +// if rm.LiveMgr.RankList != nil { +// msg.RankList = rm.LiveMgr.RankList.PlayerData +// } +// // msg.Bonus = int32(rm.RoomCfg.ColorPinoyLiveConfig.Bonus) +// +// liveAuthDuration := time.Hour * 24 +// //goland:noinspection GoDfaNilDereference +// msg.ArtcUrl, _ = artc.GetAuthedUrl( +// gconfig.LiveRtcConfig.Uri, +// gconfig.LiveRtcConfig.Key, +// u.UserInetr.GetId(), +// liveAuthDuration, +// ) +// roomArgs, _ := trtc.GetRoomArgs( +// gconfig.LiveTrtcConfig.AppId, +// gconfig.LiveTrtcConfig.SecretKey, +// int64(gconfig.LiveTrtcConfig.GameId), +// u.UserInetr.GetId(), +// liveAuthDuration, +// gconfig.GConfig.GDataConfig.VersionMode, +// ) +// msg.TrtcRoomArgs = &pb.TRTCRoomArgs{ +// AppId: roomArgs.AppId, +// StrRoomId: roomArgs.StrRoomId, +// UserId: roomArgs.UserId, +// UserSig: roomArgs.UserSig, +// } +// msg.Balance = u.Balance +// msg.BigWinner = rm.BigWinner +// if rm.GetGameStatus() < pb.ColorPinoyLiveGameStatus_ColorPinoyLiveEndBetMovie { +// msg.BigWinner = nil +// } +// msg.DealerName = rm.dealerName +// // log.Debug("同步房间信息发送场景信息 msg:", msg) +// // log.Debug(msg) +// u.SendMsg(int32(pb.ColorPinoyLiveSendToClientMessageType_ColorPinoyLiveNoticeGameSync), msg) +//} +// +//func (rm *ColorRoom) SendUserBet(u *model.User) { +// msg := new(pb.ColorPinoyLiveSceneBetInfo) +// msg.UserBets = u.TotalBets[:] +// msg.TotalBets = rm.TotalBets[:] +// msg.UserBetTotal = u.TotalBet +// // msg.MasterBetType = rm.LastMasterBetType +// msg.UserInfo = new(pb.ColorPinoyLiveUserInfo) +// msg.UserInfo.UserID = u.UserID +// msg.UserInfo.UserGlod = u.Balance +// msg.UserInfo.NikeName = u.UserInetr.GetNike() +// msg.UserInfo.Head = u.UserInetr.GetHead() +// _ = u.UserInetr.SendMsg(int32(pb.ColorPinoyLiveSendToClientMessageType_ColorPinoyLiveNoticeGameUserBet), msg) +//} +// +//func (rm *ColorRoom) SendRuleInfo() { +// // 后台配置的下注档位信息 +// msg := new(pb.ColorPinoyLiveRoomBetRuleMsg) +// for _, v := range rm.RoomCfg.ColorPinoyLiveConfig.BetList { +// betArr := new(pb.ColorPinoyLiveBetArr) +// betArr.BetArr = v +// msg.BetLevels = append(msg.BetLevels, betArr) +// } +// msg.BetMinLimit = rm.RoomCfg.BaseBet +// msg.Level = rm.RoomCfg.ColorPinoyLiveConfig.BetLevel +// msg.MulRangeConfig = rm.MulRangeConfig() +// // log.Debug("发送规则 2222 BroadcastRuleInfo:", msg) +// rm.Table.Broadcast(int32(pb.ColorPinoyLiveSendToClientMessageType_ColorPinoyLiveNoticeRoomBetRuleMsg), msg) +//} +// +//func (rm *ColorRoom) SendScene(user inter.UserInetr) bool { +// _ = user +// return true +//} +// +//func (rm *ColorRoom) copyBetAreaOdds() []*pb.ColorPinoyLiveBetAreaOdd { +// var betAreaMul []*pb.ColorPinoyLiveBetAreaOdd +// // 游戏下注区域倍率 +// for _, areaOdds := range rm.afterBetAreaOdds { +// area := &pb.ColorPinoyLiveBetAreaOdd{ +// BetArea: areaOdds.BetArea, +// Odd: areaOdds.Odd, +// ViewOdd: areaOdds.ViewOdd, +// IsBigOdd: areaOdds.IsBigOdd, +// BigSingleColorOddPos: areaOdds.BigSingleColorOddPos, +// IsWin: areaOdds.IsWin, +// IsJackpot: areaOdds.IsJackpot, +// } +// betAreaMul = append(betAreaMul, area) +// } +// return betAreaMul +//} +// +//func (rm *ColorRoom) GameSync(user inter.UserInetr) { +// // 玩家加入 牌桌 +// u := rm.getUser(user) +// rm.SendSceneMsg(u) +// rm.Table.AddTimer(100, func() { +// if rm.LiveMgr.MaintenanceStatus == 1 { +// rm.sendUserMainte(u, int32(pb.ColorPinoyLiveSendToClientMessageType_ColorPinoyLiveNoticeGameMainte)) +// } +// }) +//} +// +//// 向客户端发送结算消息 +//func (rm *ColorRoom) sendSettleMsg2Client() { +// +// MaxWinGold := int64(0) +// MaxWinUserID := int64(0) +// var RealSystemWins [config.BET_TYPE_NUM]int64 +// var RealSystemWin int64 +// var SystemTax int64 +// var PlayerData []*pb.ColorPinoyLivePlayerData +// betTypePlayerCount := [config.BET_TYPE_NUM]int64{} +// wins := rm.PokerMsg.WinBetArea +// +// // 玩家各个下注区域的输赢情况 +// var betAreaInfo []*pb.ColorPinoyLiveGameBetAreaInfo +// for i := 0; i < config.BET_TYPE_NUM; i++ { +// areaInfo := new(pb.ColorPinoyLiveGameBetAreaInfo) +// areaInfo.BetType = pb.ColorPinoyLiveBetTypeJP(i) +// for _, win := range wins { +// if win.BetArea == areaInfo.BetType { +// areaInfo.IsWin = 1 +// } +// } +// areaInfo.BetChipsInfo = []*pb.ColorPinoyLiveGameBetAreaUserInfo{} +// betAreaInfo = append(betAreaInfo, areaInfo) +// } +// +// // 获取有座玩家下注情况 暂时没有有座玩家下注 +// var betUserInfo []*pb.ColorPinoyLiveSceneUserInfo +// noChairTotalWin := int64(0) +// rm.Traverse(func(u *model.User) bool { +// if u.TotalBet > 0 && u.SettleMsg != nil { +// user := new(pb.ColorPinoyLiveSceneUserInfo) +// user.UserID = u.UserID +// user.TotalWin = u.SettleMsg.TotalWin +// user.UserScore = u.SettleMsg.UserScore +// +// for _, info := range betAreaInfo { +// for betType, betChips := range u.SettleMsg.UserBets { +// if pb.ColorPinoyLiveBetTypeJP(betType) == info.BetType && betChips != 0 { +// var betAearUser = new(pb.ColorPinoyLiveGameBetAreaUserInfo) +// betAearUser.UserID = u.UserID +// betAearUser.BetChips = betChips +// info.BetChipsInfo = append(info.BetChipsInfo, betAearUser) +// } +// } +// } +// betUserInfo = append(betUserInfo, user) +// noChairTotalWin += u.SettleMsg.TotalWin +// +// } +// return true +// }) +// +// // 单播每个玩家的结算信息 +// copyBetAreaMul := rm.copyBetAreaOdds() +// betCount := int64(0) +// GameTotalBets := [config.BET_TYPE_NUM]int64{} +// rm.Traverse(func(u *model.User) bool { +// +// SceneUserInfo := new(pb.ColorPinoyLiveSceneSettleMsg) +// // 下注区域投注信息 +// SceneUserInfo.BetAreaInfo = betAreaInfo +// // 本局走势图数据 +// trendGroup := new(pb.ColorPinoyLiveTrendGroup) +// trendGroup.LuckyDice = pb.ColorPinoyLiveDiceColorType(model.GetColor(rm.LuckyDice)) +// for _, dice := range rm.NormalDices { +// trendGroup.ThreeDice = append(trendGroup.ThreeDice, pb.ColorPinoyLiveDiceColorType(model.GetColor(dice))) +// } +// SceneUserInfo.TrendGroup = trendGroup +// // 有座玩家下注信息 暂时没有有座玩家 +// // SceneUserInfo.UserList = betUserInfo +// // 幸运骰子 +// SceneUserInfo.LuckyDice = pb.ColorPinoyLiveDiceColorType(model.GetColor(rm.LuckyDice)) +// // 3个骰子 +// SceneUserInfo.ThreeDice = []pb.ColorPinoyLiveDiceColorType{} +// for _, dice := range rm.NormalDices { +// SceneUserInfo.ThreeDice = append(SceneUserInfo.ThreeDice, pb.ColorPinoyLiveDiceColorType(model.GetColor(dice))) +// } +// // 自己的投注信息 +// if u.SettleMsg != nil { +// SceneUserInfo.SelfWinInfo = new(pb.ColorPinoyLiveSceneUserInfo) +// SceneUserInfo.SelfWinInfo.UserID = int64(u.UserInetr.GetId()) +// SceneUserInfo.SelfWinInfo.SceneSeatID = int32(u.SceneChairId) +// SceneUserInfo.SelfWinInfo.TotalWin = u.SettleMsg.TotalWin // 净利 + 投注本金 +// SceneUserInfo.SelfWinInfo.UserScore = u.SettleMsg.UserScore +// SceneUserInfo.SelfWinInfo.JackpotWin = u.SettleMsg.JackpotWin +// SceneUserInfo.SelfWinInfo.NormalWin = u.SettleMsg.TotalWin - u.SettleMsg.JackpotWin +// } +// // 上局投注信息 +// SceneUserInfo.LastTimeBet = make([]*pb.ColorPinoyLiveBetReqs, 0) +// for _, reqs := range u.LastTimeBet { +// betreq := &pb.ColorPinoyLiveBetReqs{} +// for _, req := range reqs { +// betreq.Info = append(betreq.Info, req) +// } +// SceneUserInfo.LastTimeBet = append(SceneUserInfo.LastTimeBet, betreq) +// } +// SceneUserInfo.TrendGroupEx = &pb.ColorPinoyLiveTrend{} +// SceneUserInfo.TrendGroupEx.ListTrendGroup = rm.GameTrend.ListTrendGroup +// SceneUserInfo.TrendGroupEx.LuckStarRate = rm.GetGameTrend() +// SceneUserInfo.BigWinner = rm.BigWinner +// SceneUserInfo.Jackpot = rm.jackpotMgr.GetJackpot() +// SceneUserInfo.JackpotUserName = u.SettleMsg.JackpotUserName +// // 单播玩家结算信息 +// // log.Debug("发送结算信息 SceneUserInfo BetAreaInfo:", SceneUserInfo.BetAreaInfo) +// // log.Debug("发送结算信息 SceneUserInfo UserList:", SceneUserInfo.UserList) +// // log.Debug("发送结算信息 SceneUserInfo SelfWinInfo:", SceneUserInfo.SelfWinInfo) +// u.SendMsg(int32(pb.ColorPinoyLiveSendToClientMessageType_ColorPinoyLiveNoticeGameUserSettle), SceneUserInfo) +// +// if !u.IsRobot && u.SettleMsg != nil { +// RealSystemWin += u.TotalBet +// RealSystemWin -= u.SettleMsg.TotalWin +// betCount += u.TotalBet +// SystemTax += u.SettleMsg.Tax +// if MaxWinGold < u.SettleMsg.TotalWin-u.TotalBet { +// MaxWinGold = u.SettleMsg.TotalWin - u.TotalBet +// MaxWinUserID = u.UserInetr.GetId() +// } +// for i, bet := range u.TotalBets { +// if bet > 0 { +// RealSystemWins[i] += bet +// betTypePlayerCount[i] += 1 +// RealSystemWins[i] -= u.SettleMsg.UserRealWins[i] +// GameTotalBets[i] += bet +// } +// } +// // 写入数据库统计信息 +// if u.TotalBet > 0 { +// // 玩家下注区域统计 +// u.SettleMsg.UserBetsCount = make([]int64, config.BET_TYPE_NUM) +// for i, count := range u.TotalBetsCount { +// u.SettleMsg.UserBetsCount[i] = count +// } +// PlayerData = append(PlayerData, &pb.ColorPinoyLivePlayerData{ +// Uid: u.UserID, +// TotalBets: u.SettleMsg.UserBets, // 玩家各个区域的总下注额 +// TotalBet: u.TotalBet, +// Profit: u.SettleMsg.TotalWin, +// Tax: u.SettleMsg.Tax, +// Balance: u.Balance, +// PreBalance: u.PreBalance, +// UserWins: u.SettleMsg.UserWins, // 玩家赢取的下注区域总下注额 +// UserRealWins: u.SettleMsg.UserRealWins, // 玩家赢取的下注区域总下注额 扣税后 +// AreaOdds: copyBetAreaMul, // 投注区域赔率 +// StartTime: u.StartAt, +// TransBet: u.TransBet, +// TransWin: u.TransWin, +// DevMode: u.UserInetr.GetDevMode(), +// UserBetsCount: u.SettleMsg.UserBetsCount, +// Nickname: u.UserInetr.GetNike(), +// Avatar: u.UserInetr.GetHead(), +// }) +// } +// // log.Debug("开奖倍率:", u.SettleMsg.OddsWins) +// } +// +// // u.ResetUserData() +// return true +// }) +// // rm.Table.GameBetInfo(gameBetInfos) +// cou := model.Usercount{} +// cou = rm.OnlineUserList +// sort.Sort(cou) +// +// for key, v := range pb.ColorPinoyLiveBetTypeJP_value { +// if rm.TotalBets[v] > 0 || betTypePlayerCount[v] > 0 || RealSystemWins[v] > 0 { +// log.Debug(rm.Log("%v 区域:总:%v 真:%v 真人数量:%v 真输赢:%v", key, score.GetScoreStr(rm.TotalBets[v]), score.GetScoreStr(GameTotalBets[v]), betTypePlayerCount[v], score.GetScoreStr(rm.TotalBets[v]-RealSystemWins[v]))) +// } +// } +// +// str := fmt.Sprintf("开局结果 幸运骰子:%v :普通骰子:%v ,%v ,%v ,", +// model.GetColorString(rm.LuckyDice), model.GetColorString(rm.NormalDices[0]), model.GetColorString(rm.NormalDices[1]), model.GetColorString(rm.NormalDices[2])) +// +// str += fmt.Sprintf("总押注:%v ", score.GetScoreStr(rm.TotalBet)) +// +// str += fmt.Sprintf("真人 总押注:%v , 系统输赢额度:%v ", +// score.GetScoreStr(betCount), +// score.GetScoreStr(RealSystemWin), +// ) +// +// str += fmt.Sprintf("最高获利用户ID:%v 获得:%v", +// MaxWinUserID, score.GetScoreStr(MaxWinGold)) +// +// log.Debug(rm.Log(str)) +// log.Debug(rm.Log("各区域投注:%v", rm.TotalBets)) +// log.Debug(rm.Log("真人各区域投注:%v", GameTotalBets)) +// log.Debug(rm.Log("真人各区域中奖:%v", RealSystemWins)) +// log.Debug(rm.Log("中奖区域:%v", wins)) +// +// // SceneSettleMsg.NoChairTotalWin = noChairTotalWin +// // rm.Table.Broadcast(int32(pb.SendToClientMessageType_NoticeGameSettle), SceneSettleMsg) +// rm.LiveMgr.RankList = &pb.ColorPinoyLiveRankList{ +// PlayerData: nil, +// GameNo: rm.Table.GetGameRoundId(), +// StartTime: rm.startAt, +// EndTime: rm.endAt, +// } +// +// // 发布事件 +// if PlayerData == nil || len(PlayerData) == 0 { +// return +// } +// // 开奖结果 +// var threeDice []pb.ColorPinoyLiveDiceColorType +// for _, dice := range rm.NormalDices { +// threeDice = append(threeDice, pb.ColorPinoyLiveDiceColorType(model.GetColor(dice))) +// } +// +// var startDice []pb.ColorPinoyLiveDiceColorType +// for _, dice := range rm.StartDices { +// startDice = append(startDice, pb.ColorPinoyLiveDiceColorType(model.GetColor(dice))) +// } +// +// gameDetail := &pb.ColorPinoyLiveDetail{ +// // LuckyDice: pb.ColorPinoyLiveDiceColorType(model.GetColor(rm.LuckyDice)), +// ThreeDice: threeDice, +// // Bonus: rm.RoomCfg.ColorPinoyLiveConfig.Bonus, +// StartDice: startDice, +// ResultImg: rm.ResultImgs, +// DealerName: rm.dealerName, +// BetAreaMul: copyBetAreaMul, +// JackpotFunding: rm.jackpotFunding, +// JackpotX: rm.jackpotX, +// JackpotY: rm.jackpotY, +// } +// +// gameRecordData := &pb.ColorPinoyLiveEnd{ +// GameNo: rm.Table.GetGameRoundId(), +// StartTime: rm.startAt, +// EndTime: rm.endAt, +// Level: gconfig.GConfig.GRoomConfig.Level, +// BaseBet: rm.RoomCfg.BaseBet, +// PlayerData: PlayerData, +// TaxRate: rm.RoomCfg.Rate, +// TotalBet: betCount, +// TotalBets: GameTotalBets[:], +// RealSystemWin: RealSystemWin, +// RealSystemWins: RealSystemWins[:], +// Tax: SystemTax, +// Wins: nil, +// OpToken: gconfig.GConfig.GServConfig.ChannelId, +// Detail: gameDetail, +// } +// for _, winArea := range rm.PokerMsg.WinBetArea { +// gameRecordData.Wins = append(gameRecordData.Wins, winArea.BetArea) +// } +// +// sort.Slice(PlayerData, func(i, j int) bool { +// return PlayerData[i].Profit > PlayerData[j].Profit +// }) +// +// for i := 0; i < 6 && i < len(PlayerData); i++ { +// if PlayerData[i].TransWin == 0 { +// continue +// } +// rm.LiveMgr.RankList.PlayerData = append(rm.LiveMgr.RankList.PlayerData, PlayerData[i]) +// } +// log.Debug(rm.Log("玩家数量:%v 赢家数量:%v", len(PlayerData), len(rm.LiveMgr.RankList.PlayerData))) +// go func() { +// // log.Debug("color game 游戏记录:", gameDetail) +// // log.Debug("color game 游戏记录 Tax:", gameRecordData.Tax) +// // log.Debug("color game 游戏记录 Wins:", gameRecordData.Wins) +// // log.Debug("color game 游戏记录 PlayerData:", gameRecordData.PlayerData) +// s, _ := json.Marshal(gameRecordData) +// log.Debug(rm.Log("记录区域数据:%v", string(s))) +// err := gconfig.Produce(context.Background(), define.TopicColoLiveGameGameEnd, gameRecordData) +// if err != nil { +// log.Error(rm.Log("[%s] fail to Produce TongitsGameEndEvent(%+v), err: %v", gameRecordData.GameNo, gameRecordData, err)) +// } +// }() +// +//} +// +//func (rm *ColorRoom) SendOnlinePlayerNum() { +// msg := new(pb.ColorPinoyLiveS2COnlinePlayerNum) +// msg.Num = int64(len(rm.OnlineUserList)) +// rm.Table.Broadcast(int32(pb.ColorPinoyLiveSendToClientMessageType_ColorPinoyLiveNoticeOnlinePlayerNum), msg) +//} +// +//func (rm *ColorRoom) SendRoomInfo() { +// // if rm.GetGameStatus() == 0 { +// // return +// // } +// // msg := new(pb.UpdateRoomInfoMsg) +// // msg.OnlineNum = int64(len(rm.OnlineUserList)) +// // rm.Table.Broadcast(int32(pb.SendToClientMessageType_NoticeUpdateRoomInfo), msg) +//} +// +//// 广播主播名字 +//func (rm *ColorRoom) NotifyDealerName() { +// msg := new(pb.ColorPinoyLiveDealerName) +// msg.DealerName = rm.dealerName +// rm.Table.Broadcast(int32(pb.ColorPinoyLiveSendToClientMessageType_ColorPinoyLiveNoticeDealerName), msg) +// log.Debug(rm.Log("NotifyDealerName:%v", msg)) +//} +// +//type MulRangeW struct { +// *game.ColorMulRate +// MinW int // 权重转换成数值区间 +// MaxW int // 权重转换成数值区间 +// ColorPos pb.ColorPinoyLiveBigBetAreaPos // 0:单色区域基础倍率 1:单色区域双色倍率 2:单色区域开三色倍率 3:双色区域 4:三色区域 +//} +// +//// 带有权重信息的五行倍率数组(单色单,单色双,单色三,双色,三色倍率数组) +//func (rm *ColorRoom) initMulRangeW() (mulRangeW [][]*MulRangeW) { +// mulRangeW = make([][]*MulRangeW, 0, 5) +// +// for pos, mulWs := range rm.Cfg.WinSingleColorMul { +// var single []*MulRangeW +// for _, mul := range mulWs { +// single = append(single, &MulRangeW{MulRate: mul, ColorPos: pb.ColorPinoyLiveBigBetAreaPos(pos)}) +// } +// mulRangeW = append(mulRangeW, single) +// } +// +// var double []*MulRangeW +// for _, mul := range rm.Cfg.WinDoubleColorMul { +// double = append(double, &MulRangeW{MulRate: mul, ColorPos: pb.ColorPinoyLiveBigBetAreaPos_BBA_Double}) +// } +// mulRangeW = append(mulRangeW, double) +// +// var three []*MulRangeW +// for _, mul := range rm.Cfg.WinThreeColorMul { +// three = append(three, &MulRangeW{MulRate: mul, ColorPos: pb.ColorPinoyLiveBigBetAreaPos_BBA_Three}) +// } +// mulRangeW = append(mulRangeW, three) +// +// for _, mulRws := range mulRangeW { +// begin := 0 +// for _, v := range mulRws { +// v.MinW = begin +// v.MaxW = begin + v.Rate +// begin += v.Rate +// } +// } +// +// return mulRangeW +//} +// +//// 返回单色投注区爆奖的权重数组及是爆在双色还是三色位置 +//func (rm *ColorRoom) randSingle(cfg *config.ColorPinoyLiveConfig) (singleMul []*MulRangeW, singlePos int) { +// maxWeight := 0 +// for _, w := range cfg.WinSingleColorWeight { +// maxWeight += w +// } +// weight := rand.RandInt(0, maxWeight) +// log.Debug(rm.Log("单色投注区获取爆奖在双色还是三色,随机值为:%v 最大值:%v", weight, maxWeight)) +// for pos, w := range cfg.WinSingleColorWeight { +// if weight > w { +// weight -= w +// continue +// } +// log.Debug(rm.Log("单色投注区获取爆奖根据权重随机出来的爆奖位置为:%v", pos)) +// // 爆奖只会提高开出双色或三色的赔率,基础赔率区不会爆奖 +// if pos == 0 { +// log.Debug(rm.Log("单色投注区的基础赔率区不会爆奖")) +// return nil, pos +// } +// for _, mul := range cfg.WinSingleColorMul[pos] { +// singleMul = append(singleMul, &MulRangeW{MulRate: mul, ColorPos: pb.ColorPinoyLiveBigBetAreaPos(pos)}) +// } +// begin := 0 +// for _, v := range singleMul { +// v.MinW = begin +// v.MaxW = begin + v.Rate +// begin += v.Rate +// } +// return singleMul, pos +// } +// return nil, 0 +//} +// +//// 更新 +//func (rm *ColorRoom) updateBetEndBetAreasOdds(mulRangeWs [][]*MulRangeW) { +// for pos, betArea := range rm.betEndBetAreasOdds { +// log.Debug(rm.Log("区域:%v 随机前 爆奖状态:%v", pb.ColorPinoyLiveBetTypeJP(pos), betArea.IsBigOdd)) +// betArea.IsBigOdd = false +// // 区域位置 0-2分别为单色、双色、三色投注区域, +// index := pos / 6 +// singlePos := 0 +// var mulRangeW []*MulRangeW +// if index == 0 { +// mulRangeW, singlePos = rm.randSingle(rm.Cfg) +// } else { +// mulRangeW = mulRangeWs[index+2] +// } +// if mulRangeW == nil { +// log.Error(rm.Log("投注区域:%v 获取爆奖权重数组为nil", pos)) +// continue +// } +// rdv := rand.RandInt(mulRangeW[0].MinW, mulRangeW[len(mulRangeW)-1].MaxW) +// for mulPos, mul := range mulRangeW { +// if rdv < mul.MinW || rdv >= mul.MaxW { +// continue +// } +// if index == 0 { +// betArea.Odd[singlePos] = mul.Mul +// if singlePos != 0 && mulPos != 0 { +// log.Debug(rm.Log("区域:%v 爆奖位置:%v", pb.ColorPinoyLiveBetTypeJP(pos), mul.ColorPos)) +// betArea.IsBigOdd = true +// } +// } else { +// betArea.Odd[0] = mul.Mul +// if mulPos != 0 { +// log.Debug(rm.Log("区域:%v 爆奖位置:%v", pb.ColorPinoyLiveBetTypeJP(pos), mul.ColorPos)) +// betArea.IsBigOdd = true +// } +// } +// betArea.BigSingleColorOddPos = mul.ColorPos +// break +// } +// log.Debug(rm.Log("区域:%v 爆奖权重区间:[%v,%v],随机数:%v betArea:%+v", pb.ColorPinoyLiveBetTypeJP(pos), +// mulRangeW[0].MinW, mulRangeW[len(mulRangeW)-1].MaxW, rdv, betArea)) +// } +// // 更新jackpot标记 +// _ = rm.randJackpotArea() +// return +//} +// +//func (rm *ColorRoom) randJackpotArea() []pb.ColorPinoyLiveBetTypeJP { +// betAreaInfo := make(map[int]*pb.ColorPinoyLiveGameBetAreaInfo) +// for pos, betArea := range rm.betEndBetAreasOdds { +// betAreaInfo[pos] = betArea +// } +// // 利用map的随机特性 +// for pos, betArea := range betAreaInfo { +// // 区域位置 0-2分别为单色、双色、三色投注区域, +// index := pos / 6 +// if index > 0 { +// continue +// } +// _, singlePos := rm.randSingle(rm.Cfg) +// // 在单色区域 命中三同色爆奖之后 再随jackpot概率 +// // 只会有一个区域有jackpot标签 +// if singlePos == 2 { +// if rand.RandInt(0, 10000) < rm.Cfg.JackpotRate { +// betArea.IsJackpot = true +// return []pb.ColorPinoyLiveBetTypeJP{betArea.BetType} +// } +// } +// } +// return nil +//} +// +//// 区域爆奖 +//func (rm *ColorRoom) NotifyBigBetAreaMul() { +// mulRangeW := rm.initMulRangeW() +// rm.updateBetEndBetAreasOdds(mulRangeW) +// +// for _, betArea := range rm.betEndBetAreasOdds { +// log.Debug(rm.Log("投注区域:%v 倍率:%v 是否爆奖:%v 是否jackpot:%v 倍率位置:%v", betArea.BetType, betArea.Odd, betArea.IsBigOdd, betArea.IsJackpot, betArea.BigSingleColorOddPos)) +// } +// +// msg := new(pb.ColorPinoyLiveNtfBigOddBetArea) +// msg.BetAreas = rm.betEndBetAreasOdds +// rm.Table.Broadcast(int32(pb.ColorPinoyLiveSendToClientMessageType_ColorPinoyLiveNoticeBigOddBetArea), msg) +// log.Debug(rm.Log("ColorPinoyLiveNtfBigOddBetArea:%v", msg)) +//} +// +//func (rm *ColorRoom) formatScore(score int64) string { +// s := float64(score / 100.0) +// numStr := fmt.Sprintf("%.2f", s) +// +// // result := "" +// // for i := len(numStr) - 1; i >= 0; i-- { +// // result = string(numStr[i]) + result +// // if (len(numStr)-i)%3 == 0 && i != 0 { +// // result = "," + result +// // } +// // } +// return numStr +// // return result +//} +// +//func (rm *ColorRoom) BroadHitJackpot(user *model.User, jpScore int64) { +// go func() { +// req := &fmsg.ChatReq{ +// Uid: user.UserID, +// GameId: rm.RoomCfg.GameId, +// Content: fmt.Sprintf("%v WIN ₱ %v FROM JACKPOT", user.UserInetr.GetNike(), rm.formatScore(jpScore)), +// Type: 0, +// } +// bReq, err := proto.Marshal(req) +// if err != nil { +// log.Error(rm.Log(err.Error())) +// return +// } +// lobbyMsg := &events.SingleMsgToLobbyEvent{ +// Module: events.SingleMsgToLobbyEvent_mtl_chat, +// Data: bReq, +// } +// err = gconfig.Produce(context.Background(), define.TopicSingleMsgToLobby, lobbyMsg) +// if err != nil { +// log.Error(rm.Log("fail to Produce SingleMsgToLobbyEvent_mtl_chat, err: %v", err)) +// } +// }() +//}