diff --git a/UnofficialArcaeaAPI.Lib/Core/UaaAssetsApi.cs b/UnofficialArcaeaAPI.Lib/Core/UaaAssetsApi.cs index 455eb41..ec07a93 100644 --- a/UnofficialArcaeaAPI.Lib/Core/UaaAssetsApi.cs +++ b/UnofficialArcaeaAPI.Lib/Core/UaaAssetsApi.cs @@ -15,17 +15,6 @@ internal UaaAssetsApi(HttpClient client) _client = client; } - private static async Task EnsureSuccess(HttpResponseMessage resp) - { - if (resp.StatusCode != HttpStatusCode.OK) - { - var errJson = JsonSerializer.Deserialize(await resp.Content.ReadAsStringAsync())!; - throw new UaaRequestException(errJson.Status, errJson.Message!); - } - - return await resp.Content.ReadAsByteArrayAsync(); - } - #region /assets/icon private async Task GetIconAsyncCore(int partner, bool awakened) @@ -34,7 +23,7 @@ private async Task GetIconAsyncCore(int partner, bool awakened) .Add("partner", partner.ToString()) .Add("awakened", awakened.ToString()); var resp = await _client.GetAsync("assets/icon" + qb.Build()); - return await EnsureSuccess(resp); + return await resp.EnsureDataSuccess(); } /// @@ -56,7 +45,7 @@ private async Task GetCharAsyncCore(int partner, bool awakened) .Add("partner", partner.ToString()) .Add("awakened", awakened.ToString()); var resp = await _client.GetAsync("assets/char" + qb.Build()); - return await EnsureSuccess(resp); + return await resp.EnsureDataSuccess(); } /// @@ -88,7 +77,7 @@ private async Task GetSongAsyncCore(string songNameOrFileName, AuaSongQu qb.Add("difficulty", ((int)difficulty).ToString()); var resp = await _client.GetAsync("assets/song" + qb.Build()); - return await EnsureSuccess(resp); + return await resp.EnsureDataSuccess(); } /// @@ -172,7 +161,7 @@ private async Task GetPreviewAsyncCore(string songName, AuaSongQueryType qb.Add("difficulty", ((int)difficulty).ToString()); var resp = await _client.GetAsync("assets/preview" + qb.Build()); - return await EnsureSuccess(resp); + return await resp.EnsureDataSuccess(); } /// diff --git a/UnofficialArcaeaAPI.Lib/Core/UaaImageApi.cs b/UnofficialArcaeaAPI.Lib/Core/UaaImageApi.cs new file mode 100644 index 0000000..594625a --- /dev/null +++ b/UnofficialArcaeaAPI.Lib/Core/UaaImageApi.cs @@ -0,0 +1,11 @@ +namespace UnofficialArcaeaAPI.Lib.Core; + +public sealed class UaaImageApi +{ + public UaaImageUserApi User { get; } + + internal UaaImageApi(HttpClient client) + { + User = new UaaImageUserApi(client); + } +} \ No newline at end of file diff --git a/UnofficialArcaeaAPI.Lib/Core/UaaImageUserApi.cs b/UnofficialArcaeaAPI.Lib/Core/UaaImageUserApi.cs new file mode 100644 index 0000000..2e3aa6b --- /dev/null +++ b/UnofficialArcaeaAPI.Lib/Core/UaaImageUserApi.cs @@ -0,0 +1,177 @@ +using System.Text.Json; +using UnofficialArcaeaAPI.Lib.Models; +using UnofficialArcaeaAPI.Lib.Responses; +using UnofficialArcaeaAPI.Lib.Utils; + +namespace UnofficialArcaeaAPI.Lib.Core; + +public sealed class UaaImageUserApi +{ + private readonly HttpClient _client; + + internal UaaImageUserApi(HttpClient client) + { + _client = client; + } + + #region /user/info + + private async Task GetInfoAsyncCore(string? user, int? userCode, int recent, + AuaReplyWith replyWith) + { + var qb = new QueryBuilder() + .Add("recent", recent.ToString()); + + if (user is not null) + qb.Add("user_name", user); + else + qb.Add("user_code", userCode.ToString()!); + + if (replyWith.HasFlag(AuaReplyWith.SongInfo)) + qb.Add("with_song_info", "true"); + var resp = await _client.GetAsync("image/user/info" + qb.Build()); + return await resp.EnsureDataSuccess(); + } + + /// + /// Get user info image. + /// + /// User name or 9-digit user code + /// The number of recently played songs expected, range 0-7 + /// Additional information to reply with. Supports songinfo only. + /// User info image + public Task GetInfoAsync(string user, int recent = 0, + AuaReplyWith replyWith = AuaReplyWith.None) + => GetInfoAsyncCore(user, null, recent, replyWith); + + /// + /// Get user info image. + /// + /// 9-digit user code + /// The number of recently played songs expected, range 0-7 + /// Additional information to reply with. Supports songinfo only. + /// User info image + public Task GetInfoAsync(int userCode, int recent = 0, + AuaReplyWith replyWith = AuaReplyWith.None) + => GetInfoAsyncCore(null, userCode, recent, replyWith); + + /// + /// Get user info image. + /// + /// User name or 9-digit user code + /// Additional information to reply with. Supports songinfo only. + /// User info image + public Task GetInfoAsync(string user, AuaReplyWith replyWith) + => GetInfoAsyncCore(user, null, 0, replyWith); + + /// + /// Get user info image. + /// + /// 9-digit user code + /// Additional information to reply with. Supports songinfo only. + /// User info image + public Task GetInfoAsync(int userCode, AuaReplyWith replyWith) + => GetInfoAsyncCore(null, userCode, 0, replyWith); + + #endregion /user/info + + #region /user/best + + private async Task GetBestAsyncCore(string? user, int? userCode, string songname, + AuaSongQueryType queryType, ArcaeaDifficulty difficulty, AuaReplyWith replyWith) + { + var qb = new QueryBuilder() + .Add(queryType == AuaSongQueryType.SongId ? "song_id" : "song_name", songname) + .Add("difficulty", ((int)difficulty).ToString()); + + if (user is not null) + qb.Add("user_name", user); + else + qb.Add("user_code", userCode.ToString()!); + + if (replyWith.HasFlag(AuaReplyWith.Recent)) + qb.Add("with_recent", "true"); + if (replyWith.HasFlag(AuaReplyWith.SongInfo)) + qb.Add("with_song_info", "true"); + + var resp = await _client.GetAsync("user/best" + qb.Build()); + return await resp.EnsureDataSuccess(); + } + + /// + /// Get user best score image. + /// + /// User name or 9-digit user code + /// Any song name for fuzzy querying or sid in Arcaea songlist + /// Specify the query type between songname and songid + /// Song difficulty + /// Additional information to reply with. Supports songinfo and recent. + /// User best image + public Task GetBestAsync(string user, string songName, + AuaSongQueryType queryType = AuaSongQueryType.SongName, ArcaeaDifficulty difficulty = ArcaeaDifficulty.Future, + AuaReplyWith replyWith = AuaReplyWith.None) + => GetBestAsyncCore(user, null, songName, queryType, difficulty, replyWith); + + /// + /// Get user best score image. + /// + /// 9-digit user code + /// Any song name for fuzzy querying or sid in Arcaea songlist + /// Specify the query type between songname and songid + /// Song difficulty + /// Additional information to reply with. Supports songinfo and recent. + /// User best image + public Task GetBestAsync(int userCode, string songName, + AuaSongQueryType queryType = AuaSongQueryType.SongName, ArcaeaDifficulty difficulty = ArcaeaDifficulty.Future, + AuaReplyWith replyWith = AuaReplyWith.None) + => GetBestAsyncCore(null, userCode, songName, queryType, difficulty, replyWith); + + /// + /// Get user best score image. + /// + /// User name or 9-digit user code + /// Any song name for fuzzy querying + /// Song difficulty + /// Additional information to reply with. Supports songinfo and recent. + /// User best image + public Task GetBestAsync(string user, string songName, + ArcaeaDifficulty difficulty, + AuaReplyWith replyWith = AuaReplyWith.None) + => GetBestAsyncCore(user, null, songName, AuaSongQueryType.SongName, difficulty, replyWith); + + /// + /// Get user best score image. + /// + /// 9-digit user code + /// Any song name for fuzzy querying + /// Song difficulty + /// Additional information to reply with. Supports songinfo and recent. + /// User best image + public Task GetBestAsync(int userCode, string songName, + ArcaeaDifficulty difficulty, + AuaReplyWith replyWith = AuaReplyWith.None) + => GetBestAsyncCore(null, userCode, songName, AuaSongQueryType.SongName, difficulty, replyWith); + + /// + /// Get user best score image. + /// + /// User name or 9-digit user code + /// Any song name for fuzzy querying + /// Additional information to reply with. Supports songinfo and recent. + /// User best image + public Task GetBestAsync(string user, string songName, AuaReplyWith replyWith) + => GetBestAsyncCore(user, null, songName, AuaSongQueryType.SongName, ArcaeaDifficulty.Future, replyWith); + + /// + /// Get user best score image. + /// + /// 9-digit user code + /// Any song name for fuzzy querying + /// Additional information to reply with. Supports songinfo and recent. + /// User best image + public Task GetBestAsync(int userCode, string songName, + AuaReplyWith replyWith) + => GetBestAsyncCore(null, userCode, songName, AuaSongQueryType.SongName, ArcaeaDifficulty.Future, replyWith); + + #endregion /user/best +} \ No newline at end of file diff --git a/UnofficialArcaeaAPI.Lib/Responses/UaaSongListContent.cs b/UnofficialArcaeaAPI.Lib/Responses/UaaSongListContent.cs index d6b5010..bb90bbf 100644 --- a/UnofficialArcaeaAPI.Lib/Responses/UaaSongListContent.cs +++ b/UnofficialArcaeaAPI.Lib/Responses/UaaSongListContent.cs @@ -5,5 +5,5 @@ namespace UnofficialArcaeaAPI.Lib.Responses; public class UaaSongListContent { [JsonPropertyName("songs")] - public UaaSongInfoContent[] Songs { get; set; } + public UaaSongInfoContent[] Songs { get; set; } = null!; } \ No newline at end of file diff --git a/UnofficialArcaeaAPI.Lib/UaaClient.cs b/UnofficialArcaeaAPI.Lib/UaaClient.cs index 71a1ef1..87497c4 100644 --- a/UnofficialArcaeaAPI.Lib/UaaClient.cs +++ b/UnofficialArcaeaAPI.Lib/UaaClient.cs @@ -8,6 +8,7 @@ public sealed class UaaClient public UaaSongApi Song { get; } public UaaAssetsApi Assets { get; } public UaaDataApi Data { get; } + public UaaImageApi Image { get; } public UaaClient(UaaClientOptions options) { @@ -40,5 +41,6 @@ public UaaClient(UaaClientOptions options) Song = new UaaSongApi(client); Assets = new UaaAssetsApi(client); Data = new UaaDataApi(client); + Image = new UaaImageApi(client); } } \ No newline at end of file diff --git a/UnofficialArcaeaAPI.Lib/UnofficialArcaeaAPI.Lib.csproj b/UnofficialArcaeaAPI.Lib/UnofficialArcaeaAPI.Lib.csproj index 52b5129..a39c790 100644 --- a/UnofficialArcaeaAPI.Lib/UnofficialArcaeaAPI.Lib.csproj +++ b/UnofficialArcaeaAPI.Lib/UnofficialArcaeaAPI.Lib.csproj @@ -2,7 +2,7 @@ UnofficialArcaeaAPI.Lib - 3.0.0 + 3.1.0 bsdayo API wrapper for UnofficialArcaeaAPI. arcaea;api diff --git a/UnofficialArcaeaAPI.Lib/Utils/ResponseExtensions.cs b/UnofficialArcaeaAPI.Lib/Utils/ResponseExtensions.cs index d9b0440..f04e2bb 100644 --- a/UnofficialArcaeaAPI.Lib/Utils/ResponseExtensions.cs +++ b/UnofficialArcaeaAPI.Lib/Utils/ResponseExtensions.cs @@ -1,14 +1,19 @@ -using UnofficialArcaeaAPI.Lib.Responses; +using System.Net; +using System.Text.Json; +using UnofficialArcaeaAPI.Lib.Responses; namespace UnofficialArcaeaAPI.Lib.Utils; internal static class ResponseExtensions { - /// - /// Because these status code has additional data, we should - /// - internal static bool HasAdditionalData(this UaaResponse response) + internal static async Task EnsureDataSuccess(this HttpResponseMessage resp) { - return response.Status is <= -31 and >= -33; + if (resp.StatusCode != HttpStatusCode.OK) + { + var errJson = JsonSerializer.Deserialize(await resp.Content.ReadAsStringAsync())!; + throw new UaaRequestException(errJson.Status, errJson.Message!); + } + + return await resp.Content.ReadAsByteArrayAsync(); } } \ No newline at end of file