diff --git a/DragonFruit.Six.Api.Tests/Data/GeneralStatsTests.cs b/DragonFruit.Six.Api.Tests/Data/GeneralStatsTests.cs index 204244e8..6e0b8bb7 100644 --- a/DragonFruit.Six.Api.Tests/Data/GeneralStatsTests.cs +++ b/DragonFruit.Six.Api.Tests/Data/GeneralStatsTests.cs @@ -34,6 +34,14 @@ public void WeaponStatsTest(string identifier, Platform platform) Client.GetWeaponStats(account); } + [Test] + [TestCaseSource(nameof(_accounts))] + public void WeaponTrainingStatsTest(string identifier, Platform platform) + { + var account = GetAccountInfoFor(identifier, platform); + Client.GetWeaponTrainingStats(account); + } + [Test] [TestCaseSource(nameof(_accounts))] public void PlayerLevelStatsTest(string identifier, Platform platform) @@ -51,5 +59,15 @@ public void PlayerOperatorStatsTest(string identifier, Platform platform) var account = GetAccountInfoFor(identifier, platform); Client.GetOperatorStats(account, OperatorInfo); } + + [Test] + [TestCaseSource(nameof(_accounts))] + public void PlayerOperatorTrainingStatsTest(string identifier, Platform platform) + { + OperatorInfo ??= Client.GetOperatorInfo(); + + var account = GetAccountInfoFor(identifier, platform); + Client.GetOperatorTrainingStats(account, OperatorInfo); + } } } diff --git a/DragonFruit.Six.Api/Deserializers/OperatorStatsDeserializer.cs b/DragonFruit.Six.Api/Deserializers/OperatorStatsDeserializer.cs index b73ec03a..e9dcb994 100644 --- a/DragonFruit.Six.Api/Deserializers/OperatorStatsDeserializer.cs +++ b/DragonFruit.Six.Api/Deserializers/OperatorStatsDeserializer.cs @@ -42,5 +42,35 @@ public static IEnumerable DeserializeOperatorStatsFor(this JObjec yield return op; } } + + public static IEnumerable DeserializeOperatorTrainingStatsFor(this JObject jObject, string guid, IEnumerable data) + { + var json = jObject[Misc.Results]?[guid] as JObject; + + if (json == null) + yield break; + + foreach (var op in data.Select(x => x.Clone())) + { + op.Guid = guid; + + op.Kills = json.GetUInt(Operator.KillsTraining.ToIndexedStatsKey(op.Index)); + op.Deaths = json.GetUInt(Operator.DeathsTraining.ToIndexedStatsKey(op.Index)); + + op.Wins = json.GetUInt(Operator.WinsTraining.ToIndexedStatsKey(op.Index)); + op.Losses = json.GetUInt(Operator.LossesTraining.ToIndexedStatsKey(op.Index)); + + op.RoundsPlayed = json.GetUInt(Operator.RoundsTraining.ToIndexedStatsKey(op.Index)); + op.Duration = json.GetUInt(Operator.TimeTraining.ToIndexedStatsKey(op.Index)); + + op.Headshots = json.GetUInt(Operator.HeadshotsTraining.ToIndexedStatsKey(op.Index)); + op.Downs = json.GetUInt(Operator.DownsTraining.ToIndexedStatsKey(op.Index)); + + op.Experience = json.GetUInt(Operator.ExperienceTraining.ToIndexedStatsKey(op.Index)); + op.ActionCount = (uint?)json[op.OperatorActionResultId]; + + yield return op; + } + } } } diff --git a/DragonFruit.Six.Api/Deserializers/WeaponStatsDeserializer.cs b/DragonFruit.Six.Api/Deserializers/WeaponStatsDeserializer.cs index 47e64987..a2eb9365 100644 --- a/DragonFruit.Six.Api/Deserializers/WeaponStatsDeserializer.cs +++ b/DragonFruit.Six.Api/Deserializers/WeaponStatsDeserializer.cs @@ -44,5 +44,35 @@ public static IEnumerable DeserializeWeaponStatsFor(this JObject jO }; } } + + public static IEnumerable DeserializeWeaponTrainingStatsFor(this JObject jObject, string guid) + { + var json = jObject[Misc.Results]?[guid] as JObject; + + if (json == null) + yield break; + + foreach (var index in Enum.GetValues(typeof(WeaponType)).Cast()) + { + var numericIndex = (int)index; + + yield return new WeaponStats + { + Guid = guid, + Class = index, + TimesChosen = json.GetUInt(Weapon.PickedTraining.ToIndexedStatsKey(numericIndex)), + + Kills = json.GetUInt(Weapon.KillsTraining.ToIndexedStatsKey(numericIndex)), + Deaths = json.GetUInt(Weapon.DeathsTraining.ToIndexedStatsKey(numericIndex)), + + Headshots = json.GetUInt(Weapon.HeadshotsTraining.ToIndexedStatsKey(numericIndex)), + Downs = json.GetUInt(Weapon.DownsTraining.ToIndexedStatsKey(numericIndex)), + DownAssists = json.GetUInt(Weapon.DownAssistsTraining.ToIndexedStatsKey(numericIndex)), + + ShotsFired = json.GetUInt(Weapon.ShotsFiredTraining.ToIndexedStatsKey(numericIndex)), + ShotsLanded = json.GetUInt(Weapon.ShotsHitTraining.ToIndexedStatsKey(numericIndex)) + }; + } + } } } diff --git a/DragonFruit.Six.Api/Extensions/OperatorStatsExtensions.cs b/DragonFruit.Six.Api/Extensions/OperatorStatsExtensions.cs index ba0c75a1..22c93290 100644 --- a/DragonFruit.Six.Api/Extensions/OperatorStatsExtensions.cs +++ b/DragonFruit.Six.Api/Extensions/OperatorStatsExtensions.cs @@ -39,5 +39,32 @@ public static IEnumerable> GetOperatorStats(this T } } } + + /// + /// Get the for an + /// + public static IEnumerable GetOperatorTrainingStats(this T client, AccountInfo account, IEnumerable operators, CancellationToken token = default) + where T : Dragon6Client + => GetOperatorTrainingStats(client, new[] { account }, operators, token).First(); + + /// + /// Get the for an array of s + /// + public static IEnumerable> GetOperatorTrainingStats(this T client, IEnumerable accounts, IEnumerable operators, + CancellationToken token = default) where T : Dragon6Client + { + var filteredGroups = accounts.GroupBy(x => x.Platform); + + foreach (var group in filteredGroups) + { + var request = new OperatorTrainingStatsRequest(group, operators); + var data = client.Perform(request, token); + + foreach (var id in request.AccountIds) + { + yield return data.DeserializeOperatorTrainingStatsFor(id, operators); + } + } + } } } diff --git a/DragonFruit.Six.Api/Extensions/WeaponStatsExtensions.cs b/DragonFruit.Six.Api/Extensions/WeaponStatsExtensions.cs index 9c7e99fd..67de009a 100644 --- a/DragonFruit.Six.Api/Extensions/WeaponStatsExtensions.cs +++ b/DragonFruit.Six.Api/Extensions/WeaponStatsExtensions.cs @@ -37,5 +37,30 @@ public static IEnumerable> GetWeaponStats(this T cli } } } + + /// + /// Get for an + /// + public static IEnumerable GetWeaponTrainingStats(this T client, AccountInfo account, CancellationToken token = default) where T : Dragon6Client + => GetWeaponTrainingStats(client, new[] { account }, token).First(); + + /// + /// Get for an array of s + /// + public static IEnumerable> GetWeaponTrainingStats(this T client, IEnumerable accounts, CancellationToken token = default) where T : Dragon6Client + { + var filteredGroups = accounts.GroupBy(x => x.Platform); + + foreach (var group in filteredGroups) + { + var request = new WeaponTrainingStatsRequest(group); + var data = client.Perform(request, token); + + foreach (var id in request.AccountIds) + { + yield return data.DeserializeWeaponTrainingStatsFor(id); + } + } + } } } diff --git a/DragonFruit.Six.Api/Requests/OperatorStatsRequest.cs b/DragonFruit.Six.Api/Requests/OperatorStatsRequest.cs index 3fc7ff82..a8881416 100644 --- a/DragonFruit.Six.Api/Requests/OperatorStatsRequest.cs +++ b/DragonFruit.Six.Api/Requests/OperatorStatsRequest.cs @@ -37,4 +37,33 @@ public OperatorStatsRequest(IEnumerable accounts, IEnumerable operators) + : this(new[] { account }, operators) + { + } + + public OperatorTrainingStatsRequest(IEnumerable accounts, IEnumerable operators) + : base(accounts) + { + Stats = operators.Select(x => x.OperatorActionId).Where(x => !string.IsNullOrWhiteSpace(x)).Concat(new[] + { + Operator.KillsTraining, + Operator.DeathsTraining, + + Operator.HeadshotsTraining, + Operator.DownsTraining, + + Operator.WinsTraining, + Operator.LossesTraining, + + Operator.RoundsTraining, + Operator.TimeTraining, + + Operator.ExperienceTraining + }); + } + } } diff --git a/DragonFruit.Six.Api/Requests/WeaponStatsRequest.cs b/DragonFruit.Six.Api/Requests/WeaponStatsRequest.cs index 6101af28..ee757e7f 100644 --- a/DragonFruit.Six.Api/Requests/WeaponStatsRequest.cs +++ b/DragonFruit.Six.Api/Requests/WeaponStatsRequest.cs @@ -35,4 +35,32 @@ public WeaponStatsRequest(IEnumerable accounts) Weapon.ShotsHit }; } + + public sealed class WeaponTrainingStatsRequest : BasicStatsRequest + { + public WeaponTrainingStatsRequest(AccountInfo account) + : base(account) + { + } + + public WeaponTrainingStatsRequest(IEnumerable accounts) + : base(accounts) + { + } + + public override IEnumerable Stats { get; set; } = new[] + { + Weapon.PickedTraining, + + Weapon.KillsTraining, + Weapon.DeathsTraining, + + Weapon.HeadshotsTraining, + Weapon.DownsTraining, + Weapon.DownAssistsTraining, + + Weapon.ShotsFiredTraining, + Weapon.ShotsHitTraining + }; + } } diff --git a/DragonFruit.Six.Api/Strings/Operator.cs b/DragonFruit.Six.Api/Strings/Operator.cs index ba8de965..68a03617 100644 --- a/DragonFruit.Six.Api/Strings/Operator.cs +++ b/DragonFruit.Six.Api/Strings/Operator.cs @@ -6,16 +6,25 @@ namespace DragonFruit.Six.Api.Strings public static class Operator { public static string Wins => "operatorpvp_roundwon"; + public static string WinsTraining => "operatorpve_roundwon"; public static string Losses => "operatorpvp_roundlost"; + public static string LossesTraining => "operatorpve_roundlost"; public static string Kills => "operatorpvp_kills"; + public static string KillsTraining => "operatorpve_kills"; public static string Deaths => "operatorpvp_death"; + public static string DeathsTraining => "operatorpve_death"; public static string Downs => "operatorpvp_headshot"; + public static string DownsTraining => "operatorpve_headshot"; public static string Headshots => "operatorpvp_dbno"; + public static string HeadshotsTraining => "operatorpve_dbno"; public static string Rounds => "operatorpvp_roundplayed"; + public static string RoundsTraining => "operatorpve_roundplayed"; public static string Time => "operatorpvp_timeplayed"; + public static string TimeTraining => "operatorpve_timeplayed"; public static string Experience => "operatorpvp_totalxp"; + public static string ExperienceTraining => "operatorpve_totalxp"; } } diff --git a/DragonFruit.Six.Api/Strings/Weapon.cs b/DragonFruit.Six.Api/Strings/Weapon.cs index bee7da96..8b140b6f 100644 --- a/DragonFruit.Six.Api/Strings/Weapon.cs +++ b/DragonFruit.Six.Api/Strings/Weapon.cs @@ -6,15 +6,23 @@ namespace DragonFruit.Six.Api.Strings public static class Weapon { public static string Picked => "weapontypepvp_chosen"; + public static string PickedTraining => "weapontypepve_chosen"; public static string Kills => "weapontypepvp_kills"; + public static string KillsTraining => "weapontypepve_kills"; public static string Deaths => "weapontypepvp_death"; + public static string DeathsTraining => "weapontypepve_death"; public static string Headshots => "weapontypepvp_headshot"; + public static string HeadshotsTraining => "weapontypepve_headshot"; public static string Downs => "weapontypepvp_dbno"; + public static string DownsTraining => "weapontypepve_dbno"; public static string DownAssists => "weapontypepvp_dbnoassists"; + public static string DownAssistsTraining => "weapontypepve_dbnoassists"; public static string ShotsFired => "weapontypepvp_bulletfired"; + public static string ShotsFiredTraining => "weapontypepve_bulletfired"; public static string ShotsHit => "weapontypepvp_bullethit"; + public static string ShotsHitTraining => "weapontypepve_bullethit"; } }