Skip to content
This repository has been archived by the owner on Apr 8, 2024. It is now read-only.

Commit

Permalink
Merge pull request #255 from aspriddell/crystal-guard-ranks
Browse files Browse the repository at this point in the history
add updated ranks and versions
  • Loading branch information
aspriddell authored Aug 26, 2021
2 parents e05a750 + a03b999 commit dcb7d82
Show file tree
Hide file tree
Showing 4 changed files with 90 additions and 21 deletions.
11 changes: 9 additions & 2 deletions DragonFruit.Six.Api.Tests/Utils/SeasonalRanksTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}

Expand All @@ -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");
}
}
}
6 changes: 5 additions & 1 deletion DragonFruit.Six.Api/Containers/RankInfo.cs
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
// Dragon6 API Copyright 2020 DragonFruit Network <inbox@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 class RankInfo
public struct RankInfo : IEquatable<RankInfo>, IEquatable<int>
{
internal RankInfo(byte id, string name, string iconUrl, int? minMMR, int? maxMMR)
{
Expand Down Expand Up @@ -46,5 +47,8 @@ internal RankInfo(byte id, string name, string iconUrl, int? minMMR, int? maxMMR
/// </summary>
[JsonProperty("mmr_max")]
public int? MaxMMR { get; set; }

public bool Equals(int other) => Id == other;
public bool Equals(RankInfo other) => Equals(other.Id);
}
}
9 changes: 4 additions & 5 deletions DragonFruit.Six.Api/Entities/SeasonStats.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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; }
Expand Down Expand Up @@ -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);
}
Expand Down
85 changes: 72 additions & 13 deletions DragonFruit.Six.Api/Utils/SeasonalRanks.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,29 +9,88 @@ namespace DragonFruit.Six.Api.Utils
public static class SeasonalRanks
{
/// <summary>
/// Gets the <see cref="RankInfo"/> for the current rank based on id
/// Gets the <see cref="RankInfo"/> for the provided rank and season
/// </summary>
public static RankInfo GetFromId(int rankId, bool legacy = false) => GetRank(rankId, legacy);
/// <param name="id">The id of the rank to return</param>
/// <param name="season">The id of the season (optional, -1 for the latest season)</param>
public static RankInfo GetFromId(int id, int season = -1) => GetRank(id, season);

/// <summary>
/// Gets the <see cref="RankInfo"/> for the current rank based on the MMR value
/// Gets the <see cref="RankInfo"/> for the provided mmr and season
/// </summary>
public static RankInfo GetFromMMR(int mmr, bool legacy = false) => GetRank(mmr, legacy, true);
/// <param name="mmr">The mmr of the rank to return</param>
/// <param name="season">The id of the season (optional, -1 for the latest season)</param>
public static RankInfo GetFromMMR(int mmr, int season = -1) => GetRank(mmr, season, true);

private static RankInfo GetRank(int identifier, bool isLegacyRanks = false, bool isMMR = false)
/// <summary>
/// Gets the <see cref="RankInfo"/> for the identifier and season
/// </summary>
/// <param name="identifier">The id of the rank or the mmr</param>
/// <param name="season">The id of the season (optional, -1 for the latest season)</param>
/// <param name="isMMR">Whether the <see cref="identifier"/> represents mmr.</param>
public static RankInfo GetRank(int identifier, int season = -1, bool isMMR = false)
{
var itemsSource = isLegacyRanks ? LegacyRanks : Ranks;

return isMMR switch
var itemsSource = season switch
{
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()
// season 1-14
>= 01 and <= 14 => RankingV1,

// season 15-22
>= 15 and <= 22 => RankingV2,

// season 23- (incl. latest season identifier)
_ => RankingV3
};

if (isMMR)
{
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/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[] Ranks =
private static readonly RankInfo[] RankingV2 =
{
new(0, "Unranked", "/rank/v2/0.svg", null, null),

Expand Down Expand Up @@ -65,7 +124,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),

Expand Down

0 comments on commit dcb7d82

Please sign in to comment.