diff --git a/TorchRemote/Services/ApiClientService.cs b/TorchRemote/Services/ApiClientService.cs index 6749460..0984711 100644 --- a/TorchRemote/Services/ApiClientService.cs +++ b/TorchRemote/Services/ApiClientService.cs @@ -1,14 +1,9 @@ using System; -using System.Collections.Generic; using System.Net.Http; using System.Net.Http.Headers; -using System.Net.Http.Json; using System.Net.WebSockets; -using System.Threading; using System.Threading.Tasks; -using TorchRemote.Models.Requests; -using TorchRemote.Models.Responses; -using TorchRemote.Models.Shared; +using Refit; using Websocket.Client; namespace TorchRemote.Services; @@ -31,8 +26,10 @@ public class ApiClientService public ApiClientService() { + Api = RestService.For(_client); Task.Run(ConnectionTimer); } + public IRemoteApi Api { get; } private async Task ConnectionTimer() { @@ -41,7 +38,7 @@ public class ApiClientService await Task.Delay(1000); try { - await GetServerStatusAsync(CancellationToken.None); + await Api.GetServerStatus(); break; } catch @@ -52,43 +49,6 @@ public class ApiClientService Connected?.Invoke(this, EventArgs.Empty); } - public Task GetServerStatusAsync(CancellationToken token) => - _client.GetFromJsonAsync("server/status", token)!; - - public Task GetServerSettingsAsync(CancellationToken token) => - _client.GetFromJsonAsync("server/settings", token)!; - - public Task SetServerSettingsAsync(ServerSettings settings, CancellationToken token) => - _client.PostAsJsonAsync("server/settings", settings, token); - - public Task StartServerAsync(CancellationToken token) => - _client.PostAsync("server/start", null, token); - - public Task StopServerAsync(StopServerRequest request, CancellationToken token) => - _client.PostAsJsonAsync("server/stop", request, token); - - public Task> GetWorldsAsync(CancellationToken token) => - _client.GetFromJsonAsync>("worlds", token)!; - - public Task GetWorldAsync(Guid id, CancellationToken token) => - _client.GetFromJsonAsync($"worlds/{id}", token)!; - - public Task GetSelectedWorld(CancellationToken token) => - _client.GetFromJsonAsync("worlds/selected", token); - - public Task SelectWorldAsync(Guid id, CancellationToken token) => - _client.PostAsync($"worlds/{id}/select", null, token); - - public Task SendChatMessageAsync(ChatMessageRequest request, CancellationToken token) => - _client.PostAsJsonAsync("chat/message", request, token); - - public async Task InvokeCommandAsync(ChatCommandRequest request, CancellationToken token) - { - var r = await _client.PostAsJsonAsync("chat/command", request, token); - r.EnsureSuccessStatusCode(); - return await r.Content.ReadFromJsonAsync(cancellationToken: token); - } - public Task WatchChatAsync() => StartWebsocketConnectionAsync("live/chat"); public Task WatchLogLinesAsync() => StartWebsocketConnectionAsync("live/logs"); diff --git a/TorchRemote/Services/IRemoteApi.cs b/TorchRemote/Services/IRemoteApi.cs new file mode 100644 index 0000000..38322db --- /dev/null +++ b/TorchRemote/Services/IRemoteApi.cs @@ -0,0 +1,47 @@ +using System; +using System.Collections.Generic; +using System.Threading.Tasks; +using Refit; +using TorchRemote.Models.Requests; +using TorchRemote.Models.Responses; +using TorchRemote.Models.Shared; +namespace TorchRemote.Services; + +public interface IRemoteApi +{ +#region Server + [Get("/server/status")] + Task GetServerStatus(); + [Post("/server/start")] + Task StartServer(); + [Post("/server/stop")] + Task StopServer([Body] StopServerRequest request); + [Get("/server/settings")] + Task GetServerSettings(); + [Post("/server/settings")] + Task SetServerSettings([Body] ServerSettings request); +#endregion + +#region Chat + [Post("/chat/message")] + Task SendChatMessage([Body] ChatMessageRequest request); + [Post("/chat/command")] + Task InvokeChatCommand([Body] ChatCommandRequest request); +#endregion + +#region Worlds + [Get("/worlds")] + Task> GetWorlds(); + [Get("/worlds/selected")] + Task GetSelectedWorld(); + [Get("/worlds/{id}")] + Task GetWorld(Guid id); + [Post("/worlds/{id}/select")] + Task SelectWorld(Guid id); +#endregion + +#region Settings + [Get("/settings/{id}")] + Task GetSetting(Guid id); +#endregion +} diff --git a/TorchRemote/TorchRemote.csproj b/TorchRemote/TorchRemote.csproj index 717c604..5dd147a 100644 --- a/TorchRemote/TorchRemote.csproj +++ b/TorchRemote/TorchRemote.csproj @@ -25,6 +25,7 @@ + diff --git a/TorchRemote/ViewModels/Server/ChatViewModel.cs b/TorchRemote/ViewModels/Server/ChatViewModel.cs index ee6368d..a21d0bf 100644 --- a/TorchRemote/ViewModels/Server/ChatViewModel.cs +++ b/TorchRemote/ViewModels/Server/ChatViewModel.cs @@ -34,9 +34,9 @@ public class ChatViewModel : ViewModelBase .Subscribe(s => ChatLines += $"{s}{Environment.NewLine}"); }); - SendMessageCommand = ReactiveCommand.CreateFromTask((s, t) => s.StartsWith("!") ? - clientService.InvokeCommandAsync(new(s[(s.IndexOf('!') + 1)..]), t) : - clientService.SendChatMessageAsync(new("Server", s, ChatChannel.GlobalScripted), t)); + SendMessageCommand = ReactiveCommand.CreateFromTask(s => s.StartsWith("!") ? + clientService.Api.InvokeChatCommand(new(s[(s.IndexOf('!') + 1)..])) : + clientService.Api.SendChatMessage(new("Server", s, ChatChannel.GlobalScripted))); InvalidCommandPopup = SendMessageCommand.ThrownExceptions .Where(b => b is HttpRequestException {StatusCode: HttpStatusCode.NotFound or HttpStatusCode.BadRequest}) diff --git a/TorchRemote/ViewModels/Server/DashboardViewModel.cs b/TorchRemote/ViewModels/Server/DashboardViewModel.cs index 3805971..d82b058 100644 --- a/TorchRemote/ViewModels/Server/DashboardViewModel.cs +++ b/TorchRemote/ViewModels/Server/DashboardViewModel.cs @@ -22,7 +22,7 @@ public class DashboardViewModel : ViewModelBase .Subscribe(_ => { Observable.Timer(TimeSpan.Zero, TimeSpan.FromSeconds(10)) - .Select(_ => Observable.FromAsync(t => _clientService.GetServerStatusAsync(t))) + .Select(_ => Observable.FromAsync(() => _clientService.Api.GetServerStatus())) .Concat() .ObserveOn(RxApp.MainThreadScheduler) .Subscribe(r => @@ -49,11 +49,11 @@ public class DashboardViewModel : ViewModelBase }); }); - StartCommand = ReactiveCommand.CreateFromTask(t => _clientService.StartServerAsync(t), + StartCommand = ReactiveCommand.CreateFromTask(() => _clientService.Api.StartServer(), this.WhenAnyValue(x => x.Status) .Select(b => b is ServerStatus.Stopped)); - StopCommand = ReactiveCommand.CreateFromTask((b, t) => _clientService.StopServerAsync(new(b), t), + StopCommand = ReactiveCommand.CreateFromTask(b => _clientService.Api.StopServer(new(b)), this.WhenAnyValue(x => x.Status) .Select(b => b is ServerStatus.Running)); } diff --git a/TorchRemote/ViewModels/Server/ServerConfigViewModel.cs b/TorchRemote/ViewModels/Server/ServerConfigViewModel.cs index 6ab91b6..ed00692 100644 --- a/TorchRemote/ViewModels/Server/ServerConfigViewModel.cs +++ b/TorchRemote/ViewModels/Server/ServerConfigViewModel.cs @@ -12,7 +12,7 @@ public class ServerConfigViewModel : ViewModelBase { Observable.FromEventPattern(clientService, nameof(clientService.Connected)) .ObserveOn(RxApp.MainThreadScheduler) - .Select(_ => Observable.FromAsync(clientService.GetServerSettingsAsync)) + .Select(_ => Observable.FromAsync(clientService.Api.GetServerSettings)) .Concat() .Subscribe(b => { @@ -24,33 +24,33 @@ public class ServerConfigViewModel : ViewModelBase Port = b.ListenEndPoint.Port; }); - SaveCommand = ReactiveCommand.CreateFromTask(t => - clientService.SetServerSettingsAsync(new( + SaveCommand = ReactiveCommand.CreateFromTask(() => + clientService.Api.SetServerSettings(new( Name, MapName, Description, MemberLimit, new(Ip, Port) - ), t)); + ))); Worlds = Observable.FromEventPattern(clientService, nameof(clientService.Connected)) .ObserveOn(RxApp.MainThreadScheduler) - .Select(_ => Observable.FromAsync(clientService.GetWorldsAsync)) + .Select(_ => Observable.FromAsync(clientService.Api.GetWorlds)) .Concat() .SelectMany(ids => ids) - .Select(id => Observable.FromAsync(t => clientService.GetWorldAsync(id, t)).Select(b => new World(id, b.Name, b.SizeKb))) + .Select(id => Observable.FromAsync(() => clientService.Api.GetWorld(id)).Select(b => new World(id, b.Name, b.SizeKb))) .Concat(); Observable.FromEventPattern(clientService, nameof(clientService.Connected)) .ObserveOn(RxApp.MainThreadScheduler) - .Select(_ => Observable.FromAsync(clientService.GetSelectedWorld)) + .Select(_ => Observable.FromAsync(clientService.Api.GetSelectedWorld)) .Concat() - .Select(id => Observable.FromAsync(t => clientService.GetWorldAsync(id, t)).Select(b => new World(id, b.Name, b.SizeKb))) + .Select(id => Observable.FromAsync(() => clientService.Api.GetWorld(id)).Select(b => new World(id, b.Name, b.SizeKb))) .Concat() .BindTo(this, x => x.SelectedWorld); this.ObservableForProperty(x => x.SelectedWorld) - .Select(world => Observable.FromAsync(t => clientService.SelectWorldAsync(world.Value!.Id, t))) + .Select(world => Observable.FromAsync(() => clientService.Api.SelectWorld(world.Value!.Id))) .Concat() .Subscribe(_ => { }); }