107 lines
4.2 KiB
C#
107 lines
4.2 KiB
C#
using Shogi.Contracts.Api;
|
|
using Shogi.Contracts.Types;
|
|
using Shogi.UI.Pages.Home.Account;
|
|
using System.Net;
|
|
using System.Net.Http.Json;
|
|
using System.Text.Json;
|
|
|
|
namespace Shogi.UI.Pages.Home.Api
|
|
{
|
|
public class ShogiApi : IShogiApi
|
|
{
|
|
public const string GuestClientName = "Guest";
|
|
public const string MsalClientName = "Msal";
|
|
|
|
private readonly JsonSerializerOptions serializerOptions;
|
|
private readonly AccountState accountState;
|
|
private readonly HttpClient guestHttpClient;
|
|
private readonly HttpClient msalHttpClient;
|
|
private readonly string baseUrl;
|
|
|
|
public ShogiApi(IHttpClientFactory clientFactory, AccountState accountState, IConfiguration configuration)
|
|
{
|
|
this.serializerOptions = new JsonSerializerOptions(JsonSerializerDefaults.Web);
|
|
this.accountState = accountState;
|
|
this.guestHttpClient = clientFactory.CreateClient(GuestClientName);
|
|
this.msalHttpClient = clientFactory.CreateClient(MsalClientName);
|
|
this.baseUrl = configuration["ShogiApiUrl"] ?? throw new InvalidOperationException("Configuration missing.");
|
|
this.baseUrl = this.baseUrl.TrimEnd('/');
|
|
}
|
|
|
|
private HttpClient HttpClient => accountState.User?.WhichAccountPlatform switch
|
|
{
|
|
WhichAccountPlatform.Guest => this.guestHttpClient,
|
|
WhichAccountPlatform.Microsoft => this.msalHttpClient,
|
|
_ => throw new InvalidOperationException("AccountState.User must not be null during API call.")
|
|
};
|
|
|
|
public async Task GuestLogout()
|
|
{
|
|
var response = await this.guestHttpClient.PutAsync(RelativeUri("User/GuestLogout"), null);
|
|
response.EnsureSuccessStatusCode();
|
|
}
|
|
|
|
public async Task<Session?> GetSession(string name)
|
|
{
|
|
var response = await HttpClient.GetAsync(RelativeUri($"Sessions/{name}"));
|
|
if (response.IsSuccessStatusCode)
|
|
{
|
|
return (await response.Content.ReadFromJsonAsync<ReadSessionResponse>(serializerOptions))?.Session;
|
|
}
|
|
return null;
|
|
}
|
|
|
|
public async Task<ReadSessionsPlayerCountResponse?> GetSessionsPlayerCount()
|
|
{
|
|
var response = await HttpClient.GetAsync(RelativeUri("Sessions/PlayerCount"));
|
|
if (response.IsSuccessStatusCode)
|
|
{
|
|
return await response.Content.ReadFromJsonAsync<ReadSessionsPlayerCountResponse>(serializerOptions);
|
|
}
|
|
return null;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Logs the user into the API and returns a token which can be used to request a socket connection.
|
|
/// </summary>
|
|
public async Task<CreateTokenResponse?> GetToken(WhichAccountPlatform whichAccountPlatform)
|
|
{
|
|
var httpClient = whichAccountPlatform == WhichAccountPlatform.Microsoft
|
|
? this.msalHttpClient
|
|
: this.guestHttpClient;
|
|
|
|
var response = await httpClient.GetAsync(RelativeUri("User/Token"));
|
|
if (response.IsSuccessStatusCode)
|
|
{
|
|
var content = await response.Content.ReadAsStringAsync();
|
|
if (!string.IsNullOrEmpty(content))
|
|
{
|
|
return JsonSerializer.Deserialize<CreateTokenResponse>(content, serializerOptions);
|
|
}
|
|
}
|
|
return null;
|
|
}
|
|
|
|
public async Task Move(string sessionName, MovePieceCommand command)
|
|
{
|
|
await this.HttpClient.PatchAsync(RelativeUri($"Sessions/{sessionName}/Move"), JsonContent.Create(command));
|
|
}
|
|
|
|
public async Task<HttpStatusCode> PostSession(string name, bool isPrivate)
|
|
{
|
|
var response = await HttpClient.PostAsJsonAsync(RelativeUri("Sessions"), new CreateSessionCommand
|
|
{
|
|
Name = name,
|
|
});
|
|
return response.StatusCode;
|
|
}
|
|
|
|
public Task<HttpResponseMessage> PatchJoinGame(string name)
|
|
{
|
|
return HttpClient.PatchAsync(RelativeUri($"Sessions/{name}/Join"), null);
|
|
}
|
|
|
|
private Uri RelativeUri(string path) => new($"{this.baseUrl}/{path}", UriKind.Absolute);
|
|
}
|
|
}
|