private void ProcessShowHandRSP(ShowHandRSP message, ClientRecord record, HandHistory history) { foreach (var handInfo in message.Info) { AddShowCardsAction(history, GetPlayer(history, handInfo.SeatID + 1), GetCards(handInfo)); } }
private void ProcessRoundStartBRC(RoundStartBRC message, ClientRecord record, HandHistory history) { if (message.Board != null) { foreach (int card_value in message.Board) { history.CommunityCards.Add(ConvertToCard(card_value)); } } }
private void ProcessWinnerRSP(WinnerRSP message, ClientRecord record, HandHistory history) { foreach (var winner in message.Winner) { var player = GetPlayer(history, winner.SeatID + 1); // Note that pots are raked therefore it's not correct to use following condition for ties: winning < pot // Following condition should be used instead: winning <= pot / 2. Works for raked and not raked pots. HandActionType handActionType = winner.Chips <= record.Pots[winner.PoolID] / 2 ? HandActionType.TIES : HandActionType.WINS; history.HandActions.Add(new WinningsAction( player.PlayerName, handActionType, winner.Chips, winner.PoolID )); player.Win += winner.Chips; } }
private void ProcessActionBRC(ActionBRC message, ClientRecord record, HandHistory history) { var playerName = GetPlayerName(history, message.SeatID + 1); if (BlindActionMapping.ContainsKey(message.ActionType)) { history.HandActions.Add(new HandAction( playerName, BlindActionMapping[message.ActionType], message.Chips, Street.Preflop )); } else if (ActionMapping.ContainsKey(message.ActionType)) { HandAction action; var handActionType = ActionMapping[message.ActionType]; if (InvestingHandActionTypes.Contains(handActionType) && message.HandChips == 0) { action = new AllInAction( playerName, message.Chips, history.CommunityCards.Street, false, // TODO: Find out when IsRaiseAllIn should be true ActionMapping[message.ActionType] ); } else { action = new HandAction( playerName, ActionMapping[message.ActionType], message.Chips, history.CommunityCards.Street ); } history.HandActions.Add(action); } }
private void ProcessEnterRoomRSP(EnterRoomRSP message, ClientRecord record) { if (message.RoomType == RoomType.PineRoom) { return; } bool isTournament = TournamentRoomTypes.Contains(message.RoomType); IRoomInfo roomInfo = isTournament ? (IRoomInfo)message.SngRoomInfo : (IRoomInfo)message.RoomInfo; record.RoomID = roomInfo.RoomID; record.TableID = message.TableStatus.Tid; record.IsOmaha = message.RoomType == RoomType.OmahaRoom; record.RoomName = roomInfo.RoomName.Length > 0 ? roomInfo.RoomName : roomInfo.TempID; record.Ante = roomInfo.Ante; record.BigBlind = roomInfo.Blind; record.MaxPlayers = roomInfo.SeatNum; record.IsTournament = isTournament; if (isTournament) { var utcNow = DateTime.UtcNow; long startTimestamp = message.RoomType == RoomType.MttRoom ? message.MttRoomInfo.MttStartTime : DateTimeToTimestamp(utcNow); record.TournamentID = $"{record.RoomID}-{startTimestamp}"; record.TournamentName = $"{record.RoomName}"; record.TournamentBuyIn = message.SngRoomInfo.BuyIn; record.TournamentReBuy = message.MttRoomInfo.ReBuyIn; record.TournamentAddOn = message.MttRoomInfo.AddOnBuyIn; record.TournamentBounty = message.MttRoomInfo.HunterReward; record.TournamentHasFixedRewards = message.SngRoomInfo.FixedReward; record.TournamentStartDate = message.RoomType == RoomType.MttRoom ? TimestampToDateTime(message.MttRoomInfo.MttStartTime) : utcNow; } foreach (var seat in message.TableStatus.Seat.Where(s => s.Player != null)) { record.Players[seat.SeatID] = UserBriefToRoomPlayer(seat.Player); } }
private void ProcessHandCardRSP(HandCardRSP message, ClientRecord record, HandHistory history) { var roomHero = record.Players.Values.FirstOrDefault(p => p.ID == record.HeroUid); if (roomHero == null) { LogProvider.Log.Warn($"Hero is not seated in hand {history.HandId}, room {record.RoomID}, user {record.HeroUid}"); return; } var hero = history.Players.FirstOrDefault(p => p.PlayerName == roomHero.ID.ToString()); if (hero == null) { LogProvider.Log.Warn($"Hero not found for hand {history.HandId}, room {record.RoomID}, user {record.HeroUid}"); return; } history.Hero = hero; hero.HoleCards = HoleCards.FromCards(hero.PlayerName, GetCards(message)); }
private bool ValidatePackages(ClientRecord record) { var dealerInfoPackage = record.Packages.FirstOrDefault(x => x.PackageType == PackageType.DealerInfoRSP); if (dealerInfoPackage == null) { LogProvider.Log.Warn(this, $"Hand cannot be built because DealerInfoRSP message is missing. [{record.Port}]"); return(false); } var isValid = false; ParsePackage <DealerInfoRSP>(dealerInfoPackage, x => { isValid = record.Packages.Any(p => p.PackageType == PackageType.WinnerRSP); if (!isValid) { LogProvider.Log.Warn(this, $"Hand GameID = {x.GameID} cannot be built because WinnerRSP message is missing. [{record.Port}]"); } }); return(isValid); }
private void ProcessRoundOverBRC(RoundOverBRC message, ClientRecord record, HandHistory history) { record.Pots = message.Pool; }
private HandHistory BuildHand(ClientRecord record) { HandHistory history = null; try { if (!ValidatePackages(record)) { return(history); } var isGameStarted = false; foreach (var package in record.Packages) { if (package.PackageType == PackageType.DealerInfoRSP) { history = new HandHistory { DateOfHandUtc = package.Timestamp.ToUniversalTime() }; ParsePackage <DealerInfoRSP>(package, m => ProcessDealerInfoRSP(m, record, history)); isGameStarted = true; continue; } if (!isGameStarted) { continue; } switch (package.PackageType) { case PackageType.RoundStartBRC: ParsePackage <RoundStartBRC>(package, m => ProcessRoundStartBRC(m, record, history)); break; case PackageType.RoundOverBRC: ParsePackage <RoundOverBRC>(package, m => ProcessRoundOverBRC(m, record, history)); break; case PackageType.ActionBRC: ParsePackage <ActionBRC>(package, m => ProcessActionBRC(m, record, history)); break; case PackageType.HandCardRSP: ParsePackage <HandCardRSP>(package, m => ProcessHandCardRSP(m, record, history)); break; case PackageType.ShowHandRSP: ParsePackage <ShowHandRSP>(package, m => ProcessShowHandRSP(m, record, history)); break; case PackageType.WinnerRSP: ParsePackage <WinnerRSP>(package, m => ProcessWinnerRSP(m, record, history)); break; case PackageType.ShowMyCardBRC: ParsePackage <ShowMyCardBRC>(package, m => ProcessShowMyCardBRC(m, record, history)); break; case PackageType.UserSngOverRSP: ParsePackage <UserSngOverRSP>(package, m => ProcessUserSngOverRSP(m, record, history)); break; } } AdjustHandHistory(history); return(history); } catch (Exception e) { LogProvider.Log.Error(this, $"Failed to build hand #{history?.HandId ?? 0} room #{history?.GameDescription.Identifier ?? 0} [{record.Port}]", e); return(null); } finally { record.Packages.Clear(); } }
private void ProcessDealerInfoRSP(DealerInfoRSP message, ClientRecord record, HandHistory history) { if (!TryParseHandID(message.GameID, out long handId)) { //throw new DHInternalException(new NonLocalizableString($"Failed to parse hand id from '{noticeResetGame.GameId}'.")); throw new Exception($"Failed to parse hand id from '{message.GameID}'."); } LogProvider.Log.Info($"Parsed GameID = {message.GameID} into HandID = {handId}"); history.HandId = handId; TournamentDescriptor tournament = null; if (record.IsTournament) { const int RakeProportion = 10; long rake = record.TournamentHasFixedRewards ? 0 : record.TournamentBuyIn / RakeProportion; long prizePoolValue = record.TournamentBuyIn - rake - record.TournamentBounty; tournament = new TournamentDescriptor { TournamentId = record.TournamentID, TournamentName = record.TournamentName, StartDate = record.TournamentStartDate, BuyIn = Buyin.FromBuyinRake(prizePoolValue, rake, Currency.All, record.TournamentBounty > 0, record.TournamentBounty), Rebuy = record.TournamentReBuy, Addon = record.TournamentAddOn, Speed = TournamentSpeed.Regular, // I didn't discover any reliable way to determine tournament speed from protocol messages }; } history.GameDescription = new GameDescriptor( EnumPokerSites.PPPoker, record.IsOmaha ? GameType.PotLimitOmaha : GameType.NoLimitHoldem, Limit.FromSmallBlindBigBlind(record.SmallBlind, record.BigBlind, Currency.All, record.Ante > 0, record.Ante), TableType.FromTableTypeDescriptions(record.Ante > 0 ? TableTypeDescription.Ante : TableTypeDescription.Regular), SeatType.FromMaxPlayers(record.MaxPlayers), tournament ); history.GameDescription.Identifier = record.RoomID; history.TableName = $"{record.RoomName}-{record.TableID}"; foreach (var stackInfo in message.Stacks) { if (!record.Players.ContainsKey(stackInfo.SeatID)) { throw new Exception($"Can't find a player sitting on seat #{stackInfo.SeatID} for hand {handId}. Total known players: {record.Players.Count}. Total participating players: {message.Stacks.Length}."); } var roomPlayer = record.Players[stackInfo.SeatID]; var player = new Player { PlayerName = roomPlayer.ID.ToString(), PlayerNick = roomPlayer.Name, StartingStack = stackInfo.Chips, SeatNumber = stackInfo.SeatID + 1, IsSittingOut = false }; history.Players.Add(player); } history.DealerButtonPosition = message.Dealer + 1; }
private void ProcessStandUpBRC(StandUpBRC message, ClientRecord record) { record.Players.Remove(message.SeatID); }
private void ProcessSitDownBRC(SitDownBRC message, ClientRecord record) { record.Players[message.SeatID] = UserBriefToRoomPlayer(message.Brief); }
private void ProcessSitDownRSP(SitDownRSP message, ClientRecord record) { record.HeroUid = record.Players[message.SeatID].ID; }
private void ProcessGetUserMarksRSP(GetUserMarksRSP message, ClientRecord record) { record.HeroUid = message.Uid; }
private void ProcessSelUserInfoRSP(SelUserInfoRSP message, ClientRecord record) { record.HeroUid = message.Brief.Uid; }
private void ProcessShowMyCardBRC(ShowMyCardBRC message, ClientRecord record, HandHistory history) { AddShowCardsAction(history, GetPlayer(history, message.SeatID + 1), GetCards(message)); }
private void ProcessUserSngOverRSP(UserSngOverRSP message, ClientRecord record, HandHistory history) { history.GameDescription.Tournament.FinishPosition = message.Rank; history.GameDescription.Tournament.TotalPrize = message.Money; }
private void ProcessBlindStatusBRC(BlindStatusBRC message, ClientRecord record) { record.BigBlind = message.Blind; record.Ante = message.Ante; }