From c7169ad01a7334de87821b44488edbedd3de0831 Mon Sep 17 00:00:00 2001 From: Tomi Parviainen Date: Tue, 6 Jun 2023 16:48:07 +0300 Subject: [PATCH] Add support for builder base leagues/rankings (#140) * Update NuGet packages * Update models * Add APIs for builder base leagues/rankings * Bump NuGet version to 8.8.0-rc1 --- build/version.txt | 2 +- src/ClashOfClans.Models/BuilderBaseLeague.cs | 11 ++++++ .../BuilderBaseLeagueList.cs | 8 +++++ src/ClashOfClans.Models/Clan.cs | 6 ++++ .../ClanBuilderBaseRanking.cs | 28 +++++++++++++++ .../ClanBuilderBaseRankingList.cs | 8 +++++ src/ClashOfClans.Models/ClanMember.cs | 5 +++ src/ClashOfClans.Models/ClanVersusRanking.cs | 3 ++ src/ClashOfClans.Models/Player.cs | 8 +++++ .../PlayerBuilderBaseRanking.cs | 28 +++++++++++++++ .../PlayerBuilderBaseRankingList.cs | 8 +++++ .../PlayerLegendStatistics.cs | 4 +++ .../PlayerVersusRanking.cs | 5 +++ .../ClashOfClans.Tests.Integration.csproj | 6 ++-- .../LeaguesTests.cs | 34 ++++++++++++++++-- .../LocationsTests.cs | 36 +++++++++++++++++++ .../TestsBase.cs | 4 --- src/ClashOfClans/Api/Leagues.cs | 22 ++++++++++++ src/ClashOfClans/Api/Locations.cs | 24 +++++++++++++ src/ClashOfClans/ILeagues.cs | 18 ++++++++++ src/ClashOfClans/ILocations.cs | 20 +++++++++++ 21 files changed, 278 insertions(+), 10 deletions(-) create mode 100644 src/ClashOfClans.Models/BuilderBaseLeague.cs create mode 100644 src/ClashOfClans.Models/BuilderBaseLeagueList.cs create mode 100644 src/ClashOfClans.Models/ClanBuilderBaseRanking.cs create mode 100644 src/ClashOfClans.Models/ClanBuilderBaseRankingList.cs create mode 100644 src/ClashOfClans.Models/PlayerBuilderBaseRanking.cs create mode 100644 src/ClashOfClans.Models/PlayerBuilderBaseRankingList.cs diff --git a/build/version.txt b/build/version.txt index e4dd23e8..04e4d1fa 100644 --- a/build/version.txt +++ b/build/version.txt @@ -6,4 +6,4 @@ # Patch: Backwards compatible bug fixes only # -Suffix (optional): a hyphen followed by a string denoting a pre-release version (rc1, rc2, etc.) -8.7.0 +8.8.0-rc1 diff --git a/src/ClashOfClans.Models/BuilderBaseLeague.cs b/src/ClashOfClans.Models/BuilderBaseLeague.cs new file mode 100644 index 00000000..e59d42e4 --- /dev/null +++ b/src/ClashOfClans.Models/BuilderBaseLeague.cs @@ -0,0 +1,11 @@ +namespace ClashOfClans.Models +{ + public class BuilderBaseLeague + { + private int? _id; + + public int Id { get => _id ?? default; set => _id = value; } + + public string Name { get; set; } = default!; + } +} diff --git a/src/ClashOfClans.Models/BuilderBaseLeagueList.cs b/src/ClashOfClans.Models/BuilderBaseLeagueList.cs new file mode 100644 index 00000000..bd0cbede --- /dev/null +++ b/src/ClashOfClans.Models/BuilderBaseLeagueList.cs @@ -0,0 +1,8 @@ +using System.Collections.Generic; + +namespace ClashOfClans.Models +{ + public class BuilderBaseLeagueList : List + { + } +} diff --git a/src/ClashOfClans.Models/Clan.cs b/src/ClashOfClans.Models/Clan.cs index 10c4fdb5..edd0200e 100644 --- a/src/ClashOfClans.Models/Clan.cs +++ b/src/ClashOfClans.Models/Clan.cs @@ -7,6 +7,7 @@ public class Clan : Identity private Type? _type; private int? _clanLevel; private int? _clanPoints; + private int? _clanBuilderBasePoints; private int? _clanVersusPoints; private int? _clanCapitalPoints; private int? _requiredTrophies; @@ -15,6 +16,7 @@ public class Clan : Identity private WarFrequency? _warFrequency; private int? _warWinStreak; private int? _warWins; + private int? _requiredBuilderBaseTrophies; private bool? _isWarLogPublic; private bool? _isFamilyFriendly; private int? _members; @@ -36,6 +38,8 @@ public class Clan : Identity public int ClanPoints { get => _clanPoints ?? default; set => _clanPoints = value; } + public int ClanBuilderBasePoints { get => _clanBuilderBasePoints ?? default; set => _clanBuilderBasePoints = value; } + public int ClanVersusPoints { get => _clanVersusPoints ?? default; set => _clanVersusPoints = value; } public int ClanCapitalPoints { get => _clanCapitalPoints ?? default; set => _clanCapitalPoints = value; } @@ -62,6 +66,8 @@ public class Clan : Identity /// public int WarWins { get => _warWins ?? default; set => _warWins = value; } + public int RequiredBuilderBaseTrophies { get => _requiredBuilderBaseTrophies ?? default; set => _requiredBuilderBaseTrophies = value; } + public bool IsFamilyFriendly { get => _isFamilyFriendly ?? default; set => _isFamilyFriendly = value; } public bool IsWarLogPublic { get => _isWarLogPublic ?? default; set => _isWarLogPublic = value; } diff --git a/src/ClashOfClans.Models/ClanBuilderBaseRanking.cs b/src/ClashOfClans.Models/ClanBuilderBaseRanking.cs new file mode 100644 index 00000000..d541df97 --- /dev/null +++ b/src/ClashOfClans.Models/ClanBuilderBaseRanking.cs @@ -0,0 +1,28 @@ +namespace ClashOfClans.Models +{ + public class ClanBuilderBaseRanking : Identity + { + private int? _members; + private int? _clanLevel; + private int? _rank; + private int? _previousRank; + private int? _clanBuilderBasePoints; + private int? _clanVersusPoints; + + public Location? Location { get; set; } + + public int Members { get => _members ?? default; set => _members = value; } + + public int ClanLevel { get => _clanLevel ?? default; set => _clanLevel = value; } + + public int Rank { get => _rank ?? default; set => _rank = value; } + + public int PreviousRank { get => _previousRank ?? default; set => _previousRank = value; } + + public int ClanBuilderBasePoints { get => _clanBuilderBasePoints ?? default; set => _clanBuilderBasePoints = value; } + + public int ClanVersusPoints { get => _clanVersusPoints ?? default; set => _clanVersusPoints = value; } + + public UrlContainer BadgeUrls { get; set; } = default!; + } +} diff --git a/src/ClashOfClans.Models/ClanBuilderBaseRankingList.cs b/src/ClashOfClans.Models/ClanBuilderBaseRankingList.cs new file mode 100644 index 00000000..2ea42648 --- /dev/null +++ b/src/ClashOfClans.Models/ClanBuilderBaseRankingList.cs @@ -0,0 +1,8 @@ +using System.Collections.Generic; + +namespace ClashOfClans.Models +{ + public class ClanBuilderBaseRankingList : List + { + } +} diff --git a/src/ClashOfClans.Models/ClanMember.cs b/src/ClashOfClans.Models/ClanMember.cs index 05668f04..a776d5c1 100644 --- a/src/ClashOfClans.Models/ClanMember.cs +++ b/src/ClashOfClans.Models/ClanMember.cs @@ -7,6 +7,7 @@ public class ClanMember : Identity private Role? _role; private int? _expLevel; private int? _trophies; + private int? _builderBaseTrophies; private int? _versusTrophies; private int? _clanRank; private int? _previousClanRank; @@ -21,6 +22,8 @@ public class ClanMember : Identity public int Trophies { get => _trophies ?? default; set => _trophies = value; } + public int BuilderBaseTrophies { get => _builderBaseTrophies ?? default; set => _builderBaseTrophies = value; } + public int VersusTrophies { get => _versusTrophies ?? default; set => _versusTrophies = value; } public int ClanRank { get => _clanRank ?? default; set => _clanRank = value; } @@ -32,5 +35,7 @@ public class ClanMember : Identity public int DonationsReceived { get => _donationsReceived ?? default; set => _donationsReceived = value; } public PlayerHouse? PlayerHouse { get; set; } + + public BuilderBaseLeague? BuilderBaseLeague { get; set; } } } diff --git a/src/ClashOfClans.Models/ClanVersusRanking.cs b/src/ClashOfClans.Models/ClanVersusRanking.cs index b906e9c6..1e1a09d0 100644 --- a/src/ClashOfClans.Models/ClanVersusRanking.cs +++ b/src/ClashOfClans.Models/ClanVersusRanking.cs @@ -7,6 +7,7 @@ public class ClanVersusRanking : Identity private int? _rank; private int? _previousRank; private int? _clanVersusPoints; + private int? _clanBuilderBasePoints; public Location Location { get; set; } = default!; @@ -23,5 +24,7 @@ public class ClanVersusRanking : Identity public int PreviousRank { get => _previousRank ?? default; set => _previousRank = value; } public int ClanVersusPoints { get => _clanVersusPoints ?? default; set => _clanVersusPoints = value; } + + public int ClanBuilderBasePoints { get => _clanBuilderBasePoints ?? default; set => _clanBuilderBasePoints = value; } } } diff --git a/src/ClashOfClans.Models/Player.cs b/src/ClashOfClans.Models/Player.cs index 2a5218d2..44dd2e9d 100644 --- a/src/ClashOfClans.Models/Player.cs +++ b/src/ClashOfClans.Models/Player.cs @@ -14,6 +14,8 @@ public class Player : Identity private int? _versusBattleWins; private int? _donations; private int? _donationsReceived; + private int? _builderBaseTrophies; + private int? _bestBuilderBaseTrophies; private int? _clanCapitalContributions; private int? _versusBattleWinCount; @@ -70,6 +72,10 @@ public class Player : Identity /// public int DonationsReceived { get => _donationsReceived ?? default; set => _donationsReceived = value; } + public int BuilderBaseTrophies { get => _builderBaseTrophies ?? default; set => _builderBaseTrophies = value; } + + public int BestBuilderBaseTrophies { get => _bestBuilderBaseTrophies ?? default; set => _bestBuilderBaseTrophies = value; } + /// /// Total capital contribution /// @@ -97,5 +103,7 @@ public class Player : Identity public LabelList Labels { get; set; } = default!; public PlayerHouse? PlayerHouse { get; set; } + + public BuilderBaseLeague? BuilderBaseLeague { get; set; } } } diff --git a/src/ClashOfClans.Models/PlayerBuilderBaseRanking.cs b/src/ClashOfClans.Models/PlayerBuilderBaseRanking.cs new file mode 100644 index 00000000..a72010ea --- /dev/null +++ b/src/ClashOfClans.Models/PlayerBuilderBaseRanking.cs @@ -0,0 +1,28 @@ +namespace ClashOfClans.Models +{ + public class PlayerBuilderBaseRanking : Identity + { + private int? _expLevel; + private int? _rank; + private int? _previousRank; + private int? _builderBaseTrophies; + private int? _versusTrophies; + private int? _versusBattleWins; + + public int ExpLevel { get => _expLevel ?? default; set => _expLevel = value; } + + public int Rank { get => _rank ?? default; set => _rank = value; } + + public int PreviousRank { get => _previousRank ?? default; set => _previousRank = value; } + + public int BuilderBaseTrophies { get => _builderBaseTrophies ?? default; set => _builderBaseTrophies = value; } + + public int VersusTrophies { get => _versusTrophies ?? default; set => _versusTrophies = value; } + + public int VersusBattleWins { get => _versusBattleWins ?? default; set => _versusBattleWins = value; } + + public PlayerRankingClan? Clan { get; set; } + + public BuilderBaseLeague BuilderBaseLeague { get; set; } = default!; + } +} diff --git a/src/ClashOfClans.Models/PlayerBuilderBaseRankingList.cs b/src/ClashOfClans.Models/PlayerBuilderBaseRankingList.cs new file mode 100644 index 00000000..3740c63a --- /dev/null +++ b/src/ClashOfClans.Models/PlayerBuilderBaseRankingList.cs @@ -0,0 +1,8 @@ +using System.Collections.Generic; + +namespace ClashOfClans.Models +{ + public class PlayerBuilderBaseRankingList : List + { + } +} diff --git a/src/ClashOfClans.Models/PlayerLegendStatistics.cs b/src/ClashOfClans.Models/PlayerLegendStatistics.cs index 61cb9bb1..983e5a65 100644 --- a/src/ClashOfClans.Models/PlayerLegendStatistics.cs +++ b/src/ClashOfClans.Models/PlayerLegendStatistics.cs @@ -15,5 +15,9 @@ public class PlayerLegendStatistics public LegendLeagueTournamentSeasonResult CurrentSeason { get; set; } = default!; public LegendLeagueTournamentSeasonResult? PreviousSeason { get; set; } + + public LegendLeagueTournamentSeasonResult? PreviousBuilderBaseSeason { get; set; } + + public LegendLeagueTournamentSeasonResult? BestBuilderBaseSeason { get; set; } } } diff --git a/src/ClashOfClans.Models/PlayerVersusRanking.cs b/src/ClashOfClans.Models/PlayerVersusRanking.cs index 2b4e9579..90e9b8bc 100644 --- a/src/ClashOfClans.Models/PlayerVersusRanking.cs +++ b/src/ClashOfClans.Models/PlayerVersusRanking.cs @@ -7,6 +7,7 @@ public class PlayerVersusRanking : Identity private int? _previousRank; private int? _versusTrophies; private int? _versusBattleWins; + private int? _builderBaseTrophies; public int ExpLevel { get => _expLevel ?? default; set => _expLevel = value; } @@ -18,6 +19,10 @@ public class PlayerVersusRanking : Identity public int VersusBattleWins { get => _versusBattleWins ?? default; set => _versusBattleWins = value; } + public int BuilderBaseTrophies { get => _builderBaseTrophies ?? default; set => _builderBaseTrophies = value; } + public PlayerRankingClan? Clan { get; set; } + + public BuilderBaseLeague? BuilderBaseLeague { get; set; } } } diff --git a/src/ClashOfClans.Tests.Integration/ClashOfClans.Tests.Integration.csproj b/src/ClashOfClans.Tests.Integration/ClashOfClans.Tests.Integration.csproj index d8b5a165..779a8721 100644 --- a/src/ClashOfClans.Tests.Integration/ClashOfClans.Tests.Integration.csproj +++ b/src/ClashOfClans.Tests.Integration/ClashOfClans.Tests.Integration.csproj @@ -8,9 +8,9 @@ - - - + + + diff --git a/src/ClashOfClans.Tests.Integration/LeaguesTests.cs b/src/ClashOfClans.Tests.Integration/LeaguesTests.cs index 5242ae86..364274ed 100644 --- a/src/ClashOfClans.Tests.Integration/LeaguesTests.cs +++ b/src/ClashOfClans.Tests.Integration/LeaguesTests.cs @@ -85,7 +85,8 @@ public async Task GetWarLeagueInformation() { // Arrange var leagues = _coc.Leagues; - var warLeagueId = GetRandom(_warLeagues).Id; + var warLeagues = (WarLeagueList)await _coc.Leagues.GetWarLeaguesAsync(); + var warLeagueId = GetRandom(warLeagues).Id; // Act var warLeague = await leagues.GetWarLeagueAsync(warLeagueId); @@ -112,7 +113,8 @@ public async Task GetCapitalLeagueInformation() { // Arrange var leagues = _coc.Leagues; - var capitalLeagueId = GetRandom(_capitalLeagues).Id; + var capitalLeagues = (CapitalLeagueList)await _coc.Leagues.GetCapitalLeaguesAsync(); + var capitalLeagueId = GetRandom(capitalLeagues).Id; // Act var capitalLeague = await leagues.GetCapitalLeagueAsync(capitalLeagueId); @@ -120,5 +122,33 @@ public async Task GetCapitalLeagueInformation() // Assert Assert.IsNotNull(capitalLeague); } + + [TestMethod] + public async Task ListBuilderBaseLeagues() + { + // Arrange + var leagues = _coc.Leagues; + + // Act + var builderBaseLeagueList = (BuilderBaseLeagueList)await leagues.GetBuilderBaseLeaguesAsync(); + + // Assert + Assert.IsNotNull(builderBaseLeagueList); + } + + [TestMethod] + public async Task GetBuilderBaseLeagueInformation() + { + // Arrange + var leagues = _coc.Leagues; + var builderBaseLeagues = (BuilderBaseLeagueList)await leagues.GetBuilderBaseLeaguesAsync(); + var builderBaseLeagueId = GetRandom(builderBaseLeagues).Id; + + // Act + var builderBaseLeague = await leagues.GetBuilderBaseLeagueAsync(builderBaseLeagueId); + + // Assert + Assert.IsNotNull(builderBaseLeague); + } } } diff --git a/src/ClashOfClans.Tests.Integration/LocationsTests.cs b/src/ClashOfClans.Tests.Integration/LocationsTests.cs index 5e17285c..c777827a 100644 --- a/src/ClashOfClans.Tests.Integration/LocationsTests.cs +++ b/src/ClashOfClans.Tests.Integration/LocationsTests.cs @@ -172,5 +172,41 @@ public async Task GetCapitalRankingsForASpecificLocation() Assert.IsNotNull(clanCapitalRankingList); Assert.IsTrue(clanCapitalRankingList.Count <= ItemLimit, $"Id {location.Id}"); } + + [TestMethod] + public async Task GetPlayerBuilderBaseRankingsForASpecificLocation() + { + // Arrange + var location = GetRandom(_locations, l => l.IsCountry); + var query = new Query + { + Limit = ItemLimit + }; + + // Act + var playerBuilderBaseRankingList = (PlayerBuilderBaseRankingList)await _coc.Locations.GetPlayerBuilderBaseRankingAsync(location.Id, query); + + // Assert + Assert.IsNotNull(playerBuilderBaseRankingList); + Assert.IsTrue(playerBuilderBaseRankingList.Count <= ItemLimit, $"Id {location.Id}"); + } + + [TestMethod] + public async Task GetClanBuilderBaseRankingsForASpecificLocation() + { + // Arrange + var location = GetRandom(_locations, l => l.IsCountry); + var query = new Query + { + Limit = ItemLimit + }; + + // Act + var clanBuilderBaseRankingList = (ClanBuilderBaseRankingList)await _coc.Locations.GetClanBuilderBaseRankingAsync(location.Id, query); + + // Assert + Assert.IsNotNull(clanBuilderBaseRankingList); + Assert.IsTrue(clanBuilderBaseRankingList.Count <= ItemLimit, $"Id {location.Id}"); + } } } diff --git a/src/ClashOfClans.Tests.Integration/TestsBase.cs b/src/ClashOfClans.Tests.Integration/TestsBase.cs index bf65614a..740c2a3a 100644 --- a/src/ClashOfClans.Tests.Integration/TestsBase.cs +++ b/src/ClashOfClans.Tests.Integration/TestsBase.cs @@ -17,8 +17,6 @@ public class TestsBase protected static ClanList _clans = default!; protected static LeagueList _leagues = default!; protected static LocationList _locations = default!; - protected static WarLeagueList _warLeagues = default!; - protected static CapitalLeagueList _capitalLeagues = default!; protected static IConfigurationRoot _config = default!; protected static ClashOfClansClient _coc = default!; @@ -51,8 +49,6 @@ public static async Task AssemblyInitialize(TestContext _) _clans = (ClanList)await _coc.Clans.SearchClansAsync(query); _leagues = (LeagueList)await _coc.Leagues.GetLeaguesAsync(); _locations = (LocationList)await _coc.Locations.GetLocationsAsync(); - _warLeagues = (WarLeagueList)await _coc.Leagues.GetWarLeaguesAsync(); - _capitalLeagues = (CapitalLeagueList)await _coc.Leagues.GetCapitalLeaguesAsync(); } catch (ClashOfClansException ex) { diff --git a/src/ClashOfClans/Api/Leagues.cs b/src/ClashOfClans/Api/Leagues.cs index 9668a672..aaad9911 100644 --- a/src/ClashOfClans/Api/Leagues.cs +++ b/src/ClashOfClans/Api/Leagues.cs @@ -104,5 +104,27 @@ public Task GetCapitalLeagueAsync(int? leagueId) return _gameData.RequestAsync(request); } + + public Task> GetBuilderBaseLeaguesAsync(Query? query = default) + { + var request = new AutoValidatedRequest + { + Query = query, + Uri = $"/builderbaseleagues" + }; + + return _gameData.QueryAsync(request); + } + + public Task GetBuilderBaseLeagueAsync(int? leagueId) + { + var request = new AutoValidatedRequest + { + LeagueId = leagueId, + Uri = $"/builderbaseleagues/{leagueId}" + }; + + return _gameData.RequestAsync(request); + } } } diff --git a/src/ClashOfClans/Api/Locations.cs b/src/ClashOfClans/Api/Locations.cs index 928e094b..42b0589d 100644 --- a/src/ClashOfClans/Api/Locations.cs +++ b/src/ClashOfClans/Api/Locations.cs @@ -95,5 +95,29 @@ public Task> GetClanCapitalRankingAsync(int? return _gameData.QueryAsync(request); } + + public Task> GetPlayerBuilderBaseRankingAsync(int? locationId, Query? query = default) + { + var request = new AutoValidatedRequest + { + Query = query, + LocationId = locationId, + Uri = $"/locations/{locationId}/rankings/players-versus" + }; + + return _gameData.QueryAsync(request); + } + + public Task> GetClanBuilderBaseRankingAsync(int? locationId, Query? query = default) + { + var request = new AutoValidatedRequest + { + Query = query, + LocationId = locationId, + Uri = $"/locations/{locationId}/rankings/clans-builder-base" + }; + + return _gameData.QueryAsync(request); + } } } diff --git a/src/ClashOfClans/ILeagues.cs b/src/ClashOfClans/ILeagues.cs index d43fc7de..6f634916 100644 --- a/src/ClashOfClans/ILeagues.cs +++ b/src/ClashOfClans/ILeagues.cs @@ -83,5 +83,23 @@ public interface ILeagues /// Argument is invalid /// Requested capital league Task GetCapitalLeagueAsync(int? leagueId); + + /// + /// List Builder Base leagues + /// + /// Optional query parameters + /// Communication error with the backend API + /// Argument is invalid + /// Builder Base league list + Task> GetBuilderBaseLeaguesAsync(Query? query = default); + + /// + /// Get Builder Base league information + /// + /// Identifier of the league + /// Communication error with the backend API + /// Argument is invalid + /// Requested builder base league + Task GetBuilderBaseLeagueAsync(int? leagueId); } } diff --git a/src/ClashOfClans/ILocations.cs b/src/ClashOfClans/ILocations.cs index 56fc30f3..6309299f 100644 --- a/src/ClashOfClans/ILocations.cs +++ b/src/ClashOfClans/ILocations.cs @@ -76,5 +76,25 @@ public interface ILocations /// Argument is invalid /// Clan capital ranking list Task> GetClanCapitalRankingAsync(int? locationId, Query? query = default); + + /// + /// Get player Builder Base rankings for a specific location + /// + /// Identifier of the location to retrieve + /// Optional query parameters + /// Communication error with the backend API + /// Argument is invalid + /// Player builder base ranking list + Task> GetPlayerBuilderBaseRankingAsync(int? locationId, Query? query = default); + + /// + /// Get clan Builder Base rankings for a specific location + /// + /// Identifier of the location to retrieve + /// Optional query parameters + /// Communication error with the backend API + /// Argument is invalid + /// Clan builder base ranking list + Task> GetClanBuilderBaseRankingAsync(int? locationId, Query? query = default); } }