Beispiel #1
0
        public async Task <Wn8ExpectedValues> GetXvmWn8ExpectedValuesAsync()
        {
            Log.Debug("Obtendo os WN8 da XVM");
            const string url     = "https://static.modxvm.com/wn8-data-exp/json/wn8exp.json";
            var          content = await GetContent("Wn8XVM.json", url, WebCacheAge, false, Encoding.UTF8);

            var json = content.Content;

            var ev = new Wn8ExpectedValues();

            var j = JObject.Parse(json);
            var h = j["header"];

            ev.Source  = (string)h["source"];
            ev.Version = (string)h["version"];

            var d = j["data"];

            foreach (var dd in d.Children())
            {
                ev.Add(new Wn8TankExpectedValues
                {
                    TankId  = (long)dd["IDNum"],
                    Def     = (double)dd["expDef"],
                    Frag    = (double)dd["expFrag"],
                    Spot    = (double)dd["expSpot"],
                    Damage  = (double)dd["expDamage"],
                    WinRate = (double)dd["expWinRate"] / 100.0
                });
            }

            return(ev);
        }
Beispiel #2
0
        /// <summary>
        /// Calculate all properties
        /// </summary>
        /// <param name="wn8ExpectedValues">The reference tanks</param>
        public void Calculate(Wn8ExpectedValues wn8ExpectedValues)
        {
            PruneTanks(wn8ExpectedValues);
            Performance.ExpectedValues = wn8ExpectedValues;
            Performance.CalculateAllTanks();

            TotalTime    = Performance.GetTime();
            TotalBattles = Performance.GetBattles();
            TotalWinRate = Performance.GetWinRate();
            TotalTier    = Performance.GetTier();
            TotalWn8     = Performance.GetWn8();

            MonthTime    = Performance.GetTime(ReferencePeriod.Month);
            MonthBattles = Performance.GetBattles(ReferencePeriod.Month);
            MonthWinRate = Performance.GetWinRate(ReferencePeriod.Month);
            MonthTier    = Performance.GetTier(ReferencePeriod.Week);
            MonthWn8     = Performance.GetWn8(ReferencePeriod.Month);

            WeekTime    = Performance.GetTime(ReferencePeriod.Week);
            WeekBattles = Performance.GetBattles(ReferencePeriod.Week);
            WeekWinRate = Performance.GetWinRate(ReferencePeriod.Week);
            WeekTier    = Performance.GetTier(ReferencePeriod.Week);
            WeekWn8     = Performance.GetWn8(ReferencePeriod.Week);

            Tier10TotalBattles = Performance.GetBattles(ReferencePeriod.All, 10);
            Tier10TotalTime    = Performance.GetTime(ReferencePeriod.All, 10);
            Tier10TotalWinRate = Performance.GetWinRate(ReferencePeriod.All, 10);
            Tier10TotalWn8     = Performance.GetWn8(ReferencePeriod.All, 10);

            Tier10MonthBattles = Performance.GetBattles(ReferencePeriod.Month, 10);
            Tier10MonthTime    = Performance.GetTime(ReferencePeriod.Month, 10);
            Tier10MonthWinRate = Performance.GetWinRate(ReferencePeriod.Month, 10);
            Tier10MonthWn8     = Performance.GetWn8(ReferencePeriod.Month, 10);
        }
Beispiel #3
0
        private static void TestWN8Calculation()
        {
            string            connectionString = ConfigurationManager.ConnectionStrings["Main"].ConnectionString;
            DbProvider        provider         = new DbProvider(connectionString);
            Wn8ExpectedValues expected         = provider.GetWn8ExpectedValues(Platform.XBOX);

            Dictionary <long, TankPlayerStatistics> fakePlayed = new Dictionary <long, TankPlayerStatistics>();

            foreach (Wn8TankExpectedValues e in expected.AllTanks)
            {
                fakePlayed.Add(e.TankId,
                               new TankPlayerStatistics
                {
                    Battles              = 100000,
                    DamageDealt          = (long)(e.Damage * 100000),
                    Wins                 = (long)(e.WinRate * 100000),
                    Kills                = (long)(e.Frag * 100000),
                    Spotted              = (long)(e.Spot * 100000),
                    DroppedCapturePoints = (long)(e.Def * 100000)
                });
            }

            // Teste do geral
            double wn8 = expected.CalculateWn8(fakePlayed);

            Log.Info($"WN8 de Referência: {wn8} - Deve ser proximo de 1565");

            // Teste de um jogador (eu!)
            Stopwatch sw = Stopwatch.StartNew();
            Player    p  = provider.GetPlayer(1763298, true);

            p.Calculate(expected);
            sw.Stop();
            Log.Info($"All:   {p.TotalWn8:N0} on {p.TotalBattles:N0} @ {p.TotalWinRate:P2} on Tier {p.TotalTier:N1}");
            Log.Info($"Month: {p.MonthWn8:N0} on {p.MonthBattles:N0} @ {p.MonthWinRate:P2} on Tier {p.MonthTier:N1}");
            Log.Info($"Week:  {p.WeekWn8:N0} on {p.WeekBattles:N0} @ {p.WeekWinRate:P2} on Tier {p.WeekTier:N1}");
            Log.Debug($"In {sw.Elapsed.TotalMilliseconds:N0}ms");

            foreach (KeyValuePair <long, TankPlayerStatistics> t in p.Performance.Month)
            {
                Wn8TankExpectedValues td = expected[t.Key];
                if (td.Tier < 10)
                {
                    continue;
                }

                Log.Debug($"{td.Name}: {t.Value.Wn8:N0}");
            }

            // Teste de dano esperado para um tanque qualquer (T110E5)
            sw = Stopwatch.StartNew();
            Wn8TankExpectedValues te = expected[10785];
            double damageAverage     = te.GetTargetDamage(Wn8Rating.Average);
            double damageGood        = te.GetTargetDamage(Wn8Rating.Good);
            double damageGreat       = te.GetTargetDamage(Wn8Rating.Great);
            double damageUnicum      = te.GetTargetDamage(Wn8Rating.Unicum);

            sw.Stop();
            Log.Debug($"Target Damages em {sw.Elapsed.TotalMilliseconds:N1}ms: {damageAverage:N0}; {damageGood:N0}; {damageGreat:N0}; {damageUnicum:N0}");
        }
Beispiel #4
0
        /// <summary>
        /// Calculate performance metrics on the player
        /// </summary>
        /// <param name="wn8ExpectedValues"></param>
        public void CalculatePerformance(Wn8ExpectedValues wn8ExpectedValues)
        {
            if (Tanks.Length == 0)
            {
                return;
            }

            // Only tanks that I know about
            Tanks = Tanks.Where(t => wn8ExpectedValues.Exists(t.TankId) && t.All.Battles > 0).ToArray();

            if (Tanks.Length == 0)
            {
                return;
            }

            Battles = Tanks.Sum(t => t.All.Battles);
            WinRate = Tanks.Sum(t => t.All.Wins) * 1.0 / Battles;
            AvgTier = Tanks.Sum(t => wn8ExpectedValues[t.TankId].Tier * t.All.Battles) * 1.0 / Battles;
            Wn8     = wn8ExpectedValues.CalculateWn8(Tanks.ToDictionary(t => t.TankId, t => (TankPlayerWn8Statistics)t.All));

            Tier10Tanks = Tanks.Where(t => wn8ExpectedValues[t.TankId].Tier == 10).ToArray();

            if (Tier10Tanks.Length == 0)
            {
                return;
            }

            Tier10Battles      = Tier10Tanks.Sum(t => t.All.Battles);
            Tier10WinRate      = Tier10Tanks.Sum(t => t.All.Wins) * 1.0 / Tier10Battles;
            Tier10Wn8          = wn8ExpectedValues.CalculateWn8(Tier10Tanks.ToDictionary(t => t.TankId, t => (TankPlayerWn8Statistics)t.All));
            Tier10DirectDamage = Tier10Tanks.Sum(t => t.All.DamageDealt) * 1.0 / Tier10Battles;
        }
Beispiel #5
0
        /// <summary>
        /// Salva os valores esperados no BD, e dispara a atualização local
        /// </summary>
        public void Set(Wn8ExpectedValues ev, bool computeConsoleValues)
        {
            Log.DebugFormat("Salvando Wn8 Expected Values BD...");
            var sw = Stopwatch.StartNew();

            Execute(transaction => { Set(ev, computeConsoleValues, transaction); });
            Log.DebugFormat("Salva Wn8 Expected Values no BD em {0}.", sw.Elapsed);
        }
Beispiel #6
0
        private static void Set(Wn8ExpectedValues ev, SqlTransaction t)
        {
            DateTime now = DateTime.UtcNow;

            using (var cmd = new SqlCommand("Tanks.SetWn8ExpectedLoad", t.Connection, t))
            {
                cmd.CommandType    = CommandType.StoredProcedure;
                cmd.CommandTimeout = 5 * 60;

                cmd.Parameters.AddWithValue("@date", now.Date);
                cmd.Parameters.AddWithValue("@source", ev.Source);
                cmd.Parameters.AddWithValue("@version", ev.Version);
                cmd.Parameters.AddWithValue("@moment", now);

                cmd.ExecuteNonQuery();
            }

            using (var cmd = new SqlCommand("Tanks.SetWn8ExpectedValues", t.Connection, t))
            {
                cmd.CommandType    = CommandType.StoredProcedure;
                cmd.CommandTimeout = 5 * 60;

                foreach (var v in ev.AllTanks)
                {
                    cmd.Parameters.Clear();

                    cmd.Parameters.AddWithValue("@date", now.Date);
                    cmd.Parameters.AddWithValue("@source", ev.Source);
                    cmd.Parameters.AddWithValue("@version", ev.Version);
                    cmd.Parameters.AddWithValue("@tankId", v.TankId);
                    cmd.Parameters.AddWithValue("@def", v.Def);
                    cmd.Parameters.AddWithValue("@frag", v.Frag);
                    cmd.Parameters.AddWithValue("@spot", v.Spot);
                    cmd.Parameters.AddWithValue("@damage", v.Damage);
                    cmd.Parameters.AddWithValue("@winRate", v.WinRate);

                    cmd.ExecuteNonQuery();
                }
            }

            // Dispara o completamento da tabela
            using (var cmd = new SqlCommand("Tanks.CompleteWn8Expected", t.Connection, t))
            {
                cmd.CommandType    = CommandType.StoredProcedure;
                cmd.CommandTimeout = 5 * 60;

                cmd.ExecuteNonQuery();
            }
        }
Beispiel #7
0
        private void PruneTanks(Wn8ExpectedValues wn8ExpectedValues)
        {
            void CompleteOnDictionary(IDictionary <long, TankPlayerStatistics> dic)
            {
                foreach (var kv in dic)
                {
                    var t = wn8ExpectedValues[kv.Key];
                    if (t == null)
                    {
                        continue;
                    }

                    kv.Value.Platform  = t.Platform;
                    kv.Value.TankId    = t.TankId;
                    kv.Value.Name      = t.Name;
                    kv.Value.Tag       = t.Tag;
                    kv.Value.Tier      = t.Tier;
                    kv.Value.Type      = t.Type;
                    kv.Value.Nation    = t.Nation;
                    kv.Value.IsPremium = t.IsPremium;
                }
            }

            CompleteOnDictionary(Performance.All);
            CompleteOnDictionary(Performance.Month);
            CompleteOnDictionary(Performance.Week);

            void CleanIncompleteTanks(IDictionary <long, TankPlayerStatistics> dic)
            {
                var toRemove = new HashSet <long>();

                foreach (var kv in dic)
                {
                    if (kv.Value.TankId == 0)
                    {
                        toRemove.Add(kv.Key);
                    }
                }

                foreach (var tankId in toRemove)
                {
                    dic.Remove(tankId);
                }
            }

            CleanIncompleteTanks(Performance.All);
            CleanIncompleteTanks(Performance.Month);
            CleanIncompleteTanks(Performance.Week);
        }
Beispiel #8
0
        private static void RetrievePlayer(Player player, Fetcher fetcher,
                                           DbProvider provider, DbRecorder recorder, IReadOnlyDictionary <long, Tank> allTanks,
                                           Wn8ExpectedValues wn8Expected, Putter putter)
        {
            var tanks      = fetcher.GetTanksForPlayer(player.Plataform, player.Id);
            var validTanks = tanks.Where(t => allTanks.ContainsKey(t.TankId)).ToArray();

            recorder.Set(validTanks);

            var played = provider.GetWn8RawStatsForPlayer(player.Plataform, player.Id);

            player.Performance = played;
            player.Calculate(wn8Expected);
            player.Moment = DateTime.UtcNow;
            player.Origin = PlayerDataOrigin.Self;

            var previous = provider.GetPlayer(player.Id, player.Date, true);

            if (previous != null)
            {
                if (player.Check(previous, true))
                {
                    Log.Warn($"Player {player.Name}.{player.Id}@{player.Plataform} was patched.");
                }
            }

            if (player.CanSave())
            {
                recorder.Set(player);
                if (!player.IsPatched)
                {
                    _ = Task.Run(() =>
                    {
                        try
                        {
                            putter?.Put(player);
                        }
                        catch (Exception ex)
                        {
                            Log.Error($"Error putting player {player.Id} on the remote site.", ex);
                        }
                    });
                }
            }
            else
            {
                Log.Warn($"Player {player.Name}.{player.Id}@{player.Plataform} has to much zero data.");
            }
        }
Beispiel #9
0
        /// <summary>
        ///     Exporta o WN8 esperado
        /// </summary>
        public static void CalculateWn8Expected()
        {
            string     connectionString = ConfigurationManager.ConnectionStrings["Main"].ConnectionString;
            DbProvider provider         = new DbProvider(connectionString);

            FtpPutter putter = new FtpPutter(ConfigurationManager.AppSettings["PsFtpFolder"],
                                             ConfigurationManager.AppSettings["PsFtpUser"],
                                             ConfigurationManager.AppSettings["PsFtpPassworld"]);

            string resultDirectory = ConfigurationManager.AppSettings["PsResultDirectory"];

            Wn8ExpectedValues wn8 = provider.GetWn8ExpectedValues(Platform.PS);

            if (wn8 != null)
            {
                string json = JsonConvert.SerializeObject(wn8, Formatting.Indented);
                string file = Path.Combine(resultDirectory, "MoE", $"{wn8.Date:yyyy-MM-dd}.WN8.json");
                File.WriteAllText(file, json, Encoding.UTF8);
                Log.DebugFormat("Salvo o WN8 Expected em '{0}'", file);

                putter.PutMoe(file);
                Log.Debug("Feito uploado do WN8");
            }
        }
Beispiel #10
0
        private static void Set(Wn8ExpectedValues ev, bool computeConsoleValues, SqlTransaction t)
        {
            var now = DateTime.UtcNow;

            using (var cmd = new SqlCommand("Tanks.SetWn8ExpectedLoad", t.Connection, t))
            {
                cmd.CommandType    = CommandType.StoredProcedure;
                cmd.CommandTimeout = 5 * 60;

                cmd.Parameters.AddWithValue("@date", now.Date);
                cmd.Parameters.AddWithValue("@source", ev.Source);
                cmd.Parameters.AddWithValue("@version", ev.Version);
                cmd.Parameters.AddWithValue("@moment", now);

                cmd.ExecuteNonQuery();
            }

            var setProcedure = ev.Source switch
            {
                Wn8ExpectedValuesSources.Xvm => "Tanks.[SetWn8PcExpectedValues]",
                Wn8ExpectedValuesSources.WotcStat => "Tanks.[SetWn8ConsoleExpectedValues]",
                _ => throw new ArgumentOutOfRangeException(nameof(ev.Source), ev.Source, @"Source not supported"),
            };

            using (var cmd = new SqlCommand(setProcedure, t.Connection, t))
            {
                cmd.CommandType    = CommandType.StoredProcedure;
                cmd.CommandTimeout = 5 * 60;

                foreach (var v in ev.AllTanks)
                {
                    cmd.Parameters.Clear();

                    cmd.Parameters.AddWithValue("@date", now.Date);
                    cmd.Parameters.AddWithValue("@source", ev.Source);
                    cmd.Parameters.AddWithValue("@version", ev.Version);
                    cmd.Parameters.AddWithValue("@tankId", v.TankId);
                    cmd.Parameters.AddWithValue("@def", v.Def);
                    cmd.Parameters.AddWithValue("@frag", v.Frag);
                    cmd.Parameters.AddWithValue("@spot", v.Spot);
                    cmd.Parameters.AddWithValue("@damage", v.Damage);
                    cmd.Parameters.AddWithValue("@winRate", v.WinRate);

                    cmd.ExecuteNonQuery();
                }
            }

            if (computeConsoleValues)
            {
                var computeProcedure = ev.Source switch
                {
                    Wn8ExpectedValuesSources.Xvm => "Tanks.[CalculateWn8ConsoleExpectedFromXvm]",
                    Wn8ExpectedValuesSources.WotcStat => string.Empty, // no need to compute anything
                    _ => throw new ArgumentOutOfRangeException(nameof(ev.Source), ev.Source, @"Source not supported"),
                };

                if (!string.IsNullOrWhiteSpace(computeProcedure))
                {
                    using var cmd      = new SqlCommand(computeProcedure, t.Connection, t);
                    cmd.CommandType    = CommandType.StoredProcedure;
                    cmd.CommandTimeout = 5 * 60;

                    cmd.ExecuteNonQuery();
                }
            }
        }
Beispiel #11
0
        private static void RetrievePlayer(Player player, Fetcher fetcher, Fetcher externalFetcher,
                                           DbProvider provider, DbRecorder recorder, IReadOnlyDictionary <long, Tank> allTanks, Wn8ExpectedValues wn8Expected, Putter putter)
        {
            Task <Player> externalTask = null;

            if (externalFetcher != null)
            {
                externalTask = externalFetcher.GetPlayerWn8Async((Player)player.Clone());
            }

            var tanks      = fetcher.GetTanksForPlayer(player.Plataform, player.Id);
            var validTanks = tanks.Where(t => allTanks.ContainsKey(t.TankId)).ToArray();

            recorder.Set(validTanks);

            var played = provider.GetWn8RawStatsForPlayer(player.Plataform, player.Id);

            player.Performance = played;
            player.Calculate(wn8Expected);
            player.Moment = DateTime.UtcNow;
            player.Origin = PlayerDataOrigin.Self;

            var previous = provider.GetPlayer(player.Id, player.Date, true);

            if (previous != null)
            {
                if (player.Check(previous, true))
                {
                    Log.Warn($"Player {player.Name}.{player.Id}@{player.Plataform} was patched.");
                }
            }

            if (player.CanSave())
            {
                recorder.Set(player);
                if (!player.IsPatched)
                {
                    putter?.Put(player);
                }
            }
            else
            {
                Log.Warn($"Player {player.Name}.{player.Id}@{player.Plataform} has to much zero data.");
            }

            // Se foi feita a chamada na API externa, espero o retorno, que será ignorado; mas serviu para popular o BD do parceiro.
            externalTask?.Wait();
        }
Beispiel #12
0
 public TanksWn8(Wn8ExpectedValues ev)
 {
     _ev   = ev;
     Tanks = ev.AllTanks.OrderByDescending(t => t.Tier).ThenBy(t => t.Type)
             .ThenBy(t => t.Nation).ThenBy(t => t.Nation).ToArray();
 }