From e12734981bf671e9bc92e4edf97f633c7b804e0d Mon Sep 17 00:00:00 2001 From: Mikhail Shabanov Date: Sun, 27 Dec 2020 12:39:25 +0100 Subject: [PATCH] Nullable refernce types refactoring --- .../Dictionaries/AchievementOption.cs | 8 +- .../Dictionaries/IVehiclesDictionary.cs | 8 +- .../Dictionaries/LocalizableString.cs | 2 +- .../Model/AccountInfoHistoryResponse.cs | 10 +-- .../Model/AccountInfoResponse.cs | 4 +- .../Model/AccountsSearchResponse.cs | 2 +- .../Model/AccountsSearchResponseItem.cs | 2 +- .../Model/ClanSearchResponse.cs | 2 +- .../Model/ClanSearchResponseItem.cs | 4 +- .../Model/StatisticsDifference.cs | 12 +-- .../Model/TankInfoResponse.cs | 10 +-- .../Model/UpdateDictionariesResponseItem.cs | 2 +- .../WotBlitzStatisticsPro.Common.csproj | 1 + .../Model/Accounts/AccountInfo.cs | 8 +- .../Model/Accounts/AccountInfoHistoryKey.cs | 4 +- .../Model/Accounts/TankInfo.cs | 2 +- .../Model/Accounts/TankInfoHistory.cs | 2 +- .../Model/Accounts/TankInfoHistoryKey.cs | 4 +- .../Model/Accounts/TankInfoKey.cs | 4 +- .../Model/AchievementDictionary.cs | 22 ++--- .../Model/AchievementSectionDictionary.cs | 8 +- .../Model/ClanRoleDictionary.cs | 7 +- .../Model/LanguageDictionary.cs | 5 +- .../Model/NationDictionary.cs | 7 +- .../Model/VehicleTypeDictionary.cs | 7 +- .../Model/VehiclesDictionary.cs | 29 ++++--- .../WotBlitzStatisticsPro.DataAccess.csproj | 1 + .../MongoSettings.cs | 4 +- .../WargamingApiSettings.cs | 6 +- .../WotBlitzStatisticsPro.GraphQl.csproj | 1 + ...ntHistoryInformationPipelineContextData.cs | 14 +-- .../AccountInformationPipelineContextData.cs | 12 +-- .../IDatabasePipelineContextData.cs | 2 +- .../IStatisticsPipelineData.cs | 10 +-- .../OperationContext/OperationContext.cs | 4 +- .../BuildAccountInfoResponseOperation.cs | 35 ++++++-- .../CalculateStatisticsOperation.cs | 11 ++- .../CheckIfHistoryIsEmptyOperation.cs | 6 +- .../CheckLAstBattleDateOperation.cs | 8 +- .../FillAccountInfoHistoryResponse.cs | 9 +- .../FillOverallStatisticsOperation.cs | 9 +- .../FillPeriodDifferenceOperation.cs | 7 +- .../FillPeriodStatisticsOperation.cs | 6 +- .../FillStatisticsDifferenceOperation.cs | 6 +- .../Operations/GetAccountInfoOperation.cs | 19 +++- .../Operations/GetTanksInfoOperation.cs | 21 +++-- .../ReadAccountInfoFromDbOperation.cs | 4 +- .../ReadAccountInfoHistoryFromDbOperation.cs | 4 +- .../SaveAccountAndTanksOperation.cs | 12 ++- .../AchievementsDictionaryUpdater.cs | 12 ++- .../Dictionaries/StaticDictionariesUpdater.cs | 87 +++++++++++++------ .../Dictionaries/VehiclesDictionaryUpdater.cs | 9 +- .../Mappers/AccountSearchResponseProfile.cs | 2 +- .../Mappers/ClanSearchResponseProfile.cs | 2 +- .../Mappers/ShortStatisticsProfile.cs | 6 +- .../Mappers/VehicleDictionaryProfile.cs | 8 +- .../Pipeline/IOperation.cs | 2 +- .../Pipeline/IPipeline.cs | 2 +- .../Pipeline/OperationMediator.cs | 6 +- .../Pipeline/Pipeline.cs | 2 +- .../ServiceProviderOperationFactory.cs | 2 +- .../WargamingAccounts.cs | 36 +++++--- .../WargamingSearch.cs | 12 +++ .../WotBlitzStatisticsLogicInstaller.cs | 19 ++-- .../WotBlitzStatisticsPro.Logic.csproj | 1 + .../IWargamingApiClient.cs | 10 +-- .../IWargamingDictionariesApiClient.cs | 8 +- .../IWargamingTanksApiClient.cs | 2 +- .../Model/ClanAccountInfo.cs | 4 +- .../Model/ClanInfo.cs | 46 +++++----- .../Model/WotAccountInfo.cs | 6 +- .../Model/WotAccountListResponse.cs | 2 +- .../Model/WotAccountPrivateInfo.cs | 13 ++- .../WotAccountPrivateInfoGroupedContacts.cs | 6 +- .../Model/WotAccountStatistics.cs | 4 +- .../Model/WotAccountTanksStatistics.cs | 4 +- .../Model/WotClanListResponse.cs | 4 +- .../Model/WotClanMembersDictionaryResponse.cs | 4 +- .../WotEncyclopediaAchievementsResponse.cs | 28 +++--- .../Model/WotEncyclopediaInfoResponse.cs | 14 +-- .../Model/WotEncyclopediaVehiclesResponse.cs | 24 ++--- .../ResponseBody.cs | 22 ++--- .../WagramingApiClientBase.cs | 31 ++++--- .../WargamingApiClient.cs | 32 +++---- .../WotBlitzStatisticsPro.WgApiClient.csproj | 1 + 85 files changed, 509 insertions(+), 351 deletions(-) diff --git a/WotBlitzStatisticsPro.Common/Dictionaries/AchievementOption.cs b/WotBlitzStatisticsPro.Common/Dictionaries/AchievementOption.cs index 08264aa..ae27f9b 100644 --- a/WotBlitzStatisticsPro.Common/Dictionaries/AchievementOption.cs +++ b/WotBlitzStatisticsPro.Common/Dictionaries/AchievementOption.cs @@ -10,22 +10,22 @@ namespace WotBlitzStatisticsPro.Common.Dictionaries /// /// Achievement option description /// - public List Description { get; set; } + public List? Description { get; set; } /// /// Image link /// - public string Image { get; set; } + public string? Image { get; set; } /// /// Image 180x180px link /// - public string ImageBig { get; set; } + public string? ImageBig { get; set; } /// /// Achievement option name /// - public List Name { get; set; } + public List? Name { get; set; } } } \ No newline at end of file diff --git a/WotBlitzStatisticsPro.Common/Dictionaries/IVehiclesDictionary.cs b/WotBlitzStatisticsPro.Common/Dictionaries/IVehiclesDictionary.cs index ccdd285..75d7107 100644 --- a/WotBlitzStatisticsPro.Common/Dictionaries/IVehiclesDictionary.cs +++ b/WotBlitzStatisticsPro.Common/Dictionaries/IVehiclesDictionary.cs @@ -75,22 +75,22 @@ namespace WotBlitzStatisticsPro.Common.Dictionaries /// /// Engines id list /// - int[] Engines { get; set; } + int[]? Engines { get; set; } /// /// Guns id list /// - int[] Guns { get; set; } + int[]? Guns { get; set; } /// /// List of compatible suspensions /// - int[] Suspensions { get; set; } + int[]? Suspensions { get; set; } /// /// List of compatible turrets ids /// - int[] Turrets { get; set; } + int[]? Turrets { get; set; } } } \ No newline at end of file diff --git a/WotBlitzStatisticsPro.Common/Dictionaries/LocalizableString.cs b/WotBlitzStatisticsPro.Common/Dictionaries/LocalizableString.cs index 74044e4..4bfa5db 100644 --- a/WotBlitzStatisticsPro.Common/Dictionaries/LocalizableString.cs +++ b/WotBlitzStatisticsPro.Common/Dictionaries/LocalizableString.cs @@ -15,6 +15,6 @@ namespace WotBlitzStatisticsPro.Common.Dictionaries /// /// Localizable string. /// - public string Value { get; set; } + public string? Value { get; set; } } } \ No newline at end of file diff --git a/WotBlitzStatisticsPro.Common/Model/AccountInfoHistoryResponse.cs b/WotBlitzStatisticsPro.Common/Model/AccountInfoHistoryResponse.cs index 21cfcfa..646882b 100644 --- a/WotBlitzStatisticsPro.Common/Model/AccountInfoHistoryResponse.cs +++ b/WotBlitzStatisticsPro.Common/Model/AccountInfoHistoryResponse.cs @@ -20,26 +20,26 @@ namespace WotBlitzStatisticsPro.Common.Model /// /// Player's nick /// - public string Nickname { get; set; } + public string? Nickname { get; set; } /// /// Overall statistics since account creation /// - public ShortStatistics OverallAccountStatistics { get; set; } + public ShortStatistics? OverallAccountStatistics { get; set; } /// /// Statistics for period /// - public ShortStatistics PeriodAccountStatistics { get; set; } + public ShortStatistics? PeriodAccountStatistics { get; set; } /// /// Difference between start and end of the period /// - public StatisticsDifference PeriodDifference { get; set; } + public StatisticsDifference? PeriodDifference { get; set; } /// /// The detailed history /// - public StatisticsDifference[] StatisticsHistory { get; set; } + public StatisticsDifference[]? StatisticsHistory { get; set; } } } \ No newline at end of file diff --git a/WotBlitzStatisticsPro.Common/Model/AccountInfoResponse.cs b/WotBlitzStatisticsPro.Common/Model/AccountInfoResponse.cs index 0fb7b63..dea75a5 100644 --- a/WotBlitzStatisticsPro.Common/Model/AccountInfoResponse.cs +++ b/WotBlitzStatisticsPro.Common/Model/AccountInfoResponse.cs @@ -26,7 +26,7 @@ namespace WotBlitzStatisticsPro.Common.Model /// /// Player's nick /// - public string Nickname { get; set; } + public string? Nickname { get; set; } /// /// Battles count @@ -151,7 +151,7 @@ namespace WotBlitzStatisticsPro.Common.Model /// /// All player's tanks /// - public List Tanks { get; set; } + public List? Tanks { get; set; } } } \ No newline at end of file diff --git a/WotBlitzStatisticsPro.Common/Model/AccountsSearchResponse.cs b/WotBlitzStatisticsPro.Common/Model/AccountsSearchResponse.cs index e001128..628d1e2 100644 --- a/WotBlitzStatisticsPro.Common/Model/AccountsSearchResponse.cs +++ b/WotBlitzStatisticsPro.Common/Model/AccountsSearchResponse.cs @@ -14,6 +14,6 @@ namespace WotBlitzStatisticsPro.Common.Model /// /// Found accounts list /// - public ICollection Accounts { get; set; } + public ICollection? Accounts { get; set; } } } \ No newline at end of file diff --git a/WotBlitzStatisticsPro.Common/Model/AccountsSearchResponseItem.cs b/WotBlitzStatisticsPro.Common/Model/AccountsSearchResponseItem.cs index d51d006..494855a 100644 --- a/WotBlitzStatisticsPro.Common/Model/AccountsSearchResponseItem.cs +++ b/WotBlitzStatisticsPro.Common/Model/AccountsSearchResponseItem.cs @@ -13,6 +13,6 @@ /// /// Player nick /// - public string Nickname { get; set; } + public string? Nickname { get; set; } } } \ No newline at end of file diff --git a/WotBlitzStatisticsPro.Common/Model/ClanSearchResponse.cs b/WotBlitzStatisticsPro.Common/Model/ClanSearchResponse.cs index d07f209..140b17a 100644 --- a/WotBlitzStatisticsPro.Common/Model/ClanSearchResponse.cs +++ b/WotBlitzStatisticsPro.Common/Model/ClanSearchResponse.cs @@ -14,6 +14,6 @@ namespace WotBlitzStatisticsPro.Common.Model /// /// List of clans /// - public ICollection Clans { get; set; } + public ICollection? Clans { get; set; } } } \ No newline at end of file diff --git a/WotBlitzStatisticsPro.Common/Model/ClanSearchResponseItem.cs b/WotBlitzStatisticsPro.Common/Model/ClanSearchResponseItem.cs index b331f5e..5e32175 100644 --- a/WotBlitzStatisticsPro.Common/Model/ClanSearchResponseItem.cs +++ b/WotBlitzStatisticsPro.Common/Model/ClanSearchResponseItem.cs @@ -13,12 +13,12 @@ /// /// Clan Tag /// - public string Tag { get; set; } + public string? Tag { get; set; } /// /// Clan Name /// - public string Name { get; set; } + public string? Name { get; set; } /// /// Clan created at. (UNIX Epoch time) diff --git a/WotBlitzStatisticsPro.Common/Model/StatisticsDifference.cs b/WotBlitzStatisticsPro.Common/Model/StatisticsDifference.cs index c495e98..15a56d4 100644 --- a/WotBlitzStatisticsPro.Common/Model/StatisticsDifference.cs +++ b/WotBlitzStatisticsPro.Common/Model/StatisticsDifference.cs @@ -15,32 +15,32 @@ namespace WotBlitzStatisticsPro.Common.Model /// /// Difference in Battles count /// - public StatisticsDifferenceItem Battles { get; set; } + public StatisticsDifferenceItem? Battles { get; set; } /// /// Difference in Average tier /// - public StatisticsDifferenceItem AvgTier { get; set; } + public StatisticsDifferenceItem? AvgTier { get; set; } /// /// Difference in Wn7 coefficient /// - public StatisticsDifferenceItem Wn7 { get; set; } + public StatisticsDifferenceItem? Wn7 { get; set; } /// /// Difference in Player's win rate /// - public StatisticsDifferenceItem WinRate { get; set; } + public StatisticsDifferenceItem? WinRate { get; set; } /// /// Difference in Player's average damage /// - public StatisticsDifferenceItem AvgDamage { get; set; } + public StatisticsDifferenceItem? AvgDamage { get; set; } /// /// Difference in Player's average XP /// - public StatisticsDifferenceItem AvgXp { get; set; } + public StatisticsDifferenceItem? AvgXp { get; set; } } } \ No newline at end of file diff --git a/WotBlitzStatisticsPro.Common/Model/TankInfoResponse.cs b/WotBlitzStatisticsPro.Common/Model/TankInfoResponse.cs index c3ba097..92a9be9 100644 --- a/WotBlitzStatisticsPro.Common/Model/TankInfoResponse.cs +++ b/WotBlitzStatisticsPro.Common/Model/TankInfoResponse.cs @@ -150,17 +150,17 @@ namespace WotBlitzStatisticsPro.Common.Model /// /// Tank name /// - public string Name { get; set; } + public string? Name { get; set; } /// /// Tank nation dictionary identifier /// - public string TankNationId { get; set; } + public string? TankNationId { get; set; } /// /// Localized tank nation name /// - public string TankNation { get; set; } + public string? TankNation { get; set; } /// /// Tank tier @@ -170,12 +170,12 @@ namespace WotBlitzStatisticsPro.Common.Model /// /// Tank type dictionary identifier /// - public string TankTypeId { get; set; } + public string? TankTypeId { get; set; } /// /// Localized tank type name /// - public string TankType { get; set; } + public string? TankType { get; set; } /// /// Is it premium tank or not diff --git a/WotBlitzStatisticsPro.Common/Model/UpdateDictionariesResponseItem.cs b/WotBlitzStatisticsPro.Common/Model/UpdateDictionariesResponseItem.cs index 8c31278..7075971 100644 --- a/WotBlitzStatisticsPro.Common/Model/UpdateDictionariesResponseItem.cs +++ b/WotBlitzStatisticsPro.Common/Model/UpdateDictionariesResponseItem.cs @@ -13,6 +13,6 @@ /// /// A bit summary about what have been updated /// - public string Description { get; set; } + public string? Description { get; set; } } } \ No newline at end of file diff --git a/WotBlitzStatisticsPro.Common/WotBlitzStatisticsPro.Common.csproj b/WotBlitzStatisticsPro.Common/WotBlitzStatisticsPro.Common.csproj index 3447ea9..4afb8a0 100644 --- a/WotBlitzStatisticsPro.Common/WotBlitzStatisticsPro.Common.csproj +++ b/WotBlitzStatisticsPro.Common/WotBlitzStatisticsPro.Common.csproj @@ -3,6 +3,7 @@ net5.0 true + enable diff --git a/WotBlitzStatisticsPro.DataAccess/Model/Accounts/AccountInfo.cs b/WotBlitzStatisticsPro.DataAccess/Model/Accounts/AccountInfo.cs index f1ff745..62fd9d9 100644 --- a/WotBlitzStatisticsPro.DataAccess/Model/Accounts/AccountInfo.cs +++ b/WotBlitzStatisticsPro.DataAccess/Model/Accounts/AccountInfo.cs @@ -1,4 +1,7 @@ -using MongoDB.Bson.Serialization.Attributes; +using System; +using System.ComponentModel.DataAnnotations; +using System.Diagnostics.CodeAnalysis; +using MongoDB.Bson.Serialization.Attributes; using WotBlitzStatisticsPro.Common.Model; namespace WotBlitzStatisticsPro.DataAccess.Model.Accounts @@ -32,7 +35,8 @@ namespace WotBlitzStatisticsPro.DataAccess.Model.Accounts /// /// Player's nick /// - public string Nickname { get; set; } + [Required] + public string Nickname { get; set; } = string.Empty; /// /// Player information update date diff --git a/WotBlitzStatisticsPro.DataAccess/Model/Accounts/AccountInfoHistoryKey.cs b/WotBlitzStatisticsPro.DataAccess/Model/Accounts/AccountInfoHistoryKey.cs index 4a57e34..356196c 100644 --- a/WotBlitzStatisticsPro.DataAccess/Model/Accounts/AccountInfoHistoryKey.cs +++ b/WotBlitzStatisticsPro.DataAccess/Model/Accounts/AccountInfoHistoryKey.cs @@ -19,14 +19,14 @@ namespace WotBlitzStatisticsPro.DataAccess.Model.Accounts public int LastBattleTime { get; set; } - public bool Equals(AccountInfoHistoryKey other) + public bool Equals(AccountInfoHistoryKey? other) { if (ReferenceEquals(null, other)) return false; if (ReferenceEquals(this, other)) return true; return AccountId == other.AccountId && LastBattleTime == other.LastBattleTime; } - public override bool Equals(object obj) + public override bool Equals(object? obj) { if (ReferenceEquals(null, obj)) return false; if (ReferenceEquals(this, obj)) return true; diff --git a/WotBlitzStatisticsPro.DataAccess/Model/Accounts/TankInfo.cs b/WotBlitzStatisticsPro.DataAccess/Model/Accounts/TankInfo.cs index d9e00ea..a5d6920 100644 --- a/WotBlitzStatisticsPro.DataAccess/Model/Accounts/TankInfo.cs +++ b/WotBlitzStatisticsPro.DataAccess/Model/Accounts/TankInfo.cs @@ -7,7 +7,7 @@ namespace WotBlitzStatisticsPro.DataAccess.Model.Accounts { public TankInfo() { - + TankInfoId = new TankInfoKey(); } public TankInfo(long accountId, long tankId) diff --git a/WotBlitzStatisticsPro.DataAccess/Model/Accounts/TankInfoHistory.cs b/WotBlitzStatisticsPro.DataAccess/Model/Accounts/TankInfoHistory.cs index 728abd4..dd32160 100644 --- a/WotBlitzStatisticsPro.DataAccess/Model/Accounts/TankInfoHistory.cs +++ b/WotBlitzStatisticsPro.DataAccess/Model/Accounts/TankInfoHistory.cs @@ -7,7 +7,7 @@ namespace WotBlitzStatisticsPro.DataAccess.Model.Accounts public TankInfoHistory() { - + TankInfoHistoryId = new TankInfoHistoryKey(); } public TankInfoHistory(long accountId, long tankId, int lastBattleTime) diff --git a/WotBlitzStatisticsPro.DataAccess/Model/Accounts/TankInfoHistoryKey.cs b/WotBlitzStatisticsPro.DataAccess/Model/Accounts/TankInfoHistoryKey.cs index 7431cad..a369677 100644 --- a/WotBlitzStatisticsPro.DataAccess/Model/Accounts/TankInfoHistoryKey.cs +++ b/WotBlitzStatisticsPro.DataAccess/Model/Accounts/TankInfoHistoryKey.cs @@ -31,14 +31,14 @@ namespace WotBlitzStatisticsPro.DataAccess.Model.Accounts /// public int LastBattleTime { get; set; } - public bool Equals(TankInfoHistoryKey other) + public bool Equals(TankInfoHistoryKey? other) { if (ReferenceEquals(null, other)) return false; if (ReferenceEquals(this, other)) return true; return AccountId == other.AccountId && TankId == other.TankId && LastBattleTime == other.LastBattleTime; } - public override bool Equals(object obj) + public override bool Equals(object? obj) { if (ReferenceEquals(null, obj)) return false; if (ReferenceEquals(this, obj)) return true; diff --git a/WotBlitzStatisticsPro.DataAccess/Model/Accounts/TankInfoKey.cs b/WotBlitzStatisticsPro.DataAccess/Model/Accounts/TankInfoKey.cs index f2ee5a8..06bc632 100644 --- a/WotBlitzStatisticsPro.DataAccess/Model/Accounts/TankInfoKey.cs +++ b/WotBlitzStatisticsPro.DataAccess/Model/Accounts/TankInfoKey.cs @@ -25,14 +25,14 @@ namespace WotBlitzStatisticsPro.DataAccess.Model.Accounts /// public long TankId { get; set; } - public bool Equals(TankInfoKey other) + public bool Equals(TankInfoKey? other) { if (ReferenceEquals(null, other)) return false; if (ReferenceEquals(this, other)) return true; return AccountId == other.AccountId && TankId == other.TankId; } - public override bool Equals(object obj) + public override bool Equals(object? obj) { if (ReferenceEquals(null, obj)) return false; if (ReferenceEquals(this, obj)) return true; diff --git a/WotBlitzStatisticsPro.DataAccess/Model/AchievementDictionary.cs b/WotBlitzStatisticsPro.DataAccess/Model/AchievementDictionary.cs index bcb8c1f..853912f 100644 --- a/WotBlitzStatisticsPro.DataAccess/Model/AchievementDictionary.cs +++ b/WotBlitzStatisticsPro.DataAccess/Model/AchievementDictionary.cs @@ -1,4 +1,5 @@ using System.Collections.Generic; +using System.Linq; using MongoDB.Bson.Serialization.Attributes; using WotBlitzStatisticsPro.Common.Dictionaries; @@ -6,19 +7,18 @@ namespace WotBlitzStatisticsPro.DataAccess.Model { public class AchievementDictionary : IAchievementDictionary { - [BsonId] - public string AchievementId { get; set; } - public List Condition { get; set; } - public List Description { get; set; } - public List HeroInfo { get; set; } - public string Image { get; set; } - public string ImageBig { get; set; } - public List Name { get; set; } + [BsonId] public string AchievementId { get; set; } = string.Empty; + public List Condition { get; set; } = Enumerable.Empty().ToList(); + public List Description { get; set; } = Enumerable.Empty().ToList(); + public List HeroInfo { get; set; } = Enumerable.Empty().ToList(); + public string Image { get; set; } = string.Empty; + public string ImageBig { get; set; } = string.Empty; + public List Name { get; set; } = Enumerable.Empty().ToList(); public long? Order { get; set; } public bool Outdated { get; set; } - public string SectionId { get; set; } + public string SectionId { get; set; } = string.Empty; public long? SectionOrder { get; set; } - public string Type { get; set; } - public List Options { get; set; } + public string Type { get; set; } = string.Empty; + public List Options { get; set; } = Enumerable.Empty().ToList(); } } \ No newline at end of file diff --git a/WotBlitzStatisticsPro.DataAccess/Model/AchievementSectionDictionary.cs b/WotBlitzStatisticsPro.DataAccess/Model/AchievementSectionDictionary.cs index 293f191..ea75c2a 100644 --- a/WotBlitzStatisticsPro.DataAccess/Model/AchievementSectionDictionary.cs +++ b/WotBlitzStatisticsPro.DataAccess/Model/AchievementSectionDictionary.cs @@ -1,4 +1,5 @@ using System.Collections.Generic; +using System.Linq; using MongoDB.Bson.Serialization.Attributes; using WotBlitzStatisticsPro.Common.Dictionaries; @@ -6,9 +7,10 @@ namespace WotBlitzStatisticsPro.DataAccess.Model { public class AchievementSectionDictionary: IAchievementSectionDictionary { - [BsonId] - public string AchievementSectionId { get; set; } + [BsonId] public string AchievementSectionId { get; set; } = string.Empty; public int Order { get; set; } - public List AchievementSectionNames { get; set; } + + public List AchievementSectionNames { get; set; } = + Enumerable.Empty().ToList(); } } \ No newline at end of file diff --git a/WotBlitzStatisticsPro.DataAccess/Model/ClanRoleDictionary.cs b/WotBlitzStatisticsPro.DataAccess/Model/ClanRoleDictionary.cs index 55fedf2..063612b 100644 --- a/WotBlitzStatisticsPro.DataAccess/Model/ClanRoleDictionary.cs +++ b/WotBlitzStatisticsPro.DataAccess/Model/ClanRoleDictionary.cs @@ -1,4 +1,5 @@ using System.Collections.Generic; +using System.Linq; using MongoDB.Bson.Serialization.Attributes; using WotBlitzStatisticsPro.Common.Dictionaries; @@ -6,8 +7,8 @@ namespace WotBlitzStatisticsPro.DataAccess.Model { public class ClanRoleDictionary : IClanRoleDictionary { - [BsonId] - public string ClanRoleId { get; set; } - public List ClanRoleNames { get; set; } + [BsonId] public string ClanRoleId { get; set; } = string.Empty; + public List ClanRoleNames { get; set; } = + Enumerable.Empty().ToList(); } } \ No newline at end of file diff --git a/WotBlitzStatisticsPro.DataAccess/Model/LanguageDictionary.cs b/WotBlitzStatisticsPro.DataAccess/Model/LanguageDictionary.cs index d546db4..f5a60cc 100644 --- a/WotBlitzStatisticsPro.DataAccess/Model/LanguageDictionary.cs +++ b/WotBlitzStatisticsPro.DataAccess/Model/LanguageDictionary.cs @@ -5,9 +5,8 @@ namespace WotBlitzStatisticsPro.DataAccess.Model { public class LanguageDictionary: ILanguageDictionary { - [BsonId] - public string LanguageId { get; set; } + [BsonId] public string LanguageId { get; set; } = string.Empty; - public string LanguageName { get; set; } + public string LanguageName { get; set; } = string.Empty; } } \ No newline at end of file diff --git a/WotBlitzStatisticsPro.DataAccess/Model/NationDictionary.cs b/WotBlitzStatisticsPro.DataAccess/Model/NationDictionary.cs index 36ca07a..7bb67d0 100644 --- a/WotBlitzStatisticsPro.DataAccess/Model/NationDictionary.cs +++ b/WotBlitzStatisticsPro.DataAccess/Model/NationDictionary.cs @@ -1,4 +1,5 @@ using System.Collections.Generic; +using System.Linq; using MongoDB.Bson.Serialization.Attributes; using WotBlitzStatisticsPro.Common.Dictionaries; @@ -6,8 +7,8 @@ namespace WotBlitzStatisticsPro.DataAccess.Model { public class NationDictionary : INationDictionary { - [BsonId] - public string NationId { get; set; } - public List NationNames { get; set; } + [BsonId] public string NationId { get; set; } = string.Empty; + public List NationNames { get; set; } = + Enumerable.Empty().ToList(); } } \ No newline at end of file diff --git a/WotBlitzStatisticsPro.DataAccess/Model/VehicleTypeDictionary.cs b/WotBlitzStatisticsPro.DataAccess/Model/VehicleTypeDictionary.cs index b20611b..ce0c8a2 100644 --- a/WotBlitzStatisticsPro.DataAccess/Model/VehicleTypeDictionary.cs +++ b/WotBlitzStatisticsPro.DataAccess/Model/VehicleTypeDictionary.cs @@ -1,4 +1,5 @@ using System.Collections.Generic; +using System.Linq; using MongoDB.Bson.Serialization.Attributes; using WotBlitzStatisticsPro.Common.Dictionaries; @@ -6,8 +7,8 @@ namespace WotBlitzStatisticsPro.DataAccess.Model { public class VehicleTypeDictionary : IVehicleTypeDictionary { - [BsonId] - public string VehicleTypeId { get; set; } - public List VehicleTypeNames { get; set; } + [BsonId] public string VehicleTypeId { get; set; } = string.Empty; + + public List VehicleTypeNames { get; set; } = Enumerable.Empty().ToList(); } } \ No newline at end of file diff --git a/WotBlitzStatisticsPro.DataAccess/Model/VehiclesDictionary.cs b/WotBlitzStatisticsPro.DataAccess/Model/VehiclesDictionary.cs index 0303991..f5ec992 100644 --- a/WotBlitzStatisticsPro.DataAccess/Model/VehiclesDictionary.cs +++ b/WotBlitzStatisticsPro.DataAccess/Model/VehiclesDictionary.cs @@ -1,4 +1,5 @@ using System.Collections.Generic; +using System.Linq; using MongoDB.Bson.Serialization.Attributes; using WotBlitzStatisticsPro.Common.Dictionaries; @@ -8,21 +9,25 @@ namespace WotBlitzStatisticsPro.DataAccess.Model { [BsonId] public long TankId { get; set; } - public List Name { get; set; } - public List Description { get; set; } + public List Name { get; set; } = + Enumerable.Empty().ToList(); + public List Description { get; set; } = + Enumerable.Empty().ToList(); public bool IsPremium { get; set; } - public string TypeId { get; set; } - public string NationId { get; set; } + public string TypeId { get; set; } = string.Empty; + public string NationId { get; set; } = string.Empty; public int Tier { get; set; } - public string PreviewImage { get; set; } - public string NormalImage { get; set; } + public string PreviewImage { get; set; } = string.Empty; + public string NormalImage { get; set; } = string.Empty; public decimal PriceCredit { get; set; } public decimal PriceGold { get; set; } - public List NexTanksInTree { get; set; } - public List PriceXp { get; set; } - public int[] Engines { get; set; } - public int[] Guns { get; set; } - public int[] Suspensions { get; set; } - public int[] Turrets { get; set; } + public List NexTanksInTree { get; set; } = + Enumerable.Empty().ToList(); + public List PriceXp { get; set; } = + Enumerable.Empty().ToList(); + public int[]? Engines { get; set; } + public int[]? Guns { get; set; } + public int[]? Suspensions { get; set; } + public int[]? Turrets { get; set; } } } \ No newline at end of file diff --git a/WotBlitzStatisticsPro.DataAccess/WotBlitzStatisticsPro.DataAccess.csproj b/WotBlitzStatisticsPro.DataAccess/WotBlitzStatisticsPro.DataAccess.csproj index 08fb3b8..faf43c8 100644 --- a/WotBlitzStatisticsPro.DataAccess/WotBlitzStatisticsPro.DataAccess.csproj +++ b/WotBlitzStatisticsPro.DataAccess/WotBlitzStatisticsPro.DataAccess.csproj @@ -2,6 +2,7 @@ net5.0 + enable diff --git a/WotBlitzStatisticsPro.GraphQl/MongoSettings.cs b/WotBlitzStatisticsPro.GraphQl/MongoSettings.cs index 06b7629..d3b5e7f 100644 --- a/WotBlitzStatisticsPro.GraphQl/MongoSettings.cs +++ b/WotBlitzStatisticsPro.GraphQl/MongoSettings.cs @@ -4,7 +4,7 @@ namespace WotBlitzStatisticsPro.GraphQl { public class MongoSettings : IMongoSettings { - public string ConnectionString { get; set; } - public string DatabaseName { get; set; } + public string ConnectionString { get; set; } = string.Empty; + public string DatabaseName { get; set; } = string.Empty; } } \ No newline at end of file diff --git a/WotBlitzStatisticsPro.GraphQl/WargamingApiSettings.cs b/WotBlitzStatisticsPro.GraphQl/WargamingApiSettings.cs index 4c57799..444ce46 100644 --- a/WotBlitzStatisticsPro.GraphQl/WargamingApiSettings.cs +++ b/WotBlitzStatisticsPro.GraphQl/WargamingApiSettings.cs @@ -4,8 +4,8 @@ namespace WotBlitzStatisticsPro.GraphQl { /// public class WargamingApiSettings : IWargamingApiSettings - { + { /// - public string ApplicationId { get; set; } - } + public string ApplicationId { get; set; } = string.Empty; + } } diff --git a/WotBlitzStatisticsPro.GraphQl/WotBlitzStatisticsPro.GraphQl.csproj b/WotBlitzStatisticsPro.GraphQl/WotBlitzStatisticsPro.GraphQl.csproj index c760d21..af9b300 100644 --- a/WotBlitzStatisticsPro.GraphQl/WotBlitzStatisticsPro.GraphQl.csproj +++ b/WotBlitzStatisticsPro.GraphQl/WotBlitzStatisticsPro.GraphQl.csproj @@ -4,6 +4,7 @@ net5.0 true $(NoWarn);1591 + enable diff --git a/WotBlitzStatisticsPro.Logic/AccountInformationPipeline/AccountHistoryInformationPipelineContextData.cs b/WotBlitzStatisticsPro.Logic/AccountInformationPipeline/AccountHistoryInformationPipelineContextData.cs index 59e2b3e..6778b04 100644 --- a/WotBlitzStatisticsPro.Logic/AccountInformationPipeline/AccountHistoryInformationPipelineContextData.cs +++ b/WotBlitzStatisticsPro.Logic/AccountInformationPipeline/AccountHistoryInformationPipelineContextData.cs @@ -13,14 +13,14 @@ namespace WotBlitzStatisticsPro.Logic.AccountInformationPipeline public DateTime LastBattleSince { get; } - public AccountInfo DbAccountInfo { get; set; } + public AccountInfo? DbAccountInfo { get; set; } - public IStatistics[] History { get; set; } - public ShortStatistics OverallStatistics { get; set; } - public ShortStatistics PeriodAccountStatistics { get; set; } - public StatisticsDifference PeriodDifference { get; set; } - public StatisticsDifference[] StatisticsHistory { get; set; } + public IStatistics[]? History { get; set; } + public ShortStatistics? OverallStatistics { get; set; } + public ShortStatistics? PeriodAccountStatistics { get; set; } + public StatisticsDifference? PeriodDifference { get; set; } + public StatisticsDifference[]? StatisticsHistory { get; set; } - public AccountInfoHistoryResponse Response { get; set; } + public AccountInfoHistoryResponse? Response { get; set; } } } \ No newline at end of file diff --git a/WotBlitzStatisticsPro.Logic/AccountInformationPipeline/AccountInformationPipelineContextData.cs b/WotBlitzStatisticsPro.Logic/AccountInformationPipeline/AccountInformationPipelineContextData.cs index 557d2ad..4205e73 100644 --- a/WotBlitzStatisticsPro.Logic/AccountInformationPipeline/AccountInformationPipelineContextData.cs +++ b/WotBlitzStatisticsPro.Logic/AccountInformationPipeline/AccountInformationPipelineContextData.cs @@ -6,17 +6,17 @@ namespace WotBlitzStatisticsPro.Logic.AccountInformationPipeline { public class AccountInformationPipelineContextData : IDatabasePipelineContextData { - public AccountInfo AccountInfo { get; set; } + public AccountInfo? AccountInfo { get; set; } - public AccountInfoHistory AccountInfoHistory { get; set; } + public AccountInfoHistory? AccountInfoHistory { get; set; } - public List Tanks { get; set; } + public List? Tanks { get; set; } - public Dictionary TanksHistory { get; set; } + public Dictionary? TanksHistory { get; set; } - public AccountInfoResponse Response { get; set; } + public AccountInfoResponse? Response { get; set; } - public AccountInfo DbAccountInfo { get; set; } + public AccountInfo? DbAccountInfo { get; set; } } } \ No newline at end of file diff --git a/WotBlitzStatisticsPro.Logic/AccountInformationPipeline/IDatabasePipelineContextData.cs b/WotBlitzStatisticsPro.Logic/AccountInformationPipeline/IDatabasePipelineContextData.cs index 2b5e8dd..eabb284 100644 --- a/WotBlitzStatisticsPro.Logic/AccountInformationPipeline/IDatabasePipelineContextData.cs +++ b/WotBlitzStatisticsPro.Logic/AccountInformationPipeline/IDatabasePipelineContextData.cs @@ -5,6 +5,6 @@ namespace WotBlitzStatisticsPro.Logic.AccountInformationPipeline { public interface IDatabasePipelineContextData { - AccountInfo DbAccountInfo { get; set; } + AccountInfo? DbAccountInfo { get; set; } } } \ No newline at end of file diff --git a/WotBlitzStatisticsPro.Logic/AccountInformationPipeline/IStatisticsPipelineData.cs b/WotBlitzStatisticsPro.Logic/AccountInformationPipeline/IStatisticsPipelineData.cs index bf89ece..a7e0ade 100644 --- a/WotBlitzStatisticsPro.Logic/AccountInformationPipeline/IStatisticsPipelineData.cs +++ b/WotBlitzStatisticsPro.Logic/AccountInformationPipeline/IStatisticsPipelineData.cs @@ -4,15 +4,15 @@ namespace WotBlitzStatisticsPro.Logic.AccountInformationPipeline { public interface IStatisticsPipelineData { - IStatistics[] History { get; set; } + IStatistics[]? History { get; set; } - ShortStatistics OverallStatistics { get; set; } + ShortStatistics? OverallStatistics { get; set; } - public ShortStatistics PeriodAccountStatistics { get; set; } + public ShortStatistics? PeriodAccountStatistics { get; set; } - public StatisticsDifference PeriodDifference { get; set; } + public StatisticsDifference? PeriodDifference { get; set; } - public StatisticsDifference[] StatisticsHistory { get; set; } + public StatisticsDifference[]? StatisticsHistory { get; set; } } } \ No newline at end of file diff --git a/WotBlitzStatisticsPro.Logic/AccountInformationPipeline/OperationContext/OperationContext.cs b/WotBlitzStatisticsPro.Logic/AccountInformationPipeline/OperationContext/OperationContext.cs index 1bb2f39..007bc43 100644 --- a/WotBlitzStatisticsPro.Logic/AccountInformationPipeline/OperationContext/OperationContext.cs +++ b/WotBlitzStatisticsPro.Logic/AccountInformationPipeline/OperationContext/OperationContext.cs @@ -2,7 +2,7 @@ { public class OperationContext : IOperationContext { - private object _contextData; + private object? _contextData; public OperationContext(AccountRequest request) @@ -21,7 +21,7 @@ { _contextData ??= default(TContextData); - return (TContextData)_contextData; + return (TContextData)_contextData!; } } } \ No newline at end of file diff --git a/WotBlitzStatisticsPro.Logic/AccountInformationPipeline/Operations/BuildAccountInfoResponseOperation.cs b/WotBlitzStatisticsPro.Logic/AccountInformationPipeline/Operations/BuildAccountInfoResponseOperation.cs index 1e7bd8a..39944fd 100644 --- a/WotBlitzStatisticsPro.Logic/AccountInformationPipeline/Operations/BuildAccountInfoResponseOperation.cs +++ b/WotBlitzStatisticsPro.Logic/AccountInformationPipeline/Operations/BuildAccountInfoResponseOperation.cs @@ -3,6 +3,7 @@ using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using AutoMapper; +using Microsoft.Extensions.Logging; using WotBlitzStatisticsPro.Common.Dictionaries; using WotBlitzStatisticsPro.Common.Model; using WotBlitzStatisticsPro.DataAccess; @@ -17,17 +18,31 @@ namespace WotBlitzStatisticsPro.Logic.AccountInformationPipeline.Operations { private readonly IMapper _mapper; private readonly IDictionariesDataAccessor _dictionariesDataAccessor; + private readonly ILogger _logger; - public BuildAccountInfoResponseOperation(IMapper mapper, IDictionariesDataAccessor dictionariesDataAccessor) + public BuildAccountInfoResponseOperation( + IMapper mapper, + IDictionariesDataAccessor dictionariesDataAccessor, + ILogger logger) { _mapper = mapper; _dictionariesDataAccessor = dictionariesDataAccessor; + _logger = logger; } - public async Task Invoke(IOperationContext context, Func next) + public async Task Invoke(IOperationContext context, Func? next) { var contextData = context.Get(); + if (contextData?.AccountInfo == null + || contextData?.Tanks == null + || contextData?.TanksHistory == null) + { + _logger.LogInformation( + $"contextData or AccountInfo or Tanks or TanksHistory is null"); + return; + } + contextData.Response = _mapper.Map(contextData.AccountInfo); contextData.Response = _mapper.Map(contextData.AccountInfoHistory, contextData.Response); @@ -48,13 +63,23 @@ namespace WotBlitzStatisticsPro.Logic.AccountInformationPipeline.Operations opt.Items["language"] = context.Request.RequestLanguage; opt.AfterMap((src, dest) => { - dest.TankType = tankTypes.ContainsKey(dest.TankTypeId) ? tankTypes[dest.TankTypeId] : "-"; - dest.TankNation = nations.ContainsKey(dest.TankNationId) ? nations[dest.TankNationId] : "-"; + if(dest?.TankTypeId != null) + { + dest.TankType = tankTypes.ContainsKey(dest.TankTypeId) + ? tankTypes[dest.TankTypeId] + : "-"; + } + if(dest?.TankNationId != null) + { + dest.TankNation = nations.ContainsKey(dest.TankNationId) + ? nations[dest.TankNationId] + : "-"; + } }); }); }); - await next.Invoke(context); + if (next != null) await next.Invoke(context); } private static IVehiclesDictionary CreateStubVehicle() diff --git a/WotBlitzStatisticsPro.Logic/AccountInformationPipeline/Operations/CalculateStatisticsOperation.cs b/WotBlitzStatisticsPro.Logic/AccountInformationPipeline/Operations/CalculateStatisticsOperation.cs index 8b40d58..99f106a 100644 --- a/WotBlitzStatisticsPro.Logic/AccountInformationPipeline/Operations/CalculateStatisticsOperation.cs +++ b/WotBlitzStatisticsPro.Logic/AccountInformationPipeline/Operations/CalculateStatisticsOperation.cs @@ -17,9 +17,16 @@ namespace WotBlitzStatisticsPro.Logic.AccountInformationPipeline.Operations _dictionariesDataAccessor = dictionariesDataAccessor; } - public async Task Invoke(IOperationContext context, Func next) + public async Task Invoke(IOperationContext context, Func? next) { var contextData = context.Get(); + if (contextData?.AccountInfo == null || + contextData?.AccountInfoHistory == null || + contextData?.Tanks == null || + contextData?.TanksHistory == null) + { + return; + } var tankIds = contextData.Tanks.Select(t => t.TankId).ToArray(); var tankTires = await _dictionariesDataAccessor.GetTankTires(tankIds); @@ -36,7 +43,7 @@ namespace WotBlitzStatisticsPro.Logic.AccountInformationPipeline.Operations contextData.AccountInfoHistory.CalculateMiddleTier(contextData.TanksHistory.Values.ToList(), tankTires); contextData.AccountInfoHistory.CalculateWn7(); - await next.Invoke(context); + if (next != null) await next.Invoke(context); } } } \ No newline at end of file diff --git a/WotBlitzStatisticsPro.Logic/AccountInformationPipeline/Operations/CheckIfHistoryIsEmptyOperation.cs b/WotBlitzStatisticsPro.Logic/AccountInformationPipeline/Operations/CheckIfHistoryIsEmptyOperation.cs index d4c8d35..37fcfd8 100644 --- a/WotBlitzStatisticsPro.Logic/AccountInformationPipeline/Operations/CheckIfHistoryIsEmptyOperation.cs +++ b/WotBlitzStatisticsPro.Logic/AccountInformationPipeline/Operations/CheckIfHistoryIsEmptyOperation.cs @@ -16,11 +16,11 @@ namespace WotBlitzStatisticsPro.Logic.AccountInformationPipeline.Operations } - public Task Invoke(IOperationContext context, Func next) + public Task Invoke(IOperationContext context, Func? next) { var contextData = context.Get(); - if (contextData.History == null || + if (contextData?.History == null || contextData.History.Length == 0) { _logger.LogInformation( @@ -28,7 +28,7 @@ namespace WotBlitzStatisticsPro.Logic.AccountInformationPipeline.Operations return Task.CompletedTask; } - return next.Invoke(context); + return next != null ? next.Invoke(context) : Task.CompletedTask; } } } \ No newline at end of file diff --git a/WotBlitzStatisticsPro.Logic/AccountInformationPipeline/Operations/CheckLAstBattleDateOperation.cs b/WotBlitzStatisticsPro.Logic/AccountInformationPipeline/Operations/CheckLAstBattleDateOperation.cs index d8e12bc..51927f9 100644 --- a/WotBlitzStatisticsPro.Logic/AccountInformationPipeline/Operations/CheckLAstBattleDateOperation.cs +++ b/WotBlitzStatisticsPro.Logic/AccountInformationPipeline/Operations/CheckLAstBattleDateOperation.cs @@ -15,16 +15,16 @@ namespace WotBlitzStatisticsPro.Logic.AccountInformationPipeline.Operations _logger = logger; } - public Task Invoke(IOperationContext context, Func next) + public Task Invoke(IOperationContext context, Func? next) { var contextData = context.Get(); if (contextData.DbAccountInfo == null || - contextData.DbAccountInfo.LastBattleTime < contextData.AccountInfo.LastBattleTime) + contextData.DbAccountInfo.LastBattleTime < contextData.AccountInfo?.LastBattleTime) { - return next.Invoke(context); + if (next != null) return next.Invoke(context); } - _logger.LogInformation($"Exiting without saving. Db LastBattleTime: {contextData.DbAccountInfo.LastBattleTime}, WG LastBattleTime: {contextData.AccountInfo.LastBattleTime}"); + _logger.LogInformation($"Exiting without saving. Db LastBattleTime: {contextData.DbAccountInfo?.LastBattleTime}, WG LastBattleTime: {contextData.AccountInfo?.LastBattleTime}"); return Task.CompletedTask; } } diff --git a/WotBlitzStatisticsPro.Logic/AccountInformationPipeline/Operations/FillAccountInfoHistoryResponse.cs b/WotBlitzStatisticsPro.Logic/AccountInformationPipeline/Operations/FillAccountInfoHistoryResponse.cs index 9afa183..476b1cc 100644 --- a/WotBlitzStatisticsPro.Logic/AccountInformationPipeline/Operations/FillAccountInfoHistoryResponse.cs +++ b/WotBlitzStatisticsPro.Logic/AccountInformationPipeline/Operations/FillAccountInfoHistoryResponse.cs @@ -9,10 +9,15 @@ namespace WotBlitzStatisticsPro.Logic.AccountInformationPipeline.Operations { public class FillAccountInfoHistoryResponse : IOperation { - public Task Invoke(IOperationContext context, Func next) + public Task Invoke(IOperationContext context, Func? next) { var contextData = context.Get(); + if (contextData?.DbAccountInfo == null) + { + return next != null ? next.Invoke(context) : Task.CompletedTask; + } + contextData.Response = new AccountInfoHistoryResponse { AccountId = context.Request.AccountId, @@ -24,7 +29,7 @@ namespace WotBlitzStatisticsPro.Logic.AccountInformationPipeline.Operations OverallAccountStatistics = contextData.OverallStatistics }; - return next.Invoke(context); + return next != null ? next.Invoke(context) : Task.CompletedTask; } } } \ No newline at end of file diff --git a/WotBlitzStatisticsPro.Logic/AccountInformationPipeline/Operations/FillOverallStatisticsOperation.cs b/WotBlitzStatisticsPro.Logic/AccountInformationPipeline/Operations/FillOverallStatisticsOperation.cs index 410e8dc..72c10da 100644 --- a/WotBlitzStatisticsPro.Logic/AccountInformationPipeline/Operations/FillOverallStatisticsOperation.cs +++ b/WotBlitzStatisticsPro.Logic/AccountInformationPipeline/Operations/FillOverallStatisticsOperation.cs @@ -17,13 +17,16 @@ namespace WotBlitzStatisticsPro.Logic.AccountInformationPipeline.Operations } - public Task Invoke(IOperationContext context, Func next) + public Task Invoke(IOperationContext context, Func? next) { var contextData = context.Get(); - contextData.OverallStatistics = _mapper.Map(contextData.History[0]); + if(contextData?.History != null) + { + contextData.OverallStatistics = _mapper.Map(contextData.History[0]); + } - return next.Invoke(context); + return next != null ? next.Invoke(context) : Task.CompletedTask; } } } \ No newline at end of file diff --git a/WotBlitzStatisticsPro.Logic/AccountInformationPipeline/Operations/FillPeriodDifferenceOperation.cs b/WotBlitzStatisticsPro.Logic/AccountInformationPipeline/Operations/FillPeriodDifferenceOperation.cs index 7bbace2..b8075ef 100644 --- a/WotBlitzStatisticsPro.Logic/AccountInformationPipeline/Operations/FillPeriodDifferenceOperation.cs +++ b/WotBlitzStatisticsPro.Logic/AccountInformationPipeline/Operations/FillPeriodDifferenceOperation.cs @@ -1,6 +1,5 @@ using System; using System.Threading.Tasks; -using AutoMapper; using WotBlitzStatisticsPro.Common.Model; using WotBlitzStatisticsPro.Logic.AccountInformationPipeline.OperationContext; using WotBlitzStatisticsPro.Logic.Calculations; @@ -10,11 +9,11 @@ namespace WotBlitzStatisticsPro.Logic.AccountInformationPipeline.Operations { public class FillPeriodDifferenceOperation : IOperation { - public Task Invoke(IOperationContext context, Func next) + public Task Invoke(IOperationContext context, Func? next) { var contextData = context.Get(); - if (contextData.History.Length > 1) + if (contextData?.History != null && contextData.History.Length > 1) { contextData.PeriodDifference = new StatisticsDifference(); var historyLastIndex = contextData.History.Length - 1; @@ -22,7 +21,7 @@ namespace WotBlitzStatisticsPro.Logic.AccountInformationPipeline.Operations contextData.PeriodDifference.FillDifference(contextData.History[0], contextData.History[historyLastIndex]); } - return next.Invoke(context); + return next != null ? next.Invoke(context) : Task.CompletedTask; } } } \ No newline at end of file diff --git a/WotBlitzStatisticsPro.Logic/AccountInformationPipeline/Operations/FillPeriodStatisticsOperation.cs b/WotBlitzStatisticsPro.Logic/AccountInformationPipeline/Operations/FillPeriodStatisticsOperation.cs index 5ea6093..85dbf9e 100644 --- a/WotBlitzStatisticsPro.Logic/AccountInformationPipeline/Operations/FillPeriodStatisticsOperation.cs +++ b/WotBlitzStatisticsPro.Logic/AccountInformationPipeline/Operations/FillPeriodStatisticsOperation.cs @@ -18,11 +18,11 @@ namespace WotBlitzStatisticsPro.Logic.AccountInformationPipeline.Operations } - public Task Invoke(IOperationContext context, Func next) + public Task Invoke(IOperationContext context, Func? next) { var contextData = context.Get(); - if (contextData.History.Length > 1) + if (contextData?.History != null && contextData.History.Length > 1) { var diff = new AccountInfoHistory(context.Request.AccountId, contextData.History[0].LastBattleTime); @@ -36,7 +36,7 @@ namespace WotBlitzStatisticsPro.Logic.AccountInformationPipeline.Operations contextData.PeriodAccountStatistics = _mapper.Map(diff); } - return next.Invoke(context); + return next != null ? next.Invoke(context) : Task.CompletedTask; } } } \ No newline at end of file diff --git a/WotBlitzStatisticsPro.Logic/AccountInformationPipeline/Operations/FillStatisticsDifferenceOperation.cs b/WotBlitzStatisticsPro.Logic/AccountInformationPipeline/Operations/FillStatisticsDifferenceOperation.cs index 5485669..9e94c12 100644 --- a/WotBlitzStatisticsPro.Logic/AccountInformationPipeline/Operations/FillStatisticsDifferenceOperation.cs +++ b/WotBlitzStatisticsPro.Logic/AccountInformationPipeline/Operations/FillStatisticsDifferenceOperation.cs @@ -10,11 +10,11 @@ namespace WotBlitzStatisticsPro.Logic.AccountInformationPipeline.Operations { public class FillStatisticsDifferenceOperation : IOperation { - public Task Invoke(IOperationContext context, Func next) + public Task Invoke(IOperationContext context, Func? next) { var contextData = context.Get(); - if (contextData.History.Length > 1) + if (contextData?.History != null && contextData.History.Length > 1) { contextData.StatisticsHistory = new StatisticsDifference[contextData.History.Length - 1]; for (int i = 1; i < contextData.History.Length; i++) @@ -24,7 +24,7 @@ namespace WotBlitzStatisticsPro.Logic.AccountInformationPipeline.Operations } } - return next.Invoke(context); + return next != null ? next.Invoke(context) : Task.CompletedTask; } } } \ No newline at end of file diff --git a/WotBlitzStatisticsPro.Logic/AccountInformationPipeline/Operations/GetAccountInfoOperation.cs b/WotBlitzStatisticsPro.Logic/AccountInformationPipeline/Operations/GetAccountInfoOperation.cs index ee129db..85663d9 100644 --- a/WotBlitzStatisticsPro.Logic/AccountInformationPipeline/Operations/GetAccountInfoOperation.cs +++ b/WotBlitzStatisticsPro.Logic/AccountInformationPipeline/Operations/GetAccountInfoOperation.cs @@ -1,6 +1,7 @@ using System; using System.Threading.Tasks; using AutoMapper; +using Microsoft.Extensions.Logging; using WotBlitzStatisticsPro.DataAccess.Model.Accounts; using WotBlitzStatisticsPro.Logic.AccountInformationPipeline.OperationContext; using WotBlitzStatisticsPro.Logic.Pipeline; @@ -13,29 +14,39 @@ namespace WotBlitzStatisticsPro.Logic.AccountInformationPipeline.Operations { private readonly IWargamingApiClient _wargamingApi; private readonly IMapper _mapper; + private readonly ILogger _logger; public GetAccountInfoOperation( IWargamingApiClient wargamingApi, - IMapper mapper) + IMapper mapper, + ILogger logger) { _wargamingApi = wargamingApi; _mapper = mapper; + _logger = logger; } - public async Task Invoke(IOperationContext context, Func next) + public async Task Invoke(IOperationContext context, Func? next) { var accountInfo = await _wargamingApi.GetPlayerAccountInfo(context.Request.AccountId, context.Request.RealmType, context.Request.RequestLanguage); + if (accountInfo == null) + { + _logger.LogInformation( + $"Account not found for AccountId {context.Request.AccountId} and {context.Request.RealmType} realm"); + return; + } + // Store info to AccountInfo and in AccountInfoHistory var contextData = context.Get(); contextData.AccountInfo = _mapper.Map(accountInfo); contextData.AccountInfo.Realm = context.Request.RealmType; contextData.AccountInfoHistory = new AccountInfoHistory(context.Request.AccountId, contextData.AccountInfo.LastBattleTime); - _mapper.Map(accountInfo.Statistics.All, contextData.AccountInfoHistory); + _mapper.Map(accountInfo.Statistics?.All, contextData.AccountInfoHistory); - await next.Invoke(context); + if (next != null) await next.Invoke(context); } } } \ No newline at end of file diff --git a/WotBlitzStatisticsPro.Logic/AccountInformationPipeline/Operations/GetTanksInfoOperation.cs b/WotBlitzStatisticsPro.Logic/AccountInformationPipeline/Operations/GetTanksInfoOperation.cs index da2f743..ccb1851 100644 --- a/WotBlitzStatisticsPro.Logic/AccountInformationPipeline/Operations/GetTanksInfoOperation.cs +++ b/WotBlitzStatisticsPro.Logic/AccountInformationPipeline/Operations/GetTanksInfoOperation.cs @@ -1,12 +1,13 @@ using System; using System.Collections.Generic; +using System.Linq; using System.Threading.Tasks; using AutoMapper; +using Microsoft.Extensions.Logging; using WotBlitzStatisticsPro.DataAccess.Model.Accounts; using WotBlitzStatisticsPro.Logic.AccountInformationPipeline.OperationContext; using WotBlitzStatisticsPro.Logic.Pipeline; using WotBlitzStatisticsPro.WgApiClient; -using WotBlitzStatisticsPro.WgApiClient.Model; namespace WotBlitzStatisticsPro.Logic.AccountInformationPipeline.Operations { @@ -14,26 +15,36 @@ namespace WotBlitzStatisticsPro.Logic.AccountInformationPipeline.Operations { private readonly IWargamingTanksApiClient _wargamingApi; private readonly IMapper _mapper; + private readonly ILogger _logger; public GetTanksInfoOperation( IWargamingTanksApiClient wargamingApi, - IMapper mapper) + IMapper mapper, + ILogger logger) { _wargamingApi = wargamingApi; _mapper = mapper; + _logger = logger; } - public async Task Invoke(IOperationContext context, Func next) + public async Task Invoke(IOperationContext context, Func? next) { var contextData = context.Get(); var tanksInfo = await _wargamingApi.GetPlayerAccountTanksInfo(context.Request.AccountId, context.Request.RealmType, context.Request.RequestLanguage); + if (tanksInfo == null) + { + _logger.LogInformation( + $"Tanks not found for AccountId {context.Request.AccountId} and {context.Request.RealmType} realm"); + return; + } + contextData.Tanks = new List(); contextData.TanksHistory = new Dictionary(); - tanksInfo.ForEach(tank => + tanksInfo.OrderByDescending(t => t.LastBattleTime).ToList().ForEach(tank => { var tankInfo = new TankInfo(tank.AccountId, tank.TankId); _mapper.Map(tank, tankInfo); @@ -43,7 +54,7 @@ namespace WotBlitzStatisticsPro.Logic.AccountInformationPipeline.Operations contextData.TanksHistory[stat.TankId] = stat; }); - await next.Invoke(context); + if (next != null) await next.Invoke(context); } } } \ No newline at end of file diff --git a/WotBlitzStatisticsPro.Logic/AccountInformationPipeline/Operations/ReadAccountInfoFromDbOperation.cs b/WotBlitzStatisticsPro.Logic/AccountInformationPipeline/Operations/ReadAccountInfoFromDbOperation.cs index d688460..c0b33da 100644 --- a/WotBlitzStatisticsPro.Logic/AccountInformationPipeline/Operations/ReadAccountInfoFromDbOperation.cs +++ b/WotBlitzStatisticsPro.Logic/AccountInformationPipeline/Operations/ReadAccountInfoFromDbOperation.cs @@ -15,12 +15,12 @@ namespace WotBlitzStatisticsPro.Logic.AccountInformationPipeline.Operations _accountDataAccessor = accountDataAccessor; } - public async Task Invoke(IOperationContext context, Func next) + public async Task Invoke(IOperationContext context, Func? next) { var contextData = context.Get(); contextData.DbAccountInfo = await _accountDataAccessor.ReadAccountInfo(context.Request.AccountId); - await next.Invoke(context); + if (next != null) await next.Invoke(context); } } } \ No newline at end of file diff --git a/WotBlitzStatisticsPro.Logic/AccountInformationPipeline/Operations/ReadAccountInfoHistoryFromDbOperation.cs b/WotBlitzStatisticsPro.Logic/AccountInformationPipeline/Operations/ReadAccountInfoHistoryFromDbOperation.cs index 97a02bf..266b408 100644 --- a/WotBlitzStatisticsPro.Logic/AccountInformationPipeline/Operations/ReadAccountInfoHistoryFromDbOperation.cs +++ b/WotBlitzStatisticsPro.Logic/AccountInformationPipeline/Operations/ReadAccountInfoHistoryFromDbOperation.cs @@ -17,12 +17,12 @@ namespace WotBlitzStatisticsPro.Logic.AccountInformationPipeline.Operations _accountDataAccessor = accountDataAccessor; } - public async Task Invoke(IOperationContext context, Func next) + public async Task Invoke(IOperationContext context, Func? next) { var contextData = context.Get(); contextData.History = (await _accountDataAccessor.GetAccountHistory(context.Request.AccountId, contextData.LastBattleSince.ToUnixTimestamp())).ToArray(); - await next.Invoke(context); + if (next != null) await next.Invoke(context); } } } \ No newline at end of file diff --git a/WotBlitzStatisticsPro.Logic/AccountInformationPipeline/Operations/SaveAccountAndTanksOperation.cs b/WotBlitzStatisticsPro.Logic/AccountInformationPipeline/Operations/SaveAccountAndTanksOperation.cs index 197bb62..a1805a3 100644 --- a/WotBlitzStatisticsPro.Logic/AccountInformationPipeline/Operations/SaveAccountAndTanksOperation.cs +++ b/WotBlitzStatisticsPro.Logic/AccountInformationPipeline/Operations/SaveAccountAndTanksOperation.cs @@ -22,10 +22,18 @@ namespace WotBlitzStatisticsPro.Logic.AccountInformationPipeline.Operations _logger = logger; } - public async Task Invoke(IOperationContext context, Func next) + public async Task Invoke(IOperationContext context, Func? next) { var contextData = context.Get(); + if (contextData?.AccountInfo == null || + contextData?.AccountInfoHistory == null || + contextData?.Tanks == null || + contextData?.TanksHistory == null) + { + return; + } + await _accountDataAccessor.AddOurUpdateAccountInfo(contextData.AccountInfo); await _accountDataAccessor.AddAccountInfoHistory(contextData.AccountInfoHistory); @@ -46,7 +54,7 @@ namespace WotBlitzStatisticsPro.Logic.AccountInformationPipeline.Operations _logger.LogInformation($"Updated account {contextData.AccountInfo.AccountId} and {tanksCount} tanks: {tankIdsAsString}"); - await next.Invoke(context); + if (next != null) await next.Invoke(context); } } } \ No newline at end of file diff --git a/WotBlitzStatisticsPro.Logic/Dictionaries/AchievementsDictionaryUpdater.cs b/WotBlitzStatisticsPro.Logic/Dictionaries/AchievementsDictionaryUpdater.cs index 7d31de7..52aa02a 100644 --- a/WotBlitzStatisticsPro.Logic/Dictionaries/AchievementsDictionaryUpdater.cs +++ b/WotBlitzStatisticsPro.Logic/Dictionaries/AchievementsDictionaryUpdater.cs @@ -21,7 +21,9 @@ namespace WotBlitzStatisticsPro.Logic.Dictionaries [Obsolete("Parameter-less constructor only for unit tests")] public AchievementsDictionaryUpdater() { - + _wargamingDictionariesApiClient = null!; + _dataAccessor = null!; + _mapper = null!; } public AchievementsDictionaryUpdater(IWargamingDictionariesApiClient wargamingDictionariesApiClient, IDictionariesDataAccessor dataAccessor, IMapper mapper) @@ -54,6 +56,10 @@ namespace WotBlitzStatisticsPro.Logic.Dictionaries { var wgAchievements = await _wargamingDictionariesApiClient.GetAchievementsDictionary(defaultRealmType, requestLanguage); + if (wgAchievements == null) + { + continue; + } foreach (var wgAchievement in wgAchievements) { var mappedAchievement = @@ -88,8 +94,8 @@ namespace WotBlitzStatisticsPro.Logic.Dictionaries wgAchievementOption); mappedAchievement.Options.Add(mappedOption); } - mappedOption.Name.Add(new LocalizableString { Language = requestLanguage, Value = wgAchievement.Name }); - mappedOption.Description.Add(new LocalizableString { Language = requestLanguage, Value = wgAchievement.Description }); + mappedOption.Name?.Add(new LocalizableString { Language = requestLanguage, Value = wgAchievement.Name }); + mappedOption.Description?.Add(new LocalizableString { Language = requestLanguage, Value = wgAchievement.Description }); } } } diff --git a/WotBlitzStatisticsPro.Logic/Dictionaries/StaticDictionariesUpdater.cs b/WotBlitzStatisticsPro.Logic/Dictionaries/StaticDictionariesUpdater.cs index 5d5c973..235d278 100644 --- a/WotBlitzStatisticsPro.Logic/Dictionaries/StaticDictionariesUpdater.cs +++ b/WotBlitzStatisticsPro.Logic/Dictionaries/StaticDictionariesUpdater.cs @@ -21,7 +21,9 @@ namespace WotBlitzStatisticsPro.Logic.Dictionaries [Obsolete("Parameter-less constructor only for unit tests")] public StaticDictionariesUpdater() { - + _wargamingDictionariesApiClient = null!; + _dataAccessor = null!; + _mapper = null!; } public StaticDictionariesUpdater( @@ -42,30 +44,45 @@ namespace WotBlitzStatisticsPro.Logic.Dictionaries clanRoles, achievementsSections) = await GetAndMapDictionaries(); - await _dataAccessor.UpdateLanguages(languages); - await _dataAccessor.UpdateNations(nations); - await _dataAccessor.UpdateVehicleTypes(vehicleTypes); - await _dataAccessor.UpdateClanRoles(clanRoles); - await _dataAccessor.UpdateAchievementsSections(achievementsSections); + if(languages != null) + { + await _dataAccessor.UpdateLanguages(languages); + } + if(nations != null) + { + await _dataAccessor.UpdateNations(nations); + } + if(vehicleTypes != null) + { + await _dataAccessor.UpdateVehicleTypes(vehicleTypes); + } + if(clanRoles != null) + { + await _dataAccessor.UpdateClanRoles(clanRoles); + } + if(achievementsSections != null) + { + await _dataAccessor.UpdateAchievementsSections(achievementsSections); + } return new UpdateDictionariesResponseItem { DictionaryType = DictionaryType.StaticDictionaries, Description = - $"Updated {languages.Count} items in Languages dictionary; {nations.Count} items in Nations dictionary; {vehicleTypes.Count} items in VehicleTypes dictionary; {clanRoles.Count} items in ClanRoles dictionary; {achievementsSections.Count} items in AchievementsSections dictionary" + $"Updated {languages?.Count} items in Languages dictionary; {nations?.Count} items in Nations dictionary; {vehicleTypes?.Count} items in VehicleTypes dictionary; {clanRoles?.Count} items in ClanRoles dictionary; {achievementsSections?.Count} items in AchievementsSections dictionary" }; } private async Task<( - List, - List, - List, - List, - List)> GetAndMapDictionaries() + List?, + List?, + List?, + List?, + List?)> GetAndMapDictionaries() { var defaultRealmType = RealmType.Eu; - List languages = null; + List? languages = null; var nations = new List(); var vehicleTypes = new List(); var clanRoles = new List(); @@ -76,17 +93,14 @@ namespace WotBlitzStatisticsPro.Logic.Dictionaries var (wotEncyclopediaInfoResponse, wotClanMembersDictionaryResponse) = await _wargamingDictionariesApiClient.GetStaticDictionariesAsync(defaultRealmType, requestLanguage); - if (languages == null) - { - languages = - _mapper.Map, List>(wotEncyclopediaInfoResponse - .Languages).Cast().ToList(); - } + if (wotEncyclopediaInfoResponse?.Languages != null) + languages ??= _mapper + .Map, List>(wotEncyclopediaInfoResponse.Languages).Cast().ToList(); - MapVehicleNations(requestLanguage, wotEncyclopediaInfoResponse.VehicleNations, nations); - MapVehicleTypes(requestLanguage, wotEncyclopediaInfoResponse.VehicleTypes, vehicleTypes); - MapClanRoles(requestLanguage, wotClanMembersDictionaryResponse.ClanRoles, clanRoles); - MapAchievementsSections(requestLanguage, wotEncyclopediaInfoResponse.AchievementSections, achievementsSections); + MapVehicleNations(requestLanguage, wotEncyclopediaInfoResponse?.VehicleNations, nations); + MapVehicleTypes(requestLanguage, wotEncyclopediaInfoResponse?.VehicleTypes, vehicleTypes); + MapClanRoles(requestLanguage, wotClanMembersDictionaryResponse?.ClanRoles, clanRoles); + MapAchievementsSections(requestLanguage, wotEncyclopediaInfoResponse?.AchievementSections, achievementsSections); } return (languages, nations, vehicleTypes, clanRoles, achievementsSections); @@ -94,9 +108,13 @@ namespace WotBlitzStatisticsPro.Logic.Dictionaries private void MapVehicleNations( RequestLanguage requestLanguage, - Dictionary sourceDictionary, + Dictionary? sourceDictionary, List destinationDictionary) { + if (sourceDictionary == null) + { + return; + } foreach (var source in sourceDictionary) { var destinationItem = destinationDictionary.FirstOrDefault(d => d.NationId == source.Key); @@ -116,9 +134,14 @@ namespace WotBlitzStatisticsPro.Logic.Dictionaries private void MapVehicleTypes( RequestLanguage requestLanguage, - Dictionary sourceDictionary, + Dictionary? sourceDictionary, List destinationDictionary) { + if (sourceDictionary == null) + { + return; + } + foreach (var source in sourceDictionary) { var destinationItem = destinationDictionary.FirstOrDefault(d => d.VehicleTypeId == source.Key); @@ -138,9 +161,14 @@ namespace WotBlitzStatisticsPro.Logic.Dictionaries private void MapClanRoles( RequestLanguage requestLanguage, - Dictionary sourceDictionary, + Dictionary? sourceDictionary, List destinationDictionary) { + if (sourceDictionary == null) + { + return; + } + foreach (var source in sourceDictionary) { var destinationItem = destinationDictionary.FirstOrDefault(d => d.ClanRoleId == source.Key); @@ -160,9 +188,14 @@ namespace WotBlitzStatisticsPro.Logic.Dictionaries private void MapAchievementsSections( RequestLanguage requestLanguage, - Dictionary sourceSections, + Dictionary? sourceSections, List destinationDictionary) { + if (sourceSections == null) + { + return; + } + foreach (var section in sourceSections) { var destinationItem = diff --git a/WotBlitzStatisticsPro.Logic/Dictionaries/VehiclesDictionaryUpdater.cs b/WotBlitzStatisticsPro.Logic/Dictionaries/VehiclesDictionaryUpdater.cs index 792e2ba..ad802cd 100644 --- a/WotBlitzStatisticsPro.Logic/Dictionaries/VehiclesDictionaryUpdater.cs +++ b/WotBlitzStatisticsPro.Logic/Dictionaries/VehiclesDictionaryUpdater.cs @@ -21,7 +21,9 @@ namespace WotBlitzStatisticsPro.Logic.Dictionaries [Obsolete("Parameter-less constructor only for unit tests")] public VehiclesDictionaryUpdater() { - + _wargamingDictionariesApiClient = null!; + _dataAccessor = null!; + _mapper = null!; } public VehiclesDictionaryUpdater(IWargamingDictionariesApiClient wargamingDictionariesApiClient, @@ -57,6 +59,11 @@ namespace WotBlitzStatisticsPro.Logic.Dictionaries var wgVehicles = await _wargamingDictionariesApiClient.GetVehicles(defaultRealmType, requestLanguage); + if (wgVehicles == null) + { + continue; + } + foreach (var wgVehicle in wgVehicles) { var mappedVehicle = vehicles.FirstOrDefault(v => v.TankId == wgVehicle.TankId); diff --git a/WotBlitzStatisticsPro.Logic/Mappers/AccountSearchResponseProfile.cs b/WotBlitzStatisticsPro.Logic/Mappers/AccountSearchResponseProfile.cs index 37d5c41..5156a73 100644 --- a/WotBlitzStatisticsPro.Logic/Mappers/AccountSearchResponseProfile.cs +++ b/WotBlitzStatisticsPro.Logic/Mappers/AccountSearchResponseProfile.cs @@ -11,7 +11,7 @@ namespace WotBlitzStatisticsPro.Logic.Mappers CreateMap() .ForMember( d => d.AccountId, - o => o.MapFrom(s => s.AccountId.Value)); + o => o.MapFrom(s => s.AccountId ?? -1)); } } } \ No newline at end of file diff --git a/WotBlitzStatisticsPro.Logic/Mappers/ClanSearchResponseProfile.cs b/WotBlitzStatisticsPro.Logic/Mappers/ClanSearchResponseProfile.cs index 9e38257..b0d5969 100644 --- a/WotBlitzStatisticsPro.Logic/Mappers/ClanSearchResponseProfile.cs +++ b/WotBlitzStatisticsPro.Logic/Mappers/ClanSearchResponseProfile.cs @@ -11,7 +11,7 @@ namespace WotBlitzStatisticsPro.Logic.Mappers CreateMap() .ForMember( d => d.ClanId, - o => o.MapFrom(s => s.ClanId.Value)); + o => o.MapFrom(s => s.ClanId ?? -1)); } } diff --git a/WotBlitzStatisticsPro.Logic/Mappers/ShortStatisticsProfile.cs b/WotBlitzStatisticsPro.Logic/Mappers/ShortStatisticsProfile.cs index d5a7e37..b03efba 100644 --- a/WotBlitzStatisticsPro.Logic/Mappers/ShortStatisticsProfile.cs +++ b/WotBlitzStatisticsPro.Logic/Mappers/ShortStatisticsProfile.cs @@ -12,11 +12,11 @@ namespace WotBlitzStatisticsPro.Logic.Mappers .ForMember(d => d.LastBattleTime, o => o.MapFrom(s => s.LastBattleTime.ToDateTime())) .ForMember(d => d.AvgDamage, - o => o.MapFrom(s => s.Battles.HasValue && s.Battles > 0 ? ((decimal)s.DamageDealt / s.Battles) : 0m)) + o => o.MapFrom(s => s.Battles.HasValue && s.DamageDealt.HasValue && s.Battles > 0 ? ((decimal)s.DamageDealt / s.Battles) : 0m)) .ForMember(d => d.AvgXp, - o => o.MapFrom(s => s.Battles.HasValue && s.Battles > 0 ? ((decimal)s.Xp / s.Battles) : 0m)) + o => o.MapFrom(s => s.Battles.HasValue && s.Xp.HasValue && s.Battles > 0 ? ((decimal)s.Xp / s.Battles) : 0m)) .ForMember(d => d.WinRate, - o => o.MapFrom(s => s.Battles.HasValue && s.Battles > 0 ? (100 * (decimal)s.Wins / s.Battles) : 0m)) + o => o.MapFrom(s => s.Battles.HasValue && s.Wins.HasValue && s.Battles > 0 ? (100 * (decimal)s.Wins / s.Battles) : 0m)) ; } } diff --git a/WotBlitzStatisticsPro.Logic/Mappers/VehicleDictionaryProfile.cs b/WotBlitzStatisticsPro.Logic/Mappers/VehicleDictionaryProfile.cs index d0c30d8..83bddd1 100644 --- a/WotBlitzStatisticsPro.Logic/Mappers/VehicleDictionaryProfile.cs +++ b/WotBlitzStatisticsPro.Logic/Mappers/VehicleDictionaryProfile.cs @@ -22,13 +22,13 @@ namespace WotBlitzStatisticsPro.Logic.Mappers .ForMember(d => d.Tier, o => o.MapFrom(s => s.Tier)) .ForMember(d => d.PreviewImage, - o => o.MapFrom(s => s.Images["preview"])) + o => o.MapFrom(s => s.Images == null ? string.Empty : s.Images["preview"])) .ForMember(d => d.NormalImage, - o => o.MapFrom(s => s.Images["normal"])) + o => o.MapFrom(s => s.Images == null ? string.Empty : s.Images["normal"])) .ForMember(d => d.PriceCredit, - o => o.MapFrom(s => s.Cost["price_credit"])) + o => o.MapFrom(s => s.Cost == null ? string.Empty : s.Cost["price_credit"])) .ForMember(d => d.PriceGold, - o => o.MapFrom(s => s.Cost["price_gold"])) + o => o.MapFrom(s => s.Cost == null ? string.Empty : s.Cost["price_gold"])) .ForMember(d => d.NexTanksInTree, o => o.MapFrom(s => s.NextTanks)) diff --git a/WotBlitzStatisticsPro.Logic/Pipeline/IOperation.cs b/WotBlitzStatisticsPro.Logic/Pipeline/IOperation.cs index a820266..d233b30 100644 --- a/WotBlitzStatisticsPro.Logic/Pipeline/IOperation.cs +++ b/WotBlitzStatisticsPro.Logic/Pipeline/IOperation.cs @@ -13,6 +13,6 @@ namespace WotBlitzStatisticsPro.Logic.Pipeline /// /// Pipeline context /// Next operation - Task Invoke(TContext context, Func next); + Task Invoke(TContext context, Func? next); } } \ No newline at end of file diff --git a/WotBlitzStatisticsPro.Logic/Pipeline/IPipeline.cs b/WotBlitzStatisticsPro.Logic/Pipeline/IPipeline.cs index af8885c..bc6249f 100644 --- a/WotBlitzStatisticsPro.Logic/Pipeline/IPipeline.cs +++ b/WotBlitzStatisticsPro.Logic/Pipeline/IPipeline.cs @@ -9,7 +9,7 @@ /// Builds the pipeline. /// /// First operation in pipeline. - IOperation Build(); + IOperation? Build(); /// /// Adds operation type to the pipeline diff --git a/WotBlitzStatisticsPro.Logic/Pipeline/OperationMediator.cs b/WotBlitzStatisticsPro.Logic/Pipeline/OperationMediator.cs index 2ca2fab..38b073b 100644 --- a/WotBlitzStatisticsPro.Logic/Pipeline/OperationMediator.cs +++ b/WotBlitzStatisticsPro.Logic/Pipeline/OperationMediator.cs @@ -6,15 +6,15 @@ namespace WotBlitzStatisticsPro.Logic.Pipeline public class OperationMediator: IOperation { private readonly IOperation _current; - private readonly IOperation _next; + private readonly IOperation? _next; - public OperationMediator(IOperation current, IOperation next) + public OperationMediator(IOperation current, IOperation? next) { _current = current ?? throw new ArgumentNullException(nameof(current)); _next = next; } - public Task Invoke(TContext context, Func next) + public Task Invoke(TContext context, Func? next) { return _current.Invoke(context, c => _next == null ? Task.CompletedTask : _next.Invoke(c, null)); } diff --git a/WotBlitzStatisticsPro.Logic/Pipeline/Pipeline.cs b/WotBlitzStatisticsPro.Logic/Pipeline/Pipeline.cs index 14ecd48..0e2a786 100644 --- a/WotBlitzStatisticsPro.Logic/Pipeline/Pipeline.cs +++ b/WotBlitzStatisticsPro.Logic/Pipeline/Pipeline.cs @@ -14,7 +14,7 @@ namespace WotBlitzStatisticsPro.Logic.Pipeline _operationFactory = operationFactory; } - public IOperation Build() + public IOperation? Build() { var allOperationTypes = _operations.ToArray(); var lastOperationType = allOperationTypes.LastOrDefault(); diff --git a/WotBlitzStatisticsPro.Logic/Pipeline/ServiceProviderOperationFactory.cs b/WotBlitzStatisticsPro.Logic/Pipeline/ServiceProviderOperationFactory.cs index f68513b..0c58d6f 100644 --- a/WotBlitzStatisticsPro.Logic/Pipeline/ServiceProviderOperationFactory.cs +++ b/WotBlitzStatisticsPro.Logic/Pipeline/ServiceProviderOperationFactory.cs @@ -13,7 +13,7 @@ namespace WotBlitzStatisticsPro.Logic.Pipeline public IOperation Create(Type operationType) { - return _serviceProvider.GetService(operationType) as IOperation; + return (_serviceProvider.GetService(operationType) as IOperation)!; } } } \ No newline at end of file diff --git a/WotBlitzStatisticsPro.Logic/WargamingAccounts.cs b/WotBlitzStatisticsPro.Logic/WargamingAccounts.cs index f4bbc9d..4a07688 100644 --- a/WotBlitzStatisticsPro.Logic/WargamingAccounts.cs +++ b/WotBlitzStatisticsPro.Logic/WargamingAccounts.cs @@ -30,11 +30,15 @@ namespace WotBlitzStatisticsPro.Logic .AddOperation() ; - await pipeline.Build() - .Invoke(context, null) - .ConfigureAwait(false); + var firstOperation = pipeline.Build(); + if (firstOperation != null) + { + await firstOperation + .Invoke(context, null) + .ConfigureAwait(false); + } - return contextData.Response; + return contextData?.Response ?? new AccountInfoResponse(); } public async Task GatherAndSaveAccountInformation(RealmType realm, long accountId, RequestLanguage requestLanguage) @@ -53,11 +57,15 @@ namespace WotBlitzStatisticsPro.Logic .AddOperation() ; - await pipeline.Build() - .Invoke(context, null) - .ConfigureAwait(false); + var firstOperation = pipeline.Build(); + if (firstOperation != null) + { + await firstOperation + .Invoke(context, null) + .ConfigureAwait(false); + } - return contextData.Response; + return contextData?.Response ?? new AccountInfoResponse(); } public async Task GetAccountInfoHistory(RealmType realm, long accountId, DateTime startDate, RequestLanguage requestLanguage) @@ -77,11 +85,15 @@ namespace WotBlitzStatisticsPro.Logic .AddOperation() ; - await pipeline.Build() - .Invoke(context, null) - .ConfigureAwait(false); + var firstOperation = pipeline.Build(); + if (firstOperation != null) + { + await firstOperation + .Invoke(context, null) + .ConfigureAwait(false); + } - return contextData.Response; + return contextData?.Response ?? new AccountInfoHistoryResponse(); } } } \ No newline at end of file diff --git a/WotBlitzStatisticsPro.Logic/WargamingSearch.cs b/WotBlitzStatisticsPro.Logic/WargamingSearch.cs index a61390b..d01c8bf 100644 --- a/WotBlitzStatisticsPro.Logic/WargamingSearch.cs +++ b/WotBlitzStatisticsPro.Logic/WargamingSearch.cs @@ -24,6 +24,12 @@ namespace WotBlitzStatisticsPro.Logic RequestLanguage language) { var response = await _wargamingApiClient.FindAccounts(accountNick, realmType, language); + + if (response == null) + { + return new AccountsSearchResponse(); + } + return new AccountsSearchResponse { AccountsCount = response.Count, @@ -37,6 +43,12 @@ namespace WotBlitzStatisticsPro.Logic RequestLanguage language) { var response = await _wargamingApiClient.FindClans(searchString, realmType, language); + + if (response == null) + { + return new ClanSearchResponse(); + } + return new ClanSearchResponse { ClansCount = response.Count, diff --git a/WotBlitzStatisticsPro.Logic/WotBlitzStatisticsLogicInstaller.cs b/WotBlitzStatisticsPro.Logic/WotBlitzStatisticsLogicInstaller.cs index 1a085d7..148aa45 100644 --- a/WotBlitzStatisticsPro.Logic/WotBlitzStatisticsLogicInstaller.cs +++ b/WotBlitzStatisticsPro.Logic/WotBlitzStatisticsLogicInstaller.cs @@ -1,4 +1,5 @@ -using System.Collections.Generic; +using System; +using System.Collections.Generic; using System.Runtime.CompilerServices; using AutoMapper; using Microsoft.Extensions.DependencyInjection; @@ -43,17 +44,13 @@ namespace WotBlitzStatisticsPro.Logic { services.AddTransient(serviceProvider => dictionaryType => { - switch (dictionaryType) + return dictionaryType switch { - case DictionaryType.StaticDictionaries: - return serviceProvider.GetService(); - case DictionaryType.Achievements: - return serviceProvider.GetService(); - case DictionaryType.Vehicles: - return serviceProvider.GetService(); - default: - return null; - } + DictionaryType.StaticDictionaries => serviceProvider.GetService()!, + DictionaryType.Achievements => serviceProvider.GetService()!, + DictionaryType.Vehicles => serviceProvider.GetService()!, + _ => throw new ApplicationException($"Unknown dictionary type '{dictionaryType}'") + }; }); } diff --git a/WotBlitzStatisticsPro.Logic/WotBlitzStatisticsPro.Logic.csproj b/WotBlitzStatisticsPro.Logic/WotBlitzStatisticsPro.Logic.csproj index ca2cd7c..09027a5 100644 --- a/WotBlitzStatisticsPro.Logic/WotBlitzStatisticsPro.Logic.csproj +++ b/WotBlitzStatisticsPro.Logic/WotBlitzStatisticsPro.Logic.csproj @@ -2,6 +2,7 @@ net5.0 + enable diff --git a/WotBlitzStatisticsPro.WgApiClient/IWargamingApiClient.cs b/WotBlitzStatisticsPro.WgApiClient/IWargamingApiClient.cs index ad0a120..744ed58 100644 --- a/WotBlitzStatisticsPro.WgApiClient/IWargamingApiClient.cs +++ b/WotBlitzStatisticsPro.WgApiClient/IWargamingApiClient.cs @@ -7,23 +7,23 @@ namespace WotBlitzStatisticsPro.WgApiClient { public interface IWargamingApiClient { - Task> FindAccounts(string nickName, + Task?> FindAccounts(string nickName, RealmType realmType = RealmType.Ru, RequestLanguage language = RequestLanguage.En); - Task> FindClans(string searchString, + Task?> FindClans(string searchString, RealmType realmType = RealmType.Ru, RequestLanguage language = RequestLanguage.En); - Task GetPlayerAccountInfo(long accountId, + Task GetPlayerAccountInfo(long accountId, RealmType realmType = RealmType.Ru, RequestLanguage language = RequestLanguage.En); - Task GetPlayerClanInfo(long accountId, + Task GetPlayerClanInfo(long accountId, RealmType realmType = RealmType.Ru, RequestLanguage language = RequestLanguage.En); - Task GetClanInfo(long clanId, + Task GetClanInfo(long clanId, RealmType realmType = RealmType.Ru, RequestLanguage language = RequestLanguage.En); } diff --git a/WotBlitzStatisticsPro.WgApiClient/IWargamingDictionariesApiClient.cs b/WotBlitzStatisticsPro.WgApiClient/IWargamingDictionariesApiClient.cs index 42a953b..6809b90 100644 --- a/WotBlitzStatisticsPro.WgApiClient/IWargamingDictionariesApiClient.cs +++ b/WotBlitzStatisticsPro.WgApiClient/IWargamingDictionariesApiClient.cs @@ -8,16 +8,16 @@ namespace WotBlitzStatisticsPro.WgApiClient public interface IWargamingDictionariesApiClient { Task<( - WotEncyclopediaInfoResponse, - WotClanMembersDictionaryResponse)> GetStaticDictionariesAsync( + WotEncyclopediaInfoResponse?, + WotClanMembersDictionaryResponse?)> GetStaticDictionariesAsync( RealmType realmType = RealmType.Ru, RequestLanguage language = RequestLanguage.En); - Task> GetAchievementsDictionary( + Task?> GetAchievementsDictionary( RealmType realmType = RealmType.Ru, RequestLanguage language = RequestLanguage.En); - Task> GetVehicles( + Task?> GetVehicles( RealmType realmType = RealmType.Ru, RequestLanguage language = RequestLanguage.En); } diff --git a/WotBlitzStatisticsPro.WgApiClient/IWargamingTanksApiClient.cs b/WotBlitzStatisticsPro.WgApiClient/IWargamingTanksApiClient.cs index 2798ffa..081345a 100644 --- a/WotBlitzStatisticsPro.WgApiClient/IWargamingTanksApiClient.cs +++ b/WotBlitzStatisticsPro.WgApiClient/IWargamingTanksApiClient.cs @@ -7,7 +7,7 @@ namespace WotBlitzStatisticsPro.WgApiClient { public interface IWargamingTanksApiClient { - Task> GetPlayerAccountTanksInfo(long accountId, + Task?> GetPlayerAccountTanksInfo(long accountId, RealmType realmType = RealmType.Ru, RequestLanguage language = RequestLanguage.En); } diff --git a/WotBlitzStatisticsPro.WgApiClient/Model/ClanAccountInfo.cs b/WotBlitzStatisticsPro.WgApiClient/Model/ClanAccountInfo.cs index e20d2ea..745024c 100644 --- a/WotBlitzStatisticsPro.WgApiClient/Model/ClanAccountInfo.cs +++ b/WotBlitzStatisticsPro.WgApiClient/Model/ClanAccountInfo.cs @@ -14,7 +14,7 @@ namespace WotBlitzStatisticsPro.WgApiClient.Model /// Account nick /// [JsonProperty("account_name")] - public string AccountName { get; set; } + public string? AccountName { get; set; } /// /// ClanId @@ -32,7 +32,7 @@ namespace WotBlitzStatisticsPro.WgApiClient.Model /// Player clan role /// [JsonProperty("role")] - public string Role { get; set; } + public string? Role { get; set; } } } diff --git a/WotBlitzStatisticsPro.WgApiClient/Model/ClanInfo.cs b/WotBlitzStatisticsPro.WgApiClient/Model/ClanInfo.cs index 6506b68..7cc125f 100644 --- a/WotBlitzStatisticsPro.WgApiClient/Model/ClanInfo.cs +++ b/WotBlitzStatisticsPro.WgApiClient/Model/ClanInfo.cs @@ -22,7 +22,7 @@ namespace WotBlitzStatisticsPro.WgApiClient.Model /// Clan color in HEX #RRGGBB /// [JsonProperty("color")] - public string Color { get; set; } + public string? Color { get; set; } /// /// Date of clan creation @@ -40,25 +40,25 @@ namespace WotBlitzStatisticsPro.WgApiClient.Model /// Clan creator nick /// [JsonProperty("creator_name")] - public string CreatorName { get; set; } + public string? CreatorName { get; set; } /// /// Clan description /// [JsonProperty("description")] - public string Description { get; set; } + public string? Description { get; set; } /// /// Html Clan description /// [JsonProperty("description_html")] - public string DescriptionHtml { get; set; } + public string? DescriptionHtml { get; set; } /// /// Is clan deleted. Actual info about deleted clan only in fields: clan_id, is_clan_disbanded, updated_at. /// [JsonProperty("is_clan_disbanded")] - public bool IsClanDisbanded { get; set; } + public bool? IsClanDisbanded { get; set; } /// /// Clan commander accountId @@ -70,7 +70,7 @@ namespace WotBlitzStatisticsPro.WgApiClient.Model /// Clan commander nick /// [JsonProperty("leader_name")] - public string LeaderName { get; set; } + public string? LeaderName { get; set; } /// /// Clan members count @@ -82,25 +82,25 @@ namespace WotBlitzStatisticsPro.WgApiClient.Model /// Clan motto /// [JsonProperty("motto")] - public string Motto { get; set; } + public string? Motto { get; set; } /// /// Clan name /// [JsonProperty("name")] - public string Name { get; set; } + public string? Name { get; set; } /// /// Renamed clan name /// [JsonProperty("old_name")] - public string OldName { get; set; } + public string? OldName { get; set; } /// /// Renamed clan tag /// [JsonProperty("old_tag")] - public string OldTag { get; set; } + public string? OldTag { get; set; } /// /// Clan renaming time in UTC @@ -112,7 +112,7 @@ namespace WotBlitzStatisticsPro.WgApiClient.Model /// Clan tag /// [JsonProperty("tag")] - public string Tag { get; set; } + public string? Tag { get; set; } /// /// Clan info updated at @@ -124,19 +124,19 @@ namespace WotBlitzStatisticsPro.WgApiClient.Model /// Clan emblems info /// [JsonProperty("emblems")] - public WgnClansInfoEmblems Emblems { get; set; } + public WgnClansInfoEmblems? Emblems { get; set; } /// /// Clan members information. Depends on members_key field in request. /// [JsonProperty("members")] - public WgnClansInfoMembers Members { get; set; } + public WgnClansInfoMembers? Members { get; set; } /// /// Private clan info /// [JsonProperty("private")] - public WgnClansInfoPrivate Private { get; set; } + public WgnClansInfoPrivate? Private { get; set; } } public class WgnClansInfoEmblems @@ -145,31 +145,31 @@ namespace WotBlitzStatisticsPro.WgApiClient.Model /// 195x195 px Icons list /// [JsonProperty("x195")] - public Dictionary X195 { get; set; } + public Dictionary? X195 { get; set; } /// /// 24x24 px Icons list /// [JsonProperty("x24")] - public Dictionary X24 { get; set; } + public Dictionary? X24 { get; set; } /// /// 256x256 px Icons list /// [JsonProperty("x256")] - public Dictionary X256 { get; set; } + public Dictionary? X256 { get; set; } /// /// 32x32 px Icons list /// [JsonProperty("x32")] - public Dictionary X32 { get; set; } + public Dictionary? X32 { get; set; } /// /// 64x64 px Icons list /// [JsonProperty("x64")] - public Dictionary X64 { get; set; } + public Dictionary? X64 { get; set; } } public class WgnClansInfoMembers @@ -184,7 +184,7 @@ namespace WotBlitzStatisticsPro.WgApiClient.Model /// Clan member nick /// [JsonProperty("account_name")] - public string AccountName { get; set; } + public string? AccountName { get; set; } /// /// Date of joining the clan @@ -196,19 +196,19 @@ namespace WotBlitzStatisticsPro.WgApiClient.Model /// Clan member role /// [JsonProperty("role")] - public string Role { get; set; } + public string? Role { get; set; } /// /// Localized member role /// [JsonProperty("role_i18n")] - public string RoleI18n { get; set; } + public string? RoleI18n { get; set; } } public class WgnClansInfoPrivate { [JsonProperty("online_members")] - public int[] OnlineMembers { get; set; } + public int[]? OnlineMembers { get; set; } [JsonProperty("treasury")] public long? Treasury { get; set; } diff --git a/WotBlitzStatisticsPro.WgApiClient/Model/WotAccountInfo.cs b/WotBlitzStatisticsPro.WgApiClient/Model/WotAccountInfo.cs index ba70175..dbb2fdc 100644 --- a/WotBlitzStatisticsPro.WgApiClient/Model/WotAccountInfo.cs +++ b/WotBlitzStatisticsPro.WgApiClient/Model/WotAccountInfo.cs @@ -26,7 +26,7 @@ namespace WotBlitzStatisticsPro.WgApiClient.Model /// Player's nick /// [JsonProperty("nickname")] - public string Nickname { get; set; } + public string? Nickname { get; set; } /// /// Player information update date @@ -38,12 +38,12 @@ namespace WotBlitzStatisticsPro.WgApiClient.Model /// Private account data /// [JsonProperty("private")] - public WotAccountPrivateInfo Private { get; set; } + public WotAccountPrivateInfo? Private { get; set; } /// /// Player's statistics /// [JsonProperty("statistics")] - public WotAccountStatistics Statistics { get; set; } + public WotAccountStatistics? Statistics { get; set; } } } diff --git a/WotBlitzStatisticsPro.WgApiClient/Model/WotAccountListResponse.cs b/WotBlitzStatisticsPro.WgApiClient/Model/WotAccountListResponse.cs index 4eb886e..1100d84 100644 --- a/WotBlitzStatisticsPro.WgApiClient/Model/WotAccountListResponse.cs +++ b/WotBlitzStatisticsPro.WgApiClient/Model/WotAccountListResponse.cs @@ -14,6 +14,6 @@ namespace WotBlitzStatisticsPro.WgApiClient.Model /// Player nick /// [JsonProperty("nickname")] - public string Nickname { get; set; } + public string? Nickname { get; set; } } } \ No newline at end of file diff --git a/WotBlitzStatisticsPro.WgApiClient/Model/WotAccountPrivateInfo.cs b/WotBlitzStatisticsPro.WgApiClient/Model/WotAccountPrivateInfo.cs index 3a42d18..b9bcb8e 100644 --- a/WotBlitzStatisticsPro.WgApiClient/Model/WotAccountPrivateInfo.cs +++ b/WotBlitzStatisticsPro.WgApiClient/Model/WotAccountPrivateInfo.cs @@ -8,7 +8,7 @@ namespace WotBlitzStatisticsPro.WgApiClient.Model /// Account ban info /// [JsonProperty("ban_info")] - public string BanInfo { get; set; } + public string? BanInfo { get; set; } /// /// Account ban expiration date @@ -47,23 +47,22 @@ namespace WotBlitzStatisticsPro.WgApiClient.Model public bool IsPremium { get; set; } /// - /// Premium accunt expiration time + /// Premium account expiration time /// [JsonProperty("premium_expires_at")] private int? PremiumExpiresAt { get; set; } /// - ///Группы контактов. - ///Дополнительное поле. + /// Group of contacts. /// [JsonProperty("grouped_contacts")] - public WotAccountPrivateInfoGroupedContacts GroupedContacts { get; set; } + public WotAccountPrivateInfoGroupedContacts? GroupedContacts { get; set; } /// - ///Ограничения аккаунта + /// Account restrictions /// [JsonProperty("restrictions")] - public WotAccountPrivateInfoRestrictions Restrictions { get; set; } + public WotAccountPrivateInfoRestrictions? Restrictions { get; set; } } } diff --git a/WotBlitzStatisticsPro.WgApiClient/Model/WotAccountPrivateInfoGroupedContacts.cs b/WotBlitzStatisticsPro.WgApiClient/Model/WotAccountPrivateInfoGroupedContacts.cs index eeeb8b1..be2b70f 100644 --- a/WotBlitzStatisticsPro.WgApiClient/Model/WotAccountPrivateInfoGroupedContacts.cs +++ b/WotBlitzStatisticsPro.WgApiClient/Model/WotAccountPrivateInfoGroupedContacts.cs @@ -9,18 +9,18 @@ namespace WotBlitzStatisticsPro.WgApiClient.Model /// Blocked accountIds /// [JsonProperty("blocked")] - public int[] Blocked { get; set; } + public int[]? Blocked { get; set; } /// /// Groups /// [JsonProperty("groups")] - public Dictionary Groups { get; set; } + public Dictionary? Groups { get; set; } /// /// Ungrouped accountIds /// [JsonProperty("ungrouped")] - public int[] Ungrouped { get; set; } + public int[]? Ungrouped { get; set; } } } diff --git a/WotBlitzStatisticsPro.WgApiClient/Model/WotAccountStatistics.cs b/WotBlitzStatisticsPro.WgApiClient/Model/WotAccountStatistics.cs index eac1228..7ce16ad 100644 --- a/WotBlitzStatisticsPro.WgApiClient/Model/WotAccountStatistics.cs +++ b/WotBlitzStatisticsPro.WgApiClient/Model/WotAccountStatistics.cs @@ -9,12 +9,12 @@ namespace WotBlitzStatisticsPro.WgApiClient.Model /// Amount of destroyed by player tanks. /// [JsonProperty("frags")] - public Dictionary Frags { get; set; } + public Dictionary? Frags { get; set; } /// /// Full player's statistics /// [JsonProperty("all")] - public WotAccountFullStatistics All { get; set; } + public WotAccountFullStatistics? All { get; set; } } } diff --git a/WotBlitzStatisticsPro.WgApiClient/Model/WotAccountTanksStatistics.cs b/WotBlitzStatisticsPro.WgApiClient/Model/WotAccountTanksStatistics.cs index 16e9efa..fd14f12 100644 --- a/WotBlitzStatisticsPro.WgApiClient/Model/WotAccountTanksStatistics.cs +++ b/WotBlitzStatisticsPro.WgApiClient/Model/WotAccountTanksStatistics.cs @@ -50,10 +50,10 @@ namespace WotBlitzStatisticsPro.WgApiClient.Model /// Whole statistics /// [JsonProperty("all")] - public WotAccountTanksFullStatistics All { get; set; } + public WotAccountTanksFullStatistics? All { get; set; } [JsonProperty("frags")] - public Dictionary Frags { get; set; } + public Dictionary? Frags { get; set; } } } \ No newline at end of file diff --git a/WotBlitzStatisticsPro.WgApiClient/Model/WotClanListResponse.cs b/WotBlitzStatisticsPro.WgApiClient/Model/WotClanListResponse.cs index f0476fb..8593223 100644 --- a/WotBlitzStatisticsPro.WgApiClient/Model/WotClanListResponse.cs +++ b/WotBlitzStatisticsPro.WgApiClient/Model/WotClanListResponse.cs @@ -14,13 +14,13 @@ namespace WotBlitzStatisticsPro.WgApiClient.Model /// Clan Tag /// [JsonProperty("tag")] - public string Tag { get; set; } + public string? Tag { get; set; } /// /// Clan Name /// [JsonProperty("name")] - public string Name { get; set; } + public string? Name { get; set; } /// /// Clan created at. (UNIX Epoch time) diff --git a/WotBlitzStatisticsPro.WgApiClient/Model/WotClanMembersDictionaryResponse.cs b/WotBlitzStatisticsPro.WgApiClient/Model/WotClanMembersDictionaryResponse.cs index 5d8cbaa..f415748 100644 --- a/WotBlitzStatisticsPro.WgApiClient/Model/WotClanMembersDictionaryResponse.cs +++ b/WotBlitzStatisticsPro.WgApiClient/Model/WotClanMembersDictionaryResponse.cs @@ -9,12 +9,12 @@ namespace WotBlitzStatisticsPro.WgApiClient.Model /// Clan roles list /// [JsonProperty("clans_roles")] - public Dictionary ClanRoles { get; set; } + public Dictionary? ClanRoles { get; set; } /// /// Clan settings list /// [JsonProperty("settings")] - public Dictionary Settings { get; set; } + public Dictionary? Settings { get; set; } } } \ No newline at end of file diff --git a/WotBlitzStatisticsPro.WgApiClient/Model/WotEncyclopediaAchievementsResponse.cs b/WotBlitzStatisticsPro.WgApiClient/Model/WotEncyclopediaAchievementsResponse.cs index 1e85a26..3f6c204 100644 --- a/WotBlitzStatisticsPro.WgApiClient/Model/WotEncyclopediaAchievementsResponse.cs +++ b/WotBlitzStatisticsPro.WgApiClient/Model/WotEncyclopediaAchievementsResponse.cs @@ -6,43 +6,43 @@ namespace WotBlitzStatisticsPro.WgApiClient.Model public class WotEncyclopediaAchievementsResponse { [JsonProperty("achievement_id")] - public string AchievementId { get; set; } + public string? AchievementId { get; set; } /// /// Achievement condition /// [JsonProperty("condition")] - public string Condition { get; set; } + public string? Condition { get; set; } /// /// Achievement description /// [JsonProperty("description")] - public string Description { get; set; } + public string? Description { get; set; } /// /// Historical info /// [JsonProperty("hero_info")] - public string HeroInfo { get; set; } + public string? HeroInfo { get; set; } /// /// Image link /// [JsonProperty("image")] - public string Image { get; set; } + public string? Image { get; set; } /// /// Image 180x180px link /// [JsonProperty("image_big")] - public string ImageBig { get; set; } + public string? ImageBig { get; set; } /// /// Achievement name /// [JsonProperty("name")] - public string Name { get; set; } + public string? Name { get; set; } /// /// Sort order @@ -60,7 +60,7 @@ namespace WotBlitzStatisticsPro.WgApiClient.Model /// Achievement section /// [JsonProperty("section")] - public string Section { get; set; } + public string? Section { get; set; } /// /// Achievement section order @@ -72,13 +72,13 @@ namespace WotBlitzStatisticsPro.WgApiClient.Model /// Achievement Type /// [JsonProperty("type")] - public string Type { get; set; } + public string? Type { get; set; } /// /// Achievement options /// [JsonProperty("options")] - public WotEncyclopediaAchievementsOptions[] Options { get; set; } + public WotEncyclopediaAchievementsOptions[]? Options { get; set; } } public class WotEncyclopediaAchievementsOptions @@ -88,21 +88,21 @@ namespace WotBlitzStatisticsPro.WgApiClient.Model /// Achievement description /// [JsonProperty("description")] - public string Description { get; set; } + public string? Description { get; set; } /// /// Image link /// [JsonProperty("image")] - public string Image { get; set; } + public string? Image { get; set; } /// /// Image 180x180px link /// [JsonProperty("image_big")] - public string ImageBig { get; set; } + public string? ImageBig { get; set; } [JsonProperty("name")] - public string Name { get; set; } + public string? Name { get; set; } } } \ No newline at end of file diff --git a/WotBlitzStatisticsPro.WgApiClient/Model/WotEncyclopediaInfoResponse.cs b/WotBlitzStatisticsPro.WgApiClient/Model/WotEncyclopediaInfoResponse.cs index 39db1c9..2c0b279 100644 --- a/WotBlitzStatisticsPro.WgApiClient/Model/WotEncyclopediaInfoResponse.cs +++ b/WotBlitzStatisticsPro.WgApiClient/Model/WotEncyclopediaInfoResponse.cs @@ -10,13 +10,13 @@ namespace WotBlitzStatisticsPro.WgApiClient.Model /// Game client version /// [JsonProperty("game_version")] - public string GameVersion { get; set; } + public string? GameVersion { get; set; } /// /// List of supported languages /// [JsonProperty("languages")] - public Dictionary Languages { get; set; } + public Dictionary? Languages { get; set; } /// /// Encyclopedia last update time @@ -28,25 +28,25 @@ namespace WotBlitzStatisticsPro.WgApiClient.Model /// Cru clan role /// [JsonProperty("vehicle_crew_roles")] - public Dictionary VehicleCrewRoles { get; set; } + public Dictionary? VehicleCrewRoles { get; set; } /// /// Vehicle nations dictionary /// [JsonProperty("vehicle_nations")] - public Dictionary VehicleNations { get; set; } + public Dictionary? VehicleNations { get; set; } /// /// Vehicle types dictionary /// [JsonProperty("vehicle_types")] - public Dictionary VehicleTypes { get; set; } + public Dictionary? VehicleTypes { get; set; } /// /// Achievements sections /// [JsonProperty("achievement_sections")] - public Dictionary AchievementSections { get; set; } + public Dictionary? AchievementSections { get; set; } } @@ -57,7 +57,7 @@ namespace WotBlitzStatisticsPro.WgApiClient.Model /// Achievements section name /// [JsonProperty("name")] - public string Name { get; set; } + public string? Name { get; set; } /// /// Achievement section order diff --git a/WotBlitzStatisticsPro.WgApiClient/Model/WotEncyclopediaVehiclesResponse.cs b/WotBlitzStatisticsPro.WgApiClient/Model/WotEncyclopediaVehiclesResponse.cs index a1ab26e..15a621a 100644 --- a/WotBlitzStatisticsPro.WgApiClient/Model/WotEncyclopediaVehiclesResponse.cs +++ b/WotBlitzStatisticsPro.WgApiClient/Model/WotEncyclopediaVehiclesResponse.cs @@ -9,19 +9,19 @@ namespace WotBlitzStatisticsPro.WgApiClient.Model /// Vehicle description /// [JsonProperty("description")] - public string Description { get; set; } + public string? Description { get; set; } /// /// Engines id list /// [JsonProperty("engines")] - public int[] Engines { get; set; } + public int[]? Engines { get; set; } /// /// Guns id list /// [JsonProperty("guns")] - public int[] Guns { get; set; } + public int[]? Guns { get; set; } /// /// Is vehicle premium @@ -33,13 +33,13 @@ namespace WotBlitzStatisticsPro.WgApiClient.Model /// Vehicle name /// [JsonProperty("name")] - public string Name { get; set; } + public string? Name { get; set; } /// /// Vehicle nationId /// [JsonProperty("nation")] - public string Nation { get; set; } + public string? Nation { get; set; } /// /// List of next vehicles in tree: @@ -48,26 +48,26 @@ namespace WotBlitzStatisticsPro.WgApiClient.Model /// value - amount of XP to open it /// [JsonProperty("next_tanks")] - public Dictionary NextTanks { get; set; } + public Dictionary? NextTanks { get; set; } /// /// Vehicle cost by pairs /// with keys: price_credit, price_gold /// [JsonProperty("cost")] - public Dictionary Cost { get; set; } + public Dictionary? Cost { get; set; } /// /// Price in XP for parent vehicle as key /// [JsonProperty("prices_xp")] - public Dictionary PricesXp { get; set; } + public Dictionary? PricesXp { get; set; } /// /// List of compatible suspensions /// [JsonProperty("suspensions")] - public int[] Suspensions { get; set; } + public int[]? Suspensions { get; set; } /// /// VehicleId @@ -85,13 +85,13 @@ namespace WotBlitzStatisticsPro.WgApiClient.Model /// List of compatible turrets ids /// [JsonProperty("turrets")] - public int[] Turrets { get; set; } + public int[]? Turrets { get; set; } /// /// Vehicle type id /// [JsonProperty("type")] - public string Type { get; set; } + public string? Type { get; set; } ///// ///// Default vehicle profile @@ -104,7 +104,7 @@ namespace WotBlitzStatisticsPro.WgApiClient.Model /// Keys: preview, normal /// [JsonProperty("images")] - public Dictionary Images { get; set; } + public Dictionary? Images { get; set; } ///// ///// Information about investigated modules diff --git a/WotBlitzStatisticsPro.WgApiClient/ResponseBody.cs b/WotBlitzStatisticsPro.WgApiClient/ResponseBody.cs index 0706566..4599ae7 100644 --- a/WotBlitzStatisticsPro.WgApiClient/ResponseBody.cs +++ b/WotBlitzStatisticsPro.WgApiClient/ResponseBody.cs @@ -1,20 +1,22 @@ -using Newtonsoft.Json; +using System.ComponentModel.DataAnnotations; +using System.Diagnostics.CodeAnalysis; +using Newtonsoft.Json; namespace WotBlitzStatisticsPro.WgApiClient { - internal class ResponseBody + internal class ResponseBody where T: class { [JsonProperty("status")] - public string Status { get; set; } + public string? Status { get; set; } [JsonProperty("meta")] - public Meta Meta { get; set; } + public Meta? Meta { get; set; } [JsonProperty("data")] - public T Data { get; set; } + public T? Data { get; set; } [JsonProperty("error")] - public Error Error { get; set; } + public Error? Error { get; set; } } internal class Meta @@ -26,15 +28,15 @@ namespace WotBlitzStatisticsPro.WgApiClient internal class Error { [JsonProperty("field")] - public string Field { get; set; } + public string? Field { get; set; } [JsonProperty("message")] - public string Message { get; set; } + public string? Message { get; set; } [JsonProperty("code")] - public string Code { get; set; } + public string? Code { get; set; } [JsonProperty("value")] - public string Value { get; set; } + public string? Value { get; set; } } } diff --git a/WotBlitzStatisticsPro.WgApiClient/WagramingApiClientBase.cs b/WotBlitzStatisticsPro.WgApiClient/WagramingApiClientBase.cs index a006118..830cc9d 100644 --- a/WotBlitzStatisticsPro.WgApiClient/WagramingApiClientBase.cs +++ b/WotBlitzStatisticsPro.WgApiClient/WagramingApiClientBase.cs @@ -1,6 +1,7 @@ using Newtonsoft.Json; using System; using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; using System.Net.Http; using System.Net.Http.Headers; using System.Text; @@ -36,11 +37,11 @@ namespace WotBlitzStatisticsPro.WgApiClient _wotApiUrls[RealmType.Asia] = "https://api.worldoftanks.asia/wot/"; } - protected async Task GetFromBlitzApi( + protected async Task GetFromBlitzApi( RealmType realmType, RequestLanguage language, string method, - params string[] queryParameters) + params string[] queryParameters) where T: class { string uri = GetUri(realmType, language, method, queryParameters); @@ -52,18 +53,20 @@ namespace WotBlitzStatisticsPro.WgApiClient 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); - } + switch (responseBody.Status) + { + case "ok": + return responseBody.Data; + case "error": + { + var error = responseBody.Error; + var message = $"Field:{(error?.Field ?? "undefined")} Message:{(error?.Message ?? "undefined")} Value:{(error?.Value ?? "undefined")} Code:{(error?.Code ?? "undefined")}"; + throw new ArgumentException(message); + } + default: + throw new ArgumentException($"Unexpected response body status '{responseBody.Status}'"); + } + } private string GetUri(RealmType realmType, RequestLanguage language, string method, string[] queryParameters) { diff --git a/WotBlitzStatisticsPro.WgApiClient/WargamingApiClient.cs b/WotBlitzStatisticsPro.WgApiClient/WargamingApiClient.cs index 12bd80d..28f2d3a 100644 --- a/WotBlitzStatisticsPro.WgApiClient/WargamingApiClient.cs +++ b/WotBlitzStatisticsPro.WgApiClient/WargamingApiClient.cs @@ -20,7 +20,7 @@ namespace WotBlitzStatisticsPro.WgApiClient } #region Search methods - public async Task> FindAccounts(string nickName, + public async Task?> FindAccounts(string nickName, RealmType realmType = RealmType.Ru, RequestLanguage language = RequestLanguage.En) { @@ -31,7 +31,7 @@ namespace WotBlitzStatisticsPro.WgApiClient $"search={nickName}").ConfigureAwait(false); } - public async Task> FindClans(string searchString, + public async Task?> FindClans(string searchString, RealmType realmType = RealmType.Ru, RequestLanguage language = RequestLanguage.En) { @@ -47,8 +47,8 @@ namespace WotBlitzStatisticsPro.WgApiClient #region Encyclopedia methods public async Task<( - WotEncyclopediaInfoResponse, - WotClanMembersDictionaryResponse)> GetStaticDictionariesAsync( + WotEncyclopediaInfoResponse?, + WotClanMembersDictionaryResponse?)> GetStaticDictionariesAsync( RealmType realmType = RealmType.Ru, RequestLanguage language = RequestLanguage.En) { @@ -67,24 +67,24 @@ namespace WotBlitzStatisticsPro.WgApiClient return (encyclopedia, clanGlossaryResponse); } - public async Task> GetAchievementsDictionary(RealmType realmType = RealmType.Ru, RequestLanguage language = RequestLanguage.En) + public async Task?> GetAchievementsDictionary(RealmType realmType = RealmType.Ru, RequestLanguage language = RequestLanguage.En) { var response = await GetFromBlitzApi>( realmType, language, "encyclopedia/achievements/").ConfigureAwait(false); - return response.Values.ToList(); + return response?.Values.ToList(); } - public async Task> GetVehicles(RealmType realmType = RealmType.Ru, RequestLanguage language = RequestLanguage.En) + public async Task?> GetVehicles(RealmType realmType = RealmType.Ru, RequestLanguage language = RequestLanguage.En) { var response = await GetFromBlitzApi>( realmType, language, "encyclopedia/vehicles/").ConfigureAwait(false); - return response.Values.ToList(); + return response?.Values.ToList(); } #endregion @@ -94,7 +94,7 @@ namespace WotBlitzStatisticsPro.WgApiClient - public async Task GetPlayerAccountInfo(long accountId, + public async Task GetPlayerAccountInfo(long accountId, RealmType realmType = RealmType.Ru, RequestLanguage language = RequestLanguage.En) { @@ -103,10 +103,10 @@ namespace WotBlitzStatisticsPro.WgApiClient language, "account/info/", $"account_id={accountId}").ConfigureAwait(false); - return account[accountId.ToString()]; + return account?[accountId.ToString()]; } - public async Task GetPlayerClanInfo(long accountId, + public async Task GetPlayerClanInfo(long accountId, RealmType realmType = RealmType.Ru, RequestLanguage language = RequestLanguage.En) { @@ -115,14 +115,14 @@ namespace WotBlitzStatisticsPro.WgApiClient language, "clans/accountinfo/", $"account_id={accountId}").ConfigureAwait(false); - if (clanInfo.ContainsKey(accountId.ToString())) + if (clanInfo != null && clanInfo.ContainsKey(accountId.ToString())) { return clanInfo[accountId.ToString()]; } return null; } - public async Task GetClanInfo( + public async Task GetClanInfo( long clanId, RealmType realmType = RealmType.Ru, RequestLanguage language = RequestLanguage.En) @@ -132,7 +132,7 @@ namespace WotBlitzStatisticsPro.WgApiClient language, "clans/info/", $"clan_id={clanId}").ConfigureAwait(false); - if (clanInfo.ContainsKey(clanId.ToString())) + if (clanInfo != null && clanInfo.ContainsKey(clanId.ToString())) { return clanInfo[clanId.ToString()]; } @@ -144,7 +144,7 @@ namespace WotBlitzStatisticsPro.WgApiClient #region Tanks methods - public async Task> GetPlayerAccountTanksInfo( + public async Task?> GetPlayerAccountTanksInfo( long accountId, RealmType realmType = RealmType.Ru, RequestLanguage language = RequestLanguage.En) @@ -154,7 +154,7 @@ namespace WotBlitzStatisticsPro.WgApiClient language, "tanks/stats/", $"account_id={accountId}").ConfigureAwait(false); - return tanks[accountId.ToString()] ?? new List(); + return tanks?[accountId.ToString()] ?? new List(); } #endregion diff --git a/WotBlitzStatisticsPro.WgApiClient/WotBlitzStatisticsPro.WgApiClient.csproj b/WotBlitzStatisticsPro.WgApiClient/WotBlitzStatisticsPro.WgApiClient.csproj index 691e65c..04a9ff5 100644 --- a/WotBlitzStatisticsPro.WgApiClient/WotBlitzStatisticsPro.WgApiClient.csproj +++ b/WotBlitzStatisticsPro.WgApiClient/WotBlitzStatisticsPro.WgApiClient.csproj @@ -2,6 +2,7 @@ net5.0 + enable