Exemple #1
0
        private async Task <ActionResult> UpdateFractionStatistics()
        {
            if (!await CheckIp())
            {
                return(Json(new NoPermissionFailure()));
            }
            try
            {
                var strategy = _db.Database.CreateExecutionStrategy();
                await strategy.ExecuteAsync(async() =>
                {
                    using var transaction = await _db.Database.BeginTransactionAsync();
                    await UpdateFractionStatistics_Internal();
                    await _db.SaveChangesAsync();
                    lock (_dbLock)
                    {
                        transaction.Commit();
                    }
                });

                LoggingUtil.Log("Fraction statistics have been updated.");
                return(Json(new { success = true }));
            }
            catch (Exception e)
            {
                LoggingUtil.Error("Failed to compute fraction statistics");
                LoggingUtil.Error(e.StackTrace);
                return(Json(new { success = false }));
            }
        }
Exemple #2
0
        public async Task <string> LogToFile <T>(string folder, IDictionary <string, T> toLog)
        {
            var now = DateTime.UtcNow;
            var dir = Path.Combine(_logFolder, folder);

            if (!Directory.Exists(dir))
            {
                Directory.CreateDirectory(dir);
            }
            var fileName = $"{now:yyyy_MM_dd__HH_mm_ss_ff}.log";
            var filePath = Path.Combine(dir, fileName);

            if (File.Exists(filePath))
            {
                LoggingUtil.Error($"Log {filePath} already exists!");
                return(null);
            }
            var fileContent = new StringBuilder();

            foreach (var(key, value) in toLog)
            {
                fileContent.Append($"{key}:{value}\n\n");
            }
            await File.WriteAllTextAsync(filePath, fileContent.ToString());

            return(filePath);
        }
Exemple #3
0
        private async Task <ActionResult> UpdateAbilityData(string data)
        {
            if (string.IsNullOrWhiteSpace(data))
            {
                return(Json(new MissingArgumentFailure()));
            }
            if (!data.TryToJson(out JsonDocument parsedAbilityData))
            {
                return(Json(new InvalidRequestFailure()));
            }
            var abilityData = parsedAbilityData.RootElement;

            try
            {
                var strategy = _db.Database.CreateExecutionStrategy();
                await strategy.ExecuteAsync(async() =>
                {
                    using var transaction = await _db.Database.BeginTransactionAsync();
                    var properties        = abilityData.EnumerateObject().Where(p => !string.IsNullOrWhiteSpace(p.Name));
                    var abilities         = await _db.GetOrCreateAsync(properties.Select(p => p.Name), a => a.Name, CreateAbility);
                    foreach (var(values, ability) in properties.Select(p => p.Value).Zip(abilities))
                    {
                        ability.UpdateValues(values);
                    }
                    await _db.SaveChangesAsync();
                    lock (_dbLock)
                    {
                        transaction.Commit();
                    }
                });

                return(Json(new { Success = true }));
            }
            catch (Exception e)
            {
                LoggingUtil.Error("Updating ability data failed");
                LoggingUtil.Error(e.ToString());
                await _fileLogger.LogToFile("update_ability_data", new Dictionary <string, object> {
                    { "exception", e.ToString() },
                    { "errorSource", e.Source },
                    { "targetSite", e.TargetSite }
                });

                return(Json(new { Success = false }));
            }
        }
Exemple #4
0
 private async Task <ActionResult> UpdateRankings()
 {
     if (!await CheckIp())
     {
         return(Json(new NoPermissionFailure()));
     }
     try
     {
         await UpdateRanking(RankingTypes.Rating, false);
     }
     catch (Exception e)
     {
         LoggingUtil.Error("Failed to update ranking");
         LoggingUtil.Error(e.StackTrace);
         return(Json(new { success = false }));
     }
     return(Json(new { success = true }));
 }
Exemple #5
0
        private async Task <ActionResult> UpdateUnitData(string dataString, string type = "unit")
        {
            if (string.IsNullOrWhiteSpace(dataString))
            {
                return(Json(new MissingArgumentFailure()));
            }
            if (!dataString.TryToJson(out JsonDocument parsedUnitData))
            {
                return(Json(new InvalidRequestFailure()));
            }
            var unitData = parsedUnitData.RootElement;

            try
            {
                var strategy = _db.Database.CreateExecutionStrategy();
                await strategy.ExecuteAsync(async() =>
                {
                    using var transaction = await _db.Database.BeginTransactionAsync();
                    var properties        = unitData.EnumerateObject().Where(p => !string.IsNullOrWhiteSpace(p.Name));
                    var unitNames         = properties.Select(p => p.Name);
                    var units             = await _db.GetOrCreateAsync(unitNames, u => u.Name, name => CreateUnitOrBuilder(name, type));
                    foreach (var(data, unit) in properties.Select(p => p.Value).Zip(units))
                    {
                        unit.UpdateValues(data);
                    }
                    await _db.SaveChangesAsync();

                    // Remove all old links between abilities and units
                    var sqlUnitNames  = string.Join(", ", unitNames.Select(u => $"'{u}'"));
                    var usedAbilities = new List <string>();
                    await _db.Database.ExecuteSqlRawAsync($"DELETE FROM UnitAbilities WHERE UnitName IN ({sqlUnitNames})");
                    foreach (var unitObject in unitData.EnumerateObject())
                    {
                        for (int i = 1; i <= 24; i++)
                        {
                            string abilityName = unitObject.Value.GetValueOrDefault($"Ability{i}");
                            if (!string.IsNullOrWhiteSpace(abilityName))
                            {
                                var newAbility = new UnitAbility
                                {
                                    UnitName    = unitObject.Name,
                                    AbilityName = abilityName,
                                    Slot        = i
                                };
                                _db.UnitAbilities.Add(newAbility);
                                usedAbilities.Add(abilityName);
                            }
                        }
                    }
                    if (usedAbilities.Count > 0)
                    {
                        await _db.GetOrCreateAsync(usedAbilities, a => a.Name, CreateAbility);
                    }
                    await _db.SaveChangesAsync();
                    lock (_dbLock)
                    {
                        transaction.Commit();
                    }
                });

                return(Json(new { Success = true }));
            }
            catch (Exception e)
            {
                LoggingUtil.Error($"Updating {type} data failed");
                await _fileLogger.LogToFile($"update_{type}_data", new Dictionary <string, object> {
                    { "exception", e.ToString() },
                    { "errorSource", e.Source },
                    { "targetSite", e.TargetSite }
                });

                return(Json(new { Success = false }));
            }
        }
Exemple #6
0
        private async Task UpdateRanking(RankingTypes type, bool asc)
        {
            string key = type + "|" + asc;

            _cache.Set(key, true, DateTime.UtcNow.AddDays(1));
            var oldTimeout = _db.Database.GetCommandTimeout();

            _db.Database.SetCommandTimeout(TimeSpan.FromHours(1));
            try
            {
                var strategy = _db.Database.CreateExecutionStrategy();
                await strategy.ExecuteAsync(async() =>
                {
                    using var transcation = await _db.Database.BeginTransactionAsync();
                    await _db.Database.ExecuteSqlRawAsync($"DELETE FROM Rankings WHERE Type = {(int)type} AND Ascending = {(asc ? 1 : 0)}");
                    LoggingUtil.Log($"Cleared Ranking for {type} {asc}");
                    string sql;
                    string sqlJoins = "JOIN Matches AS m \n" +
                                      "ON m.MatchId = pm.MatchId \n";
                    string sqlWheres = "WHERE m.IsTraining = FALSE \n";
                    string sqlSelects, sqlOrderBy;
                    switch (type)
                    {
                    case RankingTypes.EarnedTangos:
                        sqlSelects = ", SUM(EarnedTangos) AS Gold \n";
                        sqlOrderBy = "ORDER BY Gold " + (asc ? "ASC" : "DESC") + " \n";
                        break;

                    case RankingTypes.EarnedGold:
                        sqlSelects = ", SUM(EarnedGold) AS Gold \n";
                        sqlOrderBy = "ORDER BY Gold " + (asc ? "ASC" : "DESC") + " \n";
                        break;

                    case RankingTypes.Rating:
                    default:
                        sqlSelects = ", SUM(RatingChange) AS Rating \n";
                        sqlOrderBy = "ORDER BY Rating " + (asc ? "ASC" : "DESC") + " \n";
                        sqlJoins   = "";
                        sqlWheres  = "";
                        break;
                    }
                    sql = "INSERT INTO Rankings \n" +
                          "(Type, Ascending, PlayerId, Position) \n" +
                          $"SELECT @t := {(int)type}, @a := {(asc ? "TRUE" : "FALSE")}, PlayerId, @rownum := @rownum + 1 AS position\n" +
                          "FROM (SELECT PlayerId \n" +
                          sqlSelects +
                          "FROM PlayerMatchData AS pm \n" +
                          sqlJoins +
                          sqlWheres +
                          "GROUP BY pm.PlayerId \n" +
                          sqlOrderBy +
                          ") AS pr, \n" +
                          "(SELECT @rownum := 0) AS r \n";
                    await _db.Database.ExecuteSqlRawAsync(sql);
                    lock (_dbLock)
                    {
                        transcation.Commit();
                    }
                });

                LoggingUtil.Log("Ranking has been updated.");
            }
            catch (Exception e)
            {
                LoggingUtil.Error(e.ToString());
                LoggingUtil.Error("Failed to update ranking");
            }
            finally
            {
                _db.Database.SetCommandTimeout(oldTimeout);
            }
        }