Esempio n. 1
0
        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);
        }
Esempio n. 2
0
        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);
        }