예제 #1
0
        public async Task <BeforeMatchResponse> BeforeMatch(BeforeMatchRequest request)
        {
            var realSteamIds = request.Players.Select(ulong.Parse).ToList();
            var responses    = await _context.Players.Where(p => realSteamIds.Contains(p.SteamId))
                               .Select(p => new
            {
                SteamId = p.SteamId.ToString(),
                Patreon =
                    new BeforeMatchResponse.Patreon()
                {
                    Level         = p.PatreonLevel,
                    EmblemEnabled = p.PatreonEmblemEnabled.GetValueOrDefault(true),
                    EmblemColor   = p.PatreonEmblemColor ?? "White",
                    BootsEnabled  = p.PatreonBootsEnabled.GetValueOrDefault(true),
                },
                MatchesOnMap = p.Matches
                               .Where(m => m.Match.MapName == request.MapName)
                               .OrderByDescending(m => m.MatchId)
                               .Select(m => new { IsWinner = m.Team == m.Match.Winner, m.Kills, m.Deaths, m.Assists })
                               .ToList(),
                SmartRandomHeroesMap = p.Matches
                                       .Where(m => m.Match.MapName == request.MapName)
                                       .Where(m => m.PickReason == "pick")
                                       .OrderByDescending(m => m.MatchId)
                                       .Take(100)
                                       .GroupBy(m => m.Hero)
                                       .Where(g => g.Count() >= (int)Math.Ceiling(p.Matches.Count() / 20.0))
                                       .Select(g => g.Key)
                                       .ToList(),
                SmartRandomHeroesGlobal = p.Matches
                                          .Where(m => m.PickReason == "pick")
                                          .OrderByDescending(m => m.MatchId)
                                          .Take(100)
                                          .GroupBy(m => m.Hero)
                                          .Where(g => g.Count() >= (int)Math.Ceiling(p.Matches.Count() / 20.0))
                                          .Select(g => g.Key)
                                          .ToList(),
                LastSmartRandomUse = p.Matches
                                     .Where(m => m.PickReason == "smart-random")
                                     .OrderByDescending(m => m.Match.EndedAt)
                                     .Take(1)
                                     .Select(m => m.Match.EndedAt)
                                     .FirstOrDefault()
            })
                               .ToListAsync();

            return(new BeforeMatchResponse()
            {
                Players = request.Players
                          .Select(id =>
                {
                    var response = responses.FirstOrDefault(p => p.SteamId == id);
                    if (response == null)
                    {
                        return new BeforeMatchResponse.Player()
                        {
                            SteamId = id.ToString(),
                            Patreon = new BeforeMatchResponse.Patreon()
                            {
                                Level = 0,
                                EmblemEnabled = true,
                                EmblemColor = "White",
                                BootsEnabled = true,
                            },
                            SmartRandomHeroesError = "no_stats",
                        };
                    }

                    var player = new BeforeMatchResponse.Player
                    {
                        SteamId = id.ToString(),
                        // TODO: Remove it
                        PatreonLevel = response.Patreon.Level,
                        Patreon = response.Patreon,
                        Streak = response.MatchesOnMap.TakeWhile(w => w.IsWinner).Count(),
                        BestStreak = response.MatchesOnMap.LongestStreak(w => w.IsWinner),
                        AverageKills = response.MatchesOnMap.Select(x => (double)x.Kills)
                                       .DefaultIfEmpty()
                                       .Average(),
                        AverageDeaths = response.MatchesOnMap.Select(x => (double)x.Deaths)
                                        .DefaultIfEmpty()
                                        .Average(),
                        AverageAssists =
                            response.MatchesOnMap.Select(x => (double)x.Assists).DefaultIfEmpty().Average(),
                        Wins = response.MatchesOnMap.Count(w => w.IsWinner),
                        Loses = response.MatchesOnMap.Count(w => !w.IsWinner),
                    };

                    var canUseSmartRandom = response.Patreon.Level >= 1 ||
                                            (DateTime.UtcNow - response.LastSmartRandomUse).TotalDays >= 1;
                    if (canUseSmartRandom)
                    {
                        var heroes = response.SmartRandomHeroesMap.Count >= 5
                                ? response.SmartRandomHeroesMap
                                : response.SmartRandomHeroesGlobal;

                        if (heroes.Count >= 3)
                        {
                            player.SmartRandomHeroes = heroes;
                        }
                        else
                        {
                            player.SmartRandomHeroesError = "no_stats";
                        }
                    }
                    else
                    {
                        player.SmartRandomHeroesError = "cooldown";
                    }

                    return player;
                })
                          .ToList()
            });
        }
예제 #2
0
        public async Task <BeforeMatchResponse> Before(BeforeMatchRequest request)
        {
            var customGame = request.CustomGame.Value;
            var mapName    = request.MapName;

            var realSteamIds = request.Players.Select(ulong.Parse).ToList();
            var responses    = await _context.Players
                               .Where(p => realSteamIds.Contains(p.SteamId))
                               .Select(p => new
            {
                SteamId = p.SteamId.ToString(),
                Patreon =
                    new BeforeMatchResponse.Patreon()
                {
                    EndDate            = p.PatreonEndDate,
                    Level              = p.PatreonLevel,
                    EmblemEnabled      = p.PatreonEmblemEnabled ?? true,
                    EmblemColor        = p.PatreonEmblemColor ?? "White",
                    BootsEnabled       = p.PatreonBootsEnabled ?? true,
                    ChatWheelFavorites = p.PatreonChatWheelFavorites ?? new List <int>(),
                    Cosmetics          = p.PatreonCosmetics,
                },
                Matches = p.Matches
                          .Where(m => m.Match.CustomGame == customGame)
                          .OrderByDescending(m => m.MatchId)
                          .Select(mp => new
                {
                    mp.Kills,
                    mp.Deaths,
                    mp.Assists,
                    mp.Match.MapName,
                    mp.PickReason,
                    mp.Hero,
                    IsWinner = mp.Team == mp.Match.Winner,
                })
                          .ToList(),
            })
                               .ToListAsync();

            return(new BeforeMatchResponse()
            {
                Players = request.Players
                          .Select(id =>
                {
                    var response = responses.FirstOrDefault(p => p.SteamId == id);
                    if (response == null)
                    {
                        return new BeforeMatchResponse.Player()
                        {
                            SteamId = id.ToString(),
                            Patreon = new BeforeMatchResponse.Patreon()
                            {
                                Level = 0,
                                EmblemEnabled = true,
                                EmblemColor = "White",
                                BootsEnabled = true,
                                ChatWheelFavorites = new List <int>(),
                            },
                            SmartRandomHeroesError = "no_stats",
                        };
                    }

                    if (response.Patreon.EndDate < DateTime.UtcNow)
                    {
                        response.Patreon.Level = 0;
                    }

                    var matchesOnMap = response.Matches.Where(m => m.MapName == mapName).ToList();

                    var player = new BeforeMatchResponse.Player
                    {
                        SteamId = id.ToString(),
                        Patreon = response.Patreon,
                        Streak = matchesOnMap.TakeWhile(w => w.IsWinner).Count(),
                        BestStreak = matchesOnMap.LongestStreak(w => w.IsWinner),
                        AverageKills = matchesOnMap
                                       .Select(x => (double)x.Kills)
                                       .DefaultIfEmpty()
                                       .Average(),
                        AverageDeaths = matchesOnMap
                                        .Select(x => (double)x.Deaths)
                                        .DefaultIfEmpty()
                                        .Average(),
                        AverageAssists = matchesOnMap
                                         .Select(x => (double)x.Assists)
                                         .DefaultIfEmpty()
                                         .Average(),
                        Wins = matchesOnMap.Count(w => w.IsWinner),
                        Loses = matchesOnMap.Count(w => !w.IsWinner),
                    };

                    List <string> GetSmartRandomHeroes(bool onMap)
                    {
                        var matches = (onMap ? matchesOnMap : response.Matches).Where(m => m.PickReason == "pick");
                        return matches
                        .Take(100)
                        .GroupBy(m => m.Hero)
                        .Where(g => g.Count() >= (int)Math.Ceiling(Math.Min(matches.Count(), 100) / 20.0))
                        .Select(g => g.Key)
                        .ToList();
                    };

                    var smartRandomHeroesMap = GetSmartRandomHeroes(true);
                    var smartRandomHeroesGlobal = GetSmartRandomHeroes(false);

                    var heroes = smartRandomHeroesMap.Count >= 5
                            ? smartRandomHeroesMap
                            : smartRandomHeroesGlobal;

                    if (heroes.Count >= 3)
                    {
                        player.SmartRandomHeroes = heroes;
                    }
                    else
                    {
                        player.SmartRandomHeroesError = "no_stats";
                    }

                    return player;
                })
                          .ToList()
            });