From c5ea8fa519667f2567e16656dd6d59de76e9a4e7 Mon Sep 17 00:00:00 2001 From: Albie Date: Wed, 25 Aug 2021 09:35:08 +0100 Subject: [PATCH 1/4] add updated ranks and versions --- .../Utils/SeasonalRanksTests.cs | 11 ++- DragonFruit.Six.Api/Containers/RankInfo.cs | 2 +- DragonFruit.Six.Api/Entities/SeasonStats.cs | 9 +-- DragonFruit.Six.Api/Utils/SeasonalRanks.cs | 77 +++++++++++++++---- 4 files changed, 75 insertions(+), 24 deletions(-) diff --git a/DragonFruit.Six.Api.Tests/Utils/SeasonalRanksTests.cs b/DragonFruit.Six.Api.Tests/Utils/SeasonalRanksTests.cs index ae34a74b..26aafd75 100644 --- a/DragonFruit.Six.Api.Tests/Utils/SeasonalRanksTests.cs +++ b/DragonFruit.Six.Api.Tests/Utils/SeasonalRanksTests.cs @@ -15,7 +15,7 @@ public class SeasonalRanksTests [TestCase(6050, 23)] public void TestMMR(int mmr, byte expectedRankId) { - var rank = SeasonalRanks.GetFromMMR(mmr); + var rank = SeasonalRanks.GetRank(mmr, 22, true); Assert.AreEqual(expectedRankId, rank.Id); } @@ -25,8 +25,15 @@ public void TestMMR(int mmr, byte expectedRankId) [TestCase(4800, 20)] public void TestLegacyMMR(int mmr, byte expectedRankId) { - var rank = SeasonalRanks.GetFromMMR(mmr, true); + var rank = SeasonalRanks.GetRank(mmr, 12, true); Assert.AreEqual(expectedRankId, rank.Id); } + + [Test] + public void TestInvalidRank() + { + var rank = SeasonalRanks.GetRank(100); + Assert.AreEqual(rank.Name, "Unranked"); + } } } diff --git a/DragonFruit.Six.Api/Containers/RankInfo.cs b/DragonFruit.Six.Api/Containers/RankInfo.cs index 198bd31c..941f10ed 100644 --- a/DragonFruit.Six.Api/Containers/RankInfo.cs +++ b/DragonFruit.Six.Api/Containers/RankInfo.cs @@ -5,7 +5,7 @@ namespace DragonFruit.Six.Api.Containers { - public class RankInfo + public struct RankInfo { internal RankInfo(byte id, string name, string iconUrl, int? minMMR, int? maxMMR) { diff --git a/DragonFruit.Six.Api/Entities/SeasonStats.cs b/DragonFruit.Six.Api/Entities/SeasonStats.cs index 26b3fc71..ba5f2287 100644 --- a/DragonFruit.Six.Api/Entities/SeasonStats.cs +++ b/DragonFruit.Six.Api/Entities/SeasonStats.cs @@ -14,7 +14,7 @@ namespace DragonFruit.Six.Api.Entities [JsonObject(MemberSerialization.OptIn)] public class SeasonStats : StatsBase, IAssociatedWithAccount, IStatsResponse { - private RankInfo _rankInfo, _maxRankInfo, _mmrRankInfo; + private RankInfo? _rankInfo, _maxRankInfo, _mmrRankInfo; [JsonProperty("profile")] internal string ProfileId { get; set; } @@ -75,10 +75,9 @@ public class SeasonStats : StatsBase, IAssociatedWithAccount, IStatsResponse #endregion - public bool IsLegacySeason => SeasonId < 14; - public RankInfo RankInfo => _rankInfo ??= SeasonalRanks.GetFromId(Rank, IsLegacySeason); - public RankInfo MaxRankInfo => _maxRankInfo ??= SeasonalRanks.GetFromId(MaxRank, IsLegacySeason); - public RankInfo MMRRankInfo => _mmrRankInfo ??= SeasonalRanks.GetFromMMR((int)MMR, IsLegacySeason); + public RankInfo RankInfo => _rankInfo ??= SeasonalRanks.GetRank(Rank, SeasonId); + public RankInfo MaxRankInfo => _maxRankInfo ??= SeasonalRanks.GetRank(MaxRank, SeasonId); + public RankInfo MMRRankInfo => _mmrRankInfo ??= SeasonalRanks.GetRank((int)MMR, SeasonId, true); public bool IsAssociatedWithAccount(AccountInfo account) => account.Identifiers.Profile.Equals(ProfileId); } diff --git a/DragonFruit.Six.Api/Utils/SeasonalRanks.cs b/DragonFruit.Six.Api/Utils/SeasonalRanks.cs index 48ae8485..648f05f1 100644 --- a/DragonFruit.Six.Api/Utils/SeasonalRanks.cs +++ b/DragonFruit.Six.Api/Utils/SeasonalRanks.cs @@ -9,29 +9,74 @@ namespace DragonFruit.Six.Api.Utils public static class SeasonalRanks { /// - /// Gets the for the current rank based on id + /// Gets the for the identifier and season /// - public static RankInfo GetFromId(int rankId, bool legacy = false) => GetRank(rankId, legacy); + /// The id of the rank or the mmr + /// The id of the season (optional, -1 for the latest season) + /// Whether the represents mmr. + public static RankInfo GetRank(int identifier, int season = -1, bool isMMR = false) + { + var itemsSource = season switch + { + // season 1-14 + >= 01 and <= 14 => RankingV1, - /// - /// Gets the for the current rank based on the MMR value - /// - public static RankInfo GetFromMMR(int mmr, bool legacy = false) => GetRank(mmr, legacy, true); + // season 15-22 + >= 15 and <= 22 => RankingV2, - private static RankInfo GetRank(int identifier, bool isLegacyRanks = false, bool isMMR = false) - { - var itemsSource = isLegacyRanks ? LegacyRanks : Ranks; + // season 23- (incl. latest season identifier) + _ => RankingV3 + }; - return isMMR switch + if (isMMR) { - false => itemsSource.ElementAtOrDefault(identifier) ?? Ranks[0], - true => itemsSource.Where(x => (x.MinMMR ?? int.MinValue) <= identifier && (x.MaxMMR ?? int.MaxValue) >= identifier).OrderByDescending(x => x.Id).First() - }; + return itemsSource.Where(x => (x.MinMMR ?? int.MinValue) <= identifier && (x.MaxMMR ?? int.MaxValue) >= identifier).OrderByDescending(x => x.Id).First(); + } + + // if the rank isn't in the array, return generic unranked one + return identifier + 1 <= itemsSource.Length ? itemsSource[identifier] : RankingV3[0]; } - #region Data Source + #region Data Sources + + private static readonly RankInfo[] RankingV3 = + { + new(0, "Unranked", "/rank/v2/0.svg", null, null), + + new(1, "Copper 5", "/rank/v2/1.svg", null, 1199), + new(2, "Copper 4", "/rank/v2/2.svg", 1200, 1299), + new(3, "Copper 3", "/rank/v2/3.svg", 1300, 1399), + new(4, "Copper 2", "/rank/v2/4.svg", 1400, 1499), + new(5, "Copper 1", "/rank/v2/5.svg", 1500, 1599), + + new(6, "Bronze 5", "/rank/v2/6.svg", 1600, 1699), + new(7, "Bronze 4", "/rank/v2/7.svg", 1700, 1799), + new(8, "Bronze 3", "/rank/v2/8.svg", 1800, 1899), + new(9, "Bronze 2", "/rank/v2/9.svg", 1900, 1999), + new(10, "Bronze 1", "/rank/v2/10.svg", 2000, 2099), + + new(11, "Silver 5", "/rank/v2/11.svg", 2100, 2199), + new(12, "Silver 4", "/rank/v2/12.svg", 2200, 2299), + new(13, "Silver 3", "/rank/v2/13.svg", 2300, 2399), + new(14, "Silver 2", "/rank/v2/14.svg", 2400, 2499), + new(15, "Silver 1", "/rank/v2/15.svg", 2500, 2599), + + new(16, "Gold 3", "/rank/v2/16.svg", 2600, 2799), + new(17, "Gold 2", "/rank/v2/17.svg", 2800, 2999), + new(18, "Gold 1", "/rank/v2/18.svg", 3000, 3199), + + new(19, "Platinum 3", "/rank/v2/19.svg", 3200, 3499), + new(20, "Platinum 2", "/rank/v2/20.svg", 3500, 3799), + new(21, "Platinum 1", "/rank/v2/21.svg", 3800, 4099), + + new(22, "Diamond 3", "/rank/v2/22.svg", 4100, 4399), + new(23, "Diamond 2", "/rank/v2/22.svg", 4400, 4699), + new(24, "Diamond 1", "/rank/v2/22.svg", 4700, 4999), + + new(25, "Champion", "/rank/v2/23.svg", 5000, null) + }; - private static readonly RankInfo[] Ranks = + private static readonly RankInfo[] RankingV2 = { new(0, "Unranked", "/rank/v2/0.svg", null, null), @@ -65,7 +110,7 @@ private static RankInfo GetRank(int identifier, bool isLegacyRanks = false, bool new(23, "Champion", "/rank/v2/23.svg", 5000, null) }; - private static readonly RankInfo[] LegacyRanks = + private static readonly RankInfo[] RankingV1 = { new(0, "Unranked", "/rank/v1/0.svg", null, null), From b1466d1b8b3b2171b022ad69fdaacb35b3b500ec Mon Sep 17 00:00:00 2001 From: Albie Date: Wed, 25 Aug 2021 09:40:16 +0100 Subject: [PATCH 2/4] add back the getfrom functions --- DragonFruit.Six.Api/Utils/SeasonalRanks.cs | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/DragonFruit.Six.Api/Utils/SeasonalRanks.cs b/DragonFruit.Six.Api/Utils/SeasonalRanks.cs index 648f05f1..22fef14c 100644 --- a/DragonFruit.Six.Api/Utils/SeasonalRanks.cs +++ b/DragonFruit.Six.Api/Utils/SeasonalRanks.cs @@ -8,6 +8,20 @@ namespace DragonFruit.Six.Api.Utils { public static class SeasonalRanks { + /// + /// Gets the for the provided rank and season + /// + /// The id of the rank to return + /// The id of the season (optional, -1 for the latest season) + public static RankInfo GetFromId(int id, int season = -1) => GetRank(id, season); + + /// + /// Gets the for the provided mmr and season + /// + /// The mmr of the rank to return + /// The id of the season (optional, -1 for the latest season) + public static RankInfo GetFromMMR(int mmr, int season = -1) => GetRank(mmr, season, true); + /// /// Gets the for the identifier and season /// From 6d97aec22d43a0f6e2e615bcdc5c1083ca2cc3d7 Mon Sep 17 00:00:00 2001 From: Albie Date: Wed, 25 Aug 2021 09:58:33 +0100 Subject: [PATCH 3/4] add IEquatable checks --- DragonFruit.Six.Api/Containers/RankInfo.cs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/DragonFruit.Six.Api/Containers/RankInfo.cs b/DragonFruit.Six.Api/Containers/RankInfo.cs index 941f10ed..5d97e739 100644 --- a/DragonFruit.Six.Api/Containers/RankInfo.cs +++ b/DragonFruit.Six.Api/Containers/RankInfo.cs @@ -1,11 +1,12 @@ // Dragon6 API Copyright 2020 DragonFruit Network // Licensed under Apache-2. Please refer to the LICENSE file for more info +using System; using Newtonsoft.Json; namespace DragonFruit.Six.Api.Containers { - public struct RankInfo + public struct RankInfo : IEquatable, IEquatable { internal RankInfo(byte id, string name, string iconUrl, int? minMMR, int? maxMMR) { @@ -46,5 +47,8 @@ internal RankInfo(byte id, string name, string iconUrl, int? minMMR, int? maxMMR /// [JsonProperty("mmr_max")] public int? MaxMMR { get; set; } + + public bool Equals(int other) => Id == other; + public bool Equals(RankInfo other) => Equals(other.Id); } } From a03b99983bb065917b3e5737783de6922b6fd7fc Mon Sep 17 00:00:00 2001 From: Albie Date: Thu, 26 Aug 2021 13:03:02 +0100 Subject: [PATCH 4/4] update icon urls --- DragonFruit.Six.Api/Utils/SeasonalRanks.cs | 66 +++++++++++----------- 1 file changed, 33 insertions(+), 33 deletions(-) diff --git a/DragonFruit.Six.Api/Utils/SeasonalRanks.cs b/DragonFruit.Six.Api/Utils/SeasonalRanks.cs index 22fef14c..431789ef 100644 --- a/DragonFruit.Six.Api/Utils/SeasonalRanks.cs +++ b/DragonFruit.Six.Api/Utils/SeasonalRanks.cs @@ -55,39 +55,39 @@ public static RankInfo GetRank(int identifier, int season = -1, bool isMMR = fal private static readonly RankInfo[] RankingV3 = { - new(0, "Unranked", "/rank/v2/0.svg", null, null), - - new(1, "Copper 5", "/rank/v2/1.svg", null, 1199), - new(2, "Copper 4", "/rank/v2/2.svg", 1200, 1299), - new(3, "Copper 3", "/rank/v2/3.svg", 1300, 1399), - new(4, "Copper 2", "/rank/v2/4.svg", 1400, 1499), - new(5, "Copper 1", "/rank/v2/5.svg", 1500, 1599), - - new(6, "Bronze 5", "/rank/v2/6.svg", 1600, 1699), - new(7, "Bronze 4", "/rank/v2/7.svg", 1700, 1799), - new(8, "Bronze 3", "/rank/v2/8.svg", 1800, 1899), - new(9, "Bronze 2", "/rank/v2/9.svg", 1900, 1999), - new(10, "Bronze 1", "/rank/v2/10.svg", 2000, 2099), - - new(11, "Silver 5", "/rank/v2/11.svg", 2100, 2199), - new(12, "Silver 4", "/rank/v2/12.svg", 2200, 2299), - new(13, "Silver 3", "/rank/v2/13.svg", 2300, 2399), - new(14, "Silver 2", "/rank/v2/14.svg", 2400, 2499), - new(15, "Silver 1", "/rank/v2/15.svg", 2500, 2599), - - new(16, "Gold 3", "/rank/v2/16.svg", 2600, 2799), - new(17, "Gold 2", "/rank/v2/17.svg", 2800, 2999), - new(18, "Gold 1", "/rank/v2/18.svg", 3000, 3199), - - new(19, "Platinum 3", "/rank/v2/19.svg", 3200, 3499), - new(20, "Platinum 2", "/rank/v2/20.svg", 3500, 3799), - new(21, "Platinum 1", "/rank/v2/21.svg", 3800, 4099), - - new(22, "Diamond 3", "/rank/v2/22.svg", 4100, 4399), - new(23, "Diamond 2", "/rank/v2/22.svg", 4400, 4699), - new(24, "Diamond 1", "/rank/v2/22.svg", 4700, 4999), - - new(25, "Champion", "/rank/v2/23.svg", 5000, null) + new(0, "Unranked", "/rank/v3/0.svg", null, null), + + new(1, "Copper 5", "/rank/v3/1.svg", null, 1199), + new(2, "Copper 4", "/rank/v3/2.svg", 1200, 1299), + new(3, "Copper 3", "/rank/v3/3.svg", 1300, 1399), + new(4, "Copper 2", "/rank/v3/4.svg", 1400, 1499), + new(5, "Copper 1", "/rank/v3/5.svg", 1500, 1599), + + new(6, "Bronze 5", "/rank/v3/6.svg", 1600, 1699), + new(7, "Bronze 4", "/rank/v3/7.svg", 1700, 1799), + new(8, "Bronze 3", "/rank/v3/8.svg", 1800, 1899), + new(9, "Bronze 2", "/rank/v3/9.svg", 1900, 1999), + new(10, "Bronze 1", "/rank/v3/10.svg", 2000, 2099), + + new(11, "Silver 5", "/rank/v3/11.svg", 2100, 2199), + new(12, "Silver 4", "/rank/v3/12.svg", 2200, 2299), + new(13, "Silver 3", "/rank/v3/13.svg", 2300, 2399), + new(14, "Silver 2", "/rank/v3/14.svg", 2400, 2499), + new(15, "Silver 1", "/rank/v3/15.svg", 2500, 2599), + + new(16, "Gold 3", "/rank/v3/16.svg", 2600, 2799), + new(17, "Gold 2", "/rank/v3/17.svg", 2800, 2999), + new(18, "Gold 1", "/rank/v3/18.svg", 3000, 3199), + + new(19, "Platinum 3", "/rank/v3/19.svg", 3200, 3499), + new(20, "Platinum 2", "/rank/v3/20.svg", 3500, 3799), + new(21, "Platinum 1", "/rank/v3/21.svg", 3800, 4099), + + new(22, "Diamond 3", "/rank/v3/22.svg", 4100, 4399), + new(23, "Diamond 2", "/rank/v3/23.svg", 4400, 4699), + new(24, "Diamond 1", "/rank/v3/24.svg", 4700, 4999), + + new(25, "Champion", "/rank/v3/25.svg", 5000, null) }; private static readonly RankInfo[] RankingV2 =