diff --git a/WotBlitzStatistics.GraphQl/ObjectTypes/PlayerAccountInfoObjectType.cs b/WotBlitzStatistics.GraphQl/ObjectTypes/PlayerAccountInfoObjectType.cs new file mode 100644 index 0000000..e2bbaa1 --- /dev/null +++ b/WotBlitzStatistics.GraphQl/ObjectTypes/PlayerAccountInfoObjectType.cs @@ -0,0 +1,19 @@ +using HotChocolate.Types; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using WotBlitzStatisticsPro.Common.Model; + +namespace WotBlitzStatistics.GraphQl.ObjectTypes +{ + public class PlayerAccountInfoObjectType: ObjectType + { + protected override void Configure(IObjectTypeDescriptor descriptor) + { + base.Configure(descriptor); + // Add resolver for Clan, Tanks, Achievements + // https://hotchocolate.io/docs/schema-object-type + } + } +} diff --git a/WotBlitzStatistics.GraphQl/Program.cs b/WotBlitzStatistics.GraphQl/Program.cs new file mode 100644 index 0000000..2b58a41 --- /dev/null +++ b/WotBlitzStatistics.GraphQl/Program.cs @@ -0,0 +1,26 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Hosting; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.Hosting; +using Microsoft.Extensions.Logging; + +namespace WotBlitzStatistics.GraphQl +{ + public class Program + { + public static void Main(string[] args) + { + CreateHostBuilder(args).Build().Run(); + } + + public static IHostBuilder CreateHostBuilder(string[] args) => + Host.CreateDefaultBuilder(args) + .ConfigureWebHostDefaults(webBuilder => + { + webBuilder.UseStartup(); + }); + } +} diff --git a/WotBlitzStatistics.GraphQl/Properties/launchSettings.json b/WotBlitzStatistics.GraphQl/Properties/launchSettings.json new file mode 100644 index 0000000..82cd272 --- /dev/null +++ b/WotBlitzStatistics.GraphQl/Properties/launchSettings.json @@ -0,0 +1,30 @@ +{ + "$schema": "http://json.schemastore.org/launchsettings.json", + "iisSettings": { + "windowsAuthentication": false, + "anonymousAuthentication": true, + "iisExpress": { + "applicationUrl": "http://localhost:63522", + "sslPort": 44333 + } + }, + "profiles": { + "IIS Express": { + "commandName": "IISExpress", + "launchBrowser": true, + "launchUrl": "graphql/playground", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + }, + "WotBlitzStatistics.GraphQl": { + "commandName": "Project", + "launchBrowser": true, + "launchUrl": "graphql/playground", + "applicationUrl": "https://localhost:5001;http://localhost:5000", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + } + } +} diff --git a/WotBlitzStatistics.GraphQl/Query/WotBlitzStatisticsQuery.cs b/WotBlitzStatistics.GraphQl/Query/WotBlitzStatisticsQuery.cs new file mode 100644 index 0000000..bf85160 --- /dev/null +++ b/WotBlitzStatistics.GraphQl/Query/WotBlitzStatisticsQuery.cs @@ -0,0 +1,155 @@ +using Newtonsoft.Json; +using System.Threading.Tasks; +using WotBlitzStatisticsPro.Common.Model; +using WotBlitzStatisticsPro.WgApiClient; + +namespace WotBlitzStatistics.GraphQl.Query +{ + public class WotBlitzStatisticsQuery + { + private readonly IWargamingApiClient _wargamingApiClient; + + public WotBlitzStatisticsQuery(IWargamingApiClient wargamingApiClient) + { + _wargamingApiClient = wargamingApiClient; + } + + public async Task GetPlayerInfo(long accountId) + { + var account = await _wargamingApiClient.GetPlayerAccountInfo(accountId); + // ToDo: think abount mappers or resolvers + var accountStub = JsonConvert.DeserializeObject(AccountJson); + accountStub.AccountId = accountId; + return accountStub; + } + + + private const string AccountJson = +@" +{ + ""AccountId"": 90277267, + ""NickName"": ""Mboga [XXX_L]"", + ""AccountCreatedAt"": ""2018-01-20T11:17:35+03:00"", + ""LastBattleTime"": ""2020-02-07T20:03:34+03:00"", + ""Battles"": 10842, + ""Wn7"": 1283.4155297487303, + ""AvgTier"": 7.364785095000922, + ""Winrate"": 54.75926950747095, + ""AvgDamage"": 1266.5282235749862, + ""AvgXp"": 663.4533296439771, + ""Achievements"": [ + { + ""AchievementId"": ""medalHalonen"", + ""Section"": ""epic"", + ""Name"": ""Halonen's Medal (medalHalonen)\r\nDestroy at least 3 enemy vehicles with a tank destroyer in one battle."", + ""Image"": ""http://glossary-ru-static.gcdn.co/icons/wotb/current/achievements/medalHalonen.png"", + ""Count"": 3 + }, + { + ""AchievementId"": ""medalLehvaslaiho"", + ""Section"": ""epic"", + ""Name"": ""Lehväslaiho's Medal (medalLehvaslaiho)\r\nDestroy 2 enemy vehicles with a medium tank in one battle."", + ""Image"": ""http://glossary-ru-static.gcdn.co/icons/wotb/current/achievements/medalLehvaslaiho.png"", + ""Count"": 47 + }, + { + ""AchievementId"": ""markOfMastery"", + ""Section"": ""battle"", + ""Name"": ""Mastery badge: \nAce Tanker (markOfMastery)\r\nProve your mastery in controlling a vehicle. Earn more XP in a battle than the average highest XP of 99% of players who have fought in this vehicle for the previous 7 days."", + ""Image"": ""http://glossary-ru-static.gcdn.co/icons/wotb/current/achievements/markOfMastery.png"", + ""Count"": 73 + }, + { + ""AchievementId"": ""medalKolobanov"", + ""Section"": ""epic"", + ""Name"": ""Kolobanov's Medal (medalKolobanov)\r\nStand alone against 3 enemy vehicles and win."", + ""Image"": ""http://glossary-ru-static.gcdn.co/icons/wotb/current/achievements/medalKolobanov.png"", + ""Count"": 6 + }, + { + ""AchievementId"": ""medalLafayettePool"", + ""Section"": ""epic"", + ""Name"": ""Pool's Medal (medalLafayettePool)\r\nDestroy 6 enemy vehicles in one battle."", + ""Image"": ""http://glossary-ru-static.gcdn.co/icons/wotb/current/achievements/medalLafayettePool.png"", + ""Count"": 7 + }, + { + ""AchievementId"": ""medalOrlik"", + ""Section"": ""epic"", + ""Name"": ""Orlik's Medal (medalOrlik)\r\nDestroy at least 3 enemy vehicles with a light tank in one battle."", + ""Image"": ""http://glossary-ru-static.gcdn.co/icons/wotb/current/achievements/medalOrlik.png"", + ""Count"": 4 + }, + { + ""AchievementId"": ""medalRadleyWalters"", + ""Section"": ""epic"", + ""Name"": ""Radley-Walters's Medal (medalRadleyWalters)\r\nDestroy 5 enemy vehicles in one battle."", + ""Image"": ""http://glossary-ru-static.gcdn.co/icons/wotb/current/achievements/medalRadleyWalters.png"", + ""Count"": 33 + }, + { + ""AchievementId"": ""medalOskin"", + ""Section"": ""epic"", + ""Name"": ""Oskin's Medal (medalOskin)\r\nDestroy 3 enemy vehicles with a medium tank in one battle."", + ""Image"": ""http://glossary-ru-static.gcdn.co/icons/wotb/current/achievements/medalOskin.png"", + ""Count"": 6 + }, + { + ""AchievementId"": ""medalNikolas"", + ""Section"": ""epic"", + ""Name"": ""Nicols's Medal (medalNikolas)\r\nDestroy at least 4 enemy vehicles with a medium tank in one battle."", + ""Image"": ""http://glossary-ru-static.gcdn.co/icons/wotb/current/achievements/medalNikolas.png"", + ""Count"": 1 + } + ], + ""TopTanks"": [ + { + ""TankId"": 59905, + ""MarkOfMastery"": 4, + ""Battles"": 769, + ""WinRate"": 57.737321196358907672301690507, + ""AvgDamage"": 1378.6579973992197659297789337, + ""AvgXp"": 764.92847854356306892067620286, + ""Name"": ""T-54 first prototype"", + ""Tier"": 8, + ""TierRoman"": ""VIII"", + ""Nation"": ""ussr"", + ""Type"": ""mediumTank"", + ""IsPremium"": true, + ""PreviewImageUrl"": ""http://glossary-ru-static.gcdn.co/icons/wotb/current/uploaded/vehicles/hd_thumbnail/R112_T54_45.png"" + }, + { + ""TankId"": 13345, + ""MarkOfMastery"": 4, + ""Battles"": 662, + ""WinRate"": 55.287009063444108761329305136, + ""AvgDamage"": 1344.1555891238670694864048338, + ""AvgXp"": 776.1495468277945619335347432, + ""Name"": ""T26E4 SuperPershing"", + ""Tier"": 8, + ""TierRoman"": ""VIII"", + ""Nation"": ""usa"", + ""Type"": ""mediumTank"", + ""IsPremium"": true, + ""PreviewImageUrl"": ""http://glossary-ru-static.gcdn.co/icons/wotb/current/uploaded/vehicles/hd_thumbnail/T26_E4_SuperPershing.png"" + }, + { + ""TankId"": 9217, + ""MarkOfMastery"": 4, + ""Battles"": 439, + ""WinRate"": 55.808656036446469248291571754, + ""AvgDamage"": 1493.7220956719817767653758542, + ""AvgXp"": 737.12072892938496583143507973, + ""Name"": ""IS-6"", + ""Tier"": 8, + ""TierRoman"": ""VIII"", + ""Nation"": ""ussr"", + ""Type"": ""heavyTank"", + ""IsPremium"": true, + ""PreviewImageUrl"": ""http://glossary-ru-static.gcdn.co/icons/wotb/current/uploaded/vehicles/hd_thumbnail/Object252.png"" + } + ] +} +"; + } +} diff --git a/WotBlitzStatistics.GraphQl/Startup.cs b/WotBlitzStatistics.GraphQl/Startup.cs new file mode 100644 index 0000000..b4d6925 --- /dev/null +++ b/WotBlitzStatistics.GraphQl/Startup.cs @@ -0,0 +1,59 @@ +using HotChocolate; +using HotChocolate.AspNetCore; +using HotChocolate.AspNetCore.Voyager; +using Microsoft.AspNetCore.Builder; +using Microsoft.AspNetCore.Hosting; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.DependencyInjection; +using WotBlitzStatistics.GraphQl.Query; +using WotBlitzStatisticsPro.Common.Model; +using WotBlitzStatisticsPro.WgApiClient; + +namespace WotBlitzStatistics.GraphQl +{ + public class Startup + { + + public Startup(IConfiguration configuration) + { + Configuration = configuration; + } + + public IConfiguration Configuration { get; } + + public void ConfigureServices(IServiceCollection services) + { + var wgApiConfig = new WargamingApiSettings(); + Configuration.GetSection("WargamingApi").Bind(wgApiConfig); + + services.AddSingleton(wgApiConfig); + services.AddHttpClient(); + + // Add GraphQL Services + services.AddGraphQL(sp => SchemaBuilder.New() + .AddServices(sp) + + // Adds the authorize directive and + // enable the authorization middleware. + .AddAuthorizeDirectiveType() + + .AddQueryType() + //.AddMutationType() + //.AddSubscriptionType() + .AddType() + .AddType() + .AddType() + .AddEnumType() + .Create()); + } + + public void Configure(IApplicationBuilder app, IWebHostEnvironment env) + { + app + .UseGraphQL("/graphql") + .UsePlayground("/graphql") + .UseVoyager("/graphql") + ; + } + } +} diff --git a/WotBlitzStatistics.GraphQl/WargamingApiSettings.cs b/WotBlitzStatistics.GraphQl/WargamingApiSettings.cs new file mode 100644 index 0000000..c3e29e1 --- /dev/null +++ b/WotBlitzStatistics.GraphQl/WargamingApiSettings.cs @@ -0,0 +1,9 @@ +using WotBlitzStatisticsPro.WgApiClient; + +namespace WotBlitzStatistics.GraphQl +{ + public class WargamingApiSettings : IWargamingApiSettings + { + public string ApplicationId { get; set; } + } +} diff --git a/WotBlitzStatistics.GraphQl/WotBlitzStatistics.GraphQl.csproj b/WotBlitzStatistics.GraphQl/WotBlitzStatistics.GraphQl.csproj new file mode 100644 index 0000000..406889a --- /dev/null +++ b/WotBlitzStatistics.GraphQl/WotBlitzStatistics.GraphQl.csproj @@ -0,0 +1,21 @@ + + + + netcoreapp3.1 + + + + + + + + + + + + + + + + + diff --git a/WotBlitzStatistics.GraphQl/appsettings.Development.json b/WotBlitzStatistics.GraphQl/appsettings.Development.json new file mode 100644 index 0000000..8983e0f --- /dev/null +++ b/WotBlitzStatistics.GraphQl/appsettings.Development.json @@ -0,0 +1,9 @@ +{ + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft": "Warning", + "Microsoft.Hosting.Lifetime": "Information" + } + } +} diff --git a/WotBlitzStatistics.GraphQl/appsettings.json b/WotBlitzStatistics.GraphQl/appsettings.json new file mode 100644 index 0000000..69235aa --- /dev/null +++ b/WotBlitzStatistics.GraphQl/appsettings.json @@ -0,0 +1,14 @@ +{ + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft": "Warning", + "Microsoft.Hosting.Lifetime": "Information" + } + }, + "AllowedHosts": "*", + "WargamingApi": { + "ApplicationId": "e6bb7a6cd1b7da3ca5697f97072d2176" + + } +} diff --git a/WotBlitzStatisticsPro.Wasm/Program.cs b/WotBlitzStatisticsPro.Wasm/Program.cs index d10af18..e6ff4df 100644 --- a/WotBlitzStatisticsPro.Wasm/Program.cs +++ b/WotBlitzStatisticsPro.Wasm/Program.cs @@ -3,7 +3,7 @@ using Microsoft.AspNetCore.Blazor.Hosting; namespace WotBlitzStatisticsPro.UI.Wasm { - public class Program + public static class Program { public static void Main(string[] args) { diff --git a/WotBlitzStatisticsPro.WgApiClient/IWargamingApiClient.cs b/WotBlitzStatisticsPro.WgApiClient/IWargamingApiClient.cs new file mode 100644 index 0000000..f34658c --- /dev/null +++ b/WotBlitzStatisticsPro.WgApiClient/IWargamingApiClient.cs @@ -0,0 +1,17 @@ +using System.Collections.Generic; +using System.Threading.Tasks; +using WotBlitzStatisticsPro.WgApiClient.Model; + +namespace WotBlitzStatisticsPro.WgApiClient +{ + public interface IWargamingApiClient + { + Task> FindAccounts(string nickName, + RealmType realmType = RealmType.Ru, + RequestLanguage language = RequestLanguage.En); + + Task GetPlayerAccountInfo(long accountId, + RealmType realmType = RealmType.Ru, + RequestLanguage language = RequestLanguage.En); + } +} diff --git a/WotBlitzStatisticsPro.WgApiClient/IWargamingApiSettings.cs b/WotBlitzStatisticsPro.WgApiClient/IWargamingApiSettings.cs new file mode 100644 index 0000000..99579c4 --- /dev/null +++ b/WotBlitzStatisticsPro.WgApiClient/IWargamingApiSettings.cs @@ -0,0 +1,7 @@ +namespace WotBlitzStatisticsPro.WgApiClient +{ + public interface IWargamingApiSettings + { + string ApplicationId { get; set; } + } +} diff --git a/WotBlitzStatisticsPro.WgApiClient/Model/AccountFullStatistics.cs b/WotBlitzStatisticsPro.WgApiClient/Model/AccountFullStatistics.cs new file mode 100644 index 0000000..a9dd062 --- /dev/null +++ b/WotBlitzStatisticsPro.WgApiClient/Model/AccountFullStatistics.cs @@ -0,0 +1,124 @@ +using Newtonsoft.Json; +using System; +using System.Collections.Generic; +using System.Text; + +namespace WotBlitzStatisticsPro.WgApiClient.Model +{ + public class AccountFullStatistics + { + /// + /// Battles count + /// + [JsonProperty("battles")] + public long? Battles { get; set; } + + /// + /// Capture points + /// + [JsonProperty("capture_points")] + public long? CapturePoints { get; set; } + + /// + /// Total damage amount + /// + [JsonProperty("damage_dealt")] + public long? DamageDealt { get; set; } + + /// + /// Total amount of received damage + /// + [JsonProperty("damage_received")] + public long? DamageReceived { get; set; } + + /// + /// Dropped capture points + /// + [JsonProperty("dropped_capture_points")] + public long? DroppedCapturePoints { get; set; } + + /// + /// Total amount of frags + /// + [JsonProperty("frags")] + public long? Frags { get; set; } + + /// + /// Total amount of fras grater ten 8 lvl + /// + [JsonProperty("frags8p")] + public long? Frags8P { get; set; } + + /// + /// Total amount of hits + /// + [JsonProperty("hits")] + public long? Hits { get; set; } + + /// + /// Total amount of losses + /// + [JsonProperty("losses")] + public long? Losses { get; set; } + + /// + /// Max frags per battle + /// + [JsonProperty("max_frags")] + public long? MaxFrags { get; set; } + + /// + /// Tank id, which kills max frags per battle + /// + [JsonProperty("max_frags_tank_id")] + public long? MaxFragsTankId { get; set; } + + /// + /// Max experience per battle + /// + [JsonProperty("max_xp")] + public long? MaxXp { get; set; } + + /// + /// Tank Id which created max experiense per battle + /// + [JsonProperty("max_xp_tank_id")] + public long? MaxXpTankId { get; set; } + + /// + /// Totla shots count + /// + [JsonProperty("shots")] + public long? Shots { get; set; } + + /// + /// Totla count of spotted vehicles + /// + [JsonProperty("spotted")] + public long? Spotted { get; set; } + + /// + /// Total count of survived battles + /// + [JsonProperty("survived_battles")] + public long? SurvivedBattles { get; set; } + + /// + /// Total count of suvived and winned battles + /// + [JsonProperty("win_and_survived")] + public long? WinAndSurvived { get; set; } + + /// + /// Total wins count + /// + [JsonProperty("wins")] + public long? Wins { get; set; } + + /// + /// Total amount of experience + /// + [JsonProperty("xp")] + public long? Xp { get; set; } + } +} diff --git a/WotBlitzStatisticsPro.WgApiClient/Model/AccountInfo.cs b/WotBlitzStatisticsPro.WgApiClient/Model/AccountInfo.cs new file mode 100644 index 0000000..3713b93 --- /dev/null +++ b/WotBlitzStatisticsPro.WgApiClient/Model/AccountInfo.cs @@ -0,0 +1,49 @@ +using Newtonsoft.Json; + +namespace WotBlitzStatisticsPro.WgApiClient.Model +{ + public class AccountInfo + { + /// + /// Player account identifier + /// + [JsonProperty("account_id")] + public long? AccountId { get; set; } + + /// + /// Account creation date + /// + [JsonProperty("created_at")] + public int? CreatedAt { get; set; } + + /// + /// Last battle time + /// + [JsonProperty("last_battle_time")] + public int? LastBattleTime { get; set; } + + /// + /// Player's nick + /// + [JsonProperty("nickname")] + public string Nickname { get; set; } + + /// + /// Player information update date + /// + [JsonProperty("updated_at")] + public int? UpdatedAt { get; set; } + + /// + /// Private account data + /// + [JsonProperty("private")] + public AccountPrivateInfo Private { get; set; } + + /// + /// Player's statistics + /// + [JsonProperty("statistics")] + public AccountStatistics Statistics { get; set; } + } +} diff --git a/WotBlitzStatisticsPro.WgApiClient/Model/AccountPrivateInfo.cs b/WotBlitzStatisticsPro.WgApiClient/Model/AccountPrivateInfo.cs new file mode 100644 index 0000000..78f248d --- /dev/null +++ b/WotBlitzStatisticsPro.WgApiClient/Model/AccountPrivateInfo.cs @@ -0,0 +1,69 @@ +using Newtonsoft.Json; + +namespace WotBlitzStatisticsPro.WgApiClient.Model +{ + public class AccountPrivateInfo + { + /// + /// Account ban info + /// + [JsonProperty("ban_info")] + public string BanInfo { get; set; } + + /// + /// Account ban expiration date + /// + [JsonProperty("ban_time")] + public int? BanTime { get; set; } + + /// + /// Total time in battles until destroy in seconds + /// + [JsonProperty("battle_life_time")] + public int? BattleLifeTimeInSeconds { get; set; } + + /// + /// Amount of credits + /// + [JsonProperty("credits")] + public long? Credits { get; set; } + + /// + /// Free experience + /// + [JsonProperty("free_xp")] + public long? FreeXp { get; set; } + + /// + ///Amount of gold + /// + [JsonProperty("gold")] + public long? Gold { get; set; } + + /// + /// Is player has premium account + /// + [JsonProperty("is_premium")] + public bool IsPremium { get; set; } + + /// + /// Premium accunt expiration time + /// + [JsonProperty("premium_expires_at")] + private int? PremiumExpiresAt { get; set; } + + /// + ///Группы контактов. + ///Дополнительное поле. + /// + [JsonProperty("grouped_contacts")] + public AccountPrivateInfoGroupedContacts GroupedContacts { get; set; } + + /// + ///Ограничения аккаунта + /// + [JsonProperty("restrictions")] + public AccountPrivateInfoRestrictions Restrictions { get; set; } + + } +} diff --git a/WotBlitzStatisticsPro.WgApiClient/Model/AccountPrivateInfoGroupedContacts.cs b/WotBlitzStatisticsPro.WgApiClient/Model/AccountPrivateInfoGroupedContacts.cs new file mode 100644 index 0000000..1909159 --- /dev/null +++ b/WotBlitzStatisticsPro.WgApiClient/Model/AccountPrivateInfoGroupedContacts.cs @@ -0,0 +1,26 @@ +using Newtonsoft.Json; +using System.Collections.Generic; + +namespace WotBlitzStatisticsPro.WgApiClient.Model +{ + public class AccountPrivateInfoGroupedContacts + { + /// + /// Blocked accountIds + /// + [JsonProperty("blocked")] + public int[] Blocked { get; set; } + + /// + /// Groups + /// + [JsonProperty("groups")] + public Dictionary Groups { get; set; } + + /// + /// Ungrouped accountIds + /// + [JsonProperty("ungrouped")] + public int[] Ungrouped { get; set; } + } +} diff --git a/WotBlitzStatisticsPro.WgApiClient/Model/AccountPrivateInfoRestrictions.cs b/WotBlitzStatisticsPro.WgApiClient/Model/AccountPrivateInfoRestrictions.cs new file mode 100644 index 0000000..a6b0f80 --- /dev/null +++ b/WotBlitzStatisticsPro.WgApiClient/Model/AccountPrivateInfoRestrictions.cs @@ -0,0 +1,13 @@ +using Newtonsoft.Json; + +namespace WotBlitzStatisticsPro.WgApiClient.Model +{ + public class AccountPrivateInfoRestrictions + { + /// + /// Clan chat ban time + /// + [JsonProperty("chat_ban_time")] + public int? ChatBanTime { get; set; } + } +} diff --git a/WotBlitzStatisticsPro.WgApiClient/Model/AccountStatistics.cs b/WotBlitzStatisticsPro.WgApiClient/Model/AccountStatistics.cs new file mode 100644 index 0000000..8dc7303 --- /dev/null +++ b/WotBlitzStatisticsPro.WgApiClient/Model/AccountStatistics.cs @@ -0,0 +1,20 @@ +using Newtonsoft.Json; +using System.Collections.Generic; + +namespace WotBlitzStatisticsPro.WgApiClient.Model +{ + public class AccountStatistics + { + /// + /// Amount of destroyed by player tanks. + /// + [JsonProperty("frags")] + public Dictionary Frags { get; set; } + + /// + /// Full player's statistics + /// + [JsonProperty("all")] + public AccountFullStatistics All { get; set; } + } +} diff --git a/WotBlitzStatisticsPro.WgApiClient/Model/RealmType.cs b/WotBlitzStatisticsPro.WgApiClient/Model/RealmType.cs new file mode 100644 index 0000000..2c375c9 --- /dev/null +++ b/WotBlitzStatisticsPro.WgApiClient/Model/RealmType.cs @@ -0,0 +1,11 @@ + +namespace WotBlitzStatisticsPro.WgApiClient.Model +{ + public enum RealmType + { + Ru, + Eu, + Na, + Asia + } +} diff --git a/WotBlitzStatisticsPro.WgApiClient/Model/RequestLanguage.cs b/WotBlitzStatisticsPro.WgApiClient/Model/RequestLanguage.cs new file mode 100644 index 0000000..dca7746 --- /dev/null +++ b/WotBlitzStatisticsPro.WgApiClient/Model/RequestLanguage.cs @@ -0,0 +1,9 @@ +namespace WotBlitzStatisticsPro.WgApiClient.Model +{ + public enum RequestLanguage + { + Ru, + En, + De + } +} diff --git a/WotBlitzStatisticsPro.WgApiClient/ResponseBody.cs b/WotBlitzStatisticsPro.WgApiClient/ResponseBody.cs new file mode 100644 index 0000000..0706566 --- /dev/null +++ b/WotBlitzStatisticsPro.WgApiClient/ResponseBody.cs @@ -0,0 +1,40 @@ +using Newtonsoft.Json; + +namespace WotBlitzStatisticsPro.WgApiClient +{ + internal class ResponseBody + { + [JsonProperty("status")] + public string Status { get; set; } + + [JsonProperty("meta")] + public Meta Meta { get; set; } + + [JsonProperty("data")] + public T Data { get; set; } + + [JsonProperty("error")] + public Error Error { get; set; } + } + + internal class Meta + { + [JsonProperty("count")] + public int Count { get; set; } + } + + internal class Error + { + [JsonProperty("field")] + public string Field { get; set; } + + [JsonProperty("message")] + public string Message { get; set; } + + [JsonProperty("code")] + public string Code { get; set; } + + [JsonProperty("value")] + public string Value { get; set; } + } +} diff --git a/WotBlitzStatisticsPro.WgApiClient/WagramingApiClientBase.cs b/WotBlitzStatisticsPro.WgApiClient/WagramingApiClientBase.cs new file mode 100644 index 0000000..c482052 --- /dev/null +++ b/WotBlitzStatisticsPro.WgApiClient/WagramingApiClientBase.cs @@ -0,0 +1,85 @@ +using Newtonsoft.Json; +using System; +using System.Collections.Generic; +using System.Net.Http; +using System.Net.Http.Headers; +using System.Text; +using System.Threading.Tasks; +using WotBlitzStatisticsPro.WgApiClient.Model; + +namespace WotBlitzStatisticsPro.WgApiClient +{ + public class WagramingApiClientBase + { + private Dictionary _blitzApiUrls = new Dictionary(); + private Dictionary _wotApiUrls = new Dictionary(); + + + private readonly HttpClient _httpClient; + private readonly IWargamingApiSettings _wargamingApiSettings; + + public WagramingApiClientBase( + HttpClient httpClient, + IWargamingApiSettings wargamingApiSettings) + { + _httpClient = httpClient; + _wargamingApiSettings = wargamingApiSettings; + _blitzApiUrls[RealmType.Eu] = "https://api.wotblitz.eu/wotb/"; + _blitzApiUrls[RealmType.Ru] = "https://api.wotblitz.ru/wotb/"; + _blitzApiUrls[RealmType.Na] = "https://api.wotblitz.com/wotb/"; + _blitzApiUrls[RealmType.Asia] = "https://api.wotblitz.asia/wotb/"; + + _wotApiUrls[RealmType.Eu] = "https://api.worldoftanks.eu/wot/"; + _wotApiUrls[RealmType.Ru] = "https://api.worldoftanks.ru/wot/"; + _wotApiUrls[RealmType.Na] = "https://api.worldoftanks.com/wot/"; + _wotApiUrls[RealmType.Asia] = "https://api.worldoftanks.asia/wot/"; + } + + protected async Task GetFromBlitzApi( + RealmType realmType, + RequestLanguage language, + string method, + params string[] queryParameters) + { + string uri = GetUri(realmType, language, method, queryParameters); + + _httpClient.DefaultRequestHeaders.Accept.Clear(); + _httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); + + var response = await _httpClient.GetAsync(uri); + response.EnsureSuccessStatusCode(); + var responseString = await response.Content.ReadAsStringAsync(); + + var responseBody = JsonConvert.DeserializeObject>(responseString); + if (responseBody.Status == "ok") + { + return responseBody.Data; + } + if (responseBody.Status == "error") + { + var error = responseBody.Error; + var message = $"Field:{error.Field} Message:{error.Message} Value:{error.Value} Code:{error.Code}"; + throw new ArgumentException(message); + } + return default(T); + } + + private string GetUri(RealmType realmType, RequestLanguage language, string method, string[] queryParameters) + { + var uri = new StringBuilder($"{_blitzApiUrls[realmType]}{method}"); + uri.Append("?application_id=") + .Append(_wargamingApiSettings.ApplicationId) + .Append("&language=") + .Append(language.ToString().ToLower()); + if (queryParameters != null) + { + foreach (var param in queryParameters) + { + uri.Append("&") + .Append(param); + } + } + return uri.ToString(); + } + } +} diff --git a/WotBlitzStatisticsPro.WgApiClient/WargamingApiClient.cs b/WotBlitzStatisticsPro.WgApiClient/WargamingApiClient.cs new file mode 100644 index 0000000..4758241 --- /dev/null +++ b/WotBlitzStatisticsPro.WgApiClient/WargamingApiClient.cs @@ -0,0 +1,36 @@ +using System; +using System.Collections.Generic; +using System.Net.Http; +using System.Threading.Tasks; +using WotBlitzStatisticsPro.WgApiClient.Model; + +namespace WotBlitzStatisticsPro.WgApiClient +{ + public class WargamingApiClient : WagramingApiClientBase, IWargamingApiClient + { + public WargamingApiClient( + HttpClient httpClient, + IWargamingApiSettings wargamingApiSettings) : base(httpClient, wargamingApiSettings) + { + } + + public Task> FindAccounts(string nickName, + RealmType realmType = RealmType.Ru, + RequestLanguage language = RequestLanguage.En) + { + throw new NotImplementedException(); + } + + public async Task GetPlayerAccountInfo(long accountId, + RealmType realmType = RealmType.Ru, + RequestLanguage language = RequestLanguage.En) + { + var account = await GetFromBlitzApi>( + realmType, + language, + "account/info/", + $"account_id={accountId}"); + return account[accountId.ToString()]; + } + } +} diff --git a/WotBlitzStatisticsPro.WgApiClient/WotBlitzStatisticsPro.WgApiClient.csproj b/WotBlitzStatisticsPro.WgApiClient/WotBlitzStatisticsPro.WgApiClient.csproj new file mode 100644 index 0000000..47b6ce2 --- /dev/null +++ b/WotBlitzStatisticsPro.WgApiClient/WotBlitzStatisticsPro.WgApiClient.csproj @@ -0,0 +1,11 @@ + + + + netstandard2.1 + + + + + + + diff --git a/WotBlitzStatisticsPro.sln b/WotBlitzStatisticsPro.sln index 1a41718..fe1c6a3 100644 --- a/WotBlitzStatisticsPro.sln +++ b/WotBlitzStatisticsPro.sln @@ -11,6 +11,10 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WotBlitzStatisticsPro.Commo EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WotBlitzStatisticsPro.UI.Wasm", "WotBlitzStatisticsPro.Wasm\WotBlitzStatisticsPro.UI.Wasm.csproj", "{57E96A78-BDA4-4023-9965-EC755C68D033}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WotBlitzStatistics.GraphQl", "WotBlitzStatistics.GraphQl\WotBlitzStatistics.GraphQl.csproj", "{9B268E2D-38A5-4755-BAEC-BAF1DC7DCEC7}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WotBlitzStatisticsPro.WgApiClient", "WotBlitzStatisticsPro.WgApiClient\WotBlitzStatisticsPro.WgApiClient.csproj", "{E1AB7997-C2A1-433B-A4F5-F8E9C4B73515}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -33,6 +37,14 @@ Global {57E96A78-BDA4-4023-9965-EC755C68D033}.Debug|Any CPU.Build.0 = Debug|Any CPU {57E96A78-BDA4-4023-9965-EC755C68D033}.Release|Any CPU.ActiveCfg = Release|Any CPU {57E96A78-BDA4-4023-9965-EC755C68D033}.Release|Any CPU.Build.0 = Release|Any CPU + {9B268E2D-38A5-4755-BAEC-BAF1DC7DCEC7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {9B268E2D-38A5-4755-BAEC-BAF1DC7DCEC7}.Debug|Any CPU.Build.0 = Debug|Any CPU + {9B268E2D-38A5-4755-BAEC-BAF1DC7DCEC7}.Release|Any CPU.ActiveCfg = Release|Any CPU + {9B268E2D-38A5-4755-BAEC-BAF1DC7DCEC7}.Release|Any CPU.Build.0 = Release|Any CPU + {E1AB7997-C2A1-433B-A4F5-F8E9C4B73515}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {E1AB7997-C2A1-433B-A4F5-F8E9C4B73515}.Debug|Any CPU.Build.0 = Debug|Any CPU + {E1AB7997-C2A1-433B-A4F5-F8E9C4B73515}.Release|Any CPU.ActiveCfg = Release|Any CPU + {E1AB7997-C2A1-433B-A4F5-F8E9C4B73515}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE