Nullable refernce types refactoring

This commit is contained in:
Mikhail Shabanov committed 2020-12-27 12:39:25 +01:00
1 parent e5c90e03d3
commit e12734981b
85 files changed
+509 -351

No files matched your search

@@ -10,22 +10,22 @@ namespace WotBlitzStatisticsPro.Common.Dictionaries
///<summary> ///<summary>
/// Achievement option description /// Achievement option description
///</summary> ///</summary>
public List<LocalizableString> Description { get; set; } public List<LocalizableString>? Description { get; set; }
///<summary> ///<summary>
/// Image link /// Image link
///</summary> ///</summary>
public string Image { get; set; } public string? Image { get; set; }
///<summary> ///<summary>
/// Image 180x180px link /// Image 180x180px link
///</summary> ///</summary>
public string ImageBig { get; set; } public string? ImageBig { get; set; }
/// <summary> /// <summary>
/// Achievement option name /// Achievement option name
/// </summary> /// </summary>
public List<LocalizableString> Name { get; set; } public List<LocalizableString>? Name { get; set; }
} }
} }
@@ -75,22 +75,22 @@ namespace WotBlitzStatisticsPro.Common.Dictionaries
///<summary> ///<summary>
/// Engines id list /// Engines id list
///</summary> ///</summary>
int[] Engines { get; set; } int[]? Engines { get; set; }
///<summary> ///<summary>
/// Guns id list /// Guns id list
///</summary> ///</summary>
int[] Guns { get; set; } int[]? Guns { get; set; }
///<summary> ///<summary>
/// List of compatible suspensions /// List of compatible suspensions
///</summary> ///</summary>
int[] Suspensions { get; set; } int[]? Suspensions { get; set; }
///<summary> ///<summary>
/// List of compatible turrets ids /// List of compatible turrets ids
///</summary> ///</summary>
int[] Turrets { get; set; } int[]? Turrets { get; set; }
} }
} }
@@ -15,6 +15,6 @@ namespace WotBlitzStatisticsPro.Common.Dictionaries
/// <summary> /// <summary>
/// Localizable string. /// Localizable string.
/// </summary> /// </summary>
public string Value { get; set; } public string? Value { get; set; }
} }
} }
@@ -20,26 +20,26 @@ namespace WotBlitzStatisticsPro.Common.Model
///<summary> ///<summary>
/// Player's nick /// Player's nick
///</summary> ///</summary>
public string Nickname { get; set; } public string? Nickname { get; set; }
/// <summary> /// <summary>
/// Overall statistics since account creation /// Overall statistics since account creation
/// </summary> /// </summary>
public ShortStatistics OverallAccountStatistics { get; set; } public ShortStatistics? OverallAccountStatistics { get; set; }
/// <summary> /// <summary>
/// Statistics for period /// Statistics for period
/// </summary> /// </summary>
public ShortStatistics PeriodAccountStatistics { get; set; } public ShortStatistics? PeriodAccountStatistics { get; set; }
/// <summary> /// <summary>
/// Difference between start and end of the period /// Difference between start and end of the period
/// </summary> /// </summary>
public StatisticsDifference PeriodDifference { get; set; } public StatisticsDifference? PeriodDifference { get; set; }
/// <summary> /// <summary>
/// The detailed history /// The detailed history
/// </summary> /// </summary>
public StatisticsDifference[] StatisticsHistory { get; set; } public StatisticsDifference[]? StatisticsHistory { get; set; }
} }
} }
@@ -26,7 +26,7 @@ namespace WotBlitzStatisticsPro.Common.Model
///<summary> ///<summary>
/// Player's nick /// Player's nick
///</summary> ///</summary>
public string Nickname { get; set; } public string? Nickname { get; set; }
///<summary> ///<summary>
/// Battles count /// Battles count
@@ -151,7 +151,7 @@ namespace WotBlitzStatisticsPro.Common.Model
/// <summary> /// <summary>
/// All player's tanks /// All player's tanks
/// </summary> /// </summary>
public List<TankInfoResponse> Tanks { get; set; } public List<TankInfoResponse>? Tanks { get; set; }
} }
} }
@@ -14,6 +14,6 @@ namespace WotBlitzStatisticsPro.Common.Model
/// <summary> /// <summary>
/// Found accounts list /// Found accounts list
/// </summary> /// </summary>
public ICollection<AccountsSearchResponseItem> Accounts { get; set; } public ICollection<AccountsSearchResponseItem>? Accounts { get; set; }
} }
} }
@@ -13,6 +13,6 @@
///<summary> ///<summary>
/// Player nick /// Player nick
///</summary> ///</summary>
public string Nickname { get; set; } public string? Nickname { get; set; }
} }
} }
@@ -14,6 +14,6 @@ namespace WotBlitzStatisticsPro.Common.Model
/// <summary> /// <summary>
/// List of clans /// List of clans
/// </summary> /// </summary>
public ICollection<ClanSearchResponseItem> Clans { get; set; } public ICollection<ClanSearchResponseItem>? Clans { get; set; }
} }
} }
@@ -13,12 +13,12 @@
///<summary> ///<summary>
/// Clan Tag /// Clan Tag
///</summary> ///</summary>
public string Tag { get; set; } public string? Tag { get; set; }
///<summary> ///<summary>
/// Clan Name /// Clan Name
///</summary> ///</summary>
public string Name { get; set; } public string? Name { get; set; }
///<summary> ///<summary>
/// Clan created at. (UNIX Epoch time) /// Clan created at. (UNIX Epoch time)
@@ -15,32 +15,32 @@ namespace WotBlitzStatisticsPro.Common.Model
///<summary> ///<summary>
/// Difference in Battles count /// Difference in Battles count
///</summary> ///</summary>
public StatisticsDifferenceItem<long> Battles { get; set; } public StatisticsDifferenceItem<long>? Battles { get; set; }
/// <summary> /// <summary>
/// Difference in Average tier /// Difference in Average tier
/// </summary> /// </summary>
public StatisticsDifferenceItem<double> AvgTier { get; set; } public StatisticsDifferenceItem<double>? AvgTier { get; set; }
/// <summary> /// <summary>
/// Difference in Wn7 coefficient /// Difference in Wn7 coefficient
/// </summary> /// </summary>
public StatisticsDifferenceItem<double> Wn7 { get; set; } public StatisticsDifferenceItem<double>? Wn7 { get; set; }
/// <summary> /// <summary>
/// Difference in Player's win rate /// Difference in Player's win rate
/// </summary> /// </summary>
public StatisticsDifferenceItem<decimal> WinRate { get; set; } public StatisticsDifferenceItem<decimal>? WinRate { get; set; }
/// <summary> /// <summary>
/// Difference in Player's average damage /// Difference in Player's average damage
/// </summary> /// </summary>
public StatisticsDifferenceItem<decimal> AvgDamage { get; set; } public StatisticsDifferenceItem<decimal>? AvgDamage { get; set; }
/// <summary> /// <summary>
/// Difference in Player's average XP /// Difference in Player's average XP
/// </summary> /// </summary>
public StatisticsDifferenceItem<decimal> AvgXp { get; set; } public StatisticsDifferenceItem<decimal>? AvgXp { get; set; }
} }
} }
@@ -150,17 +150,17 @@ namespace WotBlitzStatisticsPro.Common.Model
/// <summary> /// <summary>
/// Tank name /// Tank name
/// </summary> /// </summary>
public string Name { get; set; } public string? Name { get; set; }
/// <summary> /// <summary>
/// Tank nation dictionary identifier /// Tank nation dictionary identifier
/// </summary> /// </summary>
public string TankNationId { get; set; } public string? TankNationId { get; set; }
/// <summary> /// <summary>
/// Localized tank nation name /// Localized tank nation name
/// </summary> /// </summary>
public string TankNation { get; set; } public string? TankNation { get; set; }
/// <summary> /// <summary>
/// Tank tier /// Tank tier
@@ -170,12 +170,12 @@ namespace WotBlitzStatisticsPro.Common.Model
/// <summary> /// <summary>
/// Tank type dictionary identifier /// Tank type dictionary identifier
/// </summary> /// </summary>
public string TankTypeId { get; set; } public string? TankTypeId { get; set; }
/// <summary> /// <summary>
/// Localized tank type name /// Localized tank type name
/// </summary> /// </summary>
public string TankType { get; set; } public string? TankType { get; set; }
/// <summary> /// <summary>
/// Is it premium tank or not /// Is it premium tank or not
@@ -13,6 +13,6 @@
/// <summary> /// <summary>
/// A bit summary about what have been updated /// A bit summary about what have been updated
/// </summary> /// </summary>
public string Description { get; set; } public string? Description { get; set; }
} }
} }
@@ -3,6 +3,7 @@
<PropertyGroup> <PropertyGroup>
<TargetFramework>net5.0</TargetFramework> <TargetFramework>net5.0</TargetFramework>
<GenerateDocumentationFile>true</GenerateDocumentationFile> <GenerateDocumentationFile>true</GenerateDocumentationFile>
<Nullable>enable</Nullable>
</PropertyGroup> </PropertyGroup>
</Project> </Project>
@@ -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; using WotBlitzStatisticsPro.Common.Model;
namespace WotBlitzStatisticsPro.DataAccess.Model.Accounts namespace WotBlitzStatisticsPro.DataAccess.Model.Accounts
@@ -32,7 +35,8 @@ namespace WotBlitzStatisticsPro.DataAccess.Model.Accounts
///<summary> ///<summary>
/// Player's nick /// Player's nick
///</summary> ///</summary>
public string Nickname { get; set; } [Required]
public string Nickname { get; set; } = string.Empty;
///<summary> ///<summary>
/// Player information update date /// Player information update date
@@ -19,14 +19,14 @@ namespace WotBlitzStatisticsPro.DataAccess.Model.Accounts
public int LastBattleTime { get; set; } public int LastBattleTime { get; set; }
public bool Equals(AccountInfoHistoryKey other) public bool Equals(AccountInfoHistoryKey? other)
{ {
if (ReferenceEquals(null, other)) return false; if (ReferenceEquals(null, other)) return false;
if (ReferenceEquals(this, other)) return true; if (ReferenceEquals(this, other)) return true;
return AccountId == other.AccountId && LastBattleTime == other.LastBattleTime; 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(null, obj)) return false;
if (ReferenceEquals(this, obj)) return true; if (ReferenceEquals(this, obj)) return true;
@@ -7,7 +7,7 @@ namespace WotBlitzStatisticsPro.DataAccess.Model.Accounts
{ {
public TankInfo() public TankInfo()
{ {
TankInfoId = new TankInfoKey();
} }
public TankInfo(long accountId, long tankId) public TankInfo(long accountId, long tankId)
@@ -7,7 +7,7 @@ namespace WotBlitzStatisticsPro.DataAccess.Model.Accounts
public TankInfoHistory() public TankInfoHistory()
{ {
TankInfoHistoryId = new TankInfoHistoryKey();
} }
public TankInfoHistory(long accountId, long tankId, int lastBattleTime) public TankInfoHistory(long accountId, long tankId, int lastBattleTime)
@@ -31,14 +31,14 @@ namespace WotBlitzStatisticsPro.DataAccess.Model.Accounts
///</summary> ///</summary>
public int LastBattleTime { get; set; } public int LastBattleTime { get; set; }
public bool Equals(TankInfoHistoryKey other) public bool Equals(TankInfoHistoryKey? other)
{ {
if (ReferenceEquals(null, other)) return false; if (ReferenceEquals(null, other)) return false;
if (ReferenceEquals(this, other)) return true; if (ReferenceEquals(this, other)) return true;
return AccountId == other.AccountId && TankId == other.TankId && LastBattleTime == other.LastBattleTime; 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(null, obj)) return false;
if (ReferenceEquals(this, obj)) return true; if (ReferenceEquals(this, obj)) return true;
@@ -25,14 +25,14 @@ namespace WotBlitzStatisticsPro.DataAccess.Model.Accounts
///</summary> ///</summary>
public long TankId { get; set; } public long TankId { get; set; }
public bool Equals(TankInfoKey other) public bool Equals(TankInfoKey? other)
{ {
if (ReferenceEquals(null, other)) return false; if (ReferenceEquals(null, other)) return false;
if (ReferenceEquals(this, other)) return true; if (ReferenceEquals(this, other)) return true;
return AccountId == other.AccountId && TankId == other.TankId; 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(null, obj)) return false;
if (ReferenceEquals(this, obj)) return true; if (ReferenceEquals(this, obj)) return true;
@@ -1,4 +1,5 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq;
using MongoDB.Bson.Serialization.Attributes; using MongoDB.Bson.Serialization.Attributes;
using WotBlitzStatisticsPro.Common.Dictionaries; using WotBlitzStatisticsPro.Common.Dictionaries;
@@ -6,19 +7,18 @@ namespace WotBlitzStatisticsPro.DataAccess.Model
{ {
public class AchievementDictionary : IAchievementDictionary public class AchievementDictionary : IAchievementDictionary
{ {
[BsonId] [BsonId] public string AchievementId { get; set; } = string.Empty;
public string AchievementId { get; set; } public List<LocalizableString> Condition { get; set; } = Enumerable.Empty<LocalizableString>().ToList();
public List<LocalizableString> Condition { get; set; } public List<LocalizableString> Description { get; set; } = Enumerable.Empty<LocalizableString>().ToList();
public List<LocalizableString> Description { get; set; } public List<LocalizableString> HeroInfo { get; set; } = Enumerable.Empty<LocalizableString>().ToList();
public List<LocalizableString> HeroInfo { get; set; } public string Image { get; set; } = string.Empty;
public string Image { get; set; } public string ImageBig { get; set; } = string.Empty;
public string ImageBig { get; set; } public List<LocalizableString> Name { get; set; } = Enumerable.Empty<LocalizableString>().ToList();
public List<LocalizableString> Name { get; set; }
public long? Order { get; set; } public long? Order { get; set; }
public bool Outdated { 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 long? SectionOrder { get; set; }
public string Type { get; set; } public string Type { get; set; } = string.Empty;
public List<AchievementOption> Options { get; set; } public List<AchievementOption> Options { get; set; } = Enumerable.Empty<AchievementOption>().ToList();
} }
} }
@@ -1,4 +1,5 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq;
using MongoDB.Bson.Serialization.Attributes; using MongoDB.Bson.Serialization.Attributes;
using WotBlitzStatisticsPro.Common.Dictionaries; using WotBlitzStatisticsPro.Common.Dictionaries;
@@ -6,9 +7,10 @@ namespace WotBlitzStatisticsPro.DataAccess.Model
{ {
public class AchievementSectionDictionary: IAchievementSectionDictionary public class AchievementSectionDictionary: IAchievementSectionDictionary
{ {
[BsonId] [BsonId] public string AchievementSectionId { get; set; } = string.Empty;
public string AchievementSectionId { get; set; }
public int Order { get; set; } public int Order { get; set; }
public List<LocalizableString> AchievementSectionNames { get; set; }
public List<LocalizableString> AchievementSectionNames { get; set; } =
Enumerable.Empty<LocalizableString>().ToList();
} }
} }
@@ -1,4 +1,5 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq;
using MongoDB.Bson.Serialization.Attributes; using MongoDB.Bson.Serialization.Attributes;
using WotBlitzStatisticsPro.Common.Dictionaries; using WotBlitzStatisticsPro.Common.Dictionaries;
@@ -6,8 +7,8 @@ namespace WotBlitzStatisticsPro.DataAccess.Model
{ {
public class ClanRoleDictionary : IClanRoleDictionary public class ClanRoleDictionary : IClanRoleDictionary
{ {
[BsonId] [BsonId] public string ClanRoleId { get; set; } = string.Empty;
public string ClanRoleId { get; set; } public List<LocalizableString> ClanRoleNames { get; set; } =
public List<LocalizableString> ClanRoleNames { get; set; } Enumerable.Empty<LocalizableString>().ToList();
} }
} }
@@ -5,9 +5,8 @@ namespace WotBlitzStatisticsPro.DataAccess.Model
{ {
public class LanguageDictionary: ILanguageDictionary public class LanguageDictionary: ILanguageDictionary
{ {
[BsonId] [BsonId] public string LanguageId { get; set; } = string.Empty;
public string LanguageId { get; set; }
public string LanguageName { get; set; } public string LanguageName { get; set; } = string.Empty;
} }
} }
@@ -1,4 +1,5 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq;
using MongoDB.Bson.Serialization.Attributes; using MongoDB.Bson.Serialization.Attributes;
using WotBlitzStatisticsPro.Common.Dictionaries; using WotBlitzStatisticsPro.Common.Dictionaries;
@@ -6,8 +7,8 @@ namespace WotBlitzStatisticsPro.DataAccess.Model
{ {
public class NationDictionary : INationDictionary public class NationDictionary : INationDictionary
{ {
[BsonId] [BsonId] public string NationId { get; set; } = string.Empty;
public string NationId { get; set; } public List<LocalizableString> NationNames { get; set; } =
public List<LocalizableString> NationNames { get; set; } Enumerable.Empty<LocalizableString>().ToList();
} }
} }
@@ -1,4 +1,5 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq;
using MongoDB.Bson.Serialization.Attributes; using MongoDB.Bson.Serialization.Attributes;
using WotBlitzStatisticsPro.Common.Dictionaries; using WotBlitzStatisticsPro.Common.Dictionaries;
@@ -6,8 +7,8 @@ namespace WotBlitzStatisticsPro.DataAccess.Model
{ {
public class VehicleTypeDictionary : IVehicleTypeDictionary public class VehicleTypeDictionary : IVehicleTypeDictionary
{ {
[BsonId] [BsonId] public string VehicleTypeId { get; set; } = string.Empty;
public string VehicleTypeId { get; set; }
public List<LocalizableString> VehicleTypeNames { get; set; } public List<LocalizableString> VehicleTypeNames { get; set; } = Enumerable.Empty<LocalizableString>().ToList();
} }
} }
@@ -1,4 +1,5 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq;
using MongoDB.Bson.Serialization.Attributes; using MongoDB.Bson.Serialization.Attributes;
using WotBlitzStatisticsPro.Common.Dictionaries; using WotBlitzStatisticsPro.Common.Dictionaries;
@@ -8,21 +9,25 @@ namespace WotBlitzStatisticsPro.DataAccess.Model
{ {
[BsonId] [BsonId]
public long TankId { get; set; } public long TankId { get; set; }
public List<LocalizableString> Name { get; set; } public List<LocalizableString> Name { get; set; } =
public List<LocalizableString> Description { get; set; } Enumerable.Empty<LocalizableString>().ToList();
public List<LocalizableString> Description { get; set; } =
Enumerable.Empty<LocalizableString>().ToList();
public bool IsPremium { get; set; } public bool IsPremium { get; set; }
public string TypeId { get; set; } public string TypeId { get; set; } = string.Empty;
public string NationId { get; set; } public string NationId { get; set; } = string.Empty;
public int Tier { get; set; } public int Tier { get; set; }
public string PreviewImage { get; set; } public string PreviewImage { get; set; } = string.Empty;
public string NormalImage { get; set; } public string NormalImage { get; set; } = string.Empty;
public decimal PriceCredit { get; set; } public decimal PriceCredit { get; set; }
public decimal PriceGold { get; set; } public decimal PriceGold { get; set; }
public List<VehiclePriceInXp> NexTanksInTree { get; set; } public List<VehiclePriceInXp> NexTanksInTree { get; set; } =
public List<VehiclePriceInXp> PriceXp { get; set; } Enumerable.Empty<VehiclePriceInXp>().ToList();
public int[] Engines { get; set; } public List<VehiclePriceInXp> PriceXp { get; set; } =
public int[] Guns { get; set; } Enumerable.Empty<VehiclePriceInXp>().ToList();
public int[] Suspensions { get; set; } public int[]? Engines { get; set; }
public int[] Turrets { get; set; } public int[]? Guns { get; set; }
public int[]? Suspensions { get; set; }
public int[]? Turrets { get; set; }
} }
} }
@@ -2,6 +2,7 @@
<PropertyGroup> <PropertyGroup>
<TargetFramework>net5.0</TargetFramework> <TargetFramework>net5.0</TargetFramework>
<Nullable>enable</Nullable>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
@@ -4,7 +4,7 @@ namespace WotBlitzStatisticsPro.GraphQl
{ {
public class MongoSettings : IMongoSettings public class MongoSettings : IMongoSettings
{ {
public string ConnectionString { get; set; } public string ConnectionString { get; set; } = string.Empty;
public string DatabaseName { get; set; } public string DatabaseName { get; set; } = string.Empty;
} }
} }
@@ -4,8 +4,8 @@ namespace WotBlitzStatisticsPro.GraphQl
{ {
/// <inheritdoc /> /// <inheritdoc />
public class WargamingApiSettings : IWargamingApiSettings public class WargamingApiSettings : IWargamingApiSettings
{ {
/// <inheritdoc /> /// <inheritdoc />
public string ApplicationId { get; set; } public string ApplicationId { get; set; } = string.Empty;
} }
} }
@@ -4,6 +4,7 @@
<TargetFramework>net5.0</TargetFramework> <TargetFramework>net5.0</TargetFramework>
<GenerateDocumentationFile>true</GenerateDocumentationFile> <GenerateDocumentationFile>true</GenerateDocumentationFile>
<NoWarn>$(NoWarn);1591</NoWarn> <NoWarn>$(NoWarn);1591</NoWarn>
<Nullable>enable</Nullable>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
@@ -13,14 +13,14 @@ namespace WotBlitzStatisticsPro.Logic.AccountInformationPipeline
public DateTime LastBattleSince { get; } public DateTime LastBattleSince { get; }
public AccountInfo DbAccountInfo { get; set; } public AccountInfo? DbAccountInfo { get; set; }
public IStatistics[] History { get; set; } public IStatistics[]? History { get; set; }
public ShortStatistics OverallStatistics { get; set; } public 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; }
public AccountInfoHistoryResponse Response { get; set; } public AccountInfoHistoryResponse? Response { get; set; }
} }
} }
@@ -6,17 +6,17 @@ namespace WotBlitzStatisticsPro.Logic.AccountInformationPipeline
{ {
public class AccountInformationPipelineContextData : IDatabasePipelineContextData 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<TankInfo> Tanks { get; set; } public List<TankInfo>? Tanks { get; set; }
public Dictionary<long, TankInfoHistory> TanksHistory { get; set; } public Dictionary<long, TankInfoHistory>? TanksHistory { get; set; }
public AccountInfoResponse Response { get; set; } public AccountInfoResponse? Response { get; set; }
public AccountInfo DbAccountInfo { get; set; } public AccountInfo? DbAccountInfo { get; set; }
} }
} }
@@ -5,6 +5,6 @@ namespace WotBlitzStatisticsPro.Logic.AccountInformationPipeline
{ {
public interface IDatabasePipelineContextData public interface IDatabasePipelineContextData
{ {
AccountInfo DbAccountInfo { get; set; } AccountInfo? DbAccountInfo { get; set; }
} }
} }
@@ -4,15 +4,15 @@ namespace WotBlitzStatisticsPro.Logic.AccountInformationPipeline
{ {
public interface IStatisticsPipelineData 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; }
} }
} }
@@ -2,7 +2,7 @@
{ {
public class OperationContext : IOperationContext public class OperationContext : IOperationContext
{ {
private object _contextData; private object? _contextData;
public OperationContext(AccountRequest request) public OperationContext(AccountRequest request)
@@ -21,7 +21,7 @@
{ {
_contextData ??= default(TContextData); _contextData ??= default(TContextData);
return (TContextData)_contextData; return (TContextData)_contextData!;
} }
} }
} }
@@ -3,6 +3,7 @@ using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Threading.Tasks; using System.Threading.Tasks;
using AutoMapper; using AutoMapper;
using Microsoft.Extensions.Logging;
using WotBlitzStatisticsPro.Common.Dictionaries; using WotBlitzStatisticsPro.Common.Dictionaries;
using WotBlitzStatisticsPro.Common.Model; using WotBlitzStatisticsPro.Common.Model;
using WotBlitzStatisticsPro.DataAccess; using WotBlitzStatisticsPro.DataAccess;
@@ -17,17 +18,31 @@ namespace WotBlitzStatisticsPro.Logic.AccountInformationPipeline.Operations
{ {
private readonly IMapper _mapper; private readonly IMapper _mapper;
private readonly IDictionariesDataAccessor _dictionariesDataAccessor; private readonly IDictionariesDataAccessor _dictionariesDataAccessor;
private readonly ILogger<BuildAccountInfoResponseOperation> _logger;
public BuildAccountInfoResponseOperation(IMapper mapper, IDictionariesDataAccessor dictionariesDataAccessor) public BuildAccountInfoResponseOperation(
IMapper mapper,
IDictionariesDataAccessor dictionariesDataAccessor,
ILogger<BuildAccountInfoResponseOperation> logger)
{ {
_mapper = mapper; _mapper = mapper;
_dictionariesDataAccessor = dictionariesDataAccessor; _dictionariesDataAccessor = dictionariesDataAccessor;
_logger = logger;
} }
public async Task Invoke(IOperationContext context, Func<IOperationContext, Task> next) public async Task Invoke(IOperationContext context, Func<IOperationContext, Task>? next)
{ {
var contextData = context.Get<AccountInformationPipelineContextData>(); var contextData = context.Get<AccountInformationPipelineContextData>();
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<AccountInfo, AccountInfoResponse>(contextData.AccountInfo); contextData.Response = _mapper.Map<AccountInfo, AccountInfoResponse>(contextData.AccountInfo);
contextData.Response = _mapper.Map(contextData.AccountInfoHistory, contextData.Response); contextData.Response = _mapper.Map(contextData.AccountInfoHistory, contextData.Response);
@@ -48,13 +63,23 @@ namespace WotBlitzStatisticsPro.Logic.AccountInformationPipeline.Operations
opt.Items["language"] = context.Request.RequestLanguage; opt.Items["language"] = context.Request.RequestLanguage;
opt.AfterMap((src, dest) => opt.AfterMap((src, dest) =>
{ {
dest.TankType = tankTypes.ContainsKey(dest.TankTypeId) ? tankTypes[dest.TankTypeId] : "-"; if(dest?.TankTypeId != null)
dest.TankNation = nations.ContainsKey(dest.TankNationId) ? nations[dest.TankNationId] : "-"; {
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() private static IVehiclesDictionary CreateStubVehicle()
@@ -17,9 +17,16 @@ namespace WotBlitzStatisticsPro.Logic.AccountInformationPipeline.Operations
_dictionariesDataAccessor = dictionariesDataAccessor; _dictionariesDataAccessor = dictionariesDataAccessor;
} }
public async Task Invoke(IOperationContext context, Func<IOperationContext, Task> next) public async Task Invoke(IOperationContext context, Func<IOperationContext, Task>? next)
{ {
var contextData = context.Get<AccountInformationPipelineContextData>(); var contextData = context.Get<AccountInformationPipelineContextData>();
if (contextData?.AccountInfo == null ||
contextData?.AccountInfoHistory == null ||
contextData?.Tanks == null ||
contextData?.TanksHistory == null)
{
return;
}
var tankIds = contextData.Tanks.Select(t => t.TankId).ToArray(); var tankIds = contextData.Tanks.Select(t => t.TankId).ToArray();
var tankTires = await _dictionariesDataAccessor.GetTankTires(tankIds); 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.CalculateMiddleTier(contextData.TanksHistory.Values.ToList(), tankTires);
contextData.AccountInfoHistory.CalculateWn7(); contextData.AccountInfoHistory.CalculateWn7();
await next.Invoke(context); if (next != null) await next.Invoke(context);
} }
} }
} }
@@ -16,11 +16,11 @@ namespace WotBlitzStatisticsPro.Logic.AccountInformationPipeline.Operations
} }
public Task Invoke(IOperationContext context, Func<IOperationContext, Task> next) public Task Invoke(IOperationContext context, Func<IOperationContext, Task>? next)
{ {
var contextData = context.Get<IStatisticsPipelineData>(); var contextData = context.Get<IStatisticsPipelineData>();
if (contextData.History == null || if (contextData?.History == null ||
contextData.History.Length == 0) contextData.History.Length == 0)
{ {
_logger.LogInformation( _logger.LogInformation(
@@ -28,7 +28,7 @@ namespace WotBlitzStatisticsPro.Logic.AccountInformationPipeline.Operations
return Task.CompletedTask; return Task.CompletedTask;
} }
return next.Invoke(context); return next != null ? next.Invoke(context) : Task.CompletedTask;
} }
} }
} }
@@ -15,16 +15,16 @@ namespace WotBlitzStatisticsPro.Logic.AccountInformationPipeline.Operations
_logger = logger; _logger = logger;
} }
public Task Invoke(IOperationContext context, Func<IOperationContext, Task> next) public Task Invoke(IOperationContext context, Func<IOperationContext, Task>? next)
{ {
var contextData = context.Get<AccountInformationPipelineContextData>(); var contextData = context.Get<AccountInformationPipelineContextData>();
if (contextData.DbAccountInfo == null || 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; return Task.CompletedTask;
} }
} }
@@ -9,10 +9,15 @@ namespace WotBlitzStatisticsPro.Logic.AccountInformationPipeline.Operations
{ {
public class FillAccountInfoHistoryResponse : IOperation<IOperationContext> public class FillAccountInfoHistoryResponse : IOperation<IOperationContext>
{ {
public Task Invoke(IOperationContext context, Func<IOperationContext, Task> next) public Task Invoke(IOperationContext context, Func<IOperationContext, Task>? next)
{ {
var contextData = context.Get<AccountHistoryInformationPipelineContextData>(); var contextData = context.Get<AccountHistoryInformationPipelineContextData>();
if (contextData?.DbAccountInfo == null)
{
return next != null ? next.Invoke(context) : Task.CompletedTask;
}
contextData.Response = new AccountInfoHistoryResponse contextData.Response = new AccountInfoHistoryResponse
{ {
AccountId = context.Request.AccountId, AccountId = context.Request.AccountId,
@@ -24,7 +29,7 @@ namespace WotBlitzStatisticsPro.Logic.AccountInformationPipeline.Operations
OverallAccountStatistics = contextData.OverallStatistics OverallAccountStatistics = contextData.OverallStatistics
}; };
return next.Invoke(context); return next != null ? next.Invoke(context) : Task.CompletedTask;
} }
} }
} }
@@ -17,13 +17,16 @@ namespace WotBlitzStatisticsPro.Logic.AccountInformationPipeline.Operations
} }
public Task Invoke(IOperationContext context, Func<IOperationContext, Task> next) public Task Invoke(IOperationContext context, Func<IOperationContext, Task>? next)
{ {
var contextData = context.Get<IStatisticsPipelineData>(); var contextData = context.Get<IStatisticsPipelineData>();
contextData.OverallStatistics = _mapper.Map<IStatistics, ShortStatistics>(contextData.History[0]); if(contextData?.History != null)
{
contextData.OverallStatistics = _mapper.Map<IStatistics, ShortStatistics>(contextData.History[0]);
}
return next.Invoke(context); return next != null ? next.Invoke(context) : Task.CompletedTask;
} }
} }
} }
@@ -1,6 +1,5 @@
using System; using System;
using System.Threading.Tasks; using System.Threading.Tasks;
using AutoMapper;
using WotBlitzStatisticsPro.Common.Model; using WotBlitzStatisticsPro.Common.Model;
using WotBlitzStatisticsPro.Logic.AccountInformationPipeline.OperationContext; using WotBlitzStatisticsPro.Logic.AccountInformationPipeline.OperationContext;
using WotBlitzStatisticsPro.Logic.Calculations; using WotBlitzStatisticsPro.Logic.Calculations;
@@ -10,11 +9,11 @@ namespace WotBlitzStatisticsPro.Logic.AccountInformationPipeline.Operations
{ {
public class FillPeriodDifferenceOperation : IOperation<IOperationContext> public class FillPeriodDifferenceOperation : IOperation<IOperationContext>
{ {
public Task Invoke(IOperationContext context, Func<IOperationContext, Task> next) public Task Invoke(IOperationContext context, Func<IOperationContext, Task>? next)
{ {
var contextData = context.Get<IStatisticsPipelineData>(); var contextData = context.Get<IStatisticsPipelineData>();
if (contextData.History.Length > 1) if (contextData?.History != null && contextData.History.Length > 1)
{ {
contextData.PeriodDifference = new StatisticsDifference(); contextData.PeriodDifference = new StatisticsDifference();
var historyLastIndex = contextData.History.Length - 1; var historyLastIndex = contextData.History.Length - 1;
@@ -22,7 +21,7 @@ namespace WotBlitzStatisticsPro.Logic.AccountInformationPipeline.Operations
contextData.PeriodDifference.FillDifference(contextData.History[0], contextData.History[historyLastIndex]); contextData.PeriodDifference.FillDifference(contextData.History[0], contextData.History[historyLastIndex]);
} }
return next.Invoke(context); return next != null ? next.Invoke(context) : Task.CompletedTask;
} }
} }
} }
@@ -18,11 +18,11 @@ namespace WotBlitzStatisticsPro.Logic.AccountInformationPipeline.Operations
} }
public Task Invoke(IOperationContext context, Func<IOperationContext, Task> next) public Task Invoke(IOperationContext context, Func<IOperationContext, Task>? next)
{ {
var contextData = context.Get<IStatisticsPipelineData>(); var contextData = context.Get<IStatisticsPipelineData>();
if (contextData.History.Length > 1) if (contextData?.History != null && contextData.History.Length > 1)
{ {
var diff = new AccountInfoHistory(context.Request.AccountId, contextData.History[0].LastBattleTime); var diff = new AccountInfoHistory(context.Request.AccountId, contextData.History[0].LastBattleTime);
@@ -36,7 +36,7 @@ namespace WotBlitzStatisticsPro.Logic.AccountInformationPipeline.Operations
contextData.PeriodAccountStatistics = _mapper.Map<IStatistics, ShortStatistics>(diff); contextData.PeriodAccountStatistics = _mapper.Map<IStatistics, ShortStatistics>(diff);
} }
return next.Invoke(context); return next != null ? next.Invoke(context) : Task.CompletedTask;
} }
} }
} }
@@ -10,11 +10,11 @@ namespace WotBlitzStatisticsPro.Logic.AccountInformationPipeline.Operations
{ {
public class FillStatisticsDifferenceOperation : IOperation<IOperationContext> public class FillStatisticsDifferenceOperation : IOperation<IOperationContext>
{ {
public Task Invoke(IOperationContext context, Func<IOperationContext, Task> next) public Task Invoke(IOperationContext context, Func<IOperationContext, Task>? next)
{ {
var contextData = context.Get<IStatisticsPipelineData>(); var contextData = context.Get<IStatisticsPipelineData>();
if (contextData.History.Length > 1) if (contextData?.History != null && contextData.History.Length > 1)
{ {
contextData.StatisticsHistory = new StatisticsDifference[contextData.History.Length - 1]; contextData.StatisticsHistory = new StatisticsDifference[contextData.History.Length - 1];
for (int i = 1; i < contextData.History.Length; i++) 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;
} }
} }
} }
@@ -1,6 +1,7 @@
using System; using System;
using System.Threading.Tasks; using System.Threading.Tasks;
using AutoMapper; using AutoMapper;
using Microsoft.Extensions.Logging;
using WotBlitzStatisticsPro.DataAccess.Model.Accounts; using WotBlitzStatisticsPro.DataAccess.Model.Accounts;
using WotBlitzStatisticsPro.Logic.AccountInformationPipeline.OperationContext; using WotBlitzStatisticsPro.Logic.AccountInformationPipeline.OperationContext;
using WotBlitzStatisticsPro.Logic.Pipeline; using WotBlitzStatisticsPro.Logic.Pipeline;
@@ -13,29 +14,39 @@ namespace WotBlitzStatisticsPro.Logic.AccountInformationPipeline.Operations
{ {
private readonly IWargamingApiClient _wargamingApi; private readonly IWargamingApiClient _wargamingApi;
private readonly IMapper _mapper; private readonly IMapper _mapper;
private readonly ILogger<GetAccountInfoOperation> _logger;
public GetAccountInfoOperation( public GetAccountInfoOperation(
IWargamingApiClient wargamingApi, IWargamingApiClient wargamingApi,
IMapper mapper) IMapper mapper,
ILogger<GetAccountInfoOperation> logger)
{ {
_wargamingApi = wargamingApi; _wargamingApi = wargamingApi;
_mapper = mapper; _mapper = mapper;
_logger = logger;
} }
public async Task Invoke(IOperationContext context, Func<IOperationContext, Task> next) public async Task Invoke(IOperationContext context, Func<IOperationContext, Task>? next)
{ {
var accountInfo = await var accountInfo = await
_wargamingApi.GetPlayerAccountInfo(context.Request.AccountId, context.Request.RealmType, context.Request.RequestLanguage); _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 // Store info to AccountInfo and in AccountInfoHistory
var contextData = context.Get<AccountInformationPipelineContextData>(); var contextData = context.Get<AccountInformationPipelineContextData>();
contextData.AccountInfo = _mapper.Map<WotAccountInfo, AccountInfo>(accountInfo); contextData.AccountInfo = _mapper.Map<WotAccountInfo, AccountInfo>(accountInfo);
contextData.AccountInfo.Realm = context.Request.RealmType; contextData.AccountInfo.Realm = context.Request.RealmType;
contextData.AccountInfoHistory = new AccountInfoHistory(context.Request.AccountId, contextData.AccountInfo.LastBattleTime); 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);
} }
} }
} }
@@ -1,12 +1,13 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks; using System.Threading.Tasks;
using AutoMapper; using AutoMapper;
using Microsoft.Extensions.Logging;
using WotBlitzStatisticsPro.DataAccess.Model.Accounts; using WotBlitzStatisticsPro.DataAccess.Model.Accounts;
using WotBlitzStatisticsPro.Logic.AccountInformationPipeline.OperationContext; using WotBlitzStatisticsPro.Logic.AccountInformationPipeline.OperationContext;
using WotBlitzStatisticsPro.Logic.Pipeline; using WotBlitzStatisticsPro.Logic.Pipeline;
using WotBlitzStatisticsPro.WgApiClient; using WotBlitzStatisticsPro.WgApiClient;
using WotBlitzStatisticsPro.WgApiClient.Model;
namespace WotBlitzStatisticsPro.Logic.AccountInformationPipeline.Operations namespace WotBlitzStatisticsPro.Logic.AccountInformationPipeline.Operations
{ {
@@ -14,26 +15,36 @@ namespace WotBlitzStatisticsPro.Logic.AccountInformationPipeline.Operations
{ {
private readonly IWargamingTanksApiClient _wargamingApi; private readonly IWargamingTanksApiClient _wargamingApi;
private readonly IMapper _mapper; private readonly IMapper _mapper;
private readonly ILogger<GetTanksInfoOperation> _logger;
public GetTanksInfoOperation( public GetTanksInfoOperation(
IWargamingTanksApiClient wargamingApi, IWargamingTanksApiClient wargamingApi,
IMapper mapper) IMapper mapper,
ILogger<GetTanksInfoOperation> logger)
{ {
_wargamingApi = wargamingApi; _wargamingApi = wargamingApi;
_mapper = mapper; _mapper = mapper;
_logger = logger;
} }
public async Task Invoke(IOperationContext context, Func<IOperationContext, Task> next) public async Task Invoke(IOperationContext context, Func<IOperationContext, Task>? next)
{ {
var contextData = context.Get<AccountInformationPipelineContextData>(); var contextData = context.Get<AccountInformationPipelineContextData>();
var tanksInfo = await var tanksInfo = await
_wargamingApi.GetPlayerAccountTanksInfo(context.Request.AccountId, context.Request.RealmType, context.Request.RequestLanguage); _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<TankInfo>(); contextData.Tanks = new List<TankInfo>();
contextData.TanksHistory = new Dictionary<long, TankInfoHistory>(); contextData.TanksHistory = new Dictionary<long, TankInfoHistory>();
tanksInfo.ForEach(tank => tanksInfo.OrderByDescending(t => t.LastBattleTime).ToList().ForEach(tank =>
{ {
var tankInfo = new TankInfo(tank.AccountId, tank.TankId); var tankInfo = new TankInfo(tank.AccountId, tank.TankId);
_mapper.Map(tank, tankInfo); _mapper.Map(tank, tankInfo);
@@ -43,7 +54,7 @@ namespace WotBlitzStatisticsPro.Logic.AccountInformationPipeline.Operations
contextData.TanksHistory[stat.TankId] = stat; contextData.TanksHistory[stat.TankId] = stat;
}); });
await next.Invoke(context); if (next != null) await next.Invoke(context);
} }
} }
} }
@@ -15,12 +15,12 @@ namespace WotBlitzStatisticsPro.Logic.AccountInformationPipeline.Operations
_accountDataAccessor = accountDataAccessor; _accountDataAccessor = accountDataAccessor;
} }
public async Task Invoke(IOperationContext context, Func<IOperationContext, Task> next) public async Task Invoke(IOperationContext context, Func<IOperationContext, Task>? next)
{ {
var contextData = context.Get<IDatabasePipelineContextData>(); var contextData = context.Get<IDatabasePipelineContextData>();
contextData.DbAccountInfo = await _accountDataAccessor.ReadAccountInfo(context.Request.AccountId); contextData.DbAccountInfo = await _accountDataAccessor.ReadAccountInfo(context.Request.AccountId);
await next.Invoke(context); if (next != null) await next.Invoke(context);
} }
} }
} }
@@ -17,12 +17,12 @@ namespace WotBlitzStatisticsPro.Logic.AccountInformationPipeline.Operations
_accountDataAccessor = accountDataAccessor; _accountDataAccessor = accountDataAccessor;
} }
public async Task Invoke(IOperationContext context, Func<IOperationContext, Task> next) public async Task Invoke(IOperationContext context, Func<IOperationContext, Task>? next)
{ {
var contextData = context.Get<AccountHistoryInformationPipelineContextData>(); var contextData = context.Get<AccountHistoryInformationPipelineContextData>();
contextData.History = (await _accountDataAccessor.GetAccountHistory(context.Request.AccountId, contextData.LastBattleSince.ToUnixTimestamp())).ToArray(); contextData.History = (await _accountDataAccessor.GetAccountHistory(context.Request.AccountId, contextData.LastBattleSince.ToUnixTimestamp())).ToArray();
await next.Invoke(context); if (next != null) await next.Invoke(context);
} }
} }
} }
@@ -22,10 +22,18 @@ namespace WotBlitzStatisticsPro.Logic.AccountInformationPipeline.Operations
_logger = logger; _logger = logger;
} }
public async Task Invoke(IOperationContext context, Func<IOperationContext, Task> next) public async Task Invoke(IOperationContext context, Func<IOperationContext, Task>? next)
{ {
var contextData = context.Get<AccountInformationPipelineContextData>(); var contextData = context.Get<AccountInformationPipelineContextData>();
if (contextData?.AccountInfo == null ||
contextData?.AccountInfoHistory == null ||
contextData?.Tanks == null ||
contextData?.TanksHistory == null)
{
return;
}
await _accountDataAccessor.AddOurUpdateAccountInfo(contextData.AccountInfo); await _accountDataAccessor.AddOurUpdateAccountInfo(contextData.AccountInfo);
await _accountDataAccessor.AddAccountInfoHistory(contextData.AccountInfoHistory); 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}"); _logger.LogInformation($"Updated account {contextData.AccountInfo.AccountId} and {tanksCount} tanks: {tankIdsAsString}");
await next.Invoke(context); if (next != null) await next.Invoke(context);
} }
} }
} }
@@ -21,7 +21,9 @@ namespace WotBlitzStatisticsPro.Logic.Dictionaries
[Obsolete("Parameter-less constructor only for unit tests")] [Obsolete("Parameter-less constructor only for unit tests")]
public AchievementsDictionaryUpdater() public AchievementsDictionaryUpdater()
{ {
_wargamingDictionariesApiClient = null!;
_dataAccessor = null!;
_mapper = null!;
} }
public AchievementsDictionaryUpdater(IWargamingDictionariesApiClient wargamingDictionariesApiClient, IDictionariesDataAccessor dataAccessor, IMapper mapper) public AchievementsDictionaryUpdater(IWargamingDictionariesApiClient wargamingDictionariesApiClient, IDictionariesDataAccessor dataAccessor, IMapper mapper)
@@ -54,6 +56,10 @@ namespace WotBlitzStatisticsPro.Logic.Dictionaries
{ {
var wgAchievements = var wgAchievements =
await _wargamingDictionariesApiClient.GetAchievementsDictionary(defaultRealmType, requestLanguage); await _wargamingDictionariesApiClient.GetAchievementsDictionary(defaultRealmType, requestLanguage);
if (wgAchievements == null)
{
continue;
}
foreach (var wgAchievement in wgAchievements) foreach (var wgAchievement in wgAchievements)
{ {
var mappedAchievement = var mappedAchievement =
@@ -88,8 +94,8 @@ namespace WotBlitzStatisticsPro.Logic.Dictionaries
wgAchievementOption); wgAchievementOption);
mappedAchievement.Options.Add(mappedOption); mappedAchievement.Options.Add(mappedOption);
} }
mappedOption.Name.Add(new LocalizableString { Language = requestLanguage, Value = wgAchievement.Name }); mappedOption.Name?.Add(new LocalizableString { Language = requestLanguage, Value = wgAchievement.Name });
mappedOption.Description.Add(new LocalizableString { Language = requestLanguage, Value = wgAchievement.Description }); mappedOption.Description?.Add(new LocalizableString { Language = requestLanguage, Value = wgAchievement.Description });
} }
} }
} }
@@ -21,7 +21,9 @@ namespace WotBlitzStatisticsPro.Logic.Dictionaries
[Obsolete("Parameter-less constructor only for unit tests")] [Obsolete("Parameter-less constructor only for unit tests")]
public StaticDictionariesUpdater() public StaticDictionariesUpdater()
{ {
_wargamingDictionariesApiClient = null!;
_dataAccessor = null!;
_mapper = null!;
} }
public StaticDictionariesUpdater( public StaticDictionariesUpdater(
@@ -42,30 +44,45 @@ namespace WotBlitzStatisticsPro.Logic.Dictionaries
clanRoles, clanRoles,
achievementsSections) = await GetAndMapDictionaries(); achievementsSections) = await GetAndMapDictionaries();
await _dataAccessor.UpdateLanguages(languages); if(languages != null)
await _dataAccessor.UpdateNations(nations); {
await _dataAccessor.UpdateVehicleTypes(vehicleTypes); await _dataAccessor.UpdateLanguages(languages);
await _dataAccessor.UpdateClanRoles(clanRoles); }
await _dataAccessor.UpdateAchievementsSections(achievementsSections); 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 return new UpdateDictionariesResponseItem
{ {
DictionaryType = DictionaryType.StaticDictionaries, DictionaryType = DictionaryType.StaticDictionaries,
Description = 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<( private async Task<(
List<ILanguageDictionary>, List<ILanguageDictionary>?,
List<INationDictionary>, List<INationDictionary>?,
List<IVehicleTypeDictionary>, List<IVehicleTypeDictionary>?,
List<IClanRoleDictionary>, List<IClanRoleDictionary>?,
List<IAchievementSectionDictionary>)> GetAndMapDictionaries() List<IAchievementSectionDictionary>?)> GetAndMapDictionaries()
{ {
var defaultRealmType = RealmType.Eu; var defaultRealmType = RealmType.Eu;
List<ILanguageDictionary> languages = null; List<ILanguageDictionary>? languages = null;
var nations = new List<INationDictionary>(); var nations = new List<INationDictionary>();
var vehicleTypes = new List<IVehicleTypeDictionary>(); var vehicleTypes = new List<IVehicleTypeDictionary>();
var clanRoles = new List<IClanRoleDictionary>(); var clanRoles = new List<IClanRoleDictionary>();
@@ -76,17 +93,14 @@ namespace WotBlitzStatisticsPro.Logic.Dictionaries
var (wotEncyclopediaInfoResponse, wotClanMembersDictionaryResponse) = var (wotEncyclopediaInfoResponse, wotClanMembersDictionaryResponse) =
await _wargamingDictionariesApiClient.GetStaticDictionariesAsync(defaultRealmType, requestLanguage); await _wargamingDictionariesApiClient.GetStaticDictionariesAsync(defaultRealmType, requestLanguage);
if (languages == null) if (wotEncyclopediaInfoResponse?.Languages != null)
{ languages ??= _mapper
languages = .Map<Dictionary<string, string>, List<LanguageDictionary>>(wotEncyclopediaInfoResponse.Languages).Cast<ILanguageDictionary>().ToList();
_mapper.Map<Dictionary<string, string>, List<LanguageDictionary>>(wotEncyclopediaInfoResponse
.Languages).Cast<ILanguageDictionary>().ToList();
}
MapVehicleNations(requestLanguage, wotEncyclopediaInfoResponse.VehicleNations, nations); MapVehicleNations(requestLanguage, wotEncyclopediaInfoResponse?.VehicleNations, nations);
MapVehicleTypes(requestLanguage, wotEncyclopediaInfoResponse.VehicleTypes, vehicleTypes); MapVehicleTypes(requestLanguage, wotEncyclopediaInfoResponse?.VehicleTypes, vehicleTypes);
MapClanRoles(requestLanguage, wotClanMembersDictionaryResponse.ClanRoles, clanRoles); MapClanRoles(requestLanguage, wotClanMembersDictionaryResponse?.ClanRoles, clanRoles);
MapAchievementsSections(requestLanguage, wotEncyclopediaInfoResponse.AchievementSections, achievementsSections); MapAchievementsSections(requestLanguage, wotEncyclopediaInfoResponse?.AchievementSections, achievementsSections);
} }
return (languages, nations, vehicleTypes, clanRoles, achievementsSections); return (languages, nations, vehicleTypes, clanRoles, achievementsSections);
@@ -94,9 +108,13 @@ namespace WotBlitzStatisticsPro.Logic.Dictionaries
private void MapVehicleNations( private void MapVehicleNations(
RequestLanguage requestLanguage, RequestLanguage requestLanguage,
Dictionary<string, string> sourceDictionary, Dictionary<string, string>? sourceDictionary,
List<INationDictionary> destinationDictionary) List<INationDictionary> destinationDictionary)
{ {
if (sourceDictionary == null)
{
return;
}
foreach (var source in sourceDictionary) foreach (var source in sourceDictionary)
{ {
var destinationItem = destinationDictionary.FirstOrDefault(d => d.NationId == source.Key); var destinationItem = destinationDictionary.FirstOrDefault(d => d.NationId == source.Key);
@@ -116,9 +134,14 @@ namespace WotBlitzStatisticsPro.Logic.Dictionaries
private void MapVehicleTypes( private void MapVehicleTypes(
RequestLanguage requestLanguage, RequestLanguage requestLanguage,
Dictionary<string, string> sourceDictionary, Dictionary<string, string>? sourceDictionary,
List<IVehicleTypeDictionary> destinationDictionary) List<IVehicleTypeDictionary> destinationDictionary)
{ {
if (sourceDictionary == null)
{
return;
}
foreach (var source in sourceDictionary) foreach (var source in sourceDictionary)
{ {
var destinationItem = destinationDictionary.FirstOrDefault(d => d.VehicleTypeId == source.Key); var destinationItem = destinationDictionary.FirstOrDefault(d => d.VehicleTypeId == source.Key);
@@ -138,9 +161,14 @@ namespace WotBlitzStatisticsPro.Logic.Dictionaries
private void MapClanRoles( private void MapClanRoles(
RequestLanguage requestLanguage, RequestLanguage requestLanguage,
Dictionary<string, string> sourceDictionary, Dictionary<string, string>? sourceDictionary,
List<IClanRoleDictionary> destinationDictionary) List<IClanRoleDictionary> destinationDictionary)
{ {
if (sourceDictionary == null)
{
return;
}
foreach (var source in sourceDictionary) foreach (var source in sourceDictionary)
{ {
var destinationItem = destinationDictionary.FirstOrDefault(d => d.ClanRoleId == source.Key); var destinationItem = destinationDictionary.FirstOrDefault(d => d.ClanRoleId == source.Key);
@@ -160,9 +188,14 @@ namespace WotBlitzStatisticsPro.Logic.Dictionaries
private void MapAchievementsSections( private void MapAchievementsSections(
RequestLanguage requestLanguage, RequestLanguage requestLanguage,
Dictionary<string, WotEncyclopediaInfoAchievementSection> sourceSections, Dictionary<string, WotEncyclopediaInfoAchievementSection>? sourceSections,
List<IAchievementSectionDictionary> destinationDictionary) List<IAchievementSectionDictionary> destinationDictionary)
{ {
if (sourceSections == null)
{
return;
}
foreach (var section in sourceSections) foreach (var section in sourceSections)
{ {
var destinationItem = var destinationItem =
@@ -21,7 +21,9 @@ namespace WotBlitzStatisticsPro.Logic.Dictionaries
[Obsolete("Parameter-less constructor only for unit tests")] [Obsolete("Parameter-less constructor only for unit tests")]
public VehiclesDictionaryUpdater() public VehiclesDictionaryUpdater()
{ {
_wargamingDictionariesApiClient = null!;
_dataAccessor = null!;
_mapper = null!;
} }
public VehiclesDictionaryUpdater(IWargamingDictionariesApiClient wargamingDictionariesApiClient, public VehiclesDictionaryUpdater(IWargamingDictionariesApiClient wargamingDictionariesApiClient,
@@ -57,6 +59,11 @@ namespace WotBlitzStatisticsPro.Logic.Dictionaries
var wgVehicles = var wgVehicles =
await _wargamingDictionariesApiClient.GetVehicles(defaultRealmType, requestLanguage); await _wargamingDictionariesApiClient.GetVehicles(defaultRealmType, requestLanguage);
if (wgVehicles == null)
{
continue;
}
foreach (var wgVehicle in wgVehicles) foreach (var wgVehicle in wgVehicles)
{ {
var mappedVehicle = vehicles.FirstOrDefault(v => v.TankId == wgVehicle.TankId); var mappedVehicle = vehicles.FirstOrDefault(v => v.TankId == wgVehicle.TankId);
@@ -11,7 +11,7 @@ namespace WotBlitzStatisticsPro.Logic.Mappers
CreateMap<WotAccountListResponse, AccountsSearchResponseItem>() CreateMap<WotAccountListResponse, AccountsSearchResponseItem>()
.ForMember( .ForMember(
d => d.AccountId, d => d.AccountId,
o => o.MapFrom(s => s.AccountId.Value)); o => o.MapFrom(s => s.AccountId ?? -1));
} }
} }
} }
@@ -11,7 +11,7 @@ namespace WotBlitzStatisticsPro.Logic.Mappers
CreateMap<WotClanListResponse, ClanSearchResponseItem>() CreateMap<WotClanListResponse, ClanSearchResponseItem>()
.ForMember( .ForMember(
d => d.ClanId, d => d.ClanId,
o => o.MapFrom(s => s.ClanId.Value)); o => o.MapFrom(s => s.ClanId ?? -1));
} }
} }
@@ -12,11 +12,11 @@ namespace WotBlitzStatisticsPro.Logic.Mappers
.ForMember(d => d.LastBattleTime, .ForMember(d => d.LastBattleTime,
o => o.MapFrom(s => s.LastBattleTime.ToDateTime())) o => o.MapFrom(s => s.LastBattleTime.ToDateTime()))
.ForMember(d => d.AvgDamage, .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, .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, .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))
; ;
} }
} }
@@ -22,13 +22,13 @@ namespace WotBlitzStatisticsPro.Logic.Mappers
.ForMember(d => d.Tier, .ForMember(d => d.Tier,
o => o.MapFrom(s => s.Tier)) o => o.MapFrom(s => s.Tier))
.ForMember(d => d.PreviewImage, .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, .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, .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, .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, .ForMember(d => d.NexTanksInTree,
o => o =>
o.MapFrom(s => s.NextTanks)) o.MapFrom(s => s.NextTanks))
@@ -13,6 +13,6 @@ namespace WotBlitzStatisticsPro.Logic.Pipeline
/// </summary> /// </summary>
/// <param name="context">Pipeline context</param> /// <param name="context">Pipeline context</param>
/// <param name="next">Next operation</param> /// <param name="next">Next operation</param>
Task Invoke(TContext context, Func<TContext, Task> next); Task Invoke(TContext context, Func<TContext, Task>? next);
} }
} }
@@ -9,7 +9,7 @@
/// Builds the pipeline. /// Builds the pipeline.
/// </summary> /// </summary>
/// <returns>First operation in pipeline.</returns> /// <returns>First operation in pipeline.</returns>
IOperation<TContext> Build(); IOperation<TContext>? Build();
/// <summary> /// <summary>
/// Adds operation type to the pipeline /// Adds operation type to the pipeline
@@ -6,15 +6,15 @@ namespace WotBlitzStatisticsPro.Logic.Pipeline
public class OperationMediator<TContext>: IOperation<TContext> public class OperationMediator<TContext>: IOperation<TContext>
{ {
private readonly IOperation<TContext> _current; private readonly IOperation<TContext> _current;
private readonly IOperation<TContext> _next; private readonly IOperation<TContext>? _next;
public OperationMediator(IOperation<TContext> current, IOperation<TContext> next) public OperationMediator(IOperation<TContext> current, IOperation<TContext>? next)
{ {
_current = current ?? throw new ArgumentNullException(nameof(current)); _current = current ?? throw new ArgumentNullException(nameof(current));
_next = next; _next = next;
} }
public Task Invoke(TContext context, Func<TContext, Task> next) public Task Invoke(TContext context, Func<TContext, Task>? next)
{ {
return _current.Invoke(context, c => _next == null ? Task.CompletedTask : _next.Invoke(c, null)); return _current.Invoke(context, c => _next == null ? Task.CompletedTask : _next.Invoke(c, null));
} }
@@ -14,7 +14,7 @@ namespace WotBlitzStatisticsPro.Logic.Pipeline
_operationFactory = operationFactory; _operationFactory = operationFactory;
} }
public IOperation<TContext> Build() public IOperation<TContext>? Build()
{ {
var allOperationTypes = _operations.ToArray(); var allOperationTypes = _operations.ToArray();
var lastOperationType = allOperationTypes.LastOrDefault(); var lastOperationType = allOperationTypes.LastOrDefault();
@@ -13,7 +13,7 @@ namespace WotBlitzStatisticsPro.Logic.Pipeline
public IOperation<TContext> Create<TContext>(Type operationType) public IOperation<TContext> Create<TContext>(Type operationType)
{ {
return _serviceProvider.GetService(operationType) as IOperation<TContext>; return (_serviceProvider.GetService(operationType) as IOperation<TContext>)!;
} }
} }
} }
@@ -30,11 +30,15 @@ namespace WotBlitzStatisticsPro.Logic
.AddOperation<BuildAccountInfoResponseOperation>() .AddOperation<BuildAccountInfoResponseOperation>()
; ;
await pipeline.Build() var firstOperation = pipeline.Build();
.Invoke(context, null) if (firstOperation != null)
.ConfigureAwait(false); {
await firstOperation
.Invoke(context, null)
.ConfigureAwait(false);
}
return contextData.Response; return contextData?.Response ?? new AccountInfoResponse();
} }
public async Task<AccountInfoResponse> GatherAndSaveAccountInformation(RealmType realm, long accountId, RequestLanguage requestLanguage) public async Task<AccountInfoResponse> GatherAndSaveAccountInformation(RealmType realm, long accountId, RequestLanguage requestLanguage)
@@ -53,11 +57,15 @@ namespace WotBlitzStatisticsPro.Logic
.AddOperation<BuildAccountInfoResponseOperation>() .AddOperation<BuildAccountInfoResponseOperation>()
; ;
await pipeline.Build() var firstOperation = pipeline.Build();
.Invoke(context, null) if (firstOperation != null)
.ConfigureAwait(false); {
await firstOperation
.Invoke(context, null)
.ConfigureAwait(false);
}
return contextData.Response; return contextData?.Response ?? new AccountInfoResponse();
} }
public async Task<AccountInfoHistoryResponse> GetAccountInfoHistory(RealmType realm, long accountId, DateTime startDate, RequestLanguage requestLanguage) public async Task<AccountInfoHistoryResponse> GetAccountInfoHistory(RealmType realm, long accountId, DateTime startDate, RequestLanguage requestLanguage)
@@ -77,11 +85,15 @@ namespace WotBlitzStatisticsPro.Logic
.AddOperation<FillAccountInfoHistoryResponse>() .AddOperation<FillAccountInfoHistoryResponse>()
; ;
await pipeline.Build() var firstOperation = pipeline.Build();
.Invoke(context, null) if (firstOperation != null)
.ConfigureAwait(false); {
await firstOperation
.Invoke(context, null)
.ConfigureAwait(false);
}
return contextData.Response; return contextData?.Response ?? new AccountInfoHistoryResponse();
} }
} }
} }
@@ -24,6 +24,12 @@ namespace WotBlitzStatisticsPro.Logic
RequestLanguage language) RequestLanguage language)
{ {
var response = await _wargamingApiClient.FindAccounts(accountNick, realmType, language); var response = await _wargamingApiClient.FindAccounts(accountNick, realmType, language);
if (response == null)
{
return new AccountsSearchResponse();
}
return new AccountsSearchResponse return new AccountsSearchResponse
{ {
AccountsCount = response.Count, AccountsCount = response.Count,
@@ -37,6 +43,12 @@ namespace WotBlitzStatisticsPro.Logic
RequestLanguage language) RequestLanguage language)
{ {
var response = await _wargamingApiClient.FindClans(searchString, realmType, language); var response = await _wargamingApiClient.FindClans(searchString, realmType, language);
if (response == null)
{
return new ClanSearchResponse();
}
return new ClanSearchResponse return new ClanSearchResponse
{ {
ClansCount = response.Count, ClansCount = response.Count,
@@ -1,4 +1,5 @@
using System.Collections.Generic; using System;
using System.Collections.Generic;
using System.Runtime.CompilerServices; using System.Runtime.CompilerServices;
using AutoMapper; using AutoMapper;
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
@@ -43,17 +44,13 @@ namespace WotBlitzStatisticsPro.Logic
{ {
services.AddTransient<DictionariesUpdaterResolver>(serviceProvider => dictionaryType => services.AddTransient<DictionariesUpdaterResolver>(serviceProvider => dictionaryType =>
{ {
switch (dictionaryType) return dictionaryType switch
{ {
case DictionaryType.StaticDictionaries: DictionaryType.StaticDictionaries => serviceProvider.GetService<StaticDictionariesUpdater>()!,
return serviceProvider.GetService<StaticDictionariesUpdater>(); DictionaryType.Achievements => serviceProvider.GetService<AchievementsDictionaryUpdater>()!,
case DictionaryType.Achievements: DictionaryType.Vehicles => serviceProvider.GetService<VehiclesDictionaryUpdater>()!,
return serviceProvider.GetService<AchievementsDictionaryUpdater>(); _ => throw new ApplicationException($"Unknown dictionary type '{dictionaryType}'")
case DictionaryType.Vehicles: };
return serviceProvider.GetService<VehiclesDictionaryUpdater>();
default:
return null;
}
}); });
} }
@@ -2,6 +2,7 @@
<PropertyGroup> <PropertyGroup>
<TargetFramework>net5.0</TargetFramework> <TargetFramework>net5.0</TargetFramework>
<Nullable>enable</Nullable>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
@@ -7,23 +7,23 @@ namespace WotBlitzStatisticsPro.WgApiClient
{ {
public interface IWargamingApiClient public interface IWargamingApiClient
{ {
Task<List<WotAccountListResponse>> FindAccounts(string nickName, Task<List<WotAccountListResponse>?> FindAccounts(string nickName,
RealmType realmType = RealmType.Ru, RealmType realmType = RealmType.Ru,
RequestLanguage language = RequestLanguage.En); RequestLanguage language = RequestLanguage.En);
Task<List<WotClanListResponse>> FindClans(string searchString, Task<List<WotClanListResponse>?> FindClans(string searchString,
RealmType realmType = RealmType.Ru, RealmType realmType = RealmType.Ru,
RequestLanguage language = RequestLanguage.En); RequestLanguage language = RequestLanguage.En);
Task<WotAccountInfo> GetPlayerAccountInfo(long accountId, Task<WotAccountInfo?> GetPlayerAccountInfo(long accountId,
RealmType realmType = RealmType.Ru, RealmType realmType = RealmType.Ru,
RequestLanguage language = RequestLanguage.En); RequestLanguage language = RequestLanguage.En);
Task<ClanAccountInfo> GetPlayerClanInfo(long accountId, Task<ClanAccountInfo?> GetPlayerClanInfo(long accountId,
RealmType realmType = RealmType.Ru, RealmType realmType = RealmType.Ru,
RequestLanguage language = RequestLanguage.En); RequestLanguage language = RequestLanguage.En);
Task<ClanInfo> GetClanInfo(long clanId, Task<ClanInfo?> GetClanInfo(long clanId,
RealmType realmType = RealmType.Ru, RealmType realmType = RealmType.Ru,
RequestLanguage language = RequestLanguage.En); RequestLanguage language = RequestLanguage.En);
} }
@@ -8,16 +8,16 @@ namespace WotBlitzStatisticsPro.WgApiClient
public interface IWargamingDictionariesApiClient public interface IWargamingDictionariesApiClient
{ {
Task<( Task<(
WotEncyclopediaInfoResponse, WotEncyclopediaInfoResponse?,
WotClanMembersDictionaryResponse)> GetStaticDictionariesAsync( WotClanMembersDictionaryResponse?)> GetStaticDictionariesAsync(
RealmType realmType = RealmType.Ru, RealmType realmType = RealmType.Ru,
RequestLanguage language = RequestLanguage.En); RequestLanguage language = RequestLanguage.En);
Task<List<WotEncyclopediaAchievementsResponse>> GetAchievementsDictionary( Task<List<WotEncyclopediaAchievementsResponse>?> GetAchievementsDictionary(
RealmType realmType = RealmType.Ru, RealmType realmType = RealmType.Ru,
RequestLanguage language = RequestLanguage.En); RequestLanguage language = RequestLanguage.En);
Task<List<WotEncyclopediaVehiclesResponse>> GetVehicles( Task<List<WotEncyclopediaVehiclesResponse>?> GetVehicles(
RealmType realmType = RealmType.Ru, RealmType realmType = RealmType.Ru,
RequestLanguage language = RequestLanguage.En); RequestLanguage language = RequestLanguage.En);
} }
@@ -7,7 +7,7 @@ namespace WotBlitzStatisticsPro.WgApiClient
{ {
public interface IWargamingTanksApiClient public interface IWargamingTanksApiClient
{ {
Task<List<WotAccountTanksStatistics>> GetPlayerAccountTanksInfo(long accountId, Task<List<WotAccountTanksStatistics>?> GetPlayerAccountTanksInfo(long accountId,
RealmType realmType = RealmType.Ru, RealmType realmType = RealmType.Ru,
RequestLanguage language = RequestLanguage.En); RequestLanguage language = RequestLanguage.En);
} }
@@ -14,7 +14,7 @@ namespace WotBlitzStatisticsPro.WgApiClient.Model
/// Account nick /// Account nick
///</summary> ///</summary>
[JsonProperty("account_name")] [JsonProperty("account_name")]
public string AccountName { get; set; } public string? AccountName { get; set; }
///<summary> ///<summary>
/// ClanId /// ClanId
@@ -32,7 +32,7 @@ namespace WotBlitzStatisticsPro.WgApiClient.Model
/// Player clan role /// Player clan role
///</summary> ///</summary>
[JsonProperty("role")] [JsonProperty("role")]
public string Role { get; set; } public string? Role { get; set; }
} }
} }
@@ -22,7 +22,7 @@ namespace WotBlitzStatisticsPro.WgApiClient.Model
/// Clan color in HEX #RRGGBB /// Clan color in HEX #RRGGBB
///</summary> ///</summary>
[JsonProperty("color")] [JsonProperty("color")]
public string Color { get; set; } public string? Color { get; set; }
///<summary> ///<summary>
/// Date of clan creation /// Date of clan creation
@@ -40,25 +40,25 @@ namespace WotBlitzStatisticsPro.WgApiClient.Model
/// Clan creator nick /// Clan creator nick
///</summary> ///</summary>
[JsonProperty("creator_name")] [JsonProperty("creator_name")]
public string CreatorName { get; set; } public string? CreatorName { get; set; }
///<summary> ///<summary>
/// Clan description /// Clan description
///</summary> ///</summary>
[JsonProperty("description")] [JsonProperty("description")]
public string Description { get; set; } public string? Description { get; set; }
///<summary> ///<summary>
/// Html Clan description /// Html Clan description
///</summary> ///</summary>
[JsonProperty("description_html")] [JsonProperty("description_html")]
public string DescriptionHtml { get; set; } public string? DescriptionHtml { get; set; }
///<summary> ///<summary>
/// Is clan deleted. Actual info about deleted clan only in fields: clan_id, is_clan_disbanded, updated_at. /// Is clan deleted. Actual info about deleted clan only in fields: clan_id, is_clan_disbanded, updated_at.
///</summary> ///</summary>
[JsonProperty("is_clan_disbanded")] [JsonProperty("is_clan_disbanded")]
public bool IsClanDisbanded { get; set; } public bool? IsClanDisbanded { get; set; }
///<summary> ///<summary>
/// Clan commander accountId /// Clan commander accountId
@@ -70,7 +70,7 @@ namespace WotBlitzStatisticsPro.WgApiClient.Model
/// Clan commander nick /// Clan commander nick
///</summary> ///</summary>
[JsonProperty("leader_name")] [JsonProperty("leader_name")]
public string LeaderName { get; set; } public string? LeaderName { get; set; }
///<summary> ///<summary>
/// Clan members count /// Clan members count
@@ -82,25 +82,25 @@ namespace WotBlitzStatisticsPro.WgApiClient.Model
/// Clan motto /// Clan motto
///</summary> ///</summary>
[JsonProperty("motto")] [JsonProperty("motto")]
public string Motto { get; set; } public string? Motto { get; set; }
///<summary> ///<summary>
/// Clan name /// Clan name
///</summary> ///</summary>
[JsonProperty("name")] [JsonProperty("name")]
public string Name { get; set; } public string? Name { get; set; }
///<summary> ///<summary>
/// Renamed clan name /// Renamed clan name
///</summary> ///</summary>
[JsonProperty("old_name")] [JsonProperty("old_name")]
public string OldName { get; set; } public string? OldName { get; set; }
///<summary> ///<summary>
/// Renamed clan tag /// Renamed clan tag
///</summary> ///</summary>
[JsonProperty("old_tag")] [JsonProperty("old_tag")]
public string OldTag { get; set; } public string? OldTag { get; set; }
///<summary> ///<summary>
/// Clan renaming time in UTC /// Clan renaming time in UTC
@@ -112,7 +112,7 @@ namespace WotBlitzStatisticsPro.WgApiClient.Model
/// Clan tag /// Clan tag
///</summary> ///</summary>
[JsonProperty("tag")] [JsonProperty("tag")]
public string Tag { get; set; } public string? Tag { get; set; }
///<summary> ///<summary>
/// Clan info updated at /// Clan info updated at
@@ -124,19 +124,19 @@ namespace WotBlitzStatisticsPro.WgApiClient.Model
/// Clan emblems info /// Clan emblems info
///</summary> ///</summary>
[JsonProperty("emblems")] [JsonProperty("emblems")]
public WgnClansInfoEmblems Emblems { get; set; } public WgnClansInfoEmblems? Emblems { get; set; }
///<summary> ///<summary>
/// Clan members information. Depends on members_key field in request. /// Clan members information. Depends on members_key field in request.
///</summary> ///</summary>
[JsonProperty("members")] [JsonProperty("members")]
public WgnClansInfoMembers Members { get; set; } public WgnClansInfoMembers? Members { get; set; }
///<summary> ///<summary>
/// Private clan info /// Private clan info
///</summary> ///</summary>
[JsonProperty("private")] [JsonProperty("private")]
public WgnClansInfoPrivate Private { get; set; } public WgnClansInfoPrivate? Private { get; set; }
} }
public class WgnClansInfoEmblems public class WgnClansInfoEmblems
@@ -145,31 +145,31 @@ namespace WotBlitzStatisticsPro.WgApiClient.Model
/// 195x195 px Icons list /// 195x195 px Icons list
///</summary> ///</summary>
[JsonProperty("x195")] [JsonProperty("x195")]
public Dictionary<string, string> X195 { get; set; } public Dictionary<string, string>? X195 { get; set; }
///<summary> ///<summary>
/// 24x24 px Icons list /// 24x24 px Icons list
///</summary> ///</summary>
[JsonProperty("x24")] [JsonProperty("x24")]
public Dictionary<string, string> X24 { get; set; } public Dictionary<string, string>? X24 { get; set; }
///<summary> ///<summary>
/// 256x256 px Icons list /// 256x256 px Icons list
///</summary> ///</summary>
[JsonProperty("x256")] [JsonProperty("x256")]
public Dictionary<string, string> X256 { get; set; } public Dictionary<string, string>? X256 { get; set; }
///<summary> ///<summary>
/// 32x32 px Icons list /// 32x32 px Icons list
///</summary> ///</summary>
[JsonProperty("x32")] [JsonProperty("x32")]
public Dictionary<string, string> X32 { get; set; } public Dictionary<string, string>? X32 { get; set; }
///<summary> ///<summary>
/// 64x64 px Icons list /// 64x64 px Icons list
///</summary> ///</summary>
[JsonProperty("x64")] [JsonProperty("x64")]
public Dictionary<string, string> X64 { get; set; } public Dictionary<string, string>? X64 { get; set; }
} }
public class WgnClansInfoMembers public class WgnClansInfoMembers
@@ -184,7 +184,7 @@ namespace WotBlitzStatisticsPro.WgApiClient.Model
/// Clan member nick /// Clan member nick
///</summary> ///</summary>
[JsonProperty("account_name")] [JsonProperty("account_name")]
public string AccountName { get; set; } public string? AccountName { get; set; }
///<summary> ///<summary>
/// Date of joining the clan /// Date of joining the clan
@@ -196,19 +196,19 @@ namespace WotBlitzStatisticsPro.WgApiClient.Model
/// Clan member role /// Clan member role
///</summary> ///</summary>
[JsonProperty("role")] [JsonProperty("role")]
public string Role { get; set; } public string? Role { get; set; }
///<summary> ///<summary>
/// Localized member role /// Localized member role
///</summary> ///</summary>
[JsonProperty("role_i18n")] [JsonProperty("role_i18n")]
public string RoleI18n { get; set; } public string? RoleI18n { get; set; }
} }
public class WgnClansInfoPrivate public class WgnClansInfoPrivate
{ {
[JsonProperty("online_members")] [JsonProperty("online_members")]
public int[] OnlineMembers { get; set; } public int[]? OnlineMembers { get; set; }
[JsonProperty("treasury")] [JsonProperty("treasury")]
public long? Treasury { get; set; } public long? Treasury { get; set; }
@@ -26,7 +26,7 @@ namespace WotBlitzStatisticsPro.WgApiClient.Model
/// Player's nick /// Player's nick
///</summary> ///</summary>
[JsonProperty("nickname")] [JsonProperty("nickname")]
public string Nickname { get; set; } public string? Nickname { get; set; }
///<summary> ///<summary>
/// Player information update date /// Player information update date
@@ -38,12 +38,12 @@ namespace WotBlitzStatisticsPro.WgApiClient.Model
/// Private account data /// Private account data
///</summary> ///</summary>
[JsonProperty("private")] [JsonProperty("private")]
public WotAccountPrivateInfo Private { get; set; } public WotAccountPrivateInfo? Private { get; set; }
///<summary> ///<summary>
/// Player's statistics /// Player's statistics
///</summary> ///</summary>
[JsonProperty("statistics")] [JsonProperty("statistics")]
public WotAccountStatistics Statistics { get; set; } public WotAccountStatistics? Statistics { get; set; }
} }
} }
@@ -14,6 +14,6 @@ namespace WotBlitzStatisticsPro.WgApiClient.Model
/// Player nick /// Player nick
///</summary> ///</summary>
[JsonProperty("nickname")] [JsonProperty("nickname")]
public string Nickname { get; set; } public string? Nickname { get; set; }
} }
} }
@@ -8,7 +8,7 @@ namespace WotBlitzStatisticsPro.WgApiClient.Model
/// Account ban info /// Account ban info
///</summary> ///</summary>
[JsonProperty("ban_info")] [JsonProperty("ban_info")]
public string BanInfo { get; set; } public string? BanInfo { get; set; }
///<summary> ///<summary>
/// Account ban expiration date /// Account ban expiration date
@@ -47,23 +47,22 @@ namespace WotBlitzStatisticsPro.WgApiClient.Model
public bool IsPremium { get; set; } public bool IsPremium { get; set; }
///<summary> ///<summary>
/// Premium accunt expiration time /// Premium account expiration time
///</summary> ///</summary>
[JsonProperty("premium_expires_at")] [JsonProperty("premium_expires_at")]
private int? PremiumExpiresAt { get; set; } private int? PremiumExpiresAt { get; set; }
///<summary> ///<summary>
///Группы контактов. /// Group of contacts.
///Дополнительное поле.
///</summary> ///</summary>
[JsonProperty("grouped_contacts")] [JsonProperty("grouped_contacts")]
public WotAccountPrivateInfoGroupedContacts GroupedContacts { get; set; } public WotAccountPrivateInfoGroupedContacts? GroupedContacts { get; set; }
///<summary> ///<summary>
///Ограничения аккаунта /// Account restrictions
///</summary> ///</summary>
[JsonProperty("restrictions")] [JsonProperty("restrictions")]
public WotAccountPrivateInfoRestrictions Restrictions { get; set; } public WotAccountPrivateInfoRestrictions? Restrictions { get; set; }
} }
} }
@@ -9,18 +9,18 @@ namespace WotBlitzStatisticsPro.WgApiClient.Model
/// Blocked accountIds /// Blocked accountIds
///</summary> ///</summary>
[JsonProperty("blocked")] [JsonProperty("blocked")]
public int[] Blocked { get; set; } public int[]? Blocked { get; set; }
///<summary> ///<summary>
/// Groups /// Groups
///</summary> ///</summary>
[JsonProperty("groups")] [JsonProperty("groups")]
public Dictionary<string, string> Groups { get; set; } public Dictionary<string, string>? Groups { get; set; }
///<summary> ///<summary>
/// Ungrouped accountIds /// Ungrouped accountIds
///</summary> ///</summary>
[JsonProperty("ungrouped")] [JsonProperty("ungrouped")]
public int[] Ungrouped { get; set; } public int[]? Ungrouped { get; set; }
} }
} }
@@ -9,12 +9,12 @@ namespace WotBlitzStatisticsPro.WgApiClient.Model
/// Amount of destroyed by player tanks. /// Amount of destroyed by player tanks.
///</summary> ///</summary>
[JsonProperty("frags")] [JsonProperty("frags")]
public Dictionary<string, string> Frags { get; set; } public Dictionary<string, string>? Frags { get; set; }
///<summary> ///<summary>
/// Full player's statistics /// Full player's statistics
///</summary> ///</summary>
[JsonProperty("all")] [JsonProperty("all")]
public WotAccountFullStatistics All { get; set; } public WotAccountFullStatistics? All { get; set; }
} }
} }
@@ -50,10 +50,10 @@ namespace WotBlitzStatisticsPro.WgApiClient.Model
/// Whole statistics /// Whole statistics
///</summary> ///</summary>
[JsonProperty("all")] [JsonProperty("all")]
public WotAccountTanksFullStatistics All { get; set; } public WotAccountTanksFullStatistics? All { get; set; }
[JsonProperty("frags")] [JsonProperty("frags")]
public Dictionary<string, string> Frags { get; set; } public Dictionary<string, string>? Frags { get; set; }
} }
} }
@@ -14,13 +14,13 @@ namespace WotBlitzStatisticsPro.WgApiClient.Model
/// Clan Tag /// Clan Tag
///</summary> ///</summary>
[JsonProperty("tag")] [JsonProperty("tag")]
public string Tag { get; set; } public string? Tag { get; set; }
///<summary> ///<summary>
/// Clan Name /// Clan Name
///</summary> ///</summary>
[JsonProperty("name")] [JsonProperty("name")]
public string Name { get; set; } public string? Name { get; set; }
///<summary> ///<summary>
/// Clan created at. (UNIX Epoch time) /// Clan created at. (UNIX Epoch time)
@@ -9,12 +9,12 @@ namespace WotBlitzStatisticsPro.WgApiClient.Model
/// Clan roles list /// Clan roles list
/// </summary> /// </summary>
[JsonProperty("clans_roles")] [JsonProperty("clans_roles")]
public Dictionary<string, string> ClanRoles { get; set; } public Dictionary<string, string>? ClanRoles { get; set; }
/// <summary> /// <summary>
/// Clan settings list /// Clan settings list
/// </summary> /// </summary>
[JsonProperty("settings")] [JsonProperty("settings")]
public Dictionary<string, string> Settings { get; set; } public Dictionary<string, string>? Settings { get; set; }
} }
} }
@@ -6,43 +6,43 @@ namespace WotBlitzStatisticsPro.WgApiClient.Model
public class WotEncyclopediaAchievementsResponse public class WotEncyclopediaAchievementsResponse
{ {
[JsonProperty("achievement_id")] [JsonProperty("achievement_id")]
public string AchievementId { get; set; } public string? AchievementId { get; set; }
///<summary> ///<summary>
/// Achievement condition /// Achievement condition
///</summary> ///</summary>
[JsonProperty("condition")] [JsonProperty("condition")]
public string Condition { get; set; } public string? Condition { get; set; }
///<summary> ///<summary>
/// Achievement description /// Achievement description
///</summary> ///</summary>
[JsonProperty("description")] [JsonProperty("description")]
public string Description { get; set; } public string? Description { get; set; }
///<summary> ///<summary>
/// Historical info /// Historical info
///</summary> ///</summary>
[JsonProperty("hero_info")] [JsonProperty("hero_info")]
public string HeroInfo { get; set; } public string? HeroInfo { get; set; }
///<summary> ///<summary>
/// Image link /// Image link
///</summary> ///</summary>
[JsonProperty("image")] [JsonProperty("image")]
public string Image { get; set; } public string? Image { get; set; }
///<summary> ///<summary>
/// Image 180x180px link /// Image 180x180px link
///</summary> ///</summary>
[JsonProperty("image_big")] [JsonProperty("image_big")]
public string ImageBig { get; set; } public string? ImageBig { get; set; }
///<summary> ///<summary>
/// Achievement name /// Achievement name
///</summary> ///</summary>
[JsonProperty("name")] [JsonProperty("name")]
public string Name { get; set; } public string? Name { get; set; }
///<summary> ///<summary>
/// Sort order /// Sort order
@@ -60,7 +60,7 @@ namespace WotBlitzStatisticsPro.WgApiClient.Model
/// Achievement section /// Achievement section
///</summary> ///</summary>
[JsonProperty("section")] [JsonProperty("section")]
public string Section { get; set; } public string? Section { get; set; }
///<summary> ///<summary>
/// Achievement section order /// Achievement section order
@@ -72,13 +72,13 @@ namespace WotBlitzStatisticsPro.WgApiClient.Model
/// Achievement Type /// Achievement Type
///</summary> ///</summary>
[JsonProperty("type")] [JsonProperty("type")]
public string Type { get; set; } public string? Type { get; set; }
///<summary> ///<summary>
/// Achievement options /// Achievement options
///</summary> ///</summary>
[JsonProperty("options")] [JsonProperty("options")]
public WotEncyclopediaAchievementsOptions[] Options { get; set; } public WotEncyclopediaAchievementsOptions[]? Options { get; set; }
} }
public class WotEncyclopediaAchievementsOptions public class WotEncyclopediaAchievementsOptions
@@ -88,21 +88,21 @@ namespace WotBlitzStatisticsPro.WgApiClient.Model
/// Achievement description /// Achievement description
///</summary> ///</summary>
[JsonProperty("description")] [JsonProperty("description")]
public string Description { get; set; } public string? Description { get; set; }
///<summary> ///<summary>
/// Image link /// Image link
///</summary> ///</summary>
[JsonProperty("image")] [JsonProperty("image")]
public string Image { get; set; } public string? Image { get; set; }
///<summary> ///<summary>
/// Image 180x180px link /// Image 180x180px link
///</summary> ///</summary>
[JsonProperty("image_big")] [JsonProperty("image_big")]
public string ImageBig { get; set; } public string? ImageBig { get; set; }
[JsonProperty("name")] [JsonProperty("name")]
public string Name { get; set; } public string? Name { get; set; }
} }
} }
@@ -10,13 +10,13 @@ namespace WotBlitzStatisticsPro.WgApiClient.Model
/// Game client version /// Game client version
///</summary> ///</summary>
[JsonProperty("game_version")] [JsonProperty("game_version")]
public string GameVersion { get; set; } public string? GameVersion { get; set; }
///<summary> ///<summary>
/// List of supported languages /// List of supported languages
///</summary> ///</summary>
[JsonProperty("languages")] [JsonProperty("languages")]
public Dictionary<string, string> Languages { get; set; } public Dictionary<string, string>? Languages { get; set; }
///<summary> ///<summary>
/// Encyclopedia last update time /// Encyclopedia last update time
@@ -28,25 +28,25 @@ namespace WotBlitzStatisticsPro.WgApiClient.Model
/// Cru clan role /// Cru clan role
///</summary> ///</summary>
[JsonProperty("vehicle_crew_roles")] [JsonProperty("vehicle_crew_roles")]
public Dictionary<string, string> VehicleCrewRoles { get; set; } public Dictionary<string, string>? VehicleCrewRoles { get; set; }
///<summary> ///<summary>
/// Vehicle nations dictionary /// Vehicle nations dictionary
///</summary> ///</summary>
[JsonProperty("vehicle_nations")] [JsonProperty("vehicle_nations")]
public Dictionary<string, string> VehicleNations { get; set; } public Dictionary<string, string>? VehicleNations { get; set; }
///<summary> ///<summary>
/// Vehicle types dictionary /// Vehicle types dictionary
///</summary> ///</summary>
[JsonProperty("vehicle_types")] [JsonProperty("vehicle_types")]
public Dictionary<string, string> VehicleTypes { get; set; } public Dictionary<string, string>? VehicleTypes { get; set; }
///<summary> ///<summary>
/// Achievements sections /// Achievements sections
///</summary> ///</summary>
[JsonProperty("achievement_sections")] [JsonProperty("achievement_sections")]
public Dictionary<string, WotEncyclopediaInfoAchievementSection> AchievementSections { get; set; } public Dictionary<string, WotEncyclopediaInfoAchievementSection>? AchievementSections { get; set; }
} }
@@ -57,7 +57,7 @@ namespace WotBlitzStatisticsPro.WgApiClient.Model
/// Achievements section name /// Achievements section name
///</summary> ///</summary>
[JsonProperty("name")] [JsonProperty("name")]
public string Name { get; set; } public string? Name { get; set; }
///<summary> ///<summary>
/// Achievement section order /// Achievement section order
@@ -9,19 +9,19 @@ namespace WotBlitzStatisticsPro.WgApiClient.Model
/// Vehicle description /// Vehicle description
///</summary> ///</summary>
[JsonProperty("description")] [JsonProperty("description")]
public string Description { get; set; } public string? Description { get; set; }
///<summary> ///<summary>
/// Engines id list /// Engines id list
///</summary> ///</summary>
[JsonProperty("engines")] [JsonProperty("engines")]
public int[] Engines { get; set; } public int[]? Engines { get; set; }
///<summary> ///<summary>
/// Guns id list /// Guns id list
///</summary> ///</summary>
[JsonProperty("guns")] [JsonProperty("guns")]
public int[] Guns { get; set; } public int[]? Guns { get; set; }
///<summary> ///<summary>
/// Is vehicle premium /// Is vehicle premium
@@ -33,13 +33,13 @@ namespace WotBlitzStatisticsPro.WgApiClient.Model
/// Vehicle name /// Vehicle name
///</summary> ///</summary>
[JsonProperty("name")] [JsonProperty("name")]
public string Name { get; set; } public string? Name { get; set; }
///<summary> ///<summary>
/// Vehicle nationId /// Vehicle nationId
///</summary> ///</summary>
[JsonProperty("nation")] [JsonProperty("nation")]
public string Nation { get; set; } public string? Nation { get; set; }
///<summary> ///<summary>
/// List of next vehicles in tree: /// List of next vehicles in tree:
@@ -48,26 +48,26 @@ namespace WotBlitzStatisticsPro.WgApiClient.Model
/// value - amount of XP to open it /// value - amount of XP to open it
///</summary> ///</summary>
[JsonProperty("next_tanks")] [JsonProperty("next_tanks")]
public Dictionary<string, string> NextTanks { get; set; } public Dictionary<string, string>? NextTanks { get; set; }
///<summary> ///<summary>
/// Vehicle cost by pairs /// Vehicle cost by pairs
/// with keys: price_credit, price_gold /// with keys: price_credit, price_gold
///</summary> ///</summary>
[JsonProperty("cost")] [JsonProperty("cost")]
public Dictionary<string, string> Cost { get; set; } public Dictionary<string, string>? Cost { get; set; }
///<summary> ///<summary>
/// Price in XP for parent vehicle as key /// Price in XP for parent vehicle as key
///</summary> ///</summary>
[JsonProperty("prices_xp")] [JsonProperty("prices_xp")]
public Dictionary<string, string> PricesXp { get; set; } public Dictionary<string, string>? PricesXp { get; set; }
///<summary> ///<summary>
/// List of compatible suspensions /// List of compatible suspensions
///</summary> ///</summary>
[JsonProperty("suspensions")] [JsonProperty("suspensions")]
public int[] Suspensions { get; set; } public int[]? Suspensions { get; set; }
///<summary> ///<summary>
/// VehicleId /// VehicleId
@@ -85,13 +85,13 @@ namespace WotBlitzStatisticsPro.WgApiClient.Model
/// List of compatible turrets ids /// List of compatible turrets ids
///</summary> ///</summary>
[JsonProperty("turrets")] [JsonProperty("turrets")]
public int[] Turrets { get; set; } public int[]? Turrets { get; set; }
///<summary> ///<summary>
/// Vehicle type id /// Vehicle type id
///</summary> ///</summary>
[JsonProperty("type")] [JsonProperty("type")]
public string Type { get; set; } public string? Type { get; set; }
/////<summary> /////<summary>
///// Default vehicle profile ///// Default vehicle profile
@@ -104,7 +104,7 @@ namespace WotBlitzStatisticsPro.WgApiClient.Model
/// Keys: preview, normal /// Keys: preview, normal
///</summary> ///</summary>
[JsonProperty("images")] [JsonProperty("images")]
public Dictionary<string, string> Images { get; set; } public Dictionary<string, string>? Images { get; set; }
/////<summary> /////<summary>
///// Information about investigated modules ///// Information about investigated modules
@@ -1,20 +1,22 @@
using Newtonsoft.Json; using System.ComponentModel.DataAnnotations;
using System.Diagnostics.CodeAnalysis;
using Newtonsoft.Json;
namespace WotBlitzStatisticsPro.WgApiClient namespace WotBlitzStatisticsPro.WgApiClient
{ {
internal class ResponseBody<T> internal class ResponseBody<T> where T: class
{ {
[JsonProperty("status")] [JsonProperty("status")]
public string Status { get; set; } public string? Status { get; set; }
[JsonProperty("meta")] [JsonProperty("meta")]
public Meta Meta { get; set; } public Meta? Meta { get; set; }
[JsonProperty("data")] [JsonProperty("data")]
public T Data { get; set; } public T? Data { get; set; }
[JsonProperty("error")] [JsonProperty("error")]
public Error Error { get; set; } public Error? Error { get; set; }
} }
internal class Meta internal class Meta
@@ -26,15 +28,15 @@ namespace WotBlitzStatisticsPro.WgApiClient
internal class Error internal class Error
{ {
[JsonProperty("field")] [JsonProperty("field")]
public string Field { get; set; } public string? Field { get; set; }
[JsonProperty("message")] [JsonProperty("message")]
public string Message { get; set; } public string? Message { get; set; }
[JsonProperty("code")] [JsonProperty("code")]
public string Code { get; set; } public string? Code { get; set; }
[JsonProperty("value")] [JsonProperty("value")]
public string Value { get; set; } public string? Value { get; set; }
} }
} }
@@ -1,6 +1,7 @@
using Newtonsoft.Json; using Newtonsoft.Json;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Net.Http; using System.Net.Http;
using System.Net.Http.Headers; using System.Net.Http.Headers;
using System.Text; using System.Text;
@@ -36,11 +37,11 @@ namespace WotBlitzStatisticsPro.WgApiClient
_wotApiUrls[RealmType.Asia] = "https://api.worldoftanks.asia/wot/"; _wotApiUrls[RealmType.Asia] = "https://api.worldoftanks.asia/wot/";
} }
protected async Task<T> GetFromBlitzApi<T>( protected async Task<T?> GetFromBlitzApi<T>(
RealmType realmType, RealmType realmType,
RequestLanguage language, RequestLanguage language,
string method, string method,
params string[] queryParameters) params string[] queryParameters) where T: class
{ {
string uri = GetUri(realmType, language, method, queryParameters); string uri = GetUri(realmType, language, method, queryParameters);
@@ -52,18 +53,20 @@ namespace WotBlitzStatisticsPro.WgApiClient
var responseString = await response.Content.ReadAsStringAsync(); var responseString = await response.Content.ReadAsStringAsync();
var responseBody = JsonConvert.DeserializeObject<ResponseBody<T>>(responseString); var responseBody = JsonConvert.DeserializeObject<ResponseBody<T>>(responseString);
if (responseBody.Status == "ok") switch (responseBody.Status)
{ {
return responseBody.Data; case "ok":
} return responseBody.Data;
if (responseBody.Status == "error") case "error":
{ {
var error = responseBody.Error; var error = responseBody.Error;
var message = $"Field:{error.Field} Message:{error.Message} Value:{error.Value} Code:{error.Code}"; var message = $"Field:{(error?.Field ?? "undefined")} Message:{(error?.Message ?? "undefined")} Value:{(error?.Value ?? "undefined")} Code:{(error?.Code ?? "undefined")}";
throw new ArgumentException(message); throw new ArgumentException(message);
} }
return default(T); default:
} throw new ArgumentException($"Unexpected response body status '{responseBody.Status}'");
}
}
private string GetUri(RealmType realmType, RequestLanguage language, string method, string[] queryParameters) private string GetUri(RealmType realmType, RequestLanguage language, string method, string[] queryParameters)
{ {
@@ -20,7 +20,7 @@ namespace WotBlitzStatisticsPro.WgApiClient
} }
#region Search methods #region Search methods
public async Task<List<WotAccountListResponse>> FindAccounts(string nickName, public async Task<List<WotAccountListResponse>?> FindAccounts(string nickName,
RealmType realmType = RealmType.Ru, RealmType realmType = RealmType.Ru,
RequestLanguage language = RequestLanguage.En) RequestLanguage language = RequestLanguage.En)
{ {
@@ -31,7 +31,7 @@ namespace WotBlitzStatisticsPro.WgApiClient
$"search={nickName}").ConfigureAwait(false); $"search={nickName}").ConfigureAwait(false);
} }
public async Task<List<WotClanListResponse>> FindClans(string searchString, public async Task<List<WotClanListResponse>?> FindClans(string searchString,
RealmType realmType = RealmType.Ru, RealmType realmType = RealmType.Ru,
RequestLanguage language = RequestLanguage.En) RequestLanguage language = RequestLanguage.En)
{ {
@@ -47,8 +47,8 @@ namespace WotBlitzStatisticsPro.WgApiClient
#region Encyclopedia methods #region Encyclopedia methods
public async Task<( public async Task<(
WotEncyclopediaInfoResponse, WotEncyclopediaInfoResponse?,
WotClanMembersDictionaryResponse)> GetStaticDictionariesAsync( WotClanMembersDictionaryResponse?)> GetStaticDictionariesAsync(
RealmType realmType = RealmType.Ru, RealmType realmType = RealmType.Ru,
RequestLanguage language = RequestLanguage.En) RequestLanguage language = RequestLanguage.En)
{ {
@@ -67,24 +67,24 @@ namespace WotBlitzStatisticsPro.WgApiClient
return (encyclopedia, clanGlossaryResponse); return (encyclopedia, clanGlossaryResponse);
} }
public async Task<List<WotEncyclopediaAchievementsResponse>> GetAchievementsDictionary(RealmType realmType = RealmType.Ru, RequestLanguage language = RequestLanguage.En) public async Task<List<WotEncyclopediaAchievementsResponse>?> GetAchievementsDictionary(RealmType realmType = RealmType.Ru, RequestLanguage language = RequestLanguage.En)
{ {
var response = await GetFromBlitzApi<Dictionary<string, WotEncyclopediaAchievementsResponse>>( var response = await GetFromBlitzApi<Dictionary<string, WotEncyclopediaAchievementsResponse>>(
realmType, realmType,
language, language,
"encyclopedia/achievements/").ConfigureAwait(false); "encyclopedia/achievements/").ConfigureAwait(false);
return response.Values.ToList(); return response?.Values.ToList();
} }
public async Task<List<WotEncyclopediaVehiclesResponse>> GetVehicles(RealmType realmType = RealmType.Ru, RequestLanguage language = RequestLanguage.En) public async Task<List<WotEncyclopediaVehiclesResponse>?> GetVehicles(RealmType realmType = RealmType.Ru, RequestLanguage language = RequestLanguage.En)
{ {
var response = await GetFromBlitzApi<Dictionary<string, WotEncyclopediaVehiclesResponse>>( var response = await GetFromBlitzApi<Dictionary<string, WotEncyclopediaVehiclesResponse>>(
realmType, realmType,
language, language,
"encyclopedia/vehicles/").ConfigureAwait(false); "encyclopedia/vehicles/").ConfigureAwait(false);
return response.Values.ToList(); return response?.Values.ToList();
} }
#endregion #endregion
@@ -94,7 +94,7 @@ namespace WotBlitzStatisticsPro.WgApiClient
public async Task<WotAccountInfo> GetPlayerAccountInfo(long accountId, public async Task<WotAccountInfo?> GetPlayerAccountInfo(long accountId,
RealmType realmType = RealmType.Ru, RealmType realmType = RealmType.Ru,
RequestLanguage language = RequestLanguage.En) RequestLanguage language = RequestLanguage.En)
{ {
@@ -103,10 +103,10 @@ namespace WotBlitzStatisticsPro.WgApiClient
language, language,
"account/info/", "account/info/",
$"account_id={accountId}").ConfigureAwait(false); $"account_id={accountId}").ConfigureAwait(false);
return account[accountId.ToString()]; return account?[accountId.ToString()];
} }
public async Task<ClanAccountInfo> GetPlayerClanInfo(long accountId, public async Task<ClanAccountInfo?> GetPlayerClanInfo(long accountId,
RealmType realmType = RealmType.Ru, RealmType realmType = RealmType.Ru,
RequestLanguage language = RequestLanguage.En) RequestLanguage language = RequestLanguage.En)
{ {
@@ -115,14 +115,14 @@ namespace WotBlitzStatisticsPro.WgApiClient
language, language,
"clans/accountinfo/", "clans/accountinfo/",
$"account_id={accountId}").ConfigureAwait(false); $"account_id={accountId}").ConfigureAwait(false);
if (clanInfo.ContainsKey(accountId.ToString())) if (clanInfo != null && clanInfo.ContainsKey(accountId.ToString()))
{ {
return clanInfo[accountId.ToString()]; return clanInfo[accountId.ToString()];
} }
return null; return null;
} }
public async Task<ClanInfo> GetClanInfo( public async Task<ClanInfo?> GetClanInfo(
long clanId, long clanId,
RealmType realmType = RealmType.Ru, RealmType realmType = RealmType.Ru,
RequestLanguage language = RequestLanguage.En) RequestLanguage language = RequestLanguage.En)
@@ -132,7 +132,7 @@ namespace WotBlitzStatisticsPro.WgApiClient
language, language,
"clans/info/", "clans/info/",
$"clan_id={clanId}").ConfigureAwait(false); $"clan_id={clanId}").ConfigureAwait(false);
if (clanInfo.ContainsKey(clanId.ToString())) if (clanInfo != null && clanInfo.ContainsKey(clanId.ToString()))
{ {
return clanInfo[clanId.ToString()]; return clanInfo[clanId.ToString()];
} }
@@ -144,7 +144,7 @@ namespace WotBlitzStatisticsPro.WgApiClient
#region Tanks methods #region Tanks methods
public async Task<List<WotAccountTanksStatistics>> GetPlayerAccountTanksInfo( public async Task<List<WotAccountTanksStatistics>?> GetPlayerAccountTanksInfo(
long accountId, long accountId,
RealmType realmType = RealmType.Ru, RealmType realmType = RealmType.Ru,
RequestLanguage language = RequestLanguage.En) RequestLanguage language = RequestLanguage.En)
@@ -154,7 +154,7 @@ namespace WotBlitzStatisticsPro.WgApiClient
language, language,
"tanks/stats/", "tanks/stats/",
$"account_id={accountId}").ConfigureAwait(false); $"account_id={accountId}").ConfigureAwait(false);
return tanks[accountId.ToString()] ?? new List<WotAccountTanksStatistics>(); return tanks?[accountId.ToString()] ?? new List<WotAccountTanksStatistics>();
} }
#endregion #endregion
@@ -2,6 +2,7 @@
<PropertyGroup> <PropertyGroup>
<TargetFramework>net5.0</TargetFramework> <TargetFramework>net5.0</TargetFramework>
<Nullable>enable</Nullable>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>