public void UpdateCardBaseDefinitionsAsync() { if (UpdateCardBaseDefinitionsBGW.IsBusy) { throw new Exception("Can't call to UpdateCardBaseDefinitions until the previous execution finishes"); } var argument = new UpdateCardBaseDefinitionsArgument (this, DatabaseManagerInstance, InMemoryManagerInstance, ImageDownloaderInstance, ServerQueriesManagerInstance); UpdateCardBaseDefinitionsBGW.RunWorkerAsync(argument); }
private static void UpdateCardBaseDefinitions_DoWork(object sender, DoWorkEventArgs e) { BackgroundWorker worker = (BackgroundWorker)sender; Debug.Assert(e.Argument != null); UpdateCardBaseDefinitionsArgument managers = (UpdateCardBaseDefinitionsArgument)e.Argument; worker.ReportProgress(0, "Connecting to server..."); // This process will set the locale to English. Here we take the previous value to restore it at the end. string userLocale = managers.ServerQueriesManager.GetUserLocale(); var existingIds = managers.ServerQueriesManager.GetAllCardBaseIds(); var storedIds = managers.DatabaseManager.GetAllCardBaseIds(); var idsToAnalyze = existingIds.Except(storedIds).ToList(); idsToAnalyze.Sort(); /* There are 3 API calls to get characters details: * - characters.getCharacters (labeled "oldGetCharacters") * - characters.getCharacterLevels * - urc.getCharacters (labeled "newGetCharacters") * Some details can be obtained from various of those calls, some only from one of them. * "newGetCharacters" is the fastest one, so we will get most of the details from that one, and the rest from "oldGetCharacters". * "getCharacterLevels" will not be used, all the details that we can obtain from it we can get it from the "new" one too. */ var request = new ApiRequest(); var setLocaleToEnglishCall = new ApiCallList.Players.SetLanguages(new List <string> { ServerQueriesManager.EnglishLocale }); request.EnqueueApiCall(setLocaleToEnglishCall); var oldGetCharactersCall = new ApiCallList.Characters.GetCharacters { // This call is painfully slow, so we optimize it as much as we can, asking only for the info we need charactersIDs = new List <int>(idsToAnalyze), maxLevels = true, ItemsFilter = new List <string>() { "id", "level_min", "level_max", "ability", "ability_unlock_level", "release_date" } }; request.EnqueueApiCall(oldGetCharactersCall); var newGetCharactersCall = new ApiCallList.Urc.GetCharacters(); request.EnqueueApiCall(newGetCharactersCall); string response; HttpStatusCode statusCode = managers.GlobalManager.ApiManagerInstance.SendRequest(request, out response); if (statusCode != HttpStatusCode.OK) { throw new Exception("GetCardBase SendRequest returned: " + statusCode.ToString()); // TODO: Manage timeouts gracefully (GatewayTimeout) } dynamic decoded = JsonDecoder.Decode(response); int progress = 0; var oldData = SortServerCharacterDataIntoDictionary(oldGetCharactersCall.Call, decoded); var newData = SortServerCharacterDataIntoDictionary(newGetCharactersCall.Call, decoded); foreach (int id in idsToAnalyze) { if (worker.CancellationPending == true) { e.Cancel = true; break; } int minLevel = int.Parse(oldData[id]["level_min"].ToString()); int maxLevel = int.Parse(oldData[id]["level_max"].ToString()); string abilityText = oldData[id]["ability"].ToString(); int abilityUnlockLevel = int.Parse(oldData[id]["ability_unlock_level"].ToString()); int timeSinceRelease = int.Parse(oldData[id]["release_date"].ToString()); string name = newData[id]["name"].ToString(); int clanId = int.Parse(newData[id]["clanID"].ToString()); string rarityText = newData[id]["rarity"].ToString(); var cardLevels = new List <CardLevel>(); foreach (dynamic levelItem in newData[id]["levels"]) { int level = int.Parse(levelItem["level"].ToString()); int power = int.Parse(levelItem["power"].ToString()); int damage = int.Parse(levelItem["damage"].ToString()); cardLevels.Add(new CardLevel(level, power, damage)); } worker.ReportProgress((int)(100 * progress / idsToAnalyze.Count()), $"[{id}] {name}"); progress++; var card = ApiToCardBaseAdapter.ToCardBase(id, name, clanId, minLevel, maxLevel, rarityText, abilityText, abilityUnlockLevel, timeSinceRelease, cardLevels); if (card == null) { continue; // TODO: Remove this line if day/night is implemented, or after 11/2018, whatever happens first } managers.DatabaseManager.StoreCardBase(card); managers.InMemoryManager.LoadToMemoryCardBase(card); managers.ImageDownloader.AddCardBaseToDownloadQueue(card, CharacterImageFormat.Color800x640); } managers.ServerQueriesManager.SetUserLocale(userLocale); worker.ReportProgress(100); }