コード例 #1
0
        private async Task <string> QueryAccessToken(BlizzardRegion region)
        {
            string url = $"https://{GetRegionString(region)}.battle.net/oauth/token?grant_type=client_credentials";

            client.DefaultRequestHeaders.Clear();
            client.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue(
                "Basic",
                Convert.ToBase64String(System.Text.Encoding.UTF8.GetBytes(this.secrets.ClientId + ":" + this.secrets.ClientSecret)));

            var response = await client.GetAsync(url);

            if (response.StatusCode != System.Net.HttpStatusCode.OK)
            {
                var exception = new HttpRequestException("Error connecting to Blizzard servers.");
                exception.Data.Add("response", response);

                throw exception;
            }

            string responseJson = await response.Content.ReadAsStringAsync();

            dynamic converted = JsonConvert.DeserializeObject(responseJson);

            return(converted["access_token"]);
        }
コード例 #2
0
        public async Task <string> Get(BlizzardRegion region, string realm, string guild)
        {
            string key = this.GetKey(region, realm, guild);

            if (this.cache.ContainsKey(key))
            {
                var expiringValue = this.cache[key];
                if (expiringValue.IsExpired)
                {
                    this.cache.Remove(key);
                }
                else
                {
                    return(this.cache[key].Data);
                }
            }
            else
            {
                var sqlCachedData = await this.dataRepo.GetCachedValueAsync(key);

                if (null != sqlCachedData)
                {
                    this.cache[key] = new ExpiringData <string>(sqlCachedData.ExpiresOn, sqlCachedData.Value);
                    return(sqlCachedData.Value);
                }
            }

            this.Refresh(region, guild, realm);

            return(null);
        }
コード例 #3
0
        public void Refresh(BlizzardRegion region, string guild, string realm)
        {
            string key = this.GetKey(region, realm, guild);

            if (this.updatingSet.Contains(key))
            {
                return;
            }

            this.updatingSet.Add(key);

            Task.Factory.StartNew(async() =>
            {
                using (IDataRepository dataRepo = this.serviceProvider.GetService <IDataRepository>())
                {
                    await dataRepo.SetCachedValueAsync("test_key", "test_value", TimeSpan.FromSeconds(10));
                }

                var guildData = await this.blizzardService.GetGuildMembersAsync(guild, realm, region);

                using (IDataRepository dataRepo = this.serviceProvider.GetService <IDataRepository>())
                {
                    await this.Add(region, realm, guild, guildData, CacheEntryDuration, dataRepo);
                }

                this.updatingSet.Remove(key);
            });
        }
コード例 #4
0
        public async Task <string> GetGuildMembersAsync(string guild, string realm, BlizzardRegion region)
        {
            var    regionString = GetRegionString(region);
            var    ns           = $"dynamic-{regionString}";
            string url          = $"https://{regionString}.api.blizzard.com/wow/guild/{FormatRealmName(realm)}/{FormatGuildName(guild)}?namespace={ns}&locale={DefaultLocale}&access_token={{0}}&fields=members";

            return(await this.DoBlizzardGet(url, region));
        }
コード例 #5
0
        public async Task <string> GetPlayerPetsAsync(string player, string realm, BlizzardRegion region)
        {
            var    regionString = GetRegionString(region);
            var    ns           = $"dynamic-{regionString}";
            string url          = $"https://{regionString}.api.blizzard.com/wow/character/{FormatRealmName(realm)}/{player}?namespace={ns}&locale={DefaultLocale}&access_token={{0}}&fields=pets";

            return(await DoBlizzardGet(url, region));
        }
コード例 #6
0
        public async Task <RaiderIoStatsResponse> GetRaiderIoStats(string region, string guild, string realm)
        {
            guild = BlizzardService.FormatGuildName(guild);
            realm = BlizzardService.FormatRealmName(realm);
            BlizzardRegion regionEnum = BlizzardService.GetRegionFromString(region);

            return(await this.GetRaiderIoResponse(regionEnum, realm, guild));
        }
コード例 #7
0
        private async Task Add(BlizzardRegion region, string realm, string guild, string value, TimeSpan duration, IDataRepository repo)
        {
            string key = this.GetKey(region, realm, guild);

            this.cache[key] = new ExpiringData <string>(DateTime.Now + duration, value);

            await repo.SetCachedValueAsync(key, value, duration);
        }
コード例 #8
0
        public async Task <string> GetRealmsByRegionAsync(BlizzardRegion region)
        {
            var    regionString = GetRegionString(region);
            var    ns           = $"dynamic-{regionString}";
            string url          = $"https://{regionString}.api.blizzard.com/data/wow/realm/index?namespace={ns}&locale={DefaultLocale}&access_token={{0}}";

            return(await DoBlizzardGet(url, region));
        }
コード例 #9
0
        public CommandLineArguments(IReadOnlyList <string> args)
        {
            if (args == null || args.Count == 0)
            {
                return;
            }

            var commandArg = args[0].Trim();

            if (!Enum.TryParse(commandArg, true, out Command command))
            {
                Console.WriteLine($"Unknown command: ${commandArg}");
                return;
            }

            Command = command;

            foreach (var arg in args)
            {
                switch (arg.Trim().ToLowerInvariant().TrimStart('-', '/'))
                {
                case "cn":
                    Region = BlizzardRegion.China;
                    break;

                case "us":
                    Region = BlizzardRegion.NorthAmerica;
                    break;

                case "eu":
                    Region = BlizzardRegion.Europe;
                    break;

                case "kr":
                    Region = BlizzardRegion.Korea;
                    break;

                case "tw":
                    Region = BlizzardRegion.Taiwan;
                    break;
                }
            }

            switch (Command)
            {
            case Command.None:
                break;

            case Command.Player:
                var playerQualifier = args[1].Split("-");
                Realm     = playerQualifier[0];
                Character = playerQualifier[1];
                break;

            default:
                break;
            }
        }
コード例 #10
0
        public async Task <string> GetMythicPlusDungeonData(BlizzardRegion region, string playerName, string realm)
        {
            string url = $"https://raider.io/api/v1/characters/profile?region={region.ToString().ToLower()}&"
                         + $"realm={BlizzardService.FormatRealmName(realm)}&name={playerName}&fields=mythic_plus_scores";

            var result = await this.throttler.Throttle(async() => { return(await client.GetAsync(url)); });

            return(await result.Content.ReadAsStringAsync());
        }
コード例 #11
0
        private string GetKey(BlizzardRegion region, string realm, string guild)
        {
            var regionKey = Keyifier.GetRegionKey(BlizzardUtilities.GetEfRegionFromBlizzardRegion(region));
            var realmKey  = Keyifier.GetRealmKey(realm);
            var guildKey  = Keyifier.GetGuildKey(guild);

            return(Keyifier.GetKey("raider_io_stats", new List <string> {
                regionKey, realmKey, guildKey
            }));
        }
コード例 #12
0
        public async Task <string> GetRealmAsync(string realmName, BlizzardRegion region)
        {
            var realmSlug    = BuildRealmSlug(realmName);
            var regionString = GetRegionString(region);
            var ns           = $"dynamic-{regionString}";

            var url = $"https://{regionString}.api.blizzard.com/data/wow/realm/{realmSlug}?namespace={ns}&locale={DefaultLocale}&access_token={{0}}";

            return(await DoBlizzardGet(url, region));
        }
コード例 #13
0
        public async Task <Realm> GetRealmAsync(string realmName, BlizzardRegion region)
        {
            var result = await this.blizzardService.GetRealmAsync(realmName, region);

            if (BlizzardService.DidGetFail(result))
            {
                return(null);
            }

            return(RealmParsing.GetSingleRealm(result));
        }
コード例 #14
0
        public static string GetRegionString(BlizzardRegion region)
        {
            switch (region)
            {
            case BlizzardRegion.EU:
                return("eu");

            case BlizzardRegion.US:
            default:
                return("us");
            }
        }
コード例 #15
0
 public static GameRegionEnum GetEfRegionFromBlizzardRegion(BlizzardRegion blizzardRegion)
 {
     if (blizzardRegion == BlizzardRegion.EU)
     {
         return(GameRegionEnum.EU);
     }
     else if (blizzardRegion == BlizzardRegion.US)
     {
         return(GameRegionEnum.US);
     }
     throw new ArgumentException("Unrecognized Blizzard region.");
 }
コード例 #16
0
        public async Task <GuildSlim> GetGuild(BlizzardRegion region, string realmName, string guildName)
        {
            guildName = BlizzardService.FormatGuildName(guildName);
            realmName = BlizzardService.FormatRealmName(realmName);

            var result = await this.blizzardService.GetGuildAsync(guildName, realmName, region);

            if (BlizzardService.DidGetFail(result))
            {
                return(null);
            }

            return(GuildParsing.GetGuild(result));
        }
コード例 #17
0
        public async Task RequestStatsCompleteNotification([FromBody] RequestStatsCompleteNotification input)
        {
            input.Guild = BlizzardService.FormatGuildName(input.Guild);
            input.Realm = BlizzardService.FormatRealmName(input.Realm);
            BlizzardRegion regionEnum = BlizzardService.GetRegionFromString(input.Region);

            if (!RegexUtilities.IsValidEmail(input.Email))
            {
                throw new UserReportableError("Email is not in a valid format.", (int)HttpStatusCode.BadRequest);
            }

            var key = this.guildStatsRetriever.GetKey(regionEnum, input.Realm, input.Guild);

            await this.dataRepo.AddNotification(input.Email, key, (NotificationRequestTypeEnum)input.RequestType);
        }
コード例 #18
0
        public static string GetRegionHostname(BlizzardRegion region)
        {
            switch (region)
            {
            case BlizzardRegion.NorthAmerica:
            case BlizzardRegion.Europe:
            case BlizzardRegion.Korea:
            case BlizzardRegion.Taiwan:
                return(GetRegionCode(region) + ".api.blizzard.com");

            case BlizzardRegion.China:
                return("gateway.battlenet.com.cn");

            default:
                throw new ArgumentOutOfRangeException(nameof(region), region, null);
            }
        }
コード例 #19
0
        public async Task <IEnumerable <RaiderIoStats> > GetGuildRaiderIoStats(BlizzardRegion region, string guild, string realm, IProgress <double> progress)
        {
            var guildDataJson = await this.blizzardService.GetGuildMembersAsync(guild, realm, region);

            var members = GuildMemberParsing.GetSlimPlayersFromGuildPlayerList(guildDataJson).ToList();

            int totalCount = members.Count();
            int count      = 0;

            var taskList = new List <Task <RaiderIoStats> >();

            foreach (var member in members)
            {
                taskList.Add(Task.Run(async() =>
                {
                    try
                    {
                        var result = await this.GetRaiderIoStatsAsync(member, region);

                        if (result != null)
                        {
                            result.RegionName = BlizzardService.GetRegionString(region);
                            result.GuildName  = guild;
                        }

                        return(result);
                    }
                    catch (Exception e)
                    {
                        return(null);
                    }
                    finally
                    {
                        progress.Report((double)count++ / totalCount);
                    }
                }));
            }

            await Task.WhenAll(taskList);

            var allRaiderIoStats = taskList.Select(x => x.Result).Where(x => x != null);

            return(allRaiderIoStats);
        }
コード例 #20
0
        public async Task <IEnumerable <GuildMemberStats> > GetAsync(BlizzardRegion region, string realm, string guild)
        {
            string key = this.GetKey(realm, guild);

            if (this.cache.ContainsKey(key))
            {
                var expiringValue = this.cache[key];
                if (expiringValue.IsExpired)
                {
                    this.cache.Remove(key);
                }
                else
                {
                    return(this.cache[key].Data);
                }
            }
            else
            {
                var sqlCachedData = await this.dataRepository.GetCachedValueAsync(key);

                if (null != sqlCachedData)
                {
                    var deserializedData = JsonConvert.DeserializeObject <IEnumerable <GuildMemberStats> >(sqlCachedData.Value);
                    this.cache[key] = new ExpiringData <IEnumerable <GuildMemberStats> >(sqlCachedData.ExpiresOn, deserializedData);
                    return(deserializedData);
                }
            }

            if (!this.updatingSet.Contains(key))
            {
                this.backgroundTaskQueue.QueueBackgroundWorkItem(
                    new BackgroundWorkItem()
                {
                    Key    = key,
                    Worker = async(token, serviceProvider) =>
                    {
                        await this.Refresh(region, guild, realm, serviceProvider);
                    }
                });
            }

            return(null);
        }
コード例 #21
0
        public static Uri GetUrl(BlizzardRegion region, string relativeUrl, BlizzardLocaleFlags locale = BlizzardLocaleFlags.EnglishUS, BlizzardNamespace ns = BlizzardNamespace.Dynamic)
        {
            var host    = GetRegionHostname(region);
            var builder = new UriBuilder("https", host, -1, relativeUrl);

            if (builder.Query.Length > 0)
            {
                builder.Query += "&";
            }

            builder.Query += "namespace=" + GetNamespaceString(ns, region);

            if (locale != BlizzardLocaleFlags.All && locale != BlizzardLocaleFlags.AllWowLocales)
            {
                builder.Query += "&locale=" + GetLocaleString(locale);
            }

            return(builder.Uri);
        }
コード例 #22
0
        public async Task <BlizzardPlayer> GetSinglePlayerAsync(BlizzardRegion region, string realmName, string playerName)
        {
            var playerJson = await this.blizzardService.GetPlayerAsync(playerName, realmName, region);

            if (BlizzardService.DidGetFail(playerJson))
            {
                return(null);
            }

            var player = PlayerParsing.GetSinglePlayerFromJson(playerJson);

            return(new BlizzardPlayer()
            {
                PlayerName = player.Name,
                Class = player.Class,
                Level = player.Level,
                GuildName = player.GuildName,
                GuildRealm = player.GuildRealm,
                PlayerRealmName = player.Realm
            });
        }
コード例 #23
0
        private Func <Func <CancellationToken, IServiceProvider, Task <IEnumerable <RaiderIoStats> > >, Task> taskRunner(
            string key, BlizzardRegion region, string realm, string guild)
        {
            return(async(runner) =>
            {
                this.taskQueue.QueueBackgroundWorkItem(new BackgroundWorkItem()
                {
                    Key = key,
                    Worker = async(token, serviceProvider) =>
                    {
                        await runner(token, serviceProvider);

                        await this.SendStatsCompleteNotifications(serviceProvider, key, region, realm, guild);
                    },
                    TaskFailed = async() =>
                    {
                        await this.longRunningCache.RemoveCacheItem(key);
                    }
                });
            });
        }
コード例 #24
0
        public async Task Refresh(BlizzardRegion region, string guild, string realm, IServiceProvider serviceProvider)
        {
            string key = this.GetKey(realm, guild);

            if (this.updatingSet.Contains(key))
            {
                return;
            }

            this.updatingSet.Add(key);

            var guildPlayers = await this.guildMemberService.GetLargeGuildMembersDataAsync(region, guild, realm, new Progress <double>());

            using (var serviceScope = serviceProvider.CreateScope())
            {
                var repo = serviceScope.ServiceProvider.GetService <IDataRepository>();

                await this.AddAsync(realm, guild, guildPlayers, CacheEntryDuration, repo);
            }

            this.updatingSet.Remove(key);
        }
コード例 #25
0
        public static string GetRegionCode(BlizzardRegion region)
        {
            switch (region)
            {
            case BlizzardRegion.NorthAmerica:
                return("us");

            case BlizzardRegion.Europe:
                return("eu");

            case BlizzardRegion.Korea:
                return("kr");

            case BlizzardRegion.Taiwan:
                return("tw");

            case BlizzardRegion.China:
                return("cn");

            default:
                throw new ArgumentOutOfRangeException(nameof(region), region, null);
            }
        }
コード例 #26
0
        private async Task <RaiderIoStatsResponse> GetRaiderIoResponse(BlizzardRegion regionEnum, string realm, string guild)
        {
            var guildData = await this.raiderIoStatsRetriever.GetCachedEntry(regionEnum, realm, guild);

            if (guildData.State == CachedValueState.Updating)
            {
                var positionInQueue = this.guildStatsRetriever.GetPositionInQueue(regionEnum, realm, guild);

                return(new RaiderIoStatsResponse()
                {
                    IsCompleted = false,
                    PositionInQueue = positionInQueue,
                    CompletionProgress = guildData.CompletionProgress
                });
            }
            else
            {
                return(new RaiderIoStatsResponse()
                {
                    IsCompleted = true,
                    Values = guildData.Value
                });
            }
        }
コード例 #27
0
        // Note: url must be pre-formatted with region!
        private async Task <string> DoBlizzardGet(string url, BlizzardRegion region)
        {
            if (string.IsNullOrEmpty(this.regionAccessTokens[region]))
            {
                this.regionAccessTokens[region] = await this.QueryAccessToken(region);

                await this.dataRepo.CreateOrUpdateStoredValueAsync(this.AccessTokenCacheKeys[region], this.regionAccessTokens[region]);
            }

            client.DefaultRequestHeaders.Clear();

            HttpResponseMessage response;

            response = await client.GetAsync(string.Format(url, this.regionAccessTokens[region]));

            if (response.StatusCode == System.Net.HttpStatusCode.Unauthorized)
            {
                this.regionAccessTokens[region] = await this.QueryAccessToken(region);

                await this.dataRepo.CreateOrUpdateStoredValueAsync(this.AccessTokenCacheKeys[region], this.regionAccessTokens[region]);

                response = await client.GetAsync(string.Format(url, this.regionAccessTokens[region]));

                if (response.StatusCode != System.Net.HttpStatusCode.OK)
                {
                    var exception = new HttpRequestException("Error connecting to Blizzard servers.");
                    exception.Data.Add("response", response);

                    throw exception;
                }
            }

            var jsonResponse = await response.Content.ReadAsStringAsync();

            return(jsonResponse);
        }
コード例 #28
0
        public async Task <CacheEntry <IEnumerable <RaiderIoStats> > > GetCachedEntry(BlizzardRegion region, string realm, string guild)
        {
            string key = this.GetKey(region, realm, guild);

            return(await this.longRunningCache.GetOrRefreshCachedValueAsync(
                       key,
                       this.taskRunner(key, region, realm, guild),
                       this.valueGetter(region, realm, guild)));
        }
コード例 #29
0
        private async Task SendStatsCompleteNotifications(IServiceProvider serviceProvider, string key, BlizzardRegion region, string realm, string guild)
        {
            using (var serviceScope = serviceProvider.CreateScope())
            {
                var repo = serviceScope.ServiceProvider.GetService <IDataRepository>();

                var notifications = await repo.GetAndClearNotifications(NotificationRequestTypeEnum.RaiderIoStatsRequestComplete, key);

                string url = $"raideriostats/{region.ToString()}/{BlizzardService.FormatGuildName(guild)}/{BlizzardService.FormatRealmName(realm)}";

                List <Task> mailTasks = new List <Task>();

                var generatedEmail = this.mailGenerator.GenerateStatsCompleteEmail(url);

                foreach (var notification in notifications)
                {
                    mailTasks.Add(this.mailSender.SendMailAsync(
                                      notification.Email,
                                      this.commonValues.AdminEmail,
                                      generatedEmail.Subject,
                                      generatedEmail.TextContent,
                                      generatedEmail.HtmlContent));
                }

                await Task.WhenAll(mailTasks);
            }
        }
コード例 #30
0
        string IRaiderIoStatsRetriever.GetKey(BlizzardRegion region, string realm, string guild)
        {
            string key = this.GetKey(region, realm, guild);

            return(key);
        }