public void Update(MatchInfoEntry infoEntry, DatabaseContext databaseContext)
        {
            const int maxServersCount = 50;

            foreach (var entry in databaseContext.ChangeTracker.Entries <MatchInfoEntry>())
            {
                entry.State = EntityState.Unchanged;
            }
            var recentMatches = databaseContext.RecentMatches.OrderByDescending(x => x.Timestamp).ToList();

            if (recentMatches.Count < maxServersCount)
            {
                databaseContext.RecentMatches.Add(
                    new RecentMatchEntry
                {
                    Key       = infoEntry.Key,
                    Server    = infoEntry.Endpoint,
                    Timestamp = infoEntry.Timestamp,
                });
            }
            else if (recentMatches[recentMatches.Count - 1].Timestamp < infoEntry.Timestamp)
            {
                databaseContext.RecentMatches.Remove(recentMatches[recentMatches.Count - 1]);
                databaseContext.RecentMatches.Add(
                    new RecentMatchEntry
                {
                    Key       = infoEntry.Key,
                    Server    = infoEntry.Endpoint,
                    Timestamp = infoEntry.Timestamp,
                });
            }
        }
        public async Task PutMatchInfo(string endpoint, DateTime timestamp, MatchInfoEntry infoEntry)
        {
            await Task.Run(() =>
            {
                var serverEntry = databaseContext.Servers.Find(endpoint);
                if (serverEntry == null)
                {
                    throw new BadRequestException("Bad Request");
                }

                var key = endpoint + timestamp.ToString(CultureInfo.InvariantCulture);
                if (databaseContext.Matches.Find(key) != null)
                {
                    throw new BadRequestException("Bad Request");
                }

                infoEntry.Key       = key;
                infoEntry.Endpoint  = endpoint;
                infoEntry.Timestamp = timestamp;

                lock (databaseContext)
                {
                    databaseContext.Matches.Add(infoEntry);
                    databaseContext.SaveChanges();

                    statisticsUpdater.Update(infoEntry, databaseContext);
                    databaseContext.SaveChanges();
                }
            });
        }
Ejemplo n.º 3
0
        public async Task PutMatchInfo_DoesNot_ResavesInfo()
        {
            var endpoint  = "PutServerInfo_SavesInfo";
            var timeStamp = DateTime.UtcNow.Date - TimeSpan.FromDays(3);
            var matchData = new MatchInfoEntry
            {
                Map         = "NewMap",
                GameMode    = "TDM",
                FragLimit   = 200,
                TimeLimit   = 200,
                TimeElapsed = 152.9,
                Scoreboard  = new List <ScoreEntry>
                {
                    new ScoreEntry {
                        Name = "Player2", Frags = 20, Kills = 21, Deaths = 3
                    },
                    new ScoreEntry {
                        Name = "Player1", Frags = 2, Kills = 2, Deaths = 21
                    }
                }
            };

            try
            {
                await statistics.PutMatchInfo(endpoint, timeStamp, matchData);
            }
            catch (Exception e)
            {
                Assert.IsTrue(e is BadRequestException);
            }
        }
 public void Update(MatchInfoEntry infoEntry, DatabaseContext databaseContext)
 {
     foreach (var statisticsUpdater in updaters)
     {
         statisticsUpdater.Update(infoEntry, databaseContext);
     }
 }
Ejemplo n.º 5
0
 public MatchInfo(MatchInfoEntry entry)
 {
     Map         = entry.Map;
     GameMode    = entry.GameMode;
     FragLimit   = entry.FragLimit;
     TimeLimit   = entry.TimeLimit;
     TimeElapsed = entry.TimeElapsed;
     Scoreboard  = entry.Scoreboard.Select(x => new Score(x)).ToList();
 }
        public void Update(MatchInfoEntry infoEntry, DatabaseContext databaseContext)
        {
            var previous = databaseContext.ServerStatistics.Find(infoEntry.Endpoint);

            if (previous == null)
            {
                SetFirstEntry(infoEntry, databaseContext);
            }
            else
            {
                UpdateEntry(previous, infoEntry);
            }
        }
 private void SetFirstEntry(MatchInfoEntry infoEntry, DatabaseContext databaseContext)
 {
     databaseContext.ServerStatistics.Add(new ServerStatisticsEntry
     {
         Endpoint             = infoEntry.Endpoint,
         TotalMatchesPlayed   = 1,
         MaximumMatchesPerDay = 1,
         AverageMatchesPerDay = 1,
         MaximumPopulation    = infoEntry.Scoreboard.Count,
         AveragePopulation    = infoEntry.Scoreboard.Count,
         Top5GameModes        = new List <StringEntry> {
             new StringEntry {
                 String = infoEntry.GameMode
             }
         },
         Top5Maps = new List <StringEntry> {
             new StringEntry {
                 String = infoEntry.Map
             }
         },
         MatchesPerDay = new List <DayCountEntry> {
             new DayCountEntry {
                 Day = infoEntry.Timestamp.Date, Count = 1
             }
         },
         PopulationPerMatch =
             new List <MatchCountEntry>
         {
             new MatchCountEntry
             {
                 Key       = infoEntry.Endpoint + infoEntry.Timestamp,
                 Endpoint  = infoEntry.Endpoint,
                 TimeStamp = infoEntry.Timestamp,
                 Count     = infoEntry.Scoreboard.Count
             }
         },
         GameModePopularity =
             new List <NameCountEntry> {
             new NameCountEntry {
                 Name = infoEntry.GameMode, Count = 1
             }
         },
         MapPopularity = new List <NameCountEntry>
         {
             new NameCountEntry {
                 Name = infoEntry.Map, Count = 1
             }
         }
     });
 }
Ejemplo n.º 8
0
        public async Task GetBestPlayers_DoesNotCountPlayersWithoutDeaths()
        {
            var time = DateTime.Now;
            var data = new ServerInfoEntry
            {
                Endpoint  = "GetBestPlayers_DoesNotCountPlayersWithoutDeaths",
                Name      = "Test",
                GameModes = new List <StringEntry> {
                    new StringEntry {
                        String = "DM"
                    }, new StringEntry {
                        String = "TDM"
                    }
                }
            };
            var match = new MatchInfoEntry
            {
                Map         = "1",
                GameMode    = "2",
                FragLimit   = 20,
                TimeLimit   = 300,
                TimeElapsed = 25,
                Scoreboard  = new List <ScoreEntry>
                {
                    new ScoreEntry
                    {
                        Name   = "GetBestPlayers_DoesNotCountPlayersWithoutDeaths1",
                        Deaths = 0,
                        Frags  = 2,
                        Kills  = 20
                    },
                    new ScoreEntry
                    {
                        Name   = "GetBestPlayers_DoesNotCountPlayersWithoutDeaths2",
                        Deaths = 0,
                        Frags  = 20,
                        Kills  = 2
                    }
                }
            };


            await statistics.PutServerInfo(data.Endpoint,
                                           new ServerInfoEntry { Name = data.Name, GameModes = data.GameModes });

            await statistics.PutMatchInfo(data.Endpoint, time, match);

            new GameStatistics().GetBestPlayers(50).Result.Should().BeEmpty();
        }
 public void Update(MatchInfoEntry infoEntry, DatabaseContext databaseContext)
 {
     foreach (var player in infoEntry.Scoreboard)
     {
         var previous = databaseContext.PlayersStatistics.FirstOrDefault(x => x.Name.Equals(player.Name, StringComparison.InvariantCultureIgnoreCase));
         if (previous == null)
         {
             SetFirstEntry(infoEntry, player.Name, databaseContext);
         }
         else
         {
             UpdateEntry(previous, infoEntry);
         }
     }
 }
        private void UpdateEntry(ServerStatisticsEntry previous, MatchInfoEntry infoEntry)
        {
            previous.MatchesPerDay.AddOrUpdate(x => x.Day == infoEntry.Timestamp.Date,
                                               () => new DayCountEntry {
                Day = infoEntry.Timestamp.Date, Count = 1
            }, x => x.Count++);
            previous.PopulationPerMatch.AddOrUpdate(x => x.Key == infoEntry.Endpoint + infoEntry.Timestamp,
                                                    () => new MatchCountEntry
            {
                Key       = infoEntry.Endpoint + infoEntry.Timestamp,
                Endpoint  = infoEntry.Endpoint,
                TimeStamp = infoEntry.Timestamp,
                Count     = infoEntry.Scoreboard.Count
            }, x => x.Count++);
            previous.GameModePopularity.AddOrUpdate(x => x.Name == infoEntry.GameMode,
                                                    () => new NameCountEntry {
                Name = infoEntry.GameMode, Count = 1
            }, x => x.Count++);
            previous.MapPopularity.AddOrUpdate(x => x.Name == infoEntry.Map,
                                               () => new NameCountEntry {
                Name = infoEntry.Map, Count = 1
            }, x => x.Count++);

            var totalDays = (previous.MatchesPerDay.Max(x => x.Day) - previous.MatchesPerDay.Min(x => x.Day)).TotalDays;

            previous.TotalMatchesPlayed   = previous.TotalMatchesPlayed + 1;
            previous.MaximumMatchesPerDay = previous.MatchesPerDay.Select(x => x.Count).Max();
            previous.AverageMatchesPerDay = Math.Abs(totalDays) < 0.00001 ? previous.MatchesPerDay.Select(x => x.Count).Sum() : previous.MatchesPerDay.Select(x => x.Count).Sum() / totalDays;
            previous.MaximumPopulation    = previous.PopulationPerMatch.Select(x => x.Count).Max();
            previous.AveragePopulation    = (double)previous.PopulationPerMatch.Select(x => x.Count).Sum() / previous.PopulationPerMatch.Count;

            previous.Top5GameModes = previous.GameModePopularity
                                     .OrderByDescending(x => x.Count)
                                     .Take(5)
                                     .Select(x => new StringEntry {
                String = x.Name
            })
                                     .ToList();
            previous.Top5Maps = previous.MapPopularity
                                .OrderByDescending(x => x.Count)
                                .Take(5)
                                .Select(x => new StringEntry {
                String = x.Name
            })
                                .ToList();
        }
        private void UpdateEntry(PlayerStatisticsEntry previous, MatchInfoEntry infoEntry)
        {
            var position = infoEntry.Scoreboard.FindIndex(x => x.Name == previous.Name);

            var scoreboardPercent = 100.0;

            if (infoEntry.Scoreboard.Count > 1)
            {
                scoreboardPercent = (double)(infoEntry.Scoreboard.Count - position - 1) / (infoEntry.Scoreboard.Count - 1) * 100;
            }

            var totalMatchesWon = position == 0 ? previous.TotalMatchesWon + 1 : previous.TotalMatchesWon;

            previous.ServersPopularity.AddOrUpdate(x => x.Name == infoEntry.Endpoint,
                                                   () => new NameCountEntry {
                Name = infoEntry.GameMode, Count = 1
            }, x => x.Count++);
            previous.GameModePopularity.AddOrUpdate(x => x.Name == infoEntry.GameMode,
                                                    () => new NameCountEntry {
                Name = infoEntry.GameMode, Count = 1
            }, x => x.Count++);
            previous.MatchesPerDay.AddOrUpdate(x => x.Day == infoEntry.Timestamp.Date,
                                               () => new DayCountEntry {
                Day = infoEntry.Timestamp.Date, Count = 1
            }, x => x.Count++);

            previous.TotalKills  += infoEntry.Scoreboard[position].Kills;
            previous.TotalDeaths += infoEntry.Scoreboard[position].Deaths;

            var totalDays = (previous.MatchesPerDay.Max(x => x.Day) - previous.MatchesPerDay.Min(x => x.Day)).TotalDays;
            var averageScoreboardPercent = (previous.AverageScoreboardPercent * previous.TotalMatchesPlayed + scoreboardPercent) / (previous.TotalMatchesPlayed + 1);
            var lastMatchPlayed          = infoEntry.Timestamp > previous.LastMatchPlayed ? infoEntry.Timestamp : previous.LastMatchPlayed;
            var noDeaths = previous.TotalDeaths == 0;

            previous.TotalMatchesPlayed       = previous.TotalMatchesPlayed + 1;
            previous.TotalMatchesWon          = totalMatchesWon;
            previous.FavoriteServer           = previous.ServersPopularity.OrderByDescending(x => x.Count).First().Name;
            previous.UniqueServers            = previous.ServersPopularity.Count;
            previous.FavoriteGameMode         = previous.GameModePopularity.OrderByDescending(x => x.Count).First().Name;
            previous.AverageScoreboardPercent = averageScoreboardPercent;
            previous.MaximumMatchesPerDay     = previous.MatchesPerDay.Select(x => x.Count).Max();
            previous.AverageMatchesPerDay     = Math.Abs(totalDays) < 0.01 ? previous.MatchesPerDay.Select(x => x.Count).Sum() : previous.MatchesPerDay.Select(x => x.Count).Sum() / totalDays;
            previous.LastMatchPlayed          = lastMatchPlayed;
            previous.KillToDeathRatio         = noDeaths ? previous.TotalKills : (double)previous.TotalKills / previous.TotalDeaths;
        }
        public void Update(MatchInfoEntry infoEntry, DatabaseContext databaseContext)
        {
            const int maxPlayersCount      = 50;
            const int requiredMatchesCount = 10;

            var bestPlayers = databaseContext.BestPlayers.OrderByDescending(x => x.KillToDeathRatio).ToList();

            foreach (var player in infoEntry.Scoreboard)
            {
                var playerInfo = databaseContext.PlayersStatistics.FirstOrDefault(x => x.Name.Equals(player.Name, StringComparison.InvariantCultureIgnoreCase));
                if (playerInfo == null || playerInfo.TotalDeaths == 0 ||
                    playerInfo.TotalMatchesPlayed < requiredMatchesCount)
                {
                    continue;
                }

                var previous = bestPlayers.Find(x => x.Name == player.Name);
                if (previous != null)
                {
                    previous.KillToDeathRatio = playerInfo.KillToDeathRatio;
                    continue;
                }
                if (bestPlayers.Count < maxPlayersCount)
                {
                    databaseContext.BestPlayers.Add(new BestPlayerEntry
                    {
                        Name             = playerInfo.Name,
                        KillToDeathRatio = playerInfo.KillToDeathRatio
                    });
                }
                else if (bestPlayers[bestPlayers.Count - 1].KillToDeathRatio < playerInfo.KillToDeathRatio)
                {
                    databaseContext.BestPlayers.Remove(bestPlayers[bestPlayers.Count - 1]);
                    databaseContext.BestPlayers.Add(new BestPlayerEntry
                    {
                        Name             = playerInfo.Name,
                        KillToDeathRatio = playerInfo.KillToDeathRatio
                    });
                }
            }
        }
        private void SetFirstEntry(MatchInfoEntry infoEntry, string name, DatabaseContext databaseContext)
        {
            var position          = infoEntry.Scoreboard.FindIndex(x => x.Name == name);
            var scoreboardPercent = 100.0;

            if (infoEntry.Scoreboard.Count > 1)
            {
                scoreboardPercent = (double)(infoEntry.Scoreboard.Count - position - 1) / (infoEntry.Scoreboard.Count - 1) * 100;
            }
            databaseContext.PlayersStatistics.Add(new PlayerStatisticsEntry
            {
                Name = name,
                TotalMatchesPlayed       = 1,
                TotalMatchesWon          = position == 0 ? 1 : 0,
                FavoriteServer           = infoEntry.Endpoint,
                UniqueServers            = 1,
                FavoriteGameMode         = infoEntry.GameMode,
                AverageScoreboardPercent = scoreboardPercent,
                MaximumMatchesPerDay     = 1,
                AverageMatchesPerDay     = 1,
                LastMatchPlayed          = infoEntry.Timestamp,
                KillToDeathRatio         = 0,
                ServersPopularity        = new List <NameCountEntry> {
                    new NameCountEntry {
                        Name = infoEntry.Endpoint, Count = 1
                    }
                },
                GameModePopularity = new List <NameCountEntry> {
                    new NameCountEntry {
                        Name = infoEntry.GameMode, Count = 1
                    }
                },
                MatchesPerDay = new List <DayCountEntry> {
                    new DayCountEntry {
                        Day = infoEntry.Timestamp.Date, Count = 1
                    }
                },
                TotalKills  = infoEntry.Scoreboard[position].Kills,
                TotalDeaths = infoEntry.Scoreboard[position].Deaths
            });
        }
        public void Update(MatchInfoEntry infoEntry, DatabaseContext databaseContext)
        {
            const int maxServersCount = 50;

            var popularServers   = databaseContext.PopularServers.OrderByDescending(x => x.AverageMatchesPerDay).ToList();
            var serverStatistics = databaseContext.ServerStatistics.Find(infoEntry.Endpoint);
            var serverInfo       = databaseContext.Servers.Find(infoEntry.Endpoint);

            if (serverStatistics == null || serverInfo == null)
            {
                return;
            }

            var serverName = serverInfo.Name;
            var previous   = popularServers.Find(x => x.Endpoint == serverInfo.Endpoint);

            if (previous != null)
            {
                previous.AverageMatchesPerDay = serverStatistics.AverageMatchesPerDay;
            }
            else if (popularServers.Count < maxServersCount)
            {
                databaseContext.PopularServers.Add(new PopularServerEntry
                {
                    Endpoint             = infoEntry.Endpoint,
                    Name                 = serverName,
                    AverageMatchesPerDay = serverStatistics.AverageMatchesPerDay
                });
            }
            else if (popularServers[popularServers.Count - 1].AverageMatchesPerDay < serverStatistics.AverageMatchesPerDay)
            {
                databaseContext.PopularServers.Remove(popularServers[popularServers.Count - 1]);
                databaseContext.PopularServers.Add(new PopularServerEntry
                {
                    Endpoint             = infoEntry.Endpoint,
                    Name                 = serverName,
                    AverageMatchesPerDay = serverStatistics.AverageMatchesPerDay
                });
            }
        }
Ejemplo n.º 15
0
        public async Task PutMatchInfo_SavesInfo()
        {
            var endpoint  = "PutServerInfo_SavesInfo";
            var timeStamp = DateTime.UtcNow.Date - TimeSpan.FromDays(3);
            var matchData = new MatchInfoEntry
            {
                Map         = "DM-HelloWorld",
                GameMode    = "TM",
                FragLimit   = 20,
                TimeLimit   = 20,
                TimeElapsed = 12.345678,
                Scoreboard  = new List <ScoreEntry>
                {
                    new ScoreEntry {
                        Name = "Player1", Frags = 20, Kills = 21, Deaths = 3
                    },
                    new ScoreEntry {
                        Name = "Player2", Frags = 2, Kills = 2, Deaths = 21
                    }
                }
            };

            await statistics.PutMatchInfo(endpoint, timeStamp, matchData);

            using (var databaseContext = new DatabaseContext())
            {
                var result =
                    databaseContext.Matches.Find(matchData.Endpoint + timeStamp.ToString(CultureInfo.InvariantCulture));


                result.ShouldBeEquivalentTo(matchData, o =>
                {
                    o.Excluding(x => x.Key);
                    o.Excluding(x => x.Timestamp);
                    o.Excluding(x => x.RecentMatchEntry);
                    return(o);
                });
            }
        }
Ejemplo n.º 16
0
 public async Task PutMatchInfo(MatchInfoEntry serverInfoEntry, string endpoint, DateTime timestamp)
 {
     await statistics.PutMatchInfo(endpoint, timestamp, serverInfoEntry);
 }