Пример #1
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);
        }
Пример #2
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="id">Must be a valid ID</param>
        /// <exception cref="ArgumentException"></exception>
        /// <returns></returns>
        public CardBase GetCardBase(int id)
        {
            if (id <= 0)
            {
                throw new ArgumentOutOfRangeException(nameof(id), id, "Must be greater than 0");
            }

            var setEnglishLocaleCall = new ApiCallList.Players.SetLanguages(new List <string>()
            {
                EnglishLocale
            });

            var getCardBaseInfoCall = new ApiCallList.Characters.GetCharacters();

            getCardBaseInfoCall.charactersIDs = new List <int>()
            {
                id
            };
            getCardBaseInfoCall.maxLevels   = true;
            getCardBaseInfoCall.ItemsFilter = new List <string>()
            {
                "name", "clan_id", "level_min", "level_max", "rarity", "ability", "ability_unlock_level", "release_date"
            };

            var getCardLevelsCall = new ApiCallList.Characters.GetCharacterLevels(id);

            getCardLevelsCall.levelMax    = -1; // Get all the levels
            getCardLevelsCall.ItemsFilter = new List <string>()
            {
                "level", "power", "damage"
            };

            var request = new ApiRequest();

            request.EnqueueApiCall(setEnglishLocaleCall);
            request.EnqueueApiCall(getCardBaseInfoCall);
            request.EnqueueApiCall(getCardLevelsCall);

            string         response;
            HttpStatusCode statusCode = ApiManagerInstance.SendRequest(request, out response);

            if (statusCode != HttpStatusCode.OK)
            {
                throw new Exception("GetCardBase SendRequest returned: " + statusCode.ToString());
            }
            dynamic decoded = JsonDecoder.Decode(response);

            dynamic dynBaseCard;

            try
            {
                dynBaseCard = decoded[getCardBaseInfoCall.Call]["items"][0];
            }
            catch
            {
                // TODO: Log attempt to download invalid ID
                throw new ArgumentException("The id doesn't exist", nameof(id));
            }

            string name                 = dynBaseCard["name"].ToString();
            int    clan_id              = int.Parse(dynBaseCard["clan_id"].ToString());
            int    level_min            = int.Parse(dynBaseCard["level_min"].ToString());
            int    level_max            = int.Parse(dynBaseCard["level_max"].ToString());
            string rarity               = dynBaseCard["rarity"].ToString();
            string ability              = dynBaseCard["ability"].ToString();
            int    ability_unlock_level = int.Parse(dynBaseCard["ability_unlock_level"].ToString());
            int    release_date         = int.Parse(dynBaseCard["release_date"].ToString());

            var levels = new List <CardLevel>();

            foreach (dynamic item in decoded[getCardLevelsCall.Call]["items"])
            {
                int level  = int.Parse(item["level"].ToString());
                int power  = int.Parse(item["power"].ToString());
                int damage = int.Parse(item["damage"].ToString());
                levels.Add(new CardLevel(level, power, damage));
            }

            return(ApiToCardBaseAdapter.ToCardBase(id, name, clan_id, level_min, level_max, rarity, ability, ability_unlock_level, release_date, levels));
        }