diff --git a/RiotSharp.Test/CommonTestBase.cs b/RiotSharp.Test/CommonTestBase.cs
index 1a2ea03c..090f8c82 100644
--- a/RiotSharp.Test/CommonTestBase.cs
+++ b/RiotSharp.Test/CommonTestBase.cs
@@ -31,6 +31,8 @@ public class CommonTestBase
public static string Summoner3Name = "xsunx";
public static Region Summoner3Region = (Region)Enum.Parse(typeof(Region), "Ru");
+ public static Region TftSummonerRegion = (Region)Enum.Parse(typeof(Region), "Americas");
+
///
/// Ensures that test returns data (Shows test warnings for 404 status exceptions)
///
diff --git a/RiotSharp.Test/RiotApiTest.cs b/RiotSharp.Test/RiotApiTest.cs
index ffb1a212..f88e2eb2 100644
--- a/RiotSharp.Test/RiotApiTest.cs
+++ b/RiotSharp.Test/RiotApiTest.cs
@@ -158,6 +158,7 @@ public void GetChallengerLeagueAsync_Test()
});
}
+
[TestMethod]
[TestCategory("RiotApi"), TestCategory("Async")]
public void GetMasterLeagueAsync_Test()
@@ -169,6 +170,7 @@ public void GetMasterLeagueAsync_Test()
Assert.IsTrue(league.Result.Entries.Count > 0);
});
}
+
#endregion
#region Match Tests
@@ -348,6 +350,7 @@ public void GetMatchListAsync_Index_Test()
Assert.IsTrue(matches.Count <= endIndex - beginIndex);
});
}
+
#endregion
#region Spectator Tests
@@ -476,5 +479,110 @@ public void GetThirdPartyCodeAsync_Test()
}, "Third party code was not found for the summoner. (404)");
}
#endregion
+
+ #region TFT Summoner Tests
+
+ [TestMethod]
+ [TestCategory("RiotApi"), TestCategory("Async")]
+ public void GetTftSummonerBySummonerIdAsync_ExistingId_ReturnsSummoner()
+ {
+ EnsureCredibility(() =>
+ {
+ var summoner = Api.TftSummoner.GetTftSummonerBySummonerIdAsync(Summoner1And2Region,
+ Summoner1Id);
+
+ Assert.AreEqual(Summoner1Name, summoner.Result.Name);
+ });
+ }
+
+ [TestMethod]
+ [TestCategory("RiotApi"), TestCategory("Async")]
+ public void GetTftSummonerByPuuidAsync_ExistingId_ReturnsSummoner()
+ {
+ EnsureCredibility(() =>
+ {
+ var summoner = Api.TftSummoner.GetTftSummonerByPuuidAsync(Summoner1And2Region,
+ Summoner1Puuid);
+
+ Assert.AreEqual(Summoner1Name, summoner.Result.Name);
+ });
+ }
+
+ [TestMethod]
+ [TestCategory("RiotApi"), TestCategory("Async")]
+ public void GetTftSummonerByNameAsync_ExistingName_ReturnsSummoner()
+ {
+ EnsureCredibility(() =>
+ {
+ var summoner = Api.TftSummoner.GetTftSummonerByNameAsync(Summoner1And2Region,
+ Summoner1Name);
+
+ Assert.AreEqual(Summoner1Id, summoner.Result.Id);
+ });
+ }
+
+ [TestMethod]
+ [TestCategory("RiotApi"), TestCategory("Async")]
+ public void GetTftSummonerByAccountIdAsync_ExistingAccountId_ReturnsSummoner()
+ {
+ EnsureCredibility(() =>
+ {
+ var summoner = Api.TftSummoner.GetTftSummonerByAccountIdAsync(Summoner1And2Region,
+ Summoner1AccountId);
+
+ Assert.AreEqual(Summoner1Name, summoner.Result.Name);
+ });
+ }
+ #endregion
+
+ #region TFT League Tests
+
+ [TestMethod]
+ [TestCategory("RiotApi"), TestCategory("Async")]
+ public void GetTftLeagueByTierDivisionAsync_Test()
+ {
+ EnsureCredibility(() =>
+ {
+ var league = Api.TftLeague.GetTftLeagueByTierDivisionAsync(Summoner1And2Region,
+ Endpoints.LeagueEndpoint.Enums.Tier.Bronze,
+ Endpoints.LeagueEndpoint.Enums.Division.I);
+
+ Assert.IsTrue(league.Result.Count > 0);
+ });
+ }
+
+ [TestMethod]
+ [TestCategory("RiotApi"), TestCategory("Async")]
+ public void GetTftGrandmasterLeagueAsync_Test()
+ {
+ EnsureCredibility(() =>
+ {
+ var league = Api.TftLeague.GetTftGrandmasterLeagueAsync(Summoner1And2Region);
+ Assert.IsTrue(league.Result.Entries.Count > 0);
+ });
+ }
+
+ [TestMethod]
+ [TestCategory("RiotApi"), TestCategory("Async")]
+ public void GetTftChallengerLeagueAsync_Test()
+ {
+ EnsureCredibility(() =>
+ {
+ var league = Api.TftLeague.GetTftChallengerLeagueAsync(Summoner1And2Region);
+ Assert.IsTrue(league.Result.Entries.Count > 0);
+ });
+ }
+
+ [TestMethod]
+ [TestCategory("RiotApi"), TestCategory("Async")]
+ public void GetTftMasterLeagueAsync_Test()
+ {
+ EnsureCredibility(() =>
+ {
+ var league = Api.TftLeague.GetTftMasterLeagueAsync(Summoner1And2Region);
+ Assert.IsTrue(league.Result.Entries.Count > 0);
+ });
+ }
+ #endregion
}
}
diff --git a/RiotSharp/Endpoints/Interfaces/ITftLeagueEndpoint.cs b/RiotSharp/Endpoints/Interfaces/ITftLeagueEndpoint.cs
new file mode 100644
index 00000000..a9411a5a
--- /dev/null
+++ b/RiotSharp/Endpoints/Interfaces/ITftLeagueEndpoint.cs
@@ -0,0 +1,59 @@
+using RiotSharp.Endpoints.LeagueEndpoint;
+using RiotSharp.Endpoints.TftLeagueEndpoint;
+using RiotSharp.Misc;
+using System;
+using System.Collections.Generic;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace RiotSharp.Endpoints.Interfaces
+{
+ public interface ITftLeagueEndpoint
+ {
+ ///
+ /// Get the TFT grandmaster league
+ ///
+ /// Participants server region
+ /// class
+ Task GetTftGrandmasterLeagueAsync(Region region);
+
+ ///
+ /// Get the TFT challenger league
+ ///
+ /// Participants server region
+ /// class
+ Task GetTftChallengerLeagueAsync(Region region);
+
+ ///
+ /// Get the TFT master league
+ ///
+ /// Participants server region
+ /// class
+ Task GetTftMasterLeagueAsync(Region region);
+
+ ///
+ /// Gets a list of TFT league entries
+ ///
+ /// Summoners server region
+ /// Summoners encrypted id
+ /// List of class
+ Task> GetTftLeagueEntriesBySummonerAsync(Region region, string encryptedSummonerId);
+
+ ///
+ /// Gets a list of league entries for a given tier/division
+ ///
+ /// Participants server region
+ /// Tier to get league entries from
+ /// Tier division to get league entries from
+ /// List of class
+ Task> GetTftLeagueByTierDivisionAsync(Region region, LeagueEndpoint.Enums.Tier tier, LeagueEndpoint.Enums.Division division);
+
+ ///
+ /// Gets the TFT league by league uuid
+ ///
+ /// Participants server region
+ /// UUID of the league
+ /// object/returns>
+ Task GetTftLeagueByIdAsync(Region region, string leagueId);
+ }
+}
diff --git a/RiotSharp/Endpoints/Interfaces/ITftMatchEndpoint.cs b/RiotSharp/Endpoints/Interfaces/ITftMatchEndpoint.cs
new file mode 100644
index 00000000..ac51ba22
--- /dev/null
+++ b/RiotSharp/Endpoints/Interfaces/ITftMatchEndpoint.cs
@@ -0,0 +1,28 @@
+using RiotSharp.Endpoints.TftMatchEndpoint;
+using RiotSharp.Misc;
+using System;
+using System.Collections.Generic;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace RiotSharp.Endpoints.Interfaces
+{
+ public interface ITftMatchEndpoint
+ {
+ ///
+ /// Gets a list of match ids by puuid
+ ///
+ /// Region in which the summoner is.
+ ///
+ /// A list of strings
+ Task> GetTftMatchIdsByPuuidAsync(Region region, string puuid, int count = 20);
+
+ ///
+ /// Get a match by id
+ ///
+ /// Region in which the summoner is.
+ /// The match id for the match wanting to be retrieved
+ /// object
+ Task GetTftMatchByIdAsync(Region region, string matchId);
+ }
+}
diff --git a/RiotSharp/Endpoints/Interfaces/ITftSummonerEndpoint.cs b/RiotSharp/Endpoints/Interfaces/ITftSummonerEndpoint.cs
new file mode 100644
index 00000000..bf446926
--- /dev/null
+++ b/RiotSharp/Endpoints/Interfaces/ITftSummonerEndpoint.cs
@@ -0,0 +1,47 @@
+using RiotSharp.Endpoints.TftSummonerEndpoint;
+using RiotSharp.Misc;
+using System;
+using System.Collections.Generic;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace RiotSharp.Endpoints.Interfaces
+{
+ ///
+ /// Tft Summoner Endpoint.
+ ///
+ public interface ITftSummonerEndpoint
+ {
+ ///
+ /// Get a Teamfight Tactics summoner by account id asynchronously.
+ ///
+ /// Region in which you wish to look for a summoner.
+ /// Account id of the summoner you're looking for.
+ /// A summoner.
+ Task GetTftSummonerByAccountIdAsync(Region region, string accountId);
+
+ ///
+ /// Get a Teamfight Tactics summoner by name asynchronously.
+ ///
+ /// Region in which you wish to look for a summoner.
+ /// Name of the summoner you're looking for.
+ /// A summoner.
+ Task GetTftSummonerByNameAsync(Region region, string summonerName);
+
+ ///
+ /// Get a Teamfight Tactics summoner by puuid asynchronously.
+ ///
+ /// Region in which you wish to look for a summoner.
+ /// PUUID of the summoner you're looking for.
+ /// A summoner.
+ Task GetTftSummonerByPuuidAsync(Region region, string summonerName);
+
+ ///
+ /// Get a Teamfight Tactics summoner by summoner id asynchronously.
+ ///
+ /// Region in which you wish to look for a summoner.
+ /// Id of the summoner you're looking for.
+ /// A summoner.
+ Task GetTftSummonerBySummonerIdAsync(Region region, string summonerId);
+ }
+}
diff --git a/RiotSharp/Endpoints/LeagueEndpoint/LeagueEndpoint.cs b/RiotSharp/Endpoints/LeagueEndpoint/LeagueEndpoint.cs
index 02daf8a6..cdfd5774 100644
--- a/RiotSharp/Endpoints/LeagueEndpoint/LeagueEndpoint.cs
+++ b/RiotSharp/Endpoints/LeagueEndpoint/LeagueEndpoint.cs
@@ -36,6 +36,7 @@ public async Task GetChallengerLeagueAsync(Region region, string queue)
{
var json = await _requester.CreateGetRequestAsync(LeagueRootUrl + string.Format(LeagueChallengerUrl, queue),
region).ConfigureAwait(false);
+
return JsonConvert.DeserializeObject(json);
}
@@ -44,6 +45,7 @@ public async Task GetMasterLeagueAsync(Region region, string queue)
{
var json = await _requester.CreateGetRequestAsync(LeagueRootUrl + string.Format(LeagueMasterUrl, queue),
region).ConfigureAwait(false);
+
return JsonConvert.DeserializeObject(json);
}
@@ -84,5 +86,6 @@ public async Task GetLeagueByIdAsync(Region region, string leagueId)
return JsonConvert.DeserializeObject(json);
}
+
}
}
diff --git a/RiotSharp/Endpoints/MatchEndpoint/MatchEndpoint.cs b/RiotSharp/Endpoints/MatchEndpoint/MatchEndpoint.cs
index 3bd16e33..044b093e 100644
--- a/RiotSharp/Endpoints/MatchEndpoint/MatchEndpoint.cs
+++ b/RiotSharp/Endpoints/MatchEndpoint/MatchEndpoint.cs
@@ -21,6 +21,7 @@ public class MatchEndpoint : IMatchEndpoint
private const string MatchListByAccountIdUrl = "/by-account/{0}";
private const string TimelineByMatchIdUrl = "/by-match/{0}";
private const string MatchCache = "match-{0}_{1}";
+
private const string MatchTimeLineCacheKey = "match-timeline-{0}_{1}";
private static readonly TimeSpan MatchTtl = TimeSpan.FromDays(60);
@@ -33,6 +34,7 @@ public MatchEndpoint(IRateLimitedRequester requester, ICache cache)
_cache = cache;
}
+ ///
public async Task> GetMatchIdsByTournamentCodeAsync(Region region, string tournamentCode)
{
var json = await _requester.CreateGetRequestAsync(MatchRootUrl +
@@ -42,6 +44,7 @@ public async Task> GetMatchIdsByTournamentCodeAsync(Region region, st
return JsonConvert.DeserializeObject>(json);
}
+ ///
public async Task GetMatchAsync(Region region, long matchId)
{
var matchInCache = _cache.Get(string.Format(MatchCache, region, matchId));
@@ -56,6 +59,7 @@ public async Task GetMatchAsync(Region region, long matchId)
return match;
}
+ ///
public async Task GetMatchListAsync(Region region, string accountId, List championIds = null, List queues = null, List seasons = null,
DateTime? beginTime = null, DateTime? endTime = null, long? beginIndex = null, long? endIndex = null)
{
@@ -67,6 +71,7 @@ public async Task GetMatchListAsync(Region region, string accountId,
return JsonConvert.DeserializeObject(json);
}
+ ///
public async Task GetMatchTimelineAsync(Region region, long matchId)
{
var cacheKey = string.Format(MatchTimeLineCacheKey, region, matchId);
diff --git a/RiotSharp/Endpoints/TftLeagueEndpoint/TftLeague.cs b/RiotSharp/Endpoints/TftLeagueEndpoint/TftLeague.cs
new file mode 100644
index 00000000..4ab9400f
--- /dev/null
+++ b/RiotSharp/Endpoints/TftLeagueEndpoint/TftLeague.cs
@@ -0,0 +1,44 @@
+using Newtonsoft.Json;
+using RiotSharp.Endpoints.LeagueEndpoint.Enums;
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace RiotSharp.Endpoints.TftLeagueEndpoint
+{
+ public class TftLeague
+ {
+ internal TftLeague() { }
+
+ ///
+ /// The requested tft league entries.
+ ///
+ [JsonProperty("entries")]
+ public List Entries { get; set; }
+
+ ///
+ /// This name is an internal place-holder name only.
+ /// Display and localization of names in the game client are handled client-side.
+ ///
+ [JsonProperty("name")]
+ public string Name { get; set; }
+
+ ///
+ /// The tft league id.
+ ///
+ [JsonProperty("leagueId")]
+ public string LeagueId { get; set; }
+
+ ///
+ /// Tft league queue (eg: RankedSolo5x5).
+ ///
+ [JsonProperty("queue")]
+ public string Queue { get; set; }
+
+ ///
+ /// Tft League tier (eg: Challenger).
+ ///
+ [JsonProperty("tier")]
+ public Tier Tier { get; set; }
+ }
+}
diff --git a/RiotSharp/Endpoints/TftLeagueEndpoint/TftLeagueEndpoint.cs b/RiotSharp/Endpoints/TftLeagueEndpoint/TftLeagueEndpoint.cs
new file mode 100644
index 00000000..e8ab8c9a
--- /dev/null
+++ b/RiotSharp/Endpoints/TftLeagueEndpoint/TftLeagueEndpoint.cs
@@ -0,0 +1,79 @@
+using Newtonsoft.Json;
+using RiotSharp.Endpoints.Interfaces;
+using RiotSharp.Http.Interfaces;
+using RiotSharp.Misc;
+using System.Collections.Generic;
+using System.Threading.Tasks;
+
+namespace RiotSharp.Endpoints.TftLeagueEndpoint
+{
+ public class TftLeagueEndpoint : ITftLeagueEndpoint
+ {
+ private const string TftLeagueRootUrl = "/tft/league/v1";
+ private const string TftGrandmasterLeague = "/grandmaster";
+ private const string TftChallengerLeague = "/challenger";
+ private const string TftMasterLeague = "/master";
+ private const string TftLeagueEntriesBySummoner = "/entries/by-summoner/{0}";
+ private const string TftLeagueEntriesByTierDivision = "/{0}/{1}";
+ private const string TftLeagueEntriesByLeagueId = "/leagues/{0}";
+ private readonly IRateLimitedRequester _requester;
+
+ public TftLeagueEndpoint(IRateLimitedRequester requester)
+ {
+ _requester = requester;
+ }
+
+ ///
+ public async Task GetTftGrandmasterLeagueAsync(Region region)
+ {
+ var json = await _requester.CreateGetRequestAsync(
+ TftLeagueRootUrl + TftGrandmasterLeague, region).ConfigureAwait(false);
+
+ return JsonConvert.DeserializeObject(json);
+ }
+
+ ///
+ public async Task GetTftChallengerLeagueAsync(Region region)
+ {
+ var json = await _requester.CreateGetRequestAsync(
+ TftLeagueRootUrl + TftChallengerLeague, region).ConfigureAwait(false);
+
+ return JsonConvert.DeserializeObject(json);
+ }
+
+ ///
+ public async Task GetTftMasterLeagueAsync(Region region)
+ {
+ var json = await _requester.CreateGetRequestAsync(
+ TftLeagueRootUrl + TftMasterLeague, region).ConfigureAwait(false);
+
+ return JsonConvert.DeserializeObject(json);
+ }
+
+ ///
+ public async Task> GetTftLeagueEntriesBySummonerAsync(Region region, string encryptedSummonerId)
+ {
+ var json = await _requester.CreateGetRequestAsync(
+ TftLeagueRootUrl + string.Format(TftLeagueEntriesBySummoner, encryptedSummonerId), region).ConfigureAwait(false);
+
+ return JsonConvert.DeserializeObject>(json);
+ }
+
+ ///
+ public async Task GetTftLeagueByIdAsync(Region region, string leagueId)
+ {
+ var json = await _requester.CreateGetRequestAsync(
+ TftLeagueRootUrl + string.Format(TftLeagueEntriesByLeagueId, leagueId), region).ConfigureAwait(false);
+ return JsonConvert.DeserializeObject(json);
+ }
+
+ ///
+ public async Task> GetTftLeagueByTierDivisionAsync(Region region, LeagueEndpoint.Enums.Tier tier,
+ LeagueEndpoint.Enums.Division division)
+ {
+ var json = await _requester.CreateGetRequestAsync(
+ string.Format(TftLeagueRootUrl + TftLeagueEntriesByTierDivision, tier, division), region).ConfigureAwait(false);
+ return JsonConvert.DeserializeObject>(json);
+ }
+ }
+}
diff --git a/RiotSharp/Endpoints/TftLeagueEndpoint/TftLeagueEntry.cs b/RiotSharp/Endpoints/TftLeagueEndpoint/TftLeagueEntry.cs
new file mode 100644
index 00000000..9667c60a
--- /dev/null
+++ b/RiotSharp/Endpoints/TftLeagueEndpoint/TftLeagueEntry.cs
@@ -0,0 +1,30 @@
+using Newtonsoft.Json;
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace RiotSharp.Endpoints.TftLeagueEndpoint
+{
+ public class TftLeagueEntry : TftLeagueItem
+ {
+ internal TftLeagueEntry() { }
+
+ ///
+ /// The Id of the league of the participant.
+ ///
+ [JsonProperty("leagueId")]
+ public string LeagueId { get; set; }
+
+ ///
+ /// The queue type of the league.
+ ///
+ [JsonProperty("queueType")]
+ public string QueueType { get; set; }
+
+ ///
+ /// The league tier of the participant.
+ ///
+ [JsonProperty("tier")]
+ public string Tier { get; set; }
+ }
+}
diff --git a/RiotSharp/Endpoints/TftLeagueEndpoint/TftLeagueItem.cs b/RiotSharp/Endpoints/TftLeagueEndpoint/TftLeagueItem.cs
new file mode 100644
index 00000000..b4edb6d4
--- /dev/null
+++ b/RiotSharp/Endpoints/TftLeagueEndpoint/TftLeagueItem.cs
@@ -0,0 +1,78 @@
+using Newtonsoft.Json;
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace RiotSharp.Endpoints.TftLeagueEndpoint
+{
+ public class TftLeagueItem
+ {
+ internal TftLeagueItem() { }
+
+ ///
+ /// The rank of the participant in a league.
+ ///
+ [JsonProperty("rank")]
+ public string Rank { get; set; }
+
+ ///
+ /// Specifies if the participant is fresh blood.
+ ///
+ [JsonProperty("freshBlood")]
+ public bool FreshBlood { get; set; }
+
+ ///
+ /// Specifies if the participant is on a hot streak.
+ ///
+ [JsonProperty("hotStreak")]
+ public bool HotStreak { get; set; }
+
+ ///
+ /// Specifies if the participant is inactive.
+ ///
+ [JsonProperty("inactive")]
+ public bool Inactive { get; set; }
+
+ ///
+ /// Specifies if the participant is a veteran.
+ ///
+ [JsonProperty("veteran")]
+ public bool Veteran { get; set; }
+
+ ///
+ /// The league points of the participant.
+ ///
+ [JsonProperty("leaguePoints")]
+ public int LeaguePoints { get; set; }
+
+ ///
+ /// The number of losses for the participant.
+ ///
+ [JsonProperty("losses")]
+ public int Losses { get; set; }
+
+ ///
+ /// Mini series data for the participant. Only present if the participant is currently in a mini series.
+ ///
+ [JsonProperty("miniSeries")]
+ public TftMiniSeries MiniSeries { get; set; }
+
+ ///
+ /// The name of the the summoner represented by this entry.
+ ///
+ [JsonProperty("summonerName")]
+ public string SummonerName { get; set; }
+
+ ///
+ /// The encrypted id of the the summoner represented by this entry.
+ ///
+ [JsonProperty("summonerId")]
+ public string SummonerId { get; set; }
+
+ ///
+ /// The number of wins for the participant.
+ ///
+ [JsonProperty("wins")]
+ public int Wins { get; set; }
+ }
+}
diff --git a/RiotSharp/Endpoints/TftLeagueEndpoint/TftMiniSeries.cs b/RiotSharp/Endpoints/TftLeagueEndpoint/TftMiniSeries.cs
new file mode 100644
index 00000000..88a92317
--- /dev/null
+++ b/RiotSharp/Endpoints/TftLeagueEndpoint/TftMiniSeries.cs
@@ -0,0 +1,36 @@
+using Newtonsoft.Json;
+using RiotSharp.Endpoints.LeagueEndpoint.Enums.Converters;
+
+namespace RiotSharp.Endpoints.TftLeagueEndpoint
+{
+ public class TftMiniSeries
+ {
+ internal TftMiniSeries() { }
+
+ ///
+ /// Number of current losses in the mini series.
+ ///
+ [JsonProperty("losses")]
+ public int Losses { get; set; }
+
+ ///
+ /// String showing the current, sequential mini series progress where 'W' represents a win, 'L' represents a
+ /// loss, and 'N' represents a game that hasn't been played yet.
+ ///
+ [JsonProperty("progress")]
+ [JsonConverter(typeof(CharArrayConverter))]
+ public char[] Progress { get; set; }
+
+ ///
+ /// Number of wins required for promotion.
+ ///
+ [JsonProperty("target")]
+ public int Target { get; set; }
+
+ ///
+ /// Number of current wins in the mini series.
+ ///
+ [JsonProperty("wins")]
+ public int Wins { get; set; }
+ }
+}
diff --git a/RiotSharp/Endpoints/TftMatchEndpoint/TftMatch.cs b/RiotSharp/Endpoints/TftMatchEndpoint/TftMatch.cs
new file mode 100644
index 00000000..7f9dad5d
--- /dev/null
+++ b/RiotSharp/Endpoints/TftMatchEndpoint/TftMatch.cs
@@ -0,0 +1,88 @@
+using Newtonsoft.Json;
+using RiotSharp.Endpoints.MatchEndpoint;
+using RiotSharp.Misc.Converters;
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace RiotSharp.Endpoints.TftMatchEndpoint
+{
+ public class TftMatch
+ {
+ internal TftMatch() { }
+
+ ///
+ /// The season ID.
+ ///
+ [JsonProperty("seasonId")]
+ public int SeasonId { get; set; }
+
+ ///
+ /// Specifies the Queue ID.
+ ///
+ [JsonProperty("queueId")]
+ public int QueueId { get; set; }
+
+ ///
+ /// Equivalent to match id
+ ///
+ [JsonProperty("gameId")]
+ public long GameId { get; set; }
+
+ ///
+ /// The participants identities.
+ ///
+ [JsonProperty("participantIdentities")]
+ public List ParticipantIdentities { get; set; }
+
+ ///
+ /// The game version.
+ ///
+ [JsonProperty("gameVersion")]
+ public string GameVersion { get; set; }
+
+ ///
+ /// The game mode.
+ ///
+ [JsonProperty("gameMode")]
+ public string GameMode { get; set; }
+
+ ///
+ /// The map ID.
+ ///
+ [JsonProperty("mapId")]
+ public int MapId { get; set; }
+
+ ///
+ /// The game type.
+ ///
+ [JsonProperty("gameType")]
+ public string GameType { get; set; }
+
+ ///
+ /// The teams.
+ ///
+ [JsonProperty("teams")]
+ public List Teams { get; set; }
+
+ ///
+ /// The participants.
+ ///
+ [JsonProperty("participants")]
+ public List Participants { get; set; }
+
+ ///
+ /// The game duration.
+ ///
+ [JsonProperty("gameDuration")]
+ [JsonConverter(typeof(TimeSpanConverterFromSeconds))]
+ public TimeSpan GameDuration { get; set; }
+
+ ///
+ /// The date time of the game creation.
+ ///
+ [JsonProperty("gameCreation")]
+ [JsonConverter(typeof(DateTimeConverterFromLong))]
+ public DateTime GameCreation { get; set; }
+ }
+}
diff --git a/RiotSharp/Endpoints/TftMatchEndpoint/TftMatchEndpoint.cs b/RiotSharp/Endpoints/TftMatchEndpoint/TftMatchEndpoint.cs
new file mode 100644
index 00000000..d012383a
--- /dev/null
+++ b/RiotSharp/Endpoints/TftMatchEndpoint/TftMatchEndpoint.cs
@@ -0,0 +1,65 @@
+using Newtonsoft.Json;
+using RiotSharp.Caching;
+using RiotSharp.Endpoints.Interfaces;
+using RiotSharp.Endpoints.TftMatchEndpoint;
+using RiotSharp.Http.Interfaces;
+using RiotSharp.Misc;
+using System;
+using System.Collections.Generic;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace RiotSharp.TftMatchEndpoint
+{
+ public class TftMatchEndpoint : ITftMatchEndpoint
+ {
+ private const string TftMatchRootUrl = "/tft/match/v1/matches";
+ private const string TftMatchByPuuidUrl = "/by-puuid/{0}/ids?count={1}";
+ private const string TftMatchCache = "tft-match-{0}_{1}";
+ private const string TftMatchByIdUrl = "/{0}";
+ private static readonly TimeSpan TftMatchTtl = TimeSpan.FromDays(60);
+
+ private readonly ICache _cache;
+ private readonly IRateLimitedRequester _requester;
+
+ public TftMatchEndpoint(IRateLimitedRequester requester, ICache cache)
+ {
+ _requester = requester;
+ _cache = cache;
+ }
+
+ ///
+ public async Task> GetTftMatchIdsByPuuidAsync(Region region, string puuid, int count = 20)
+ {
+ var json = await _requester.CreateGetRequestAsync(
+ string.Format(TftMatchRootUrl + TftMatchByPuuidUrl, puuid, count), region).ConfigureAwait(false);
+
+ return JsonConvert.DeserializeObject>(json);
+ }
+
+ ///
+ public async Task GetTftMatchByIdAsync(Region region, string matchId)
+ {
+ var cacheKey = string.Format(TftMatchCache, region, matchId);
+ var match = _cache.Get(cacheKey);
+
+ if (match != null)
+ {
+ return match;
+ }
+
+ var json = await _requester.CreateGetRequestAsync(
+ string.Format(TftMatchRootUrl + TftMatchByIdUrl, matchId), region).ConfigureAwait(false);
+
+ match = JsonConvert.DeserializeObject(json);
+
+ if (match != null)
+ {
+ _cache.Add(cacheKey, match, TftMatchTtl);
+ }
+
+ return match;
+
+ }
+ }
+}
diff --git a/RiotSharp/Endpoints/TftSummonerEndpoint/TftSummoner.cs b/RiotSharp/Endpoints/TftSummonerEndpoint/TftSummoner.cs
new file mode 100644
index 00000000..a25f36c8
--- /dev/null
+++ b/RiotSharp/Endpoints/TftSummonerEndpoint/TftSummoner.cs
@@ -0,0 +1,67 @@
+using Newtonsoft.Json;
+using RiotSharp.Misc;
+using RiotSharp.Misc.Converters;
+using System;
+
+namespace RiotSharp.Endpoints.TftSummonerEndpoint
+{
+ public class TftSummoner
+ {
+ ///
+ /// Defines the Region of a Summoner.
+ ///
+ public Region Region { get; set; }
+
+ internal TftSummoner() { }
+
+ internal TftSummoner(string id, string name, Region region)
+ {
+ Region = region;
+ Name = name;
+ Id = id;
+ }
+
+ ///
+ /// ID of the summoner icon associated with the summoner.
+ ///
+ [JsonProperty("profileIconId")]
+ public int ProfileIconId { get; set; }
+
+ ///
+ /// Date summoner was last modified.
+ ///
+ [JsonProperty("revisionDate")]
+ [JsonConverter(typeof(DateTimeConverterFromLong))]
+ public DateTime RevisionDate { get; set; }
+
+ ///
+ /// Summoner level associated with the summoner.
+ ///
+ [JsonProperty("summonerLevel")]
+ public long Level { get; set; }
+
+ ///
+ /// Encrypted summoner ID. Max length 63 characters.
+ ///
+ [JsonProperty("id")]
+ public string Id { get; set; }
+
+ ///
+ /// Encrypted account ID. Max length 56 characters.
+ ///
+ [JsonProperty("accountId")]
+ public string AccountId { get; set; }
+
+ ///
+ /// Summoner name.
+ ///
+ [JsonProperty("name")]
+ public string Name { get; set; }
+
+ ///
+ /// Encrypted PUUID. Exact length of 78 characters.
+ ///
+ [JsonProperty("puuid")]
+ public string Puuid { get; set; }
+ }
+}
diff --git a/RiotSharp/Endpoints/TftSummonerEndpoint/TftSummonerEndpoint.cs b/RiotSharp/Endpoints/TftSummonerEndpoint/TftSummonerEndpoint.cs
new file mode 100644
index 00000000..4bc7c81c
--- /dev/null
+++ b/RiotSharp/Endpoints/TftSummonerEndpoint/TftSummonerEndpoint.cs
@@ -0,0 +1,119 @@
+using Newtonsoft.Json;
+using RiotSharp.Caching;
+using RiotSharp.Endpoints.Interfaces;
+using RiotSharp.Http.Interfaces;
+using RiotSharp.Misc;
+using System;
+using System.Collections.Generic;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace RiotSharp.Endpoints.TftSummonerEndpoint
+{
+ class TftSummonerEndpoint : ITftSummonerEndpoint
+ {
+ private const string TftSummonerRootUrl = "/tft/summoner/v1/summoners";
+ private const string TftSummonerByAccountIdUrl = "/by-account/{0}";
+ private const string TftSummonerBySummonerIdUrl = "/{0}";
+ private const string TftSummonerByNameUrl = "/by-name/{0}";
+ private const string TftSummonerByPuuid = "/by-puuid/{0}";
+ private const string TftSummonerCache = "tft-summoner-{0}_{1}";
+ private static readonly TimeSpan TftSummonerTtl = TimeSpan.FromDays(30);
+
+ private readonly IRateLimitedRequester _requester;
+ private readonly ICache _cache;
+ public TftSummonerEndpoint(IRateLimitedRequester requester, ICache cache)
+ {
+ _requester = requester;
+ _cache = cache;
+ }
+
+ ///
+ public async Task GetTftSummonerByAccountIdAsync(Region region, string accountId)
+ {
+ var summonerInCache = _cache.Get(string.Format(TftSummonerCache, region, accountId));
+ if (summonerInCache != null)
+ {
+ return summonerInCache;
+ }
+
+ var jsonResponse = await _requester.CreateGetRequestAsync(
+ string.Format(TftSummonerRootUrl + TftSummonerByAccountIdUrl, accountId), region).ConfigureAwait(false);
+ var summoner = JsonConvert.DeserializeObject(jsonResponse);
+
+ if (summoner != null)
+ {
+ summoner.Region = region;
+ }
+
+ _cache.Add(string.Format(TftSummonerCache, region, accountId), summoner, TftSummonerTtl);
+ return summoner;
+ }
+
+ ///
+ public async Task GetTftSummonerByNameAsync(Region region, string summonerName)
+ {
+ var summonerInCache = _cache.Get(string.Format(TftSummonerCache, region, summonerName));
+ if (summonerInCache != null)
+ {
+ return summonerInCache;
+ }
+
+ var jsonResponse = await _requester.CreateGetRequestAsync(
+ string.Format(TftSummonerRootUrl + TftSummonerByNameUrl, summonerName), region).ConfigureAwait(false);
+
+ var summoner = JsonConvert.DeserializeObject(jsonResponse);
+
+ if (summoner != null)
+ {
+ summoner.Region = region;
+ }
+ _cache.Add(string.Format(TftSummonerCache, region, summonerName), summoner, TftSummonerTtl);
+ return summoner;
+ }
+
+ ///
+ public async Task GetTftSummonerByPuuidAsync(Region region, string puuid)
+ {
+ var summonerInCache = _cache.Get(string.Format(TftSummonerCache, region, puuid));
+ if (summonerInCache != null)
+ {
+ return summonerInCache;
+ }
+
+ var jsonResponse = await _requester.CreateGetRequestAsync(
+ string.Format(TftSummonerRootUrl + TftSummonerByPuuid, puuid), region).ConfigureAwait(false);
+
+ var summoner = JsonConvert.DeserializeObject(jsonResponse);
+
+ if (summoner != null)
+ {
+ summoner.Region = region;
+ }
+ _cache.Add(string.Format(TftSummonerCache, region, puuid), summoner, TftSummonerTtl);
+ return summoner;
+ }
+
+ ///
+ public async Task GetTftSummonerBySummonerIdAsync(Region region, string summonerId)
+ {
+ var summonerInCache = _cache.Get(string.Format(TftSummonerCache, region, summonerId));
+ if (summonerInCache != null)
+ {
+ return summonerInCache;
+ }
+
+ var jsonResponse = await _requester.CreateGetRequestAsync(
+ string.Format(TftSummonerRootUrl + TftSummonerBySummonerIdUrl, summonerId), region).ConfigureAwait(false);
+
+ var summoner = JsonConvert.DeserializeObject(jsonResponse);
+
+ if (summoner != null)
+ {
+ summoner.Region = region;
+ }
+ _cache.Add(string.Format(TftSummonerCache, region, summonerId), summoner, TftSummonerTtl);
+ return summoner;
+ }
+ }
+}
diff --git a/RiotSharp/RiotApi.cs b/RiotSharp/RiotApi.cs
index 397bf56c..ba68608c 100644
--- a/RiotSharp/RiotApi.cs
+++ b/RiotSharp/RiotApi.cs
@@ -58,6 +58,15 @@ public class RiotApi : IRiotApi
///
public IStatusEndpoint Status { get; }
+
+ ///
+ public ITftLeagueEndpoint TftLeague { get; }
+
+ ///
+ public ITftMatchEndpoint TftMatch { get; }
+
+ ///
+ public ITftSummonerEndpoint TftSummoner { get; }
#endregion
///