private static bool ComparePlayers(PokerStarsZoomDataObject data1, PokerStarsZoomDataObject data2)
        {
            if (ReferenceEquals(data1, data2))
            {
                return(true);
            }

            if (data1.Players.Length != data2.Players.Length)
            {
                return(false);
            }

            var players1 = data1.Players.OrderBy(x => x.Seat).ToArray();
            var players2 = data2.Players.OrderBy(x => x.Seat).ToArray();

            for (var i = 0; i < players1.Length; i++)
            {
                if (!players1[i].Player.Equals(players2[i].Player, StringComparison.Ordinal))
                {
                    return(false);
                }
            }

            return(true);
        }
        private PokerStarsZoomDataObject ParseAuditFile(string auditFile)
        {
            try
            {
                string auditFileContent = null;

                using (var fs = new FileStream(auditFile, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
                {
                    using (var sr = new StreamReader(fs))
                    {
                        if (!sr.EndOfStream)
                        {
                            auditFileContent = sr.ReadToEnd();
                        }
                    }
                }

                if (string.IsNullOrEmpty(auditFileContent))
                {
                    return(null);
                }

                var auditData = auditFileContent
                                .Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries)
                                .Select(x =>
                {
                    var keyValue     = x.Trim().Split('=');
                    var keyValuePair = new KeyValuePair <string, string>(keyValue[0].ToLowerInvariant(), keyValue.Length < 1 ? string.Empty : keyValue[1]);
                    return(keyValuePair);
                })
                                .ToDictionary(x => x.Key, x => x.Value);

                var dataObject = new PokerStarsZoomDataObject();

                // Parse hand number
                if (auditData.TryGetValue("hand", out string handNumberText) && long.TryParse(handNumberText, out long handNumber))
                {
                    dataObject.HandNumber = handNumber;
                }

                // Parse table name
                if (auditData.TryGetValue("tablenumber", out string tableName))
                {
                    dataObject.TableName = tableName;

                    var tableHandle = FindWindow(tableName, out string title);
                    dataObject.Handle = tableHandle.ToInt32();
                    dataObject.Title  = title;
                }

                // Parse game type
                if (auditData.TryGetValue("game", out string game))
                {
                    if (game.ContainsIgnoreCase("HOLDEM"))
                    {
                        dataObject.GameType = Bovada.GameType.Holdem;
                    }
                    else if (game.ContainsIgnoreCase("OMAHA"))
                    {
                        if (auditData.TryGetValue("hi-lo", out string hiLo) && bool.TryParse(hiLo, out bool isHiLo))
                        {
                            dataObject.GameType = isHiLo ? Bovada.GameType.OmahaHiLo : Bovada.GameType.Omaha;
                        }
                        else
                        {
                            dataObject.GameType = Bovada.GameType.Omaha;
                        }
                    }
                }

                // Parse game format
                if (auditData.TryGetValue("zoom", out string zoom) && bool.TryParse(zoom, out bool isZoom))
                {
                    if (auditData.TryGetValue("currency", out string currency) &&
                        currency.Equals("TOURNAMENT", StringComparison.OrdinalIgnoreCase))
                    {
                        dataObject.GameFormat = GameFormat.MTT;
                    }
                    else
                    {
                        dataObject.GameFormat = isZoom ? GameFormat.Zoom : GameFormat.Cash;
                    }
                }

                // Parse maxseats
                if (auditData.TryGetValue("maxseats", out string maxseats) && byte.TryParse(maxseats, out byte maxPlayers))
                {
                    dataObject.MaxPlayers = maxPlayers;
                    dataObject.TableType  = (EnumTableType)maxPlayers;
                }

                // Parse hero
                if (auditData.TryGetValue("user", out string heroName))
                {
                    dataObject.HeroName = HttpUtility.UrlDecode(heroName);
                }

                var players = new List <PlayerDataObject>();

                // Parse players
                for (byte i = 1; i <= dataObject.MaxPlayers; i++)
                {
                    if (auditData.TryGetValue($"seat{i}", out string playerName))
                    {
                        players.Add(new PlayerDataObject
                        {
                            Player = HttpUtility.UrlDecode(playerName),
                            Seat   = i
                        });
                    }
                }

                if (players.Count != 0)
                {
                    dataObject.Players = players.ToArray();
                }

                if (dataObject.IsValid)
                {
                    return(dataObject);
                }
            }
            catch (Exception ex)
            {
                LogProvider.Log.Error(this, $"Could not parse audit file at {auditFile} [{Identifier}]", ex);
            }

            return(null);
        }
        public void ProcessData(PokerStarsZoomDataObject catcherDataObject)
        {
            if (catcherDataObject == null || catcherDataObject.Handle == 0)
            {
                return;
            }

            try
            {
                PokerStarsZoomCacheData cachedObject;

                var isNew = false;

                if (!cachedData.ContainsKey(catcherDataObject.Handle))
                {
                    cachedObject = new PokerStarsZoomCacheData
                    {
                        Data = catcherDataObject
                    };

                    cachedData.Add(catcherDataObject.Handle, cachedObject);

                    isNew = true;
                }
                else
                {
                    cachedObject = cachedData[catcherDataObject.Handle];
                }

                cachedObject.LastModified = DateTime.Now;

                RemoveExpiredCache();

                if (!isNew)
                {
                    if (cachedObject.IsProcessed && ComparePlayers(cachedObject.Data, catcherDataObject))
                    {
                        return;
                    }

                    cachedObject.Data = catcherDataObject;
                }

                LoadPlayers(catcherDataObject.Players.Select(x => x.Player));

                var gameInfo = new GameInfo
                {
                    Session      = catcherDataObject.Handle.ToString(),
                    WindowHandle = catcherDataObject.Handle,
                    PokerSite    = EnumPokerSites.PokerStars,
                    GameType     = catcherDataObject.GameType,
                    TableType    = catcherDataObject.TableType,
                    GameFormat   = catcherDataObject.GameFormat,
                    GameNumber   = catcherDataObject.HandNumber
                };

                // Initialize cache
                gameInfo.ResetPlayersCacheInfo();

                var players = new PlayerList(catcherDataObject.Players.Select(x =>
                                                                              new Player(x.Player, 0, x.Seat)
                {
                    PlayerId = playerNamePlayerIdMap.ContainsKey(x.Player) ? playerNamePlayerIdMap[x.Player] : 0
                }));

                var heroPlayer = ProcessPlayers(gameInfo, players, catcherDataObject);

                if (heroPlayer == null || (gameInfo.GameFormat != GameFormat.Zoom && gameInfo.GameFormat != GameFormat.Cash))
                {
                    return;
                }

                var importedArgs = new DataImportedEventArgs(players, gameInfo, heroPlayer, 0);
                eventAggregator.GetEvent <DataImportedEvent>().Publish(importedArgs);

                cachedObject.IsProcessed = true;
#if DEBUG
                Console.WriteLine($@"Data has been send to {catcherDataObject.TableName}, {catcherDataObject.Handle}, {catcherDataObject.TableName} {(int)catcherDataObject.TableType}-max, {string.Join(", ", players.Select(x => $"{x.PlayerName}[{x.PlayerId}]").ToArray())}");
#endif
            }
            catch (Exception ex)
            {
                LogProvider.Log.Error(this, "Stream data was in wrong format", ex);
            }
        }
        private Player ProcessPlayers(GameInfo gameInfo, PlayerList players, PokerStarsZoomDataObject catcherDataObject)
        {
            Player heroPlayer = null;

            var heroName = catcherDataObject.HeroName;

            foreach (var player in players)
            {
                if (player.PlayerId == 0)
                {
                    continue;
                }

                var isHero = false;

                if (player.PlayerName.Equals(heroName))
                {
                    heroPlayer = player;
                    isHero     = true;
                }

                var playerCollectionItem = new PlayerCollectionItem
                {
                    PlayerId  = player.PlayerId,
                    Name      = player.PlayerName,
                    PokerSite = EnumPokerSites.PokerStars
                };

                var playerCacheStatistic = importerSessionCacheService.GetPlayerStats(gameInfo.Session, playerCollectionItem, out bool exists);

                if (exists && playerCacheStatistic.IsHero)
                {
                    heroPlayer          = player;
                    gameInfo.GameFormat = playerCacheStatistic.GameFormat;
                    break;
                }
                else if (!exists && gameInfo.GameFormat == GameFormat.Zoom)
                {
                    var playerCacheInfo = new PlayerStatsSessionCacheInfo
                    {
                        Session    = gameInfo.Session,
                        GameFormat = gameInfo.GameFormat,
                        Player     = playerCollectionItem,
                        IsHero     = isHero,
                        Stats      = new Playerstatistic
                        {
                            SessionCode     = gameInfo.Session,
                            PokergametypeId = ParsePokergametypeIdFromTitle(catcherDataObject.Title)
                        }
                    };

                    if (playerCacheInfo.Stats.PokergametypeId != 0)
                    {
                        gameInfo.AddToPlayersCacheInfo(playerCacheInfo);
                    }
                }
            }

            if (heroPlayer == null)
            {
                return(null);
            }

            int prefferedSeatNumber = 0;

            if (gameInfo.GameFormat == GameFormat.Zoom)
            {
                // zoom is always auto-centered
                switch (gameInfo.TableType)
                {
                case EnumTableType.HU:
                    prefferedSeatNumber = 2;
                    break;

                case EnumTableType.Six:
                    prefferedSeatNumber = 3;
                    break;

                case EnumTableType.Nine:
                    prefferedSeatNumber = 5;
                    break;
                }
            }
            else
            {
                var preferredSeats = ServiceLocator.Current.GetInstance <ISettingsService>().GetSettings().
                                     SiteSettings.SitesModelList.FirstOrDefault(x => x.PokerSite == EnumPokerSites.PokerStars)?.PrefferedSeats;

                var prefferedSeat = preferredSeats?.FirstOrDefault(x => x.TableType == catcherDataObject.TableType && x.IsPreferredSeatEnabled);

                if (prefferedSeat != null)
                {
                    prefferedSeatNumber = prefferedSeat.PreferredSeat;
                }
            }

            if (prefferedSeatNumber > 0)
            {
                var shift = (prefferedSeatNumber - heroPlayer.SeatNumber) % catcherDataObject.MaxPlayers;

                foreach (var player in players)
                {
                    player.SeatNumber = GeneralHelpers.ShiftPlayerSeat(player.SeatNumber, shift, catcherDataObject.MaxPlayers);
                }
            }

            return(heroPlayer);
        }