private HandHistoryObject CreateHandHistoryObject(string fileName, EnumPokerSites pokerSite, string playerName) { var handHistoryFileFullName = Path.Combine(TestDataFolder, fileName); var handHistoryFileInfo = new FileInfo(handHistoryFileFullName); Assert.That(handHistoryFileInfo.Exists, $"{handHistoryFileFullName} doesn't exists. Please check."); var handHistoryText = File.ReadAllText(handHistoryFileInfo.FullName); var parsingResult = ParseHandHistory(pokerSite, handHistoryText); var player = parsingResult.Players.FirstOrDefault(x => x.Playername == playerName); Assert.IsNotNull(player, $"Player {playerName} has not been found"); var playerStatisticCalculator = ServiceLocator.Current.GetInstance <IPlayerStatisticCalculator>(); var creationInfo = new PlayerStatisticCreationInfo { ParsingResult = parsingResult, Player = player, EquityData = new Dictionary <string, Model.Solvers.EquityData>() }; var stat = playerStatisticCalculator.CalculateStatistic(creationInfo); return(new HandHistoryObject { HandHistory = parsingResult.Source, Stat = stat }); }
/// <summary> /// Builds player statistic /// </summary> /// <param name="handHistory"></param> /// <param name="player"></param> private Playerstatistic BuildPlayerStatistic(PlayerStatisticCreationInfo playerStatisticCreationInfo) { var playerStatisticCalculator = ServiceLocator.Current.GetInstance <IPlayerStatisticCalculator>(playerStatisticCreationInfo.GetServiceName()); var playerStat = playerStatisticCalculator.CalculateStatistic(playerStatisticCreationInfo); return(playerStat); }
/// <summary> /// Builds player statistic /// </summary> /// <param name="handHistory"></param> /// <param name="player"></param> private void BuildPlayerStatistic(Handhistory dbHandHistory, PlayerStatisticCreationInfo playerStatisticCreationInfo) { try { var playerStatisticCalculator = ServiceLocator.Current.GetInstance <IPlayerStatisticCalculator>(playerStatisticCreationInfo.GetServiceName()); var statistic = playerStatisticCalculator.CalculateStatistic(playerStatisticCreationInfo); if (!string.IsNullOrEmpty(dbHandHistory.Tourneynumber)) { statistic.IsTourney = true; statistic.TournamentId = dbHandHistory.Tourneynumber; } StorePlayerStatistic(statistic); } catch (Exception e) { LogProvider.Log.Error(this, $"Failed to process hand #{dbHandHistory.Gamenumber}, player {playerStatisticCreationInfo.Player?.Playername} .", e); throw new DHInternalException(new NonLocalizableString($"Failed to rebuild stats of hand #{dbHandHistory.Gamenumber}")); } }
public void ProcessNotes(IEnumerable <NoteObject> notes, CancellationTokenSource cancellationTokenSource) { try { if (!licenseService.IsRegistered || (cancellationTokenSource != null && cancellationTokenSource.IsCancellationRequested)) { return; } var currentPlayerIds = new HashSet <int>(storageModel.PlayerSelectedItem.PlayerIds); var noteService = ServiceLocator.Current.GetInstance <IPlayerNotesService>() as IPlayerXRayNoteService; var sinceDate = noteService.CurrentNotesAppSettings.IsNoteCreationSinceDate ? noteService.CurrentNotesAppSettings.NoteCreationSinceDate : (DateTime?)null; var isAdvancedLogEnabled = noteService.CurrentNotesAppSettings.IsAdvancedLogEnabled; var takesNotesOnHero = noteService.CurrentNotesAppSettings.TakesNotesOnHero; using (var session = ModelEntities.OpenStatelessSession()) { BuildPlayersDictonary(session); BuildPlayersNotesDictonary(session); var entitiesCount = sinceDate != null? session.Query <Handhistory>().Count(x => x.Handtimestamp >= sinceDate.Value) : session.Query <Handhistory>().Count(); var progressCounter = 0; var progress = 0; var numOfQueries = (int)Math.Ceiling((double)entitiesCount / handHistoryRowsPerQuery); LogProvider.Log.Info(CustomModulesNames.PlayerXRay, $"Processing notes [{notes.Count()}] for {entitiesCount} hands."); for (var i = 0; i < numOfQueries; i++) { if (cancellationTokenSource != null && cancellationTokenSource.IsCancellationRequested) { LogProvider.Log.Info(CustomModulesNames.PlayerXRay, $"The note processing has been canceled [{i}/{numOfQueries}]."); break; } using (var pf = new PerformanceMonitor($"Proccesing notes [{i}/{numOfQueries} iteration].", isAdvancedLogEnabled, CustomModulesNames.PlayerXRay)) { var numOfRowToStartQuery = i * handHistoryRowsPerQuery; var handHistories = sinceDate != null? session.Query <Handhistory>() .Where(x => x.Handtimestamp >= sinceDate.Value) .Skip(numOfRowToStartQuery) .Take(handHistoryRowsPerQuery) .ToArray() : session.Query <Handhistory>() .Skip(numOfRowToStartQuery) .Take(handHistoryRowsPerQuery) .ToArray(); var notesToInsert = new ConcurrentBag <Playernotes>(); Parallel.ForEach(handHistories, handHistory => { try { var parsingResult = ParseHandHistory(handHistory); if (parsingResult != null) { var matchInfo = new GameMatchInfo { GameType = parsingResult.Source.GameDescription.GameType, CashBuyIn = !parsingResult.Source.GameDescription.IsTournament ? Utils.ConvertToCents(parsingResult.Source.GameDescription.Limit.BigBlind) : 0, TournamentBuyIn = parsingResult.Source.GameDescription.IsTournament ? parsingResult.Source.GameDescription.Tournament.BuyIn.PrizePoolValue : 0 }; if (!Limit.IsMatch(matchInfo)) { return; } var playerStatisticCreationInfo = new PlayerStatisticCreationInfo { ParsingResult = parsingResult }; foreach (var player in parsingResult.Players) { // skip notes for current player (need to check setting) if (!takesNotesOnHero && currentPlayerIds.Contains(player.PlayerId)) { continue; } var calculatedEquity = new Dictionary <string, Dictionary <Street, decimal> >(); if (player.PlayerId != 0) { var playerNoteKey = new PlayerPokerSiteKey(player.PlayerId, player.PokersiteId); playerStatisticCreationInfo.Player = player; var playerStatistic = BuildPlayerStatistic(playerStatisticCreationInfo); var playerNotes = ProcessHand(notes, playerStatistic, parsingResult.Source); if (playerNotes.Count() == 0) { continue; } // if player has no notes, then just save all new notes if (!playersNotesDictionary.ContainsKey(playerNoteKey) || (playersNotesDictionary.ContainsKey(playerNoteKey) && !playersNotesDictionary[playerNoteKey].ContainsKey(handHistory.Gamenumber))) { playerNotes.ForEach(note => notesToInsert.Add(note)); continue; } var existingNotes = playersNotesDictionary[playerNoteKey][handHistory.Gamenumber]; var notesToAdd = (from playerNote in playerNotes join existingNote in existingNotes on playerNote.Note equals existingNote.Note into gj from note in gj.DefaultIfEmpty() where note == null select playerNote).ToArray(); notesToAdd.ForEach(note => notesToInsert.Add(note)); } } ; } } catch (Exception hhEx) { LogProvider.Log.Error(CustomModulesNames.PlayerXRay, $"Hand history {handHistory.Gamenumber} has not been processed", hhEx); } // reporting progress progressCounter++; var currentProgress = progressCounter * 100 / entitiesCount; if (progress < currentProgress) { progress = currentProgress; ProgressChanged?.Invoke(this, new NoteProcessingServiceProgressChangedEventArgs(progress)); } }); using (var transaction = session.BeginTransaction()) { notesToInsert.ForEach(x => session.Insert(x)); transaction.Commit(); } } } LogProvider.Log.Info(CustomModulesNames.PlayerXRay, $"Notes have been processed."); } } catch (Exception e) { LogProvider.Log.Error(CustomModulesNames.PlayerXRay, "Notes have not been processed.", e); } }
/// <summary> /// Imports hand histories stored in DB /// </summary> private void ImportHandHistories() { using (var session = ModelEntities.OpenStatelessSession()) { var entitiesCount = session.Query <Handhistory>().Count(); var numOfQueries = (int)Math.Ceiling((double)entitiesCount / handHistoryRowsPerQuery); progress?.Report(new LocalizableString("Progress_RebuildingStatistics_Status", 0, entitiesCount)); var progressResult = 0; for (var i = 0; i < numOfQueries; i++) { var numOfRowToStartQuery = i * handHistoryRowsPerQuery; var handHistories = session.Query <Handhistory>() .OrderBy(x => x.Handtimestamp) .Skip(numOfRowToStartQuery) .Take(handHistoryRowsPerQuery) .ToArray(); // close opened handles var minDateOfHand = handHistories.MinOrDefault(x => x.Handtimestamp); if (minDateOfHand.HasValue) { ClosePlayerstatisticStreams(minDateOfHand.Value); } Parallel.ForEach(handHistories, handHistory => { var parsingResult = ParseHandHistory(handHistory); if (parsingResult != null) { var playerStatisticCreationInfo = new PlayerStatisticCreationInfo { ParsingResult = parsingResult }; parsingResult.Players.ForEach(player => { var calculatedEquity = new Dictionary <string, Dictionary <Street, decimal> >(); if (player.PlayerId != 0) { playerStatisticCreationInfo.Player = player; BuildPlayerStatistic(handHistory, playerStatisticCreationInfo); } }); } }); GC.Collect(); progressResult += handHistories.Length; progress?.Report(new LocalizableString("Progress_RebuildingStatistics_Status", progressResult, entitiesCount)); } } }