This commit is contained in:
liuxiaobo 2025-06-08 00:52:17 +08:00
parent bea141f772
commit 0cd61a60c2
11 changed files with 9201 additions and 40 deletions

View File

@ -3,7 +3,578 @@ package pb;
option go_package = "common/proto/pb";
// color玩法配置信息
message ColorRoomInfo
{
}
//
enum ColorPinoyLiveDiceColorType {
ColorPinoyLiveType_Void = 0;
ColorPinoyLiveType_YELLOW = 1; //
ColorPinoyLiveType_WHITE = 2; //
ColorPinoyLiveType_PINK = 3; //
ColorPinoyLiveType_BLUE = 4; //
ColorPinoyLiveType_RED = 5; //
ColorPinoyLiveType_GREEN = 6; //绿
}
// jackpot版本的押注类型
enum ColorPinoyLiveBetTypeJP {
CLJ_Yellow = 0; //
CLJ_White = 1; //
CLJ_Pink = 2; //
CLJ_Blue = 3; //
CLJ_Red = 4; //
CLJ_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; // 绿
CLJ_Three_Yellow = 12; //
CLJ_Three_White = 13; //
CLJ_Three_Pink = 14; //
CLJ_Three_Blue = 15; //
CLJ_Three_Red = 16; //
CLJ_Three_Green = 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 ColorPinoyLiveLeaveReason {
ColorPinoyLiveLeaveReason_void = 0;
ColorPinoyLiveLeaveReason_PLAYER_QUIT_ROOM=2; //
ColorPinoyLiveLeaveReason_Maintaince=20; //
ColorPinoyLiveLeaveReason_Server_Update=21; //
ColorPinoyLiveLeaveReason_Ban=22; //
}
message ColorPinoyLiveStatusMessage{
int32 Status = 1; //
int32 StatusTime = 2; //
int32 StatusRemainTime = 3; //
int64 jackpot = 4;
}
message ColorPinoyLiveGameOpenThreeDice{
int32 Status = 1; //
repeated ColorPinoyLiveDiceColorType color = 2; // 3
int32 aniRouteIndex = 3; //
}
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 {
string Nick = 1; //
string Head = 2; //
int64 Score = 3; //
int32 SeatId = 4; //id
int64 UserID = 5; //ID
}
// 线
message ColorPinoyLiveS2COnlinePlayerNum{
int64 Num = 1; //
}
//
message ColorPinoyLivePlayerBigWinner
{
repeated ColorPinoyLiveBigWinner bigBet = 34; //
int64 jackpot = 1; // jackpot值
}
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
{
string nickName = 5;//
string avatar = 2;
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
{
repeated ColorPinoyLiveGameBetAreaInfo betAreas = 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
{
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; //
}

View File

@ -30,6 +30,43 @@ enum MsgId
C2SMatchRoomId = 2200; //
S2CMatchRoomId = 2201;
NtfUserEnterRoomId = 2202; //
// color game 2300-2499
ColorPinoyLiveNoticeGameSync = 201;
ColorPinoyLiveNoticeGameReady = 202;
ColorPinoyLiveNoticeGameStart = 203;
ColorPinoyLiveNoticeGameStartBet = 204;
ColorPinoyLiveNoticeGameEndBet = 205;
ColorPinoyLiveNoticeGameOpenLuckyDice = 206;
ColorPinoyLiveNoticeGameOpenThreeDice = 207;
ColorPinoyLiveNoticeGameUserSettle = 208; //
ColorPinoyLiveNoticeGameSettle = 209; // 广
ColorPinoyLiveNoticeGameSeatUserBet = 210; // 广
ColorPinoyLiveNoticeGameUserBet = 211; //
ColorPinoyLiveNoticeGameTrendInfo = 212; //
ColorPinoyLiveNoticePlayerLeaveNtf = 213; // 广
ColorPinoyLiveNoticeOnlinePlayerNum = 214; // 线
ColorPinoyLiveNoticeUpdateRoomInfo = 215; // 1
ColorPinoyLiveNoticeUndoBet = 216; //
ColorPinoyLiveNoticeBetFail = 217; // ...
ColorPinoyLiveNoticeKickOutUser = 218; //
ColorPinoyLiveNoticeRoomBetRuleMsg = 219; //
ColorPinoyLiveNoticePlayerUseProps = 220; // 使
ColorPinoyLiveNoticePlayerBetEndResultFailed = 221; //
ColorPinoyLiveNoticeGameMainte = 222; // ColorPinoyLiveMainteNtf
ColorPinoyLiveNoticeDiscard = 223; // ColorPinoyLiveMainteNtf
ColorPinoyLiveNoticeRankList = 224; // ColorPinoyLiveRankList
ColorPinoyLiveNoticeGameBigWinner = 225; //
ColorPinoyLiveNoticeDealerName = 226; //
ColorPinoyLiveNoticeBigOddBetArea = 228; //
ColorPinoyLiveApplyBetChips = 101; //
ColorPinoyLiveApplyGetTrend = 102; //
ColorPinoyLiveApplyBetDouble = 104; //
ColorPinoyLiveApplyUndoBet = 105; //
ColorPinoyLiveApplyLeave = 107; //
ColorPinoyLiveApplyBetAgain = 108; //
}

File diff suppressed because it is too large Load Diff

View File

@ -44,6 +44,40 @@ const (
MsgId_C2SMatchRoomId MsgId = 2200 // 匹配服
MsgId_S2CMatchRoomId MsgId = 2201
MsgId_NtfUserEnterRoomId MsgId = 2202 // 玩家进入房间 所有玩法共用此消息
// color game 2300-2499
MsgId_ColorPinoyLiveNoticeGameSync MsgId = 201
MsgId_ColorPinoyLiveNoticeGameReady MsgId = 202
MsgId_ColorPinoyLiveNoticeGameStart MsgId = 203
MsgId_ColorPinoyLiveNoticeGameStartBet MsgId = 204
MsgId_ColorPinoyLiveNoticeGameEndBet MsgId = 205
MsgId_ColorPinoyLiveNoticeGameOpenLuckyDice MsgId = 206
MsgId_ColorPinoyLiveNoticeGameOpenThreeDice MsgId = 207
MsgId_ColorPinoyLiveNoticeGameUserSettle MsgId = 208 // 用户自己结算返回
MsgId_ColorPinoyLiveNoticeGameSettle MsgId = 209 // 广播本局结算信息
MsgId_ColorPinoyLiveNoticeGameSeatUserBet MsgId = 210 // 广播座位上的玩家下注信息
MsgId_ColorPinoyLiveNoticeGameUserBet MsgId = 211 // 玩家下注成功返回
MsgId_ColorPinoyLiveNoticeGameTrendInfo MsgId = 212 // 走势图
MsgId_ColorPinoyLiveNoticePlayerLeaveNtf MsgId = 213 // 离开广播
MsgId_ColorPinoyLiveNoticeOnlinePlayerNum MsgId = 214 // 在线玩家数量
MsgId_ColorPinoyLiveNoticeUpdateRoomInfo MsgId = 215 // 更新房间信息 1秒一次
MsgId_ColorPinoyLiveNoticeUndoBet MsgId = 216 // 撤销下注
MsgId_ColorPinoyLiveNoticeBetFail MsgId = 217 // 下注失败 撤销下注失败 ...
MsgId_ColorPinoyLiveNoticeKickOutUser MsgId = 218 // 踢出玩家发送原因
MsgId_ColorPinoyLiveNoticeRoomBetRuleMsg MsgId = 219 // 推送玩家下注规则
MsgId_ColorPinoyLiveNoticePlayerUseProps MsgId = 220 // 推送玩家使用道具
MsgId_ColorPinoyLiveNoticePlayerBetEndResultFailed MsgId = 221 // 推送玩家结束下注时扣钱失败
MsgId_ColorPinoyLiveNoticeGameMainte MsgId = 222 // 推送游戏维护 ColorPinoyLiveMainteNtf
MsgId_ColorPinoyLiveNoticeDiscard MsgId = 223 // 推送废弃 ColorPinoyLiveMainteNtf
MsgId_ColorPinoyLiveNoticeRankList MsgId = 224 // 推送排行榜 ColorPinoyLiveRankList
MsgId_ColorPinoyLiveNoticeGameBigWinner MsgId = 225 // 大客投注信息
MsgId_ColorPinoyLiveNoticeDealerName MsgId = 226 // 设置或清空主播名字
MsgId_ColorPinoyLiveNoticeBigOddBetArea MsgId = 228 // 下注结束后更新区域爆奖信息
MsgId_ColorPinoyLiveApplyBetChips MsgId = 101 // 下注信息
MsgId_ColorPinoyLiveApplyGetTrend MsgId = 102 //获取走势图
MsgId_ColorPinoyLiveApplyBetDouble MsgId = 104 //一键翻倍押注
MsgId_ColorPinoyLiveApplyUndoBet MsgId = 105 //撤回押注
MsgId_ColorPinoyLiveApplyLeave MsgId = 107 //申请离开
MsgId_ColorPinoyLiveApplyBetAgain MsgId = 108 //申请重复下注
)
// Enum value maps for MsgId.
@ -62,6 +96,39 @@ var (
2200: "C2SMatchRoomId",
2201: "S2CMatchRoomId",
2202: "NtfUserEnterRoomId",
201: "ColorPinoyLiveNoticeGameSync",
202: "ColorPinoyLiveNoticeGameReady",
203: "ColorPinoyLiveNoticeGameStart",
204: "ColorPinoyLiveNoticeGameStartBet",
205: "ColorPinoyLiveNoticeGameEndBet",
206: "ColorPinoyLiveNoticeGameOpenLuckyDice",
207: "ColorPinoyLiveNoticeGameOpenThreeDice",
208: "ColorPinoyLiveNoticeGameUserSettle",
209: "ColorPinoyLiveNoticeGameSettle",
210: "ColorPinoyLiveNoticeGameSeatUserBet",
211: "ColorPinoyLiveNoticeGameUserBet",
212: "ColorPinoyLiveNoticeGameTrendInfo",
213: "ColorPinoyLiveNoticePlayerLeaveNtf",
214: "ColorPinoyLiveNoticeOnlinePlayerNum",
215: "ColorPinoyLiveNoticeUpdateRoomInfo",
216: "ColorPinoyLiveNoticeUndoBet",
217: "ColorPinoyLiveNoticeBetFail",
218: "ColorPinoyLiveNoticeKickOutUser",
219: "ColorPinoyLiveNoticeRoomBetRuleMsg",
220: "ColorPinoyLiveNoticePlayerUseProps",
221: "ColorPinoyLiveNoticePlayerBetEndResultFailed",
222: "ColorPinoyLiveNoticeGameMainte",
223: "ColorPinoyLiveNoticeDiscard",
224: "ColorPinoyLiveNoticeRankList",
225: "ColorPinoyLiveNoticeGameBigWinner",
226: "ColorPinoyLiveNoticeDealerName",
228: "ColorPinoyLiveNoticeBigOddBetArea",
101: "ColorPinoyLiveApplyBetChips",
102: "ColorPinoyLiveApplyGetTrend",
104: "ColorPinoyLiveApplyBetDouble",
105: "ColorPinoyLiveApplyUndoBet",
107: "ColorPinoyLiveApplyLeave",
108: "ColorPinoyLiveApplyBetAgain",
}
MsgId_value = map[string]int32{
"MI_Unknown": 0,
@ -77,6 +144,39 @@ var (
"C2SMatchRoomId": 2200,
"S2CMatchRoomId": 2201,
"NtfUserEnterRoomId": 2202,
"ColorPinoyLiveNoticeGameSync": 201,
"ColorPinoyLiveNoticeGameReady": 202,
"ColorPinoyLiveNoticeGameStart": 203,
"ColorPinoyLiveNoticeGameStartBet": 204,
"ColorPinoyLiveNoticeGameEndBet": 205,
"ColorPinoyLiveNoticeGameOpenLuckyDice": 206,
"ColorPinoyLiveNoticeGameOpenThreeDice": 207,
"ColorPinoyLiveNoticeGameUserSettle": 208,
"ColorPinoyLiveNoticeGameSettle": 209,
"ColorPinoyLiveNoticeGameSeatUserBet": 210,
"ColorPinoyLiveNoticeGameUserBet": 211,
"ColorPinoyLiveNoticeGameTrendInfo": 212,
"ColorPinoyLiveNoticePlayerLeaveNtf": 213,
"ColorPinoyLiveNoticeOnlinePlayerNum": 214,
"ColorPinoyLiveNoticeUpdateRoomInfo": 215,
"ColorPinoyLiveNoticeUndoBet": 216,
"ColorPinoyLiveNoticeBetFail": 217,
"ColorPinoyLiveNoticeKickOutUser": 218,
"ColorPinoyLiveNoticeRoomBetRuleMsg": 219,
"ColorPinoyLiveNoticePlayerUseProps": 220,
"ColorPinoyLiveNoticePlayerBetEndResultFailed": 221,
"ColorPinoyLiveNoticeGameMainte": 222,
"ColorPinoyLiveNoticeDiscard": 223,
"ColorPinoyLiveNoticeRankList": 224,
"ColorPinoyLiveNoticeGameBigWinner": 225,
"ColorPinoyLiveNoticeDealerName": 226,
"ColorPinoyLiveNoticeBigOddBetArea": 228,
"ColorPinoyLiveApplyBetChips": 101,
"ColorPinoyLiveApplyGetTrend": 102,
"ColorPinoyLiveApplyBetDouble": 104,
"ColorPinoyLiveApplyUndoBet": 105,
"ColorPinoyLiveApplyLeave": 107,
"ColorPinoyLiveApplyBetAgain": 108,
}
)
@ -111,7 +211,7 @@ var File_msgId_proto protoreflect.FileDescriptor
const file_msgId_proto_rawDesc = "" +
"\n" +
"\vmsgId.proto\x12\x02pb*\x91\x02\n" +
"\vmsgId.proto\x12\x02pb*\xf3\v\n" +
"\x05MsgId\x12\x0e\n" +
"\n" +
"MI_Unknown\x10\x00\x12\x12\n" +
@ -126,7 +226,40 @@ const file_msgId_proto_rawDesc = "" +
"\x10NtfUserOfflineId\x10\xba\x10\x12\x13\n" +
"\x0eC2SMatchRoomId\x10\x98\x11\x12\x13\n" +
"\x0eS2CMatchRoomId\x10\x99\x11\x12\x17\n" +
"\x12NtfUserEnterRoomId\x10\x9a\x11B\x11Z\x0fcommon/proto/pbb\x06proto3"
"\x12NtfUserEnterRoomId\x10\x9a\x11\x12!\n" +
"\x1cColorPinoyLiveNoticeGameSync\x10\xc9\x01\x12\"\n" +
"\x1dColorPinoyLiveNoticeGameReady\x10\xca\x01\x12\"\n" +
"\x1dColorPinoyLiveNoticeGameStart\x10\xcb\x01\x12%\n" +
" ColorPinoyLiveNoticeGameStartBet\x10\xcc\x01\x12#\n" +
"\x1eColorPinoyLiveNoticeGameEndBet\x10\xcd\x01\x12*\n" +
"%ColorPinoyLiveNoticeGameOpenLuckyDice\x10\xce\x01\x12*\n" +
"%ColorPinoyLiveNoticeGameOpenThreeDice\x10\xcf\x01\x12'\n" +
"\"ColorPinoyLiveNoticeGameUserSettle\x10\xd0\x01\x12#\n" +
"\x1eColorPinoyLiveNoticeGameSettle\x10\xd1\x01\x12(\n" +
"#ColorPinoyLiveNoticeGameSeatUserBet\x10\xd2\x01\x12$\n" +
"\x1fColorPinoyLiveNoticeGameUserBet\x10\xd3\x01\x12&\n" +
"!ColorPinoyLiveNoticeGameTrendInfo\x10\xd4\x01\x12'\n" +
"\"ColorPinoyLiveNoticePlayerLeaveNtf\x10\xd5\x01\x12(\n" +
"#ColorPinoyLiveNoticeOnlinePlayerNum\x10\xd6\x01\x12'\n" +
"\"ColorPinoyLiveNoticeUpdateRoomInfo\x10\xd7\x01\x12 \n" +
"\x1bColorPinoyLiveNoticeUndoBet\x10\xd8\x01\x12 \n" +
"\x1bColorPinoyLiveNoticeBetFail\x10\xd9\x01\x12$\n" +
"\x1fColorPinoyLiveNoticeKickOutUser\x10\xda\x01\x12'\n" +
"\"ColorPinoyLiveNoticeRoomBetRuleMsg\x10\xdb\x01\x12'\n" +
"\"ColorPinoyLiveNoticePlayerUseProps\x10\xdc\x01\x121\n" +
",ColorPinoyLiveNoticePlayerBetEndResultFailed\x10\xdd\x01\x12#\n" +
"\x1eColorPinoyLiveNoticeGameMainte\x10\xde\x01\x12 \n" +
"\x1bColorPinoyLiveNoticeDiscard\x10\xdf\x01\x12!\n" +
"\x1cColorPinoyLiveNoticeRankList\x10\xe0\x01\x12&\n" +
"!ColorPinoyLiveNoticeGameBigWinner\x10\xe1\x01\x12#\n" +
"\x1eColorPinoyLiveNoticeDealerName\x10\xe2\x01\x12&\n" +
"!ColorPinoyLiveNoticeBigOddBetArea\x10\xe4\x01\x12\x1f\n" +
"\x1bColorPinoyLiveApplyBetChips\x10e\x12\x1f\n" +
"\x1bColorPinoyLiveApplyGetTrend\x10f\x12 \n" +
"\x1cColorPinoyLiveApplyBetDouble\x10h\x12\x1e\n" +
"\x1aColorPinoyLiveApplyUndoBet\x10i\x12\x1c\n" +
"\x18ColorPinoyLiveApplyLeave\x10k\x12\x1f\n" +
"\x1bColorPinoyLiveApplyBetAgain\x10lB\x11Z\x0fcommon/proto/pbb\x06proto3"
var (
file_msgId_proto_rawDescOnce sync.Once

View File

@ -0,0 +1,518 @@
package room
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++
// }
//
// 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 (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)
}

View File

@ -0,0 +1,225 @@
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) {
return
}
func (rm *ColorRoom) OnEnterRoom(user *ColorPlayer, iMsg *ipb.InternalMsg, req *pb.C2SMatchRoom) {
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)
}

View File

@ -1,15 +1,68 @@
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"
)
type ColorRoom struct {
*baseroom.BaseRoom[ColorSeat]
//---------------------------------
Status pb.ColorPinoyLiveGameStatus // 房间状态1 表示
StatusTime int64 // 切换状态时的时间戳
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) {
@ -45,3 +98,408 @@ func (rm *ColorRoom) AddGold(user *ColorPlayer, add int64) (int64, bool) {
user.costGold += add
return user.Gold - user.costGold, false
}
// ---------------------------------------------------------------------------------------------------
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() {
}

File diff suppressed because it is too large Load Diff

View File

@ -1,16 +0,0 @@
package room
import (
"game/common/proto/pb"
"github.com/fox/fox/ipb"
)
func (rm *ColorRoom) checkEnterRoom(user *ColorPlayer, iMsg *ipb.InternalMsg, req *pb.C2SMatchRoom) {
return
}
func (rm *ColorRoom) OnEnterRoom(user *ColorPlayer, iMsg *ipb.InternalMsg, req *pb.C2SMatchRoom) {
return
}

View File

@ -0,0 +1,117 @@
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()
}

View File

@ -0,0 +1,703 @@
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))
}
}()
}