diff --git a/.github/workflows/Publish - Dev.yml b/.github/workflows/Publish - Dev.yml new file mode 100644 index 0000000..2dadaff --- /dev/null +++ b/.github/workflows/Publish - Dev.yml @@ -0,0 +1,27 @@ +name: Dev - Build + Publish + +on: + push: + branches: [ dev-*, dev/**, develop, develop/* ] + +jobs: + build: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - name: Setup .NET + uses: actions/setup-dotnet@v1 + with: + dotnet-version: 6.0.x + + - name: Build Nuget Packages + run: "mkdir build && dotnet pack -p:IncludeSymbols=true -p:SymbolPackageFormat=snupkg --include-source -o build -p:VersionSuffix='nightly' -p:BuildNumber=0$((${{ github.run_number }} ))" + + - name: Publish Nuget Packages + run: "dotnet nuget push \"build/*\" -k ${{ secrets.ALEX_NUGET_API_KEY }} -s https://api.nuget.org/v3/index.json" + + - name: "Upload Nuget Packages To Github Actions" + uses: actions/upload-artifact@v3 + with: + name: PR Nuget Packages + path: build/* \ No newline at end of file diff --git a/.github/workflows/Publish - Release.yml b/.github/workflows/Publish - Release.yml new file mode 100644 index 0000000..cecee1a --- /dev/null +++ b/.github/workflows/Publish - Release.yml @@ -0,0 +1,28 @@ +name: Release - Build + Deploy + +on: + push: + branches: [ master ] + +jobs: + build: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - name: Setup .NET + uses: actions/setup-dotnet@v1 + with: + dotnet-version: 5.0.100 + - name: Restore dependencies + run: dotnet restore + - name: Build + run: dotnet build --no-restore + - name: Test + run: dotnet test --no-build --verbosity normal + - name: Deploy - Release + uses: alexr03/publish-nuget@master + with: + PROJECT_FILE_PATH: TCAdminApiSharp/TCAdminApiSharp.csproj + NUGET_KEY: ${{secrets.ALEX_NUGET_API_KEY}} + VERSION_REGEX: ^\s*(.*)<\/AssemblyVersion>\s*$ + TAG_VERSION: release-v*-${{steps.datetime.outputs.date}}-${{github.run_number}} \ No newline at end of file diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml deleted file mode 100644 index 3ba30ef..0000000 --- a/.github/workflows/publish.yml +++ /dev/null @@ -1,41 +0,0 @@ -name: Deploy to Nuget - -on: - push: - branches: [ master, dev ] - -jobs: - build: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v2 - - name: Setup .NET - uses: actions/setup-dotnet@v1 - with: - dotnet-version: 5.0.100 - - name: Restore dependencies - run: dotnet restore - - name: Build - run: dotnet build --no-restore - - name: Test - run: dotnet test --no-build --verbosity normal - - name: Deploy - Release - uses: alexr03/publish-nuget@master - if: github.ref == 'refs/heads/master' - with: - PROJECT_FILE_PATH: TCAdminApiSharp/TCAdminApiSharp.csproj - NUGET_KEY: ${{secrets.ALEX_NUGET_API_KEY}} - VERSION_REGEX: ^\s*(.*)<\/AssemblyVersion>\s*$ - - name: Get DateTime - if: github.ref != 'refs/heads/master' - id: datetime - run: echo "::set-output name=date::$(date +'%Y%m%d')" - - name: Deploy - Dev - uses: alexr03/publish-nuget@master - if: github.ref != 'refs/heads/master' - with: - PROJECT_FILE_PATH: TCAdminApiSharp/TCAdminApiSharp.csproj - NUGET_KEY: ${{secrets.ALEX_NUGET_API_KEY}} - VERSION_REGEX: ^\s*(.*)<\/AssemblyVersion>\s*$ - VERSION_SUFFIX: -dev-${{steps.datetime.outputs.date}}-${{github.run_number}} - TAG_COMMIT: false diff --git a/.idea/.idea.TCAdminApiSharp/.idea/indexLayout.xml b/.idea/.idea.TCAdminApiSharp/.idea/indexLayout.xml index 27ba142..7b08163 100644 --- a/.idea/.idea.TCAdminApiSharp/.idea/indexLayout.xml +++ b/.idea/.idea.TCAdminApiSharp/.idea/indexLayout.xml @@ -1,6 +1,6 @@ - + diff --git a/.idea/.idea.TCAdminApiSharp/.idea/riderModule.iml b/.idea/.idea.TCAdminApiSharp/.idea/riderModule.iml deleted file mode 100644 index 024158d..0000000 --- a/.idea/.idea.TCAdminApiSharp/.idea/riderModule.iml +++ /dev/null @@ -1,14 +0,0 @@ - - - - - - - - - - - - - - \ No newline at end of file diff --git a/TCAdminApiSharp.Tests/ClientTests.cs b/TCAdminApiSharp.Tests/ClientTests.cs index 19e8a06..9b08ed8 100644 --- a/TCAdminApiSharp.Tests/ClientTests.cs +++ b/TCAdminApiSharp.Tests/ClientTests.cs @@ -1,26 +1,25 @@ using System; using NUnit.Framework; -namespace TCAdminApiSharp.Tests +namespace TCAdminApiSharp.Tests; + +public class ClientTests { - public class ClientTests + [Test] + public void CreateClientWithoutHost() { - [Test] - public void CreateClientWithoutHost() + Assert.Catch(() => { - Assert.Catch(() => - { - var _ = new TcaClient("", "-"); - }); - } + var _ = new TcaClient("", "-"); + }); + } - [Test] - public void CreateClientWithoutToken() + [Test] + public void CreateClientWithoutToken() + { + Assert.Catch(() => { - Assert.Catch(() => - { - var _ = new TcaClient("https://4a815e4e-aaa8-4351-a948-5ca3f92e5c8b.mock.pstmn.io", ""); - }); - } + var _ = new TcaClient("https://4a815e4e-aaa8-4351-a948-5ca3f92e5c8b.mock.pstmn.io", ""); + }); } } \ No newline at end of file diff --git a/TCAdminApiSharp.Tests/ServerTests.cs b/TCAdminApiSharp.Tests/ServerTests.cs new file mode 100644 index 0000000..4d99d09 --- /dev/null +++ b/TCAdminApiSharp.Tests/ServerTests.cs @@ -0,0 +1,39 @@ +using System.Threading.Tasks; +using Microsoft.Extensions.Configuration; +using NUnit.Framework; + +namespace TCAdminApiSharp.Tests; + +public class ServerTests +{ + private TcaClient _tcaClient; + + [SetUp] + public void Setup() + { + var config = new ConfigurationBuilder().AddJsonFile("appsettings.json") + .AddJsonFile("appsettings.local.json", true) + .Build().GetSection("TCAdmin"); + var activeProfile = config["ActiveProfile"]; + var profileSection = config.GetSection("Profiles").GetSection(activeProfile); + var host = profileSection["Host"]; + var key = profileSection["Key"]; + _tcaClient = new TcaClient(host, key, TcaClientSettings.Debug); + } + + [Test] + public async Task GetServerTest() + { + var server = await _tcaClient.ServersController.GetServer(1); + Assert.AreEqual("Master", server.Name); + } + + // [Test] + // public async Task GetServersTest() + // { + // var server = await _tcaClient.ServersController.GetServers(); + // Assert.IsTrue(server.Success); + // Assert.AreEqual(1, server.Result.Count); + // Assert.AreEqual("Master", server.Result[0].Name); + // } +} \ No newline at end of file diff --git a/TCAdminApiSharp.Tests/ServiceTests.cs b/TCAdminApiSharp.Tests/ServiceTests.cs index ccd143f..77b26c8 100644 --- a/TCAdminApiSharp.Tests/ServiceTests.cs +++ b/TCAdminApiSharp.Tests/ServiceTests.cs @@ -1,113 +1,156 @@ using System; -using System.Collections.Generic; -using Newtonsoft.Json.Linq; +using System.Threading.Tasks; +using Microsoft.Extensions.Configuration; using NUnit.Framework; -using Serilog.Events; using TCAdminApiSharp.Entities.Service; -using TCAdminApiSharp.Exceptions; using TCAdminApiSharp.Exceptions.API; -namespace TCAdminApiSharp.Tests +namespace TCAdminApiSharp.Tests; + +public class ServiceTests { - public class ServiceTests - { - private TcaClient _tcaClient; + private TcaClient _tcaClient; - [SetUp] - public void Setup() - { - _tcaClient = new TcaClient("https://4a815e4e-aaa8-4351-a948-5ca3f92e5c8b.mock.pstmn.io", "-", LogEventLevel.Debug); - } + [SetUp] + public void Setup() + { + var config = new ConfigurationBuilder().AddJsonFile("appsettings.json").AddJsonFile("appsettings.local.json", true).Build().GetSection("TCAdmin"); + var activeProfile = config["ActiveProfile"]; + var profileSection = config.GetSection("Profiles").GetSection(activeProfile); + var host = profileSection["Host"]; + var key = profileSection["Key"]; + _tcaClient = new TcaClient(host, key, TcaClientSettings.Debug); + } - [Test] - public void GetServiceTest() - { - var service = _tcaClient.ServicesController.GetService(2); - Assert.AreEqual(2, service.ServiceId); - } - - [Test] - public void GetNonExistentServiceTest() - { - Assert.Catch(() => - { - var _ = _tcaClient.ServicesController.GetService(0); - }); - } + [Test] + public async Task GetServiceTest() + { + var service = await _tcaClient.ServicesController.GetService(1); + Assert.AreEqual(1, service.ServiceId); + } + + [Test] + public async Task ServiceStart() + { + var service = await _tcaClient.ServicesController.GetService(1); + await service.Start(); + service = await _tcaClient.ServicesController.GetService(1); + Assert.AreEqual(EServiceStatus.Running, service.EServiceStatus); + } - [Test] - public void GetServicesListTest() - { - var services = _tcaClient.ServicesController.GetServices(); - Assert.AreEqual(2, services.VirtualCount); - } + [Test] + public async Task GetServicesListTest() + { + var services = await _tcaClient.ServicesController.GetServices(); + Assert.AreEqual(2, services.Count); + } - [Test] - public void GetServiceExceptionTest() + [Test] + public async Task GetServiceExceptionTest() + { + Assert.ThrowsAsync(async () => { - try - { - var _ = _tcaClient.ServicesController.GetService(-1); - } - catch (ApiResponseException e) - { - Console.WriteLine(e.ErrorResponse); - } - } + var service = await _tcaClient.ServicesController.GetService(-1); + Console.WriteLine(service.ServiceId); + }); + } + + [Test] + public async Task GetServiceFileManagerService() + { + var service = await _tcaClient.ServicesController.GetService(3); + Assert.NotNull(service.FileManagerService); + } + + [Test] + public async Task FileManagerGetFileInfo() + { + var service = await _tcaClient.ServicesController.GetService(3); + var fileInfo = await service.FileManagerService.GetFileInfo("/cfg/server.cfg"); + Assert.AreEqual("server.cfg", fileInfo.Name); + Assert.AreEqual(".cfg", fileInfo.Extension); + } + + [Test] + public async Task FileManagerCopyFileInfo() + { + var service = await _tcaClient.ServicesController.GetService(3); + var fileInfo = await service.FileManagerService.GetFileInfo("/cfg/server.cfg"); + var copy = await fileInfo.Copy("/cfg2"); + Assert.IsTrue(copy); + } + + [Test] + public async Task FileManagerCompressDirectory() + { + var service = await _tcaClient.ServicesController.GetService(3); + var directoryListing = await service.FileManagerService.GetDirectoryListing("/cfg"); + var compressModel = await directoryListing.Compress("/cfg2"); + Assert.IsNotNull(compressModel.Zip); + } - [Test] - public void UpdateServiceTest() + [Test] + public async Task UpdateServiceTest() + { + var service = await _tcaClient.ServicesController.GetService(1); + Assert.AreEqual(1, service.ServiceId); + await service.Update(x => { - var service = _tcaClient.ServicesController.GetService(1); - service.Update(x => - { - x.Slots = 12; - x.Executable = "changed.exe"; - }); - - Assert.Pass("Service Updated"); - } + x.Slots = 5; + x.Variables.Add("test", 123); + // x.Executable = "changed.exe"; + }); + } - [Test] - public void UpdateServiceExceptionTest() - { - var service = _tcaClient.ServicesController.GetService(2); - try - { - service.Update(x => - { - x.Slots = 12; - x.Executable = "changed.exe"; - }); - } - catch (ApiResponseException e) - { - var result = ((JObject) e.ErrorResponse.Result).ToObject(); - if (result?.Source == "TCAdmin.Web.MVC") //todo Update this to the specific Update Service exception type. - { - Assert.Pass("Correct exception returned"); - } - Console.WriteLine(result); - } - - Assert.Fail("No exception"); - } + // [Test] + // public async Task UpdateServiceExceptionTest() + // { + // var service = await _tcaClient.ServicesController.GetService(2); + // try + // { + // await service.Update(x => + // { + // x.Slots = 12; + // x.Executable = "changed.exe"; + // }); + // } + // catch (ApiResponseException e) + // { + // var result = (e.HttpResponseMessage).ToObject(); + // if (result?.Source == "TCAdmin.Web.MVC") //todo Update this to the specific Update Service exception type. + // { + // Assert.Pass("Correct exception returned"); + // } + // Console.WriteLine(result); + // } + // + // Assert.Fail("No exception"); + // } - // [Test] - // public void ServiceCreateJsonTest() - // { - // var serviceBuilder = new ServiceBuilder() - // .WithAutomaticPort(true) - // .WithGameId(12) - // .WithBranded(true) - // .WithDatacenterId(1) - // .WithVariables(new Dictionary() - // { - // {"test", 123} - // }) - // .WithSlots(100) - // .WithBillingId("100Not4Me"); - // _tcaClient.ServicesController.CreateService(serviceBuilder); - // } - } + // [Test] + // public async Task ServiceCreateJsonTest() + // { + // var serviceBuilder = new ServiceBuilder() + // .WithAutomaticPort(true) + // .WithGameId(67) + // .WithBranded(true) + // .WithDatacenterId(1) + // // .WithVariables(new TcaXmlField() + // // { + // // {"test", 123} + // // }) + // .WithSlots(100) + // .WithBillingId("100Not4Me"); + // try + // { + // var service = await _tcaClient.ServicesController.CreateService(serviceBuilder); + // Console.WriteLine("Sv: " + service); + // } + // catch (ApiResponseException e) + // { + // Console.WriteLine(e.ExceptionResponse.Success); + // Console.WriteLine(e.ExceptionResponse.Message); + // throw; + // } + // } } \ No newline at end of file diff --git a/TCAdminApiSharp.Tests/TCAdminApiSharp.Tests.csproj b/TCAdminApiSharp.Tests/TCAdminApiSharp.Tests.csproj index d8cfe75..05440cf 100644 --- a/TCAdminApiSharp.Tests/TCAdminApiSharp.Tests.csproj +++ b/TCAdminApiSharp.Tests/TCAdminApiSharp.Tests.csproj @@ -1,19 +1,30 @@ - net5.0 + net6.0 false - - - + + + + + + + + Always + + + Always + + + diff --git a/TCAdminApiSharp.Tests/UserTests.cs b/TCAdminApiSharp.Tests/UserTests.cs new file mode 100644 index 0000000..d83490c --- /dev/null +++ b/TCAdminApiSharp.Tests/UserTests.cs @@ -0,0 +1,57 @@ +using System.Linq; +using System.Threading.Tasks; +using Microsoft.Extensions.Configuration; +using NUnit.Framework; +using TCAdminApiSharp.Entities.User; +using TCAdminApiSharp.Querying; +using TCAdminApiSharp.Querying.Operations; + +namespace TCAdminApiSharp.Tests; + +public class UserTests +{ + private TcaClient _tcaClient; + + [SetUp] + public void Setup() + { + var config = new ConfigurationBuilder().AddJsonFile("appsettings.json") + .AddJsonFile("appsettings.local.json", true) + .Build().GetSection("TCAdmin"); + var activeProfile = config["ActiveProfile"]; + var profileSection = config.GetSection("Profiles").GetSection(activeProfile); + var host = profileSection["Host"]; + var key = profileSection["Key"]; + _tcaClient = new TcaClient(host, key, TcaClientSettings.Debug); + } + + [Test] + public async Task GetUserAdvancedTest() + { + var users = await _tcaClient.UsersController.FindUsers(new QueryableInfo(new WhereList(nameof(User.UserName), "admin"))); + Assert.AreEqual(1, users.Count); + var user = users.Result.First(); + Assert.AreEqual("Admin", user.UserName); + } + + [Test] + public async Task GetUserTest() + { + var user = await _tcaClient.UsersController.GetUser(3); + Assert.AreEqual("Admin", user.UserName); + } + + [Test] + public async Task UpdateUserTest() + { + var user = await _tcaClient.UsersController.GetUser(4); + await user.Update(x => + { + x.FirstName = "Api"; + x.LastName = "Update"; + }); + user = await _tcaClient.UsersController.GetUser(4); + Assert.AreEqual("Api", user.FirstName); + Assert.AreEqual("Update", user.LastName); + } +} \ No newline at end of file diff --git a/TCAdminApiSharp.Tests/appsettings.json b/TCAdminApiSharp.Tests/appsettings.json new file mode 100644 index 0000000..b758d66 --- /dev/null +++ b/TCAdminApiSharp.Tests/appsettings.json @@ -0,0 +1,11 @@ +{ + "TCAdmin": { + "ActiveProfile": "Mock", + "Profiles": { + "Mock": { + "Host": "https://dbc851a7-3a7a-4a85-8b02-8ad9fa519e3c.mock.pstmn.io", + "Key": "mock-key" + } + } + } +} \ No newline at end of file diff --git a/TCAdminApiSharp.Tests/appsettings.local.json b/TCAdminApiSharp.Tests/appsettings.local.json new file mode 100644 index 0000000..c793369 --- /dev/null +++ b/TCAdminApiSharp.Tests/appsettings.local.json @@ -0,0 +1,11 @@ +{ + "TCAdmin": { + "ActiveProfile": "Admin", + "Profiles": { + "Admin": { + "Host": "http://tcadmin-d01/api", + "Key": "oD50BKoFaOABml9Ax+o3wY3nk18FsI6FhOJwepc2TGFaWfu4lbfb5FfeSrh3/zBOVgJq/VwxKZRGBwwGEy352B/wQqP7Fh5gQ8lTEdWfMT/McK3F9Pcbuj94MJ1vgfzW9Od0Dat5JkZbziZRc7YQMzL9xYzLXC2zVlmE5o91Qfc030SPyBHifKq8d5KVRaKbO0lwO+1+lZrb4dDl8zRog5SoleZYiSXNhPE1Qj2z8d4=" + } + } + } +} \ No newline at end of file diff --git a/TCAdminApiSharp/Controllers/BaseController.cs b/TCAdminApiSharp/Controllers/BaseController.cs index 2f5956d..906ac13 100644 --- a/TCAdminApiSharp/Controllers/BaseController.cs +++ b/TCAdminApiSharp/Controllers/BaseController.cs @@ -1,104 +1,155 @@ using System; +using System.Collections; +using System.Collections.Generic; using System.Linq; -using System.Net; +using System.Net.Http; using System.Threading.Tasks; -using Microsoft.Extensions.DependencyInjection; using Newtonsoft.Json; -using RestSharp; using Serilog; using TCAdminApiSharp.Entities.API; +using TCAdminApiSharp.Entities.Generic; using TCAdminApiSharp.Exceptions.API; +using TCAdminApiSharp.Helpers; +using TCAdminApiSharp.Querying; -namespace TCAdminApiSharp.Controllers +namespace TCAdminApiSharp.Controllers; + +public class BaseController { - public class BaseController + public readonly TcaClient TcaClient; + public readonly string BaseResource; + internal readonly ILogger Logger; + + protected BaseController(TcaClient tcaClient, string baseResource) + { + Logger = Log.ForContext(GetType()); + TcaClient = tcaClient; + BaseResource = baseResource; + + if (!baseResource.EndsWith("/")) BaseResource = baseResource + "/"; + } + + public HttpRequestMessage GenerateDefaultRequest() + { + var httpRequestMessage = new HttpRequestMessage(); + httpRequestMessage.RequestUri = Append(new Uri(BaseResource, UriKind.RelativeOrAbsolute)); + return httpRequestMessage; + } + + public HttpRequestMessage GenerateDefaultRequest(params string[] paths) + { + var httpRequestMessage = new HttpRequestMessage(); + httpRequestMessage.RequestUri = Append(new Uri(BaseResource, UriKind.RelativeOrAbsolute), paths); + return httpRequestMessage; + } + + public HttpRequestMessage GenerateDefaultRequest(HttpMethod httpMethod, params string[] paths) + { + var httpRequestMessage = new HttpRequestMessage(); + httpRequestMessage.RequestUri = Append(new Uri(BaseResource, UriKind.RelativeOrAbsolute), paths); + httpRequestMessage.Method = httpMethod; + return httpRequestMessage; + } + + public async Task> AdvancedRequest(string resource, QueryableInfo query, HttpMethod method) { - public readonly TcaClient TcaClient = - TcaClient.ServiceProvider.GetService() ?? throw new InvalidOperationException(); - public readonly string BaseResource; - public readonly ILogger Logger; + var request = GenerateDefaultRequest(resource); + request.Method = method; + query.BuildQuery(request); + return await ExecuteBaseResponseRequest(request); + } + + public async Task> AdvancedListRequest(string resource, QueryableInfo query, HttpMethod method) + { + var request = GenerateDefaultRequest(resource); + request.Method = method; + query.BuildQuery(request); + return await ExecuteListResponseRequest(request); + } + + public async Task ExecuteBaseResponseRequest(HttpRequestMessage requestMessage) + { + var (baseResponse, httpResponse) = await ExecuteRequestAsync(requestMessage); + baseResponse.RequestMessage = requestMessage; + baseResponse.ResponseMessage = httpResponse; + return baseResponse; + } + + public async Task> ExecuteBaseResponseRequest(HttpRequestMessage requestMessage) + { + var (baseResponse, httpResponse) = await ExecuteRequestAsync>(requestMessage); + baseResponse.RequestMessage = requestMessage; + baseResponse.ResponseMessage = httpResponse; + return baseResponse; + } + + public async Task> ExecuteListResponseRequest(HttpRequestMessage requestMessage) + { + var (baseResponse, restResponse) = await ExecuteRequestAsync>(requestMessage); + return baseResponse; + } - protected BaseController(string baseResource) + public async Task> ExecuteRequestAsync(HttpRequestMessage request) + { + Logger.Debug("Request: {Request}", request.ToString()); + var httpResponseMessage = await TcaClient.HttpClient.SendAsync(request); + Logger.Debug("Response: {Response}", httpResponseMessage.ToString()); + var strResponse = await httpResponseMessage.Content.ReadAsStringAsync(); + if (!httpResponseMessage.IsSuccessStatusCode) { - Logger = Log.ForContext(GetType()); - BaseResource = baseResource; + if (!TcaClient.Settings.ThrowOnApiResponseStatusNonComplete) + return new Tuple(default!, httpResponseMessage); - if (!baseResource.EndsWith("/")) + if (!string.IsNullOrEmpty(strResponse)) { - BaseResource = baseResource + "/"; + var exceptionResponse = JsonConvert.DeserializeObject>(strResponse); + if (exceptionResponse != null) throw new ApiResponseException(httpResponseMessage, exceptionResponse); } + + throw new ApiResponseException(httpResponseMessage, $"Response Status Code is: {httpResponseMessage.StatusCode} ({httpResponseMessage.ReasonPhrase})"); } - public RestRequest GenerateDefaultRequest() - { - //Testchange2 - return new(BaseResource); - } - - internal BaseResponse ExecuteBaseResponseRequest(RestRequest request) - { - var response = ExecuteRequest(request, out var restResponse); - response.RestResponse = restResponse; - return response; - } + var response = + JsonConvert.DeserializeObject(strResponse, Constants.IgnoreDefaultValues); + if (response != null) ApplyObjectBaseTcaClient(response, true); - internal BaseResponse ExecuteBaseResponseRequest(RestRequest request) - { - var response = ExecuteRequest>(request, out var restResponse); - response.RestResponse = restResponse; - return response; - } - - internal ListResponse ExecuteListResponseRequest(RestRequest request) - { - var response = ExecuteRequest>(request, out var restResponse); - response.RestResponse = restResponse; - return response; - } - - internal T ExecuteRequest(RestRequest request) - { - return ExecuteRequest(request, out _); - } + return new Tuple(response, httpResponseMessage);; + } - internal T ExecuteRequest(RestRequest request, out IRestResponse restResponse) + public void ApplyObjectBaseTcaClient(object obj, bool recursive) + { + var type = obj.GetType(); + // if (type.IsSubclassOf(typeof(ITCAdminClientCompatible))) + if (typeof(ITCAdminClientCompatible).IsAssignableFrom(type)) { - var (t, restResponse2) = ExecuteRequestAsync(request).ConfigureAwait(false).GetAwaiter().GetResult(); - restResponse = restResponse2; - return t; + type.GetProperty(nameof(ITCAdminClientCompatible.TcaClient))?.SetValue(obj, TcaClient); } - internal async Task> ExecuteRequestAsync(RestRequest request) + if (recursive) { - Logger.Debug("Request URL: " + TcaClient.RestClient.BuildUri(request)); - var restResponse = await TcaClient.RestClient.ExecuteAsync(request); - Logger.Debug(restResponse.Content); - Logger.Debug("Response Status: " + restResponse.ResponseStatus); - Logger.Debug("Status Code: " + restResponse.StatusCode); - if (restResponse.ResponseStatus != ResponseStatus.Completed) + if (type.IsSubclassOf(typeof(BaseResponse))) { - throw new ApiResponseException(restResponse, "Response Status is: " + restResponse.ResponseStatus); - } - - if (restResponse.StatusCode != HttpStatusCode.OK) - { - throw new ApiResponseException(restResponse, "Status code is: " + restResponse.StatusCode); + var value = type.GetProperty("Result")?.GetValue(obj); + if (value != null) + { + ApplyObjectBaseTcaClient(value, recursive); + } } - var baseResponse = JsonConvert.DeserializeObject>(restResponse.Content); - baseResponse.RestResponse = restResponse; - if (!baseResponse.Success) + if (typeof(IEnumerable).IsAssignableFrom(type)) { - var tType = typeof(T); - if (tType.GenericTypeArguments.Contains(baseResponse.Result.GetType())) + var enumerable = (IEnumerable)obj; + foreach (var o in enumerable) { - return new Tuple(JsonConvert.DeserializeObject(restResponse.Content), restResponse); + ApplyObjectBaseTcaClient(o, recursive); } - - throw new ApiResponseException(restResponse, "API returned an error"); } - - return new Tuple(JsonConvert.DeserializeObject(restResponse.Content), restResponse); } } + + public static Uri Append(Uri uri, params string[] paths) + { + return new Uri(paths.Aggregate(uri.ToString(), (current, path) => + $"{current.TrimEnd('/')}/{path.TrimStart('/')}"), UriKind.RelativeOrAbsolute); + } } \ No newline at end of file diff --git a/TCAdminApiSharp/Controllers/ServersController.cs b/TCAdminApiSharp/Controllers/ServersController.cs new file mode 100644 index 0000000..f6dab2d --- /dev/null +++ b/TCAdminApiSharp/Controllers/ServersController.cs @@ -0,0 +1,27 @@ +using System.Threading.Tasks; +using TCAdminApiSharp.Entities.API; +using TCAdminApiSharp.Entities.Server; + +namespace TCAdminApiSharp.Controllers; + +public class ServersController : BaseController +{ + public ServersController(TcaClient tcaClient) : base(tcaClient, "api/server") + { + } + + public async Task GetServer(int serverId) + { + var request = GenerateDefaultRequest(serverId.ToString()); + var result = (await ExecuteBaseResponseRequest(request)).Result; + return result; + } + + public async Task> GetServers() + { + var request = GenerateDefaultRequest(); + var result = await ExecuteListResponseRequest(request); + + return result; + } +} \ No newline at end of file diff --git a/TCAdminApiSharp/Controllers/ServicesController.cs b/TCAdminApiSharp/Controllers/ServicesController.cs index 5a8149d..6f65264 100644 --- a/TCAdminApiSharp/Controllers/ServicesController.cs +++ b/TCAdminApiSharp/Controllers/ServicesController.cs @@ -1,53 +1,62 @@ -using System; -using System.Net; -using RestSharp; +using System.Collections.Generic; +using System.Net.Http; +using System.Threading.Tasks; +using Microsoft.AspNetCore.WebUtilities; using TCAdminApiSharp.Entities.API; using TCAdminApiSharp.Entities.Service; -using TCAdminApiSharp.Exceptions; -using TCAdminApiSharp.Exceptions.API; +using TCAdminApiSharp.Querying; +using TCAdminApiSharp.Querying.Operations; +using TCAdminApiSharp.Querying.Operators; -namespace TCAdminApiSharp.Controllers +namespace TCAdminApiSharp.Controllers; + +public class ServicesController : BaseController { - public class ServicesController : BaseController + public ServicesController(TcaClient tcaClient) : base(tcaClient, "api/service") + { + } + + public async Task CreateService(ServiceBuilder builder) + { + var body = builder.GenerateRequestBody(); + var request = GenerateDefaultRequest("create"); + request.Method = HttpMethod.Post; + request.Content = new FormUrlEncodedContent(new []{new KeyValuePair("createinfo", body)}); + var response = await ExecuteBaseResponseRequest(request); + return response.Result; + } + + public async Task> FindServices(QueryableInfo query) + { + var request = GenerateDefaultRequest(HttpMethod.Post, "gameservices"); + query.BuildQuery(request); + var result = await ExecuteListResponseRequest(request); + return result; + } + + public async Task GetService(int serviceId) + { + var request = GenerateDefaultRequest(serviceId.ToString()); + var result = (await ExecuteBaseResponseRequest(request)).Result; + return result; + } + + public async Task> GetServices() + { + var request = GenerateDefaultRequest("gameservices"); + var result = await ExecuteListResponseRequest(request); + return result; + } + + public Task> GetServicesByBillingId(string billingId) + { + return FindServices(new QueryableInfo(new WhereList("BillingId", ColumnOperator.Equal, billingId))); + } + + public async Task> GetServicesByUserId(int userId) { - public ServicesController() : base("api/service") - { - } - - public int CreateService(ServiceBuilder builder) - { - var body = builder.GenerateRequestBody(); - var request = GenerateDefaultRequest(); - request.Resource += "create"; - request.Method = Method.POST; - request.AddParameter("createinfo", body, ParameterType.GetOrPost); - return ExecuteBaseResponseRequest(request).Result; - } - - public Service GetService(int serviceId) - { - try - { - var request = GenerateDefaultRequest(); - request.Resource += serviceId; - return ExecuteBaseResponseRequest(request).Result; - } - catch (ApiResponseException e) - { - if (e.ErrorResponse.RestResponse.StatusCode == HttpStatusCode.NotFound) - { - throw new NotFoundException(typeof(Service), e, new []{serviceId}); - } - - throw; - } - } - - public ListResponse GetServices() - { - var request = GenerateDefaultRequest(); - request.Resource += "gameservices"; - return ExecuteListResponseRequest(request); - } + var request = GenerateDefaultRequest(QueryHelpers.AddQueryString("gameservices", nameof(userId), userId.ToString())); + var result = await ExecuteListResponseRequest(request); + return result; } } \ No newline at end of file diff --git a/TCAdminApiSharp/Controllers/TasksController.cs b/TCAdminApiSharp/Controllers/TasksController.cs index 0fdff4e..ee36202 100644 --- a/TCAdminApiSharp/Controllers/TasksController.cs +++ b/TCAdminApiSharp/Controllers/TasksController.cs @@ -1,52 +1,34 @@ -using System.Net; -using RestSharp; +using System; +using System.Threading.Tasks; +using Microsoft.AspNetCore.WebUtilities; using TCAdminApiSharp.Entities.API; using TCAdminApiSharp.Entities.Task; -using TCAdminApiSharp.Entities.User; -using TCAdminApiSharp.Exceptions; -using TCAdminApiSharp.Exceptions.API; +using Task = TCAdminApiSharp.Entities.Task.Task; -namespace TCAdminApiSharp.Controllers +namespace TCAdminApiSharp.Controllers; + +public class TasksController : BaseController { - public class TasksController : BaseController + public TasksController(TcaClient tcaClient) : base(tcaClient, "api/task") { - public TasksController() : base("api/task") - { - } + } - public Task GetTask(int taskId) - { - try - { - var request = GenerateDefaultRequest(); - request.Resource += taskId; - return ExecuteBaseResponseRequest(request).Result; - } - catch (ApiResponseException e) - { - if (e.ErrorResponse.RestResponse.StatusCode == HttpStatusCode.NotFound) - { - throw new NotFoundException(typeof(Task), e, new[] {taskId}); - } + public async Task GetTask(int taskId) + { + var request = GenerateDefaultRequest(taskId.ToString()); + return (await ExecuteBaseResponseRequest(request)).Result; + } - throw; - } - } + public Task> GetPendingTasks(int serverId) + { + var request = GenerateDefaultRequest(QueryHelpers.AddQueryString("getpendingtasks", nameof(serverId), serverId.ToString())); + return ExecuteListResponseRequest(request); + } - public ListResponse GetPendingTasks(int serverId) - { - var request = GenerateDefaultRequest(); - request.Resource += "getpendingtasks"; - request.AddParameter("serverId", serverId, ParameterType.QueryString); - return ExecuteListResponseRequest(request); - } - - public ListResponse GetTaskSteps(int taskId) - { - var request = GenerateDefaultRequest(); - request.Resource = "api/taskstep/getsteps"; - request.AddParameter("taskId", taskId, ParameterType.QueryString); - return ExecuteListResponseRequest(request); - } + public Task> GetTaskSteps(int taskId) + { + var request = GenerateDefaultRequest(); + request.RequestUri = new Uri(QueryHelpers.AddQueryString("api/taskstep/getsteps", nameof(taskId), taskId.ToString()), UriKind.RelativeOrAbsolute); + return ExecuteListResponseRequest(request); } } \ No newline at end of file diff --git a/TCAdminApiSharp/Controllers/UsersController.cs b/TCAdminApiSharp/Controllers/UsersController.cs index 428cea5..40e6d2e 100644 --- a/TCAdminApiSharp/Controllers/UsersController.cs +++ b/TCAdminApiSharp/Controllers/UsersController.cs @@ -1,65 +1,49 @@ -using System.Net; +using System.Net.Http; +using System.Threading.Tasks; using TCAdminApiSharp.Entities.API; using TCAdminApiSharp.Entities.User; -using TCAdminApiSharp.Exceptions; -using TCAdminApiSharp.Exceptions.API; +using TCAdminApiSharp.Querying; -namespace TCAdminApiSharp.Controllers +namespace TCAdminApiSharp.Controllers; + +public class UsersController : BaseController { - public class UsersController : BaseController + public UsersController(TcaClient tcaClient) : base(tcaClient, "api/user") + { + } + + public async Task GetUser(int userId) + { + var request = GenerateDefaultRequest(userId.ToString()); + var response = await ExecuteBaseResponseRequest(request); + return response.Result; + } + + public async Task GetMe() + { + var request = GenerateDefaultRequest("me"); + var response = await ExecuteBaseResponseRequest(request); + return response.Result; + } + + public async Task> FindUsers(QueryableInfo query) + { + var tokenUserId = await TcaClient.GetTokenUserId(); + var request = GenerateDefaultRequest(HttpMethod.Post, "myusers", tokenUserId.ToString()); + request.Method = HttpMethod.Post; + query.BuildQuery(request); + return await ExecuteListResponseRequest(request); + } + + public async Task> GetMyUsers() + { + var request = GenerateDefaultRequest("myusers"); + return await ExecuteListResponseRequest(request); + } + + public async Task> GetUsers() { - public UsersController() : base("api/user") - { - } - - public User GetUser(int userId) - { - try - { - var request = GenerateDefaultRequest(); - request.Resource += userId; - return ExecuteBaseResponseRequest(request).Result; - } - catch (ApiResponseException e) - { - if (e.ErrorResponse.RestResponse.StatusCode == HttpStatusCode.NotFound) - { - throw new NotFoundException(typeof(User), e, new []{userId}); - } - throw; - } - } - - public User GetMe() - { - try - { - var request = GenerateDefaultRequest(); - request.Resource += "me"; - return ExecuteBaseResponseRequest(request).Result; - } - catch (ApiResponseException e) - { - if (e.ErrorResponse.RestResponse.StatusCode == HttpStatusCode.NotFound) - { - throw new NotFoundException(typeof(User), e, new []{TcaClient.GetTokenUserId()}); - } - throw; - } - } - - public ListResponse GetMyUsers() - { - var request = GenerateDefaultRequest(); - request.Resource += "myusers"; - return ExecuteListResponseRequest(request); - } - - public ListResponse GetUsers() - { - var request = GenerateDefaultRequest(); - request.Resource += $"users/{TcaClient.GetTokenUserId()}"; - return ExecuteListResponseRequest(request); - } + var request = GenerateDefaultRequest("users", TcaClient.GetTokenUserId().ToString()); + return await ExecuteListResponseRequest(request); } } \ No newline at end of file diff --git a/TCAdminApiSharp/Entities/API/BaseResponse.cs b/TCAdminApiSharp/Entities/API/BaseResponse.cs index 34596a8..beba987 100644 --- a/TCAdminApiSharp/Entities/API/BaseResponse.cs +++ b/TCAdminApiSharp/Entities/API/BaseResponse.cs @@ -1,28 +1,28 @@ -using Newtonsoft.Json; -using RestSharp; +using System.Net.Http; +using Newtonsoft.Json; -namespace TCAdminApiSharp.Entities.API +namespace TCAdminApiSharp.Entities.API; + +public class BaseResponse { - public class BaseResponse - { - // Default to true - [JsonProperty("Success")] public bool Success { get; private set; } = true; + // Default to true + [JsonProperty("Success")] public bool Success { get; private set; } = true; - [JsonProperty("Message")] public string? Message { get; private set; } - - public IRestResponse RestResponse { get; internal set; } + [JsonProperty("Message")] public string? Message { get; private set; } - internal BaseResponse() - { - } + [JsonIgnore] public HttpResponseMessage ResponseMessage { get; internal set; } + [JsonIgnore] public HttpRequestMessage RequestMessage { get; internal set; } + + internal BaseResponse() + { } - - public class BaseResponse : BaseResponse +} + +public class BaseResponse : BaseResponse +{ + [JsonProperty("Result")] public T Result { get; private set; } + + internal BaseResponse() { - [JsonProperty("Result")] public T Result { get; private set; } - - internal BaseResponse() - { - } } } \ No newline at end of file diff --git a/TCAdminApiSharp/Entities/API/EmptyResponse.cs b/TCAdminApiSharp/Entities/API/EmptyResponse.cs deleted file mode 100644 index b4753a6..0000000 --- a/TCAdminApiSharp/Entities/API/EmptyResponse.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace TCAdminApiSharp.Entities.API -{ - public class EmptyResponse - { - - } -} \ No newline at end of file diff --git a/TCAdminApiSharp/Entities/API/ErrorResponse.cs b/TCAdminApiSharp/Entities/API/ErrorResponse.cs index 5c4422e..de6d397 100644 --- a/TCAdminApiSharp/Entities/API/ErrorResponse.cs +++ b/TCAdminApiSharp/Entities/API/ErrorResponse.cs @@ -1,22 +1,22 @@ using System; +using System.Net.Http; using Newtonsoft.Json; -using RestSharp; -namespace TCAdminApiSharp.Entities.API +namespace TCAdminApiSharp.Entities.API; + +public class ErrorResponse : BaseResponse { - public class ErrorResponse : BaseResponse + internal ErrorResponse(HttpResponseMessage responseMessage) { - internal ErrorResponse(IRestResponse restResponse) + try + { + JsonConvert.PopulateObject(responseMessage.Content.ReadAsStringAsync().Result, this); + } + catch (Exception e) { - try - { - JsonConvert.PopulateObject(restResponse.Content, this); - } - catch (Exception e) - { - throw new Exception("Couldn't parse API error to object!", e); - } - this.RestResponse = restResponse; + throw new Exception("Couldn't parse API error to object!", e); } + + ResponseMessage = responseMessage; } } \ No newline at end of file diff --git a/TCAdminApiSharp/Entities/API/ListResponse.cs b/TCAdminApiSharp/Entities/API/ListResponse.cs index d7ecf3c..2b1e540 100644 --- a/TCAdminApiSharp/Entities/API/ListResponse.cs +++ b/TCAdminApiSharp/Entities/API/ListResponse.cs @@ -1,13 +1,13 @@ using System.Collections.Generic; using Newtonsoft.Json; -namespace TCAdminApiSharp.Entities.API +namespace TCAdminApiSharp.Entities.API; + +public class ListResponse : BaseResponse> { - public class ListResponse : BaseResponse> - { - /// - /// Only returns when "RowCount" was specified in the request. - /// - [JsonProperty("VirtualCount")] public int VirtualCount { get; internal set; } - } + /// + /// Only returns when "RowCount" was specified in the request. + /// + [JsonProperty("Count")] + public int Count { get; internal set; } } \ No newline at end of file diff --git a/TCAdminApiSharp/Entities/Billing/BillingStatus.cs b/TCAdminApiSharp/Entities/Billing/BillingStatus.cs index 9cf3823..0e1642e 100644 --- a/TCAdminApiSharp/Entities/Billing/BillingStatus.cs +++ b/TCAdminApiSharp/Entities/Billing/BillingStatus.cs @@ -1,8 +1,7 @@ -namespace TCAdminApiSharp.Entities.Billing +namespace TCAdminApiSharp.Entities.Billing; + +public enum BillingStatus { - public enum BillingStatus - { - Active = 1, - Suspended = 2, - } + Active = 1, + Suspended = 2 } \ No newline at end of file diff --git a/TCAdminApiSharp/Entities/Generic/IPowerable.cs b/TCAdminApiSharp/Entities/Generic/IPowerable.cs index 79eef94..68a951d 100644 --- a/TCAdminApiSharp/Entities/Generic/IPowerable.cs +++ b/TCAdminApiSharp/Entities/Generic/IPowerable.cs @@ -1,11 +1,10 @@ using System.Threading.Tasks; -namespace TCAdminApiSharp.Entities.Generic +namespace TCAdminApiSharp.Entities.Generic; + +public interface IPowerable { - public interface IPowerable - { - public void Start(string reason = ""); - public void Restart(string reason = ""); - public void Stop(string reason = ""); - } + public Task Start(string reason = ""); + public Task Restart(string reason = ""); + public Task Stop(string reason = ""); } \ No newline at end of file diff --git a/TCAdminApiSharp/Entities/Generic/ObjectBase.cs b/TCAdminApiSharp/Entities/Generic/ObjectBase.cs index cc9a736..741065e 100644 --- a/TCAdminApiSharp/Entities/Generic/ObjectBase.cs +++ b/TCAdminApiSharp/Entities/Generic/ObjectBase.cs @@ -1,25 +1,33 @@ using System; +using System.Threading.Tasks; using Newtonsoft.Json; -namespace TCAdminApiSharp.Entities.Generic +namespace TCAdminApiSharp.Entities.Generic; + +public class ObjectBase : ITCAdminClientCompatible { - public class ObjectBase - { - [JsonProperty("AppData")] public TcaXmlField AppData { get; set; } - - [JsonProperty("CreatedOn")] public DateTime CreatedOn { get; set; } + [JsonProperty("AppData")] public TcaXmlField AppData { get; set; } + + [JsonProperty("CreatedOn")] public DateTime CreatedOn { get; set; } - [JsonProperty("CreatedBy")] public int CreatedBy { get; set; } + [JsonProperty("CreatedBy")] public int CreatedBy { get; set; } - [JsonProperty("ModifiedOn")] public DateTime ModifiedOn { get; set; } + [JsonProperty("ModifiedOn")] public DateTime ModifiedOn { get; set; } - [JsonProperty("ModifiedBy")] public int ModifiedBy { get; set; } - } + [JsonProperty("ModifiedBy")] public int ModifiedBy { get; set; } + + // ReSharper disable once UnusedAutoPropertyAccessor.Global + [JsonIgnore] public TcaClient TcaClient { get; internal set; } +} - public interface IObjectBaseCrud - { - public void Update(Action action); +public interface ITCAdminClientCompatible +{ + [JsonIgnore] public TcaClient TcaClient { get; } +} + +public interface IObjectBaseCrud +{ + public Task Update(Action action); - public void Delete(); - } + public Task Delete(); } \ No newline at end of file diff --git a/TCAdminApiSharp/Entities/Generic/TcaXmlField.cs b/TCAdminApiSharp/Entities/Generic/TcaXmlField.cs index d009119..0065840 100644 --- a/TCAdminApiSharp/Entities/Generic/TcaXmlField.cs +++ b/TCAdminApiSharp/Entities/Generic/TcaXmlField.cs @@ -1,15 +1,14 @@ using System.Collections.Generic; -namespace TCAdminApiSharp.Entities.Generic +namespace TCAdminApiSharp.Entities.Generic; + +public class TcaXmlField : Dictionary { - public class TcaXmlField : Dictionary + public TcaXmlField() { - public TcaXmlField() - { - } + } - public TcaXmlField(IDictionary dictionary) : base(dictionary) - { - } + public TcaXmlField(IDictionary dictionary) : base(dictionary) + { } } \ No newline at end of file diff --git a/TCAdminApiSharp/Entities/Server/Server.cs b/TCAdminApiSharp/Entities/Server/Server.cs new file mode 100644 index 0000000..789c833 --- /dev/null +++ b/TCAdminApiSharp/Entities/Server/Server.cs @@ -0,0 +1,256 @@ +using System; +using System.Net.Http; +using System.Text; +using System.Threading.Tasks; +using Newtonsoft.Json; +using TCAdminApiSharp.Entities.Generic; +using TCAdminApiSharp.Helpers; + +namespace TCAdminApiSharp.Entities.Server; + +public class Server : ObjectBase, IObjectBaseCrud +{ + [JsonProperty("DisableNewServices")] public bool DisableNewServices { get; set; } + + [JsonProperty("GameFilesPath")] public string GameFilesPath { get; set; } + + [JsonProperty("VSUseCustomGameFiles")] public bool VsUseCustomGameFiles { get; set; } + + [JsonProperty("ExtractSpeed")] public int ExtractSpeed { get; set; } + + [JsonProperty("UserFilesPath")] public string UserFilesPath { get; set; } + + [JsonProperty("FolderTemplate")] public string FolderTemplate { get; set; } + + [JsonProperty("KeepLocalCopy")] public bool KeepLocalCopy { get; set; } + + [JsonProperty("LastServiceCreationUtc")] + public DateTime LastServiceCreationUtc { get; set; } + + [JsonProperty("EnableFileSharing")] public bool EnableFileSharing { get; set; } + + [JsonProperty("EnableFastDownload")] public bool EnableFastDownload { get; set; } + + [JsonProperty("ServerFileProviderModuleId")] + public string ServerFileProviderModuleId { get; set; } + + [JsonProperty("ServerFileProviderId")] public int ServerFileProviderId { get; set; } + + [JsonProperty("ClientFileProviderModuleId")] + public string ClientFileProviderModuleId { get; set; } + + [JsonProperty("ClientFileProviderId")] public int ClientFileProviderId { get; set; } + + [JsonProperty("ClientFileProviderSourceId")] + public int ClientFileProviderSourceId { get; set; } + + [JsonProperty("FastDownloadFolderTemplate")] + public string FastDownloadFolderTemplate { get; set; } + + [JsonProperty("FastDownloadSavePath")] public string FastDownloadSavePath { get; set; } + + [JsonProperty("FastDownloadUrl")] public string FastDownloadUrl { get; set; } + + [JsonProperty("ClientFastDownloadProviderModuleId")] + public string ClientFastDownloadProviderModuleId { get; set; } + + [JsonProperty("ClientFastDownloadProviderId")] + public int ClientFastDownloadProviderId { get; set; } + + [JsonProperty("ClientFastDownloadProviderSourceId")] + public int ClientFastDownloadProviderSourceId { get; set; } + + [JsonProperty("NumberOfServices")] public int NumberOfServices { get; set; } + + [JsonProperty("NumberOfVoiceServices")] + public int NumberOfVoiceServices { get; set; } + + [JsonProperty("NumberOfSlots")] public int NumberOfSlots { get; set; } + + [JsonProperty("NumberOfVoiceSlots")] public int NumberOfVoiceSlots { get; set; } + + [JsonProperty("MaxSlots")] public int MaxSlots { get; set; } + + [JsonProperty("SkipSuspendedServices")] + public bool SkipSuspendedServices { get; set; } + + [JsonProperty("SeparateVoiceSots")] public bool SeparateVoiceSots { get; set; } + + [JsonProperty("MaxVoiceSlots")] public int MaxVoiceSlots { get; set; } + + [JsonProperty("MaxServices")] public int MaxServices { get; set; } + + [JsonProperty("SeparateVoiceServices")] + public bool SeparateVoiceServices { get; set; } + + [JsonProperty("MaxVoiceServices")] public int MaxVoiceServices { get; set; } + + [JsonProperty("ServerId")] public int ServerId { get; set; } + + [JsonProperty("PrivateNetworkId")] public int PrivateNetworkId { get; set; } + + [JsonProperty("PrivateNetworkIp")] public string PrivateNetworkIp { get; set; } + + [JsonProperty("DisableVirtualServerUser")] + public bool DisableVirtualServerUser { get; set; } + + [JsonProperty("UseCustomDatacenterId")] + public bool UseCustomDatacenterId { get; set; } + + [JsonProperty("DatacenterId")] public int DatacenterId { get; set; } + + [JsonProperty("OwnerId")] public int OwnerId { get; set; } + + [JsonProperty("OwnerIdFriendlyName")] public string OwnerIdFriendlyName { get; set; } + + [JsonProperty("IsMaster")] public bool IsMaster { get; set; } + + [JsonProperty("OperatingSystem")] public int OperatingSystem { get; set; } + + [JsonProperty("PrimaryIp")] public string PrimaryIp { get; set; } + + [JsonProperty("SecurePort")] public int SecurePort { get; set; } + + [JsonProperty("StandardPort")] public int StandardPort { get; set; } + + [JsonProperty("BindAllIps")] public bool BindAllIps { get; set; } + + [JsonProperty("FirewallIp")] public string FirewallIp { get; set; } + + [JsonProperty("Name")] public string Name { get; set; } + + [JsonProperty("Enabled")] public bool Enabled { get; set; } + + [JsonProperty("DisableUpdates")] public bool DisableUpdates { get; set; } + + [JsonProperty("MonitorVirtualDirectory")] + public string MonitorVirtualDirectory { get; set; } + + [JsonProperty("PublicVirtualDirectory")] + public string PublicVirtualDirectory { get; set; } + + [JsonProperty("ControlPanelEnableBasicAuth")] + public bool ControlPanelEnableBasicAuth { get; set; } + + [JsonProperty("ControlPanelRealm")] public string ControlPanelRealm { get; set; } + + [JsonProperty("ControlPanelLogOutUrl")] + public string ControlPanelLogOutUrl { get; set; } + + [JsonProperty("WindowsFirewallEnabled")] + public bool WindowsFirewallEnabled { get; set; } + + [JsonProperty("uPnPPortForwardingEnabled")] + public bool UPnPPortForwardingEnabled { get; set; } + + [JsonProperty("MonitorLogin")] public string MonitorLogin { get; set; } + + [JsonProperty("MonitorPassword")] public string MonitorPassword { get; set; } + + [JsonProperty("MonitorVersion")] public string MonitorVersion { get; set; } + + [JsonProperty("FileSystemComparison")] public int FileSystemComparison { get; set; } + + [JsonProperty("FileSystemDirectorySeparator")] + public string FileSystemDirectorySeparator { get; set; } + + [JsonProperty("DatacenterName")] public string DatacenterName { get; set; } + + [JsonProperty("IsVirtual")] public bool IsVirtual { get; set; } + + [JsonProperty("RealServerId")] public int RealServerId { get; set; } + + [JsonProperty("RealServerName")] public string RealServerName { get; set; } + + [JsonProperty("KeepAlive")] public int KeepAlive { get; set; } + + [JsonProperty("NumberOfProcessors")] public int NumberOfProcessors { get; set; } + + [JsonProperty("MaxNumaNode")] public int MaxNumaNode { get; set; } + + [JsonProperty("MonitorAffinity")] public int MonitorAffinity { get; set; } + + [JsonProperty("MonitorNumaNode")] public int MonitorNumaNode { get; set; } + + [JsonProperty("MonitorPriority")] public int MonitorPriority { get; set; } + + [JsonProperty("Affinity")] public int Affinity { get; set; } + + [JsonProperty("NumaNode")] public int NumaNode { get; set; } + + [JsonProperty("Memory")] public long Memory { get; set; } + + [JsonProperty("MemoryMB")] public int MemoryMb { get; set; } + + [JsonProperty("MemoryString")] public string MemoryString { get; set; } + + [JsonProperty("DiskSpace")] public int DiskSpace { get; set; } + + [JsonProperty("DiskSpaceMB")] public int DiskSpaceMb { get; set; } + + [JsonProperty("DiskSpaceString")] public string DiskSpaceString { get; set; } + + [JsonProperty("DiskDrive")] public string DiskDrive { get; set; } + + [JsonProperty("CustomField1")] public string CustomField1 { get; set; } + + [JsonProperty("CustomField2")] public string CustomField2 { get; set; } + + [JsonProperty("CustomField3")] public string CustomField3 { get; set; } + + [JsonProperty("CustomField4")] public string CustomField4 { get; set; } + + [JsonProperty("CustomField5")] public string CustomField5 { get; set; } + + [JsonProperty("CustomField6")] public string CustomField6 { get; set; } + + [JsonProperty("CustomField7")] public string CustomField7 { get; set; } + + [JsonProperty("CustomField8")] public string CustomField8 { get; set; } + + [JsonProperty("CustomField9")] public string CustomField9 { get; set; } + + [JsonProperty("CustomField10")] public string CustomField10 { get; set; } + + [JsonProperty("CustomField11")] public string CustomField11 { get; set; } + + [JsonProperty("CustomField12")] public string CustomField12 { get; set; } + + [JsonProperty("CustomField13")] public string CustomField13 { get; set; } + + [JsonProperty("CustomField14")] public string CustomField14 { get; set; } + + [JsonProperty("CustomField15")] public string CustomField15 { get; set; } + + [JsonProperty("BillingId")] public string BillingId { get; set; } + + [JsonProperty("BillingStatus")] public int BillingStatus { get; set; } + + [JsonProperty("PeakMemoryMB")] public double PeakMemoryMb { get; set; } + + [JsonProperty("PeakCPU")] public double PeakCpu { get; set; } + + [JsonProperty("DCSyncUrl")] public string DcSyncUrl { get; set; } + + [JsonProperty("DCDownloadServer")] public string DcDownloadServer { get; set; } + + [JsonProperty("DCDownloadUser")] public string DcDownloadUser { get; set; } + + [JsonProperty("DCDownloadPassword")] public string DcDownloadPassword { get; set; } + + public async Task Update(Action action) + { + var server = new Server(); + action(server); + var putJson = JsonConvert.SerializeObject(server, Constants.IgnoreDefaultValues); + var request = TcaClient.ServersController.GenerateDefaultRequest(ServerId.ToString()); + request.Method = HttpMethod.Put; + request.Content = new StringContent(putJson, Encoding.UTF8, Constants.JsonContentType); + return (await TcaClient.ServersController.ExecuteBaseResponseRequest(request)).Success; + } + + public Task Delete() + { + throw new NotImplementedException(); + } +} \ No newline at end of file diff --git a/TCAdminApiSharp/Entities/Service/EServiceStatus.cs b/TCAdminApiSharp/Entities/Service/EServiceStatus.cs new file mode 100644 index 0000000..be0f05c --- /dev/null +++ b/TCAdminApiSharp/Entities/Service/EServiceStatus.cs @@ -0,0 +1,16 @@ +namespace TCAdminApiSharp.Entities.Service; + +public enum EServiceStatus +{ + Processing = -3, // 0xFFFFFFFD + StartError = -2, // 0xFFFFFFFE + Unknown = -1, // 0xFFFFFFFF + Disabled = 0, + Stopped = 1, + Starting = 2, + Stopping = 3, + Running = 4, + Resuming = 5, + Pausing = 6, + Paused = 7 +} \ No newline at end of file diff --git a/TCAdminApiSharp/Entities/Service/FileManager/CompressModel.cs b/TCAdminApiSharp/Entities/Service/FileManager/CompressModel.cs new file mode 100644 index 0000000..40180f2 --- /dev/null +++ b/TCAdminApiSharp/Entities/Service/FileManager/CompressModel.cs @@ -0,0 +1,9 @@ +using Newtonsoft.Json; + +namespace TCAdminApiSharp.Entities.Service.FileManager; + +public class CompressModel +{ + [JsonProperty("Zip")] + public string Zip { get; set; } +} \ No newline at end of file diff --git a/TCAdminApiSharp/Entities/Service/FileManager/DirectoryListing.cs b/TCAdminApiSharp/Entities/Service/FileManager/DirectoryListing.cs new file mode 100644 index 0000000..6893175 --- /dev/null +++ b/TCAdminApiSharp/Entities/Service/FileManager/DirectoryListing.cs @@ -0,0 +1,48 @@ +using System; +using Newtonsoft.Json; + +namespace TCAdminApiSharp.Entities.Service.FileManager; + +public class DirectoryListing +{ + [JsonProperty("Name")] + public string Name { get; set; } + + [JsonProperty("Size")] + public long Size { get; set; } + + [JsonProperty("Path")] + public string Path { get; set; } + + [JsonProperty("Extension")] + public string Extension { get; set; } + + [JsonProperty("IsDirectory")] + public bool IsDirectory { get; set; } + + [JsonIgnore] public bool IsFile => !IsDirectory; + + [JsonProperty("HasDirectories")] + public bool HasDirectories { get; set; } + + [JsonProperty("Created")] + public DateTimeOffset Created { get; set; } + + [JsonProperty("CreatedUtc")] + public DateTimeOffset CreatedUtc { get; set; } + + [JsonProperty("Modified")] + public DateTimeOffset Modified { get; set; } + + [JsonProperty("ModifiedUtc")] + public DateTimeOffset ModifiedUtc { get; set; } + + [JsonIgnore] + public FileManagerService FileManagerService { get; internal set; } + + public System.Threading.Tasks.Task Rename(string newName) => FileManagerService.Rename(this.Path, newName); + public System.Threading.Tasks.Task Move(string target, bool overwrite = true) => FileManagerService.Move(new []{this.Path}, target, overwrite); + public System.Threading.Tasks.Task Copy(string target, bool overwrite = true) => FileManagerService.Copy(new []{this.Path}, target, overwrite); + public System.Threading.Tasks.Task Compress(string target) => FileManagerService.Compress(new []{this.Path}, target); + public System.Threading.Tasks.Task Delete() => FileManagerService.Delete(this.Path); +} \ No newline at end of file diff --git a/TCAdminApiSharp/Entities/Service/FileManager/FileInfo.cs b/TCAdminApiSharp/Entities/Service/FileManager/FileInfo.cs new file mode 100644 index 0000000..17dacf0 --- /dev/null +++ b/TCAdminApiSharp/Entities/Service/FileManager/FileInfo.cs @@ -0,0 +1,62 @@ +using System; +using Newtonsoft.Json; + +namespace TCAdminApiSharp.Entities.Service.FileManager; + +public class FileInfo +{ + [JsonProperty("Attributes")] + public long Attributes { get; set; } + + [JsonProperty("CreationTime")] + public DateTimeOffset CreationTime { get; set; } + + [JsonProperty("CreationTimeUtc")] + public DateTimeOffset CreationTimeUtc { get; set; } + + [JsonProperty("Exists")] + public bool Exists { get; set; } + + [JsonProperty("Extension")] + public string Extension { get; set; } + + [JsonProperty("FullName")] + public string FullName { get; set; } + + [JsonProperty("LastAccessTime")] + public DateTimeOffset LastAccessTime { get; set; } + + [JsonProperty("LastAccessTimeUtc")] + public DateTimeOffset LastAccessTimeUtc { get; set; } + + [JsonProperty("LastWriteTime")] + public DateTimeOffset LastWriteTime { get; set; } + + [JsonProperty("LastWriteTimeUtc")] + public DateTimeOffset LastWriteTimeUtc { get; set; } + + [JsonProperty("Name")] + public string Name { get; set; } + + [JsonProperty("Directory")] + public string Directory { get; set; } + + [JsonProperty("IsReadOnly")] + public bool IsReadOnly { get; set; } + + [JsonProperty("Length")] + public long Length { get; set; } + + [JsonProperty("LinuxExecutable")] + public bool LinuxExecutable { get; set; } + + [JsonIgnore] + public FileManagerService FileManagerService { get; internal set; } + + public System.Threading.Tasks.Task Rename(string newName) => FileManagerService.Rename(this.FullName, newName); + public System.Threading.Tasks.Task Move(string target, bool overwrite = true) => FileManagerService.Move(new []{this.FullName}, target, overwrite); + public System.Threading.Tasks.Task Copy(string target, bool overwrite = true) => FileManagerService.Copy(new []{this.FullName}, target, overwrite); + public System.Threading.Tasks.Task Compress(string target) => FileManagerService.Compress(new []{this.FullName}, target); + public System.Threading.Tasks.Task Extract(string target) => FileManagerService.Extract(this.FullName, target); + public System.Threading.Tasks.Task Delete() => FileManagerService.Delete(this.FullName); +} \ No newline at end of file diff --git a/TCAdminApiSharp/Entities/Service/FileManager/FileManagerService.cs b/TCAdminApiSharp/Entities/Service/FileManager/FileManagerService.cs new file mode 100644 index 0000000..9514c1c --- /dev/null +++ b/TCAdminApiSharp/Entities/Service/FileManager/FileManagerService.cs @@ -0,0 +1,145 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Net.Http; +using Microsoft.AspNetCore.WebUtilities; +using Newtonsoft.Json; +using TCAdminApiSharp.Entities.Generic; + +namespace TCAdminApiSharp.Entities.Service.FileManager; + +public class FileManagerService : ITCAdminClientCompatible +{ + public TcaClient TcaClient { get; set; } + private readonly Service _service; + private string FileManagerEndpoint => _service.ServiceId + "/FileManager"; + + public FileManagerService(TcaClient tcaClient, Service service) + { + _service = service; + TcaClient = tcaClient; + } + + public FileManagerService(Service service) : this(service.TcaClient, service) + { + } + + public async System.Threading.Tasks.Task GetDirectoryListing(string path = "/") + { + var realPath = path[(path.LastIndexOf("/", StringComparison.Ordinal) + 1)..]; + var parentPath = path[..(path.LastIndexOf("/", StringComparison.Ordinal) + 1)]; + var directoryListings = await GetDirectoryListings(parentPath); + var directoryListing = directoryListings.First(x => x.Path == realPath); + return directoryListing; + } + + public async System.Threading.Tasks.Task> GetDirectoryListings(string path = "/") + { + if (string.IsNullOrEmpty(path)) + { + path = "/"; + } + + path = path.Replace("\\", "/"); + + var endpoint = QueryHelpers.AddQueryString(FileManagerEndpoint, nameof(path), path); + var request = TcaClient.ServicesController.GenerateDefaultRequest(endpoint); + var executeBaseResponseRequest = await TcaClient.ServicesController.ExecuteBaseResponseRequest>(request); + foreach (var directoryListing in executeBaseResponseRequest.Result) + { + directoryListing.FileManagerService = this; + } + return executeBaseResponseRequest.Result; + } + + public async System.Threading.Tasks.Task GetFileInfo(string path) + { + if (path == null) throw new ArgumentNullException(nameof(path)); + var endpoint = QueryHelpers.AddQueryString(FileManagerEndpoint, nameof(path), path); + var request = TcaClient.ServicesController.GenerateDefaultRequest(endpoint); + var executeBaseResponseRequest = await TcaClient.ServicesController.ExecuteBaseResponseRequest(request); + executeBaseResponseRequest.Result.FileManagerService = this; + return executeBaseResponseRequest.Result; + } + + public async System.Threading.Tasks.Task Rename(string path, string newName) + { + if (path == null) throw new ArgumentNullException(nameof(path)); + if (newName == null) throw new ArgumentNullException(nameof(newName)); + var request = TcaClient.ServicesController.GenerateDefaultRequest(HttpMethod.Post, FileManagerEndpoint,nameof(Rename)); + request.Content = new FormUrlEncodedContent(new KeyValuePair[] + { + new(nameof(path), path), + new(nameof(newName), newName) + }); + var executeBaseResponseRequest = await TcaClient.ServicesController.ExecuteBaseResponseRequest(request); + return executeBaseResponseRequest.Success; + } + + public async System.Threading.Tasks.Task Move(string[] files, string target, bool overwrite = true) + { + if (files == null) throw new ArgumentNullException(nameof(files)); + if (target == null) throw new ArgumentNullException(nameof(target)); + var request = TcaClient.ServicesController.GenerateDefaultRequest(HttpMethod.Post, FileManagerEndpoint, nameof(Move)); + request.Content = new FormUrlEncodedContent(new KeyValuePair[] + { + new(nameof(files), JsonConvert.SerializeObject(files)), + new(nameof(target), target), + new(nameof(overwrite), overwrite.ToString()) + }); + var executeBaseResponseRequest = await TcaClient.ServicesController.ExecuteBaseResponseRequest(request); + return executeBaseResponseRequest.Success; + } + + public async System.Threading.Tasks.Task Copy(string[] files, string target, bool overwrite = true) + { + if (files == null) throw new ArgumentNullException(nameof(files)); + if (target == null) throw new ArgumentNullException(nameof(target)); + var request = TcaClient.ServicesController.GenerateDefaultRequest(HttpMethod.Post, FileManagerEndpoint, nameof(Copy)); + request.Content = new FormUrlEncodedContent(new KeyValuePair[] + { + new(nameof(files), JsonConvert.SerializeObject(files)), + new(nameof(target), target), + new(nameof(overwrite), overwrite.ToString()) + }); + var executeBaseResponseRequest = await TcaClient.ServicesController.ExecuteBaseResponseRequest(request); + return executeBaseResponseRequest.Success; + } + + public async System.Threading.Tasks.Task Compress(string[] files, string target) + { + if (files == null) throw new ArgumentNullException(nameof(files)); + if (target == null) throw new ArgumentNullException(nameof(target)); + var request = TcaClient.ServicesController.GenerateDefaultRequest(HttpMethod.Post, FileManagerEndpoint, nameof(Compress)); + request.Content = new FormUrlEncodedContent(new KeyValuePair[] + { + new(nameof(files), JsonConvert.SerializeObject(files)), + new(nameof(target), target), + }); + var executeBaseResponseRequest = await TcaClient.ServicesController.ExecuteBaseResponseRequest(request); + return executeBaseResponseRequest.Result; + } + + public async System.Threading.Tasks.Task Extract(string file, string extractPath) + { + if (file == null) throw new ArgumentNullException(nameof(file)); + if (extractPath == null) throw new ArgumentNullException(nameof(extractPath)); + var request = TcaClient.ServicesController.GenerateDefaultRequest(HttpMethod.Post, FileManagerEndpoint, nameof(Compress)); + request.Content = new FormUrlEncodedContent(new KeyValuePair[] + { + new(nameof(file), file), + new(nameof(extractPath), extractPath), + }); + var executeBaseResponseRequest = await TcaClient.ServicesController.ExecuteBaseResponseRequest(request); + return executeBaseResponseRequest.Success; + } + + public async System.Threading.Tasks.Task Delete(string path) + { + if (path == null) throw new ArgumentNullException(nameof(path)); + var endpoint = QueryHelpers.AddQueryString(FileManagerEndpoint, nameof(path), path); + var request = TcaClient.ServicesController.GenerateDefaultRequest(HttpMethod.Post, endpoint); + var executeBaseResponseRequest = await TcaClient.ServicesController.ExecuteBaseResponseRequest(request); + return executeBaseResponseRequest.Success; + } +} \ No newline at end of file diff --git a/TCAdminApiSharp/Entities/Service/Player.cs b/TCAdminApiSharp/Entities/Service/Player.cs new file mode 100644 index 0000000..6a4b8e8 --- /dev/null +++ b/TCAdminApiSharp/Entities/Service/Player.cs @@ -0,0 +1,12 @@ +using Newtonsoft.Json; + +namespace TCAdminApiSharp.Entities.Service; + +public class Player +{ + [JsonProperty("Name", NullValueHandling = NullValueHandling.Ignore)] + public string Name { get; set; } + + [JsonProperty("Ping", NullValueHandling = NullValueHandling.Ignore)] + public int Ping { get; set; } +} \ No newline at end of file diff --git a/TCAdminApiSharp/Entities/Service/Service.cs b/TCAdminApiSharp/Entities/Service/Service.cs index 4e961de..aad74f7 100644 --- a/TCAdminApiSharp/Entities/Service/Service.cs +++ b/TCAdminApiSharp/Entities/Service/Service.cs @@ -1,304 +1,328 @@ using System; using System.Collections.Generic; -using Microsoft.Extensions.DependencyInjection; +using System.Net.Http; +using System.Text; +using System.Threading.Tasks; using Newtonsoft.Json; -using RestSharp; -using TCAdminApiSharp.Controllers; using TCAdminApiSharp.Entities.Billing; using TCAdminApiSharp.Entities.Generic; +using TCAdminApiSharp.Entities.Service.FileManager; using TCAdminApiSharp.Helpers; +// ReSharper disable UnusedMember.Global -namespace TCAdminApiSharp.Entities.Service +namespace TCAdminApiSharp.Entities.Service; + +public class Service : ObjectBase, IObjectBaseCrud, IPowerable { - public class Service : ObjectBase, IObjectBaseCrud, IPowerable - { - [JsonIgnore] - public readonly ServicesController ServicesController = - TcaClient.ServiceProvider.GetService() ?? throw new InvalidOperationException(); - - [JsonProperty("EnableGameSwitching")] public bool EnableGameSwitching { get; set; } + [JsonProperty("EnableGameSwitching")] public bool EnableGameSwitching { get; set; } - [JsonProperty("DisableQueryMonitoring")] - public bool DisableQueryMonitoring { get; set; } + [JsonProperty("DisableQueryMonitoring")] + public bool DisableQueryMonitoring { get; set; } - [JsonProperty("DisableSlotMonitoring")] - public bool DisableSlotMonitoring { get; set; } + [JsonProperty("DisableSlotMonitoring")] + public bool DisableSlotMonitoring { get; set; } - [JsonProperty("DisablePrivateMonitoring")] - public bool DisablePrivateMonitoring { get; set; } + [JsonProperty("DisablePrivateMonitoring")] + public bool DisablePrivateMonitoring { get; set; } - [JsonProperty("DisableBrandedMonitoring")] - public bool DisableBrandedMonitoring { get; set; } + [JsonProperty("DisableBrandedMonitoring")] + public bool DisableBrandedMonitoring { get; set; } - [JsonProperty("GameSwitchingAllowedGames")] - public IList GameSwitchingAllowedGames { get; set; } + [JsonProperty("GameSwitchingAllowedGames")] + public IList GameSwitchingAllowedGames { get; set; } - [JsonProperty("FastDownloadUsage")] public int FastDownloadUsage { get; set; } + [JsonProperty("FastDownloadUsage")] public int FastDownloadUsage { get; set; } - [JsonProperty("FastDownloadFileCount")] - public int FastDownloadFileCount { get; set; } + [JsonProperty("FastDownloadFileCount")] + public int FastDownloadFileCount { get; set; } - [JsonProperty("ServiceId")] public int ServiceId { get; set; } + [JsonProperty("ServiceId")] public int ServiceId { get; set; } - [JsonProperty("MemoryLimitMB")] public int MemoryLimitMB { get; set; } + [JsonProperty("MemoryLimitMB")] public int MemoryLimitMB { get; set; } - [JsonProperty("CpuLimit")] public int CpuLimit { get; set; } + [JsonProperty("CpuLimit")] public int CpuLimit { get; set; } - [JsonProperty("ServerId")] public int ServerId { get; set; } + [JsonProperty("ServerId")] public int ServerId { get; set; } - [JsonProperty("BillingId")] public string BillingId { get; set; } + [JsonProperty("BillingId")] public string BillingId { get; set; } - [JsonProperty("BillingStatus")] public BillingStatus BillingStatus { get; set; } + [JsonProperty("BillingStatus")] public BillingStatus BillingStatus { get; set; } - [JsonProperty("GameId")] public int GameId { get; set; } + [JsonProperty("GameId")] public int GameId { get; set; } - [JsonProperty("UserPackageId")] public int UserPackageId { get; set; } + [JsonProperty("UserPackageId")] public int UserPackageId { get; set; } - [JsonProperty("UserId")] public int UserId { get; set; } + [JsonProperty("UserId")] public int UserId { get; set; } - [JsonProperty("Executable")] public string? Executable { get; set; } + [JsonProperty("Executable")] public string? Executable { get; set; } - [JsonProperty("UnparsedCommandLine")] public string UnparsedCommandLine { get; set; } + [JsonProperty("UnparsedCommandLine")] public string UnparsedCommandLine { get; set; } - [JsonProperty("WorkingDirectory")] public string WorkingDirectory { get; set; } + [JsonProperty("WorkingDirectory")] public string WorkingDirectory { get; set; } - [JsonProperty("RootDirectory")] public string RootDirectory { get; set; } + [JsonProperty("RootDirectory")] public string RootDirectory { get; set; } - [JsonProperty("Private")] public bool Private { get; set; } + [JsonProperty("Private")] public bool Private { get; set; } - [JsonProperty("Slots")] public int Slots { get; set; } + [JsonProperty("Slots")] public int Slots { get; set; } - [JsonProperty("CurrentOnline")] public bool CurrentOnline { get; set; } + [JsonProperty("CurrentOnline")] public bool CurrentOnline { get; set; } - [JsonProperty("CurrentPid")] public int CurrentPid { get; set; } + [JsonProperty("CurrentPid")] public int CurrentPid { get; set; } - [JsonProperty("CurrentPlayers")] public int CurrentPlayers { get; set; } + [JsonProperty("CurrentPlayers")] public int CurrentPlayers { get; set; } - [JsonProperty("CurrentMaxPlayers")] public int CurrentMaxPlayers { get; set; } + [JsonProperty("CurrentMaxPlayers")] public int CurrentMaxPlayers { get; set; } - [JsonProperty("CurrentCpu")] public double CurrentCpu { get; set; } + [JsonProperty("CurrentCpu")] public double CurrentCpu { get; set; } - [JsonProperty("CurrentMemory")] public double CurrentMemory { get; set; } + [JsonProperty("CurrentMemory")] public double CurrentMemory { get; set; } - [JsonProperty("CurrentMemoryLimit")] public double CurrentMemoryLimit { get; set; } + [JsonProperty("CurrentMemoryLimit")] public double CurrentMemoryLimit { get; set; } - [JsonProperty("CurrentMemoryPercent")] public double CurrentMemoryPercent { get; set; } + [JsonProperty("CurrentMemoryPercent")] public double CurrentMemoryPercent { get; set; } - [JsonProperty("CurrentBandwidth")] public double CurrentBandwidth { get; set; } + [JsonProperty("CurrentBandwidth")] public double CurrentBandwidth { get; set; } - [JsonProperty("CurrentMap")] public string CurrentMap { get; set; } + [JsonProperty("CurrentMap")] public string CurrentMap { get; set; } - [JsonProperty("CurrentGameType")] public string CurrentGameType { get; set; } + [JsonProperty("CurrentGameType")] public string CurrentGameType { get; set; } - [JsonProperty("CurrentName")] public string CurrentName { get; set; } + [JsonProperty("CurrentName")] public string CurrentName { get; set; } - [JsonProperty("ServiceStatus")] public ServiceStatus ServiceStatus { get; set; } + [JsonProperty("ServiceStatus")] public EServiceStatus EServiceStatus { get; set; } - [JsonProperty("StartTime")] public DateTime StartTime { get; set; } + [JsonProperty("StartTime")] public DateTime StartTime { get; set; } - [JsonProperty("JoinUrl")] public string JoinUrl { get; set; } + [JsonProperty("JoinUrl")] public string JoinUrl { get; set; } - [JsonProperty("Branded")] public bool Branded { get; set; } + [JsonProperty("Branded")] public bool Branded { get; set; } - [JsonProperty("ConnectionInfo")] public string ConnectionInfo { get; set; } + [JsonProperty("ConnectionInfo")] public string ConnectionInfo { get; set; } - [JsonProperty("QueryInfo")] public string QueryInfo { get; set; } + [JsonProperty("QueryInfo")] public string QueryInfo { get; set; } - [JsonProperty("RConInfo")] public string RConInfo { get; set; } + [JsonProperty("RConInfo")] public string RConInfo { get; set; } - [JsonProperty("FtpInfo")] public string FtpInfo { get; set; } + [JsonProperty("FtpInfo")] public string FtpInfo { get; set; } - [JsonProperty("IpAddress")] public string IpAddress { get; set; } + [JsonProperty("IpAddress")] public string IpAddress { get; set; } - [JsonProperty("IpHostname")] public string IpHostname { get; set; } + [JsonProperty("IpHostname")] public string IpHostname { get; set; } - [JsonProperty("PublicIpAddress")] public string PublicIpAddress { get; set; } + [JsonProperty("PublicIpAddress")] public string PublicIpAddress { get; set; } - [JsonProperty("GamePort")] public int GamePort { get; set; } + [JsonProperty("GamePort")] public int GamePort { get; set; } - [JsonProperty("QueryPort")] public int QueryPort { get; set; } + [JsonProperty("QueryPort")] public int QueryPort { get; set; } - [JsonProperty("RConPort")] public int RConPort { get; set; } + [JsonProperty("RConPort")] public int RConPort { get; set; } - [JsonProperty("CustomPort1")] public int CustomPort1 { get; set; } + [JsonProperty("CustomPort1")] public int CustomPort1 { get; set; } - [JsonProperty("CustomPort2")] public int CustomPort2 { get; set; } + [JsonProperty("CustomPort2")] public int CustomPort2 { get; set; } - [JsonProperty("CustomPort3")] public int CustomPort3 { get; set; } + [JsonProperty("CustomPort3")] public int CustomPort3 { get; set; } - [JsonProperty("CustomPort4")] public int CustomPort4 { get; set; } + [JsonProperty("CustomPort4")] public int CustomPort4 { get; set; } - [JsonProperty("CustomPort5")] public int CustomPort5 { get; set; } + [JsonProperty("CustomPort5")] public int CustomPort5 { get; set; } - [JsonProperty("CustomPort6")] public int CustomPort6 { get; set; } + [JsonProperty("CustomPort6")] public int CustomPort6 { get; set; } - [JsonProperty("CustomPort7")] public int CustomPort7 { get; set; } + [JsonProperty("CustomPort7")] public int CustomPort7 { get; set; } - [JsonProperty("CustomPort8")] public int CustomPort8 { get; set; } + [JsonProperty("CustomPort8")] public int CustomPort8 { get; set; } - [JsonProperty("CustomPort9")] public int CustomPort9 { get; set; } + [JsonProperty("CustomPort9")] public int CustomPort9 { get; set; } - [JsonProperty("CustomPort10")] public int CustomPort10 { get; set; } + [JsonProperty("CustomPort10")] public int CustomPort10 { get; set; } - [JsonProperty("CustomPort11")] public int CustomPort11 { get; set; } + [JsonProperty("CustomPort11")] public int CustomPort11 { get; set; } - [JsonProperty("CustomPort12")] public int CustomPort12 { get; set; } + [JsonProperty("CustomPort12")] public int CustomPort12 { get; set; } - [JsonProperty("CustomPort13")] public int CustomPort13 { get; set; } + [JsonProperty("CustomPort13")] public int CustomPort13 { get; set; } - [JsonProperty("CustomPort14")] public int CustomPort14 { get; set; } + [JsonProperty("CustomPort14")] public int CustomPort14 { get; set; } - [JsonProperty("CustomPort15")] public int CustomPort15 { get; set; } + [JsonProperty("CustomPort15")] public int CustomPort15 { get; set; } - [JsonProperty("CustomPort16")] public int CustomPort16 { get; set; } + [JsonProperty("CustomPort16")] public int CustomPort16 { get; set; } - [JsonProperty("CustomPort17")] public int CustomPort17 { get; set; } + [JsonProperty("CustomPort17")] public int CustomPort17 { get; set; } - [JsonProperty("CustomPort18")] public int CustomPort18 { get; set; } + [JsonProperty("CustomPort18")] public int CustomPort18 { get; set; } - [JsonProperty("CustomPort19")] public int CustomPort19 { get; set; } + [JsonProperty("CustomPort19")] public int CustomPort19 { get; set; } - [JsonProperty("CustomPort20")] public int CustomPort20 { get; set; } + [JsonProperty("CustomPort20")] public int CustomPort20 { get; set; } - [JsonProperty("CustomPort21")] public int CustomPort21 { get; set; } + [JsonProperty("CustomPort21")] public int CustomPort21 { get; set; } - [JsonProperty("CustomPort22")] public int CustomPort22 { get; set; } + [JsonProperty("CustomPort22")] public int CustomPort22 { get; set; } - [JsonProperty("CustomPort23")] public int CustomPort23 { get; set; } + [JsonProperty("CustomPort23")] public int CustomPort23 { get; set; } - [JsonProperty("CustomPort24")] public int CustomPort24 { get; set; } + [JsonProperty("CustomPort24")] public int CustomPort24 { get; set; } - [JsonProperty("CustomPort25")] public int CustomPort25 { get; set; } + [JsonProperty("CustomPort25")] public int CustomPort25 { get; set; } - [JsonProperty("CustomPort26")] public int CustomPort26 { get; set; } + [JsonProperty("CustomPort26")] public int CustomPort26 { get; set; } - [JsonProperty("CustomPort27")] public int CustomPort27 { get; set; } + [JsonProperty("CustomPort27")] public int CustomPort27 { get; set; } - [JsonProperty("CustomPort28")] public int CustomPort28 { get; set; } + [JsonProperty("CustomPort28")] public int CustomPort28 { get; set; } - [JsonProperty("CustomPort29")] public int CustomPort29 { get; set; } + [JsonProperty("CustomPort29")] public int CustomPort29 { get; set; } - [JsonProperty("CustomPort30")] public int CustomPort30 { get; set; } + [JsonProperty("CustomPort30")] public int CustomPort30 { get; set; } - [JsonProperty("CustomPort31")] public int CustomPort31 { get; set; } + [JsonProperty("CustomPort31")] public int CustomPort31 { get; set; } - [JsonProperty("CustomPort32")] public int CustomPort32 { get; set; } + [JsonProperty("CustomPort32")] public int CustomPort32 { get; set; } - [JsonProperty("CustomPort33")] public int CustomPort33 { get; set; } + [JsonProperty("CustomPort33")] public int CustomPort33 { get; set; } - [JsonProperty("CustomPort34")] public int CustomPort34 { get; set; } + [JsonProperty("CustomPort34")] public int CustomPort34 { get; set; } - [JsonProperty("CustomPort35")] public int CustomPort35 { get; set; } + [JsonProperty("CustomPort35")] public int CustomPort35 { get; set; } - [JsonProperty("CustomPort36")] public int CustomPort36 { get; set; } + [JsonProperty("CustomPort36")] public int CustomPort36 { get; set; } - [JsonProperty("CustomPort37")] public int CustomPort37 { get; set; } + [JsonProperty("CustomPort37")] public int CustomPort37 { get; set; } - [JsonProperty("CustomPort38")] public int CustomPort38 { get; set; } + [JsonProperty("CustomPort38")] public int CustomPort38 { get; set; } - [JsonProperty("CustomPort39")] public int CustomPort39 { get; set; } + [JsonProperty("CustomPort39")] public int CustomPort39 { get; set; } - [JsonProperty("CustomPort40")] public int CustomPort40 { get; set; } + [JsonProperty("CustomPort40")] public int CustomPort40 { get; set; } - [JsonProperty("CustomPort41")] public int CustomPort41 { get; set; } + [JsonProperty("CustomPort41")] public int CustomPort41 { get; set; } - [JsonProperty("CustomPort42")] public int CustomPort42 { get; set; } + [JsonProperty("CustomPort42")] public int CustomPort42 { get; set; } - [JsonProperty("CustomPort43")] public int CustomPort43 { get; set; } + [JsonProperty("CustomPort43")] public int CustomPort43 { get; set; } - [JsonProperty("CustomPort44")] public int CustomPort44 { get; set; } + [JsonProperty("CustomPort44")] public int CustomPort44 { get; set; } - [JsonProperty("CustomPort45")] public int CustomPort45 { get; set; } + [JsonProperty("CustomPort45")] public int CustomPort45 { get; set; } - [JsonProperty("CustomPort46")] public int CustomPort46 { get; set; } + [JsonProperty("CustomPort46")] public int CustomPort46 { get; set; } - [JsonProperty("CustomPort47")] public int CustomPort47 { get; set; } + [JsonProperty("CustomPort47")] public int CustomPort47 { get; set; } - [JsonProperty("CustomPort48")] public int CustomPort48 { get; set; } + [JsonProperty("CustomPort48")] public int CustomPort48 { get; set; } - [JsonProperty("CustomPort49")] public int CustomPort49 { get; set; } + [JsonProperty("CustomPort49")] public int CustomPort49 { get; set; } - [JsonProperty("CustomPort50")] public int CustomPort50 { get; set; } + [JsonProperty("CustomPort50")] public int CustomPort50 { get; set; } - [JsonProperty("Startup")] public ServiceStartup Startup { get; set; } + [JsonProperty("Startup")] public ServiceStartup Startup { get; set; } - [JsonProperty("Priority")] public int Priority { get; set; } + [JsonProperty("Priority")] public int Priority { get; set; } - [JsonProperty("Affinity")] public int Affinity { get; set; } + [JsonProperty("Affinity")] public int Affinity { get; set; } - [JsonProperty("NumaNode")] public int NumaNode { get; set; } + [JsonProperty("NumaNode")] public int NumaNode { get; set; } - [JsonProperty("GameKey")] public string GameKey { get; set; } + [JsonProperty("GameKey")] public string GameKey { get; set; } - [JsonProperty("Variables")] public TcaXmlField Variables { get; set; } + [JsonProperty("Variables")] public TcaXmlField Variables { get; set; } = new(); - [JsonProperty("InstalledMods")] public IList InstalledMods { get; set; } + [JsonProperty("InstalledMods")] public IList InstalledMods { get; set; } - [JsonProperty("InstalledUpdate")] public string InstalledUpdate { get; set; } + [JsonProperty("InstalledUpdate")] public string InstalledUpdate { get; set; } - [JsonProperty("OverrideCommandLine")] public bool OverrideCommandLine { get; set; } + [JsonProperty("OverrideCommandLine")] public bool OverrideCommandLine { get; set; } - [JsonProperty("Notes")] public string Notes { get; set; } + [JsonProperty("Notes")] public string Notes { get; set; } - public void Update(Action action) - { - var service = new Service(); - action(service); - var putJson = JsonConvert.SerializeObject(service, Constants.IgnoreDefaultValues); - var request = ServicesController.GenerateDefaultRequest(); - request.Resource += this.ServiceId; - request.Method = Method.PUT; - request.AddParameter(Constants.JsonContentType, putJson, ParameterType.RequestBody); - ServicesController.ExecuteBaseResponseRequest(request); - } + [JsonIgnore] public FileManagerService FileManagerService => new(this); + + public async Task Update(Action action) + { + var service = new Service(); + action(service); + var putJson = JsonConvert.SerializeObject(service, Constants.IgnoreDefaultValues); + var request = TcaClient.ServicesController.GenerateDefaultRequest(ServiceId.ToString()); + request.Method = HttpMethod.Put; + request.Content = new StringContent(putJson, Encoding.UTF8, Constants.JsonContentType); + return (await TcaClient.ServicesController.ExecuteBaseResponseRequest(request)).Success; + } - public void Delete() - { - throw new NotImplementedException(); - } + public Task Delete() + { + // todo: Luis hurry up implement pls + throw new NotImplementedException(); + } - public void Start(string reason = "") + public async Task Start(string reason = "") + { + var request = TcaClient.ServicesController.GenerateDefaultRequest( ServiceId.ToString(), nameof(Start)); + request.Method = HttpMethod.Post; + if (!string.IsNullOrEmpty(reason)) { - var request = ServicesController.GenerateDefaultRequest(); - request.Resource += $"start/{this.ServiceId}"; - request.Method = Method.POST; - if (!string.IsNullOrEmpty(reason)) - { - request.AddParameter("reason", reason); - } - ServicesController.ExecuteBaseResponseRequest(request); + request.Content = new FormUrlEncodedContent(new[] + { new KeyValuePair(nameof(reason), reason) }); } + return (await TcaClient.ServicesController.ExecuteBaseResponseRequest(request)).Success; + } - public void Restart(string reason = "") + public async Task Restart(string reason = "") + { + var request = TcaClient.ServicesController.GenerateDefaultRequest( ServiceId.ToString(), nameof(Restart)); + request.Method = HttpMethod.Post; + if (!string.IsNullOrEmpty(reason)) { - var request = ServicesController.GenerateDefaultRequest(); - request.Resource += $"restart/{this.ServiceId}"; - request.Method = Method.POST; - if (!string.IsNullOrEmpty(reason)) - { - request.AddParameter("reason", reason); - } - ServicesController.ExecuteBaseResponseRequest(request); + request.Content = new FormUrlEncodedContent(new[] + { new KeyValuePair(nameof(reason), reason) }); } + return (await TcaClient.ServicesController.ExecuteBaseResponseRequest(request)).Success; + } - public void Stop(string reason = "") - { - var request = ServicesController.GenerateDefaultRequest(); - request.Resource += $"stop/{this.ServiceId}"; - request.Method = Method.POST; - if (!string.IsNullOrEmpty(reason)) - { - request.AddParameter("reason", reason); - } - ServicesController.ExecuteBaseResponseRequest(request); - } - - public void Configure() + public async Task Stop(string reason = "") + { + var request = TcaClient.ServicesController.GenerateDefaultRequest( ServiceId.ToString(), nameof(Stop)); + request.Method = HttpMethod.Post; + if (!string.IsNullOrEmpty(reason)) { - var request = ServicesController.GenerateDefaultRequest(); - request.Resource += $"configure/{this.ServiceId}"; - request.Method = Method.POST; - ServicesController.ExecuteBaseResponseRequest(request); + request.Content = new FormUrlEncodedContent(new[] + { new KeyValuePair(nameof(reason), reason) }); } + return (await TcaClient.ServicesController.ExecuteBaseResponseRequest(request)).Success; + } + + public async Task Configure() + { + var request = TcaClient.ServicesController.GenerateDefaultRequest( ServiceId.ToString(), nameof(Configure)); + request.Method = HttpMethod.Post; + return (await TcaClient.ServicesController.ExecuteBaseResponseRequest(request)).Success; + } + + public async Task Suspend() + { + var request = TcaClient.ServicesController.GenerateDefaultRequest( ServiceId.ToString(), nameof(Suspend)); + request.Method = HttpMethod.Post; + return (await TcaClient.ServicesController.ExecuteBaseResponseRequest(request)).Success; + } + + public async Task Unsuspend() + { + var request = TcaClient.ServicesController.GenerateDefaultRequest( ServiceId.ToString(), nameof(Unsuspend)); + request.Method = HttpMethod.Post; + return (await TcaClient.ServicesController.ExecuteBaseResponseRequest(request)).Success; + } + + public async Task GetStatus() + { + var request = TcaClient.ServicesController.GenerateDefaultRequest( ServiceId.ToString(), "Status"); + return (await TcaClient.ServicesController.ExecuteBaseResponseRequest(request)).Result; + } + + public async Task GetQuery() + { + var request = TcaClient.ServicesController.GenerateDefaultRequest( ServiceId.ToString(), "Query"); + return (await TcaClient.ServicesController.ExecuteBaseResponseRequest(request)).Result; } } \ No newline at end of file diff --git a/TCAdminApiSharp/Entities/Service/ServiceBuilder.cs b/TCAdminApiSharp/Entities/Service/ServiceBuilder.cs index ec7e053..35c757d 100644 --- a/TCAdminApiSharp/Entities/Service/ServiceBuilder.cs +++ b/TCAdminApiSharp/Entities/Service/ServiceBuilder.cs @@ -6,184 +6,181 @@ using Serilog; using TCAdminApiSharp.Entities.Generic; using TCAdminApiSharp.Helpers; + // ReSharper disable UnusedMember.Global // ReSharper disable UnusedMethodReturnValue.Global -namespace TCAdminApiSharp.Entities.Service +namespace TCAdminApiSharp.Entities.Service; + +public class ServiceBuilder { - public class ServiceBuilder - { - private readonly ILogger _logger = Log.ForContext(); - private readonly Service _service; - private readonly Dictionary _extraData = new(); - - public ServiceBuilder() - { - _service = new Service(); - WithStartup(ServiceStartup.Automatic); - WithPriority(ProcessPriorityClass.Normal); - } - - public ServiceBuilder WithServerId(int id) - { - _service.ServerId = id; - return this; - } - - public ServiceBuilder WithDatacenterId(int id) - { - _extraData["DatacenterId"] = id; - return this; - } - - public ServiceBuilder WithUserId(int id) - { - _service.UserId = id; - return this; - } - - public ServiceBuilder WithUser(User.User user) - { - _service.UserId = user.UserId; - return this; - } - - public ServiceBuilder WithGameId(int id) - { - _service.GameId = id; - return this; - } - - public ServiceBuilder WithAutomaticPort(bool auto) - { - _extraData["AutomaticPort"] = auto; - return this; - } - - public ServiceBuilder WithPort(int port) - { - _service.GamePort = port; - return this; - } - - public ServiceBuilder WithSlots(int slots) - { - _service.Slots = slots; - return this; - } - - public ServiceBuilder WithPrivate(bool priv) - { - _service.Private = priv; - return this; - } - - public ServiceBuilder WithVariables(Dictionary variables) - { - _service.Variables = new TcaXmlField(variables); - return this; - } - - public ServiceBuilder WithStartup(ServiceStartup startup) - { - _service.Startup = startup; - return this; - } - - public ServiceBuilder WithPriority(ProcessPriorityClass priority) - { - _service.Priority = (int)priority; - return this; - } - - public ServiceBuilder WithAffinity(int affinity) - { - _service.Affinity = affinity; - return this; - } - - public ServiceBuilder WithNumaNode(int numaNode) - { - _service.NumaNode = numaNode; - return this; - } - - public ServiceBuilder WithBranded(bool branded) - { - _service.Branded = branded; - return this; - } - - public ServiceBuilder WithStartAfterCreated(bool startAfterCreation) - { - _extraData["StartAfterCreated"] = startAfterCreation; - return this; - } - - public ServiceBuilder WithScheduleDelete(bool scheduleDelete) - { - _extraData["ScheduleDelete"] = scheduleDelete; - return this; - } - - public ServiceBuilder WithDeleteTimeUtc(DateTime deletionTime) - { - _extraData["DeleteTimeUtc"] = deletionTime; - return this; - } - - public ServiceBuilder WithDeleteOwner(bool deleteOwner) - { - _extraData["DeleteOwner"] = deleteOwner; - return this; - } - - public ServiceBuilder WithUserPackageId(int userPackageId) - { - _service.UserPackageId = userPackageId; - return this; - } - - public ServiceBuilder WithGameSwitchingAllowedGames(string[] gameIds) - { - _service.GameSwitchingAllowedGames = gameIds; - return this; - } - - public ServiceBuilder WithBillingId(string billingId) - { - _service.BillingId = billingId; - return this; - } - - public ServiceBuilder WithCpuLimit(int cpuLimit) - { - _service.CpuLimit = cpuLimit; - return this; - } - - public ServiceBuilder WithVirtualMemoryLimitMb(int mb) - { - _extraData["VirtualMemoryLimitMB"] = mb; - return this; - } - - public ServiceBuilder WithMemoryLimitMb(int mb) - { - _service.MemoryLimitMB = mb; - return this; - } - - internal string GenerateRequestBody() - { - var jo = JObject.FromObject(this._service, JsonSerializer.Create(Constants.IgnoreDefaultValues)); - foreach (var keyValuePair in _extraData) - { - jo.Add(keyValuePair.Key, new JValue(keyValuePair.Value)); - } - _logger.Debug(jo.ToString()); - - return jo.ToString(); - } + private readonly ILogger _logger = Log.ForContext(); + private readonly Service _service; + private readonly Dictionary _extraData = new(); + + public ServiceBuilder() + { + _service = new Service(); + WithStartup(ServiceStartup.Automatic); + WithPriority(ProcessPriorityClass.Normal); + } + + public ServiceBuilder WithServerId(int id) + { + _service.ServerId = id; + return this; + } + + public ServiceBuilder WithDatacenterId(int id) + { + _extraData["DatacenterId"] = id; + return this; + } + + public ServiceBuilder WithUserId(int id) + { + _service.UserId = id; + return this; + } + + public ServiceBuilder WithUser(User.User user) + { + _service.UserId = user.UserId; + return this; + } + + public ServiceBuilder WithGameId(int id) + { + _service.GameId = id; + return this; + } + + public ServiceBuilder WithAutomaticPort(bool auto) + { + _extraData["AutomaticPort"] = auto; + return this; + } + + public ServiceBuilder WithPort(int port) + { + _service.GamePort = port; + return this; + } + + public ServiceBuilder WithSlots(int slots) + { + _service.Slots = slots; + return this; + } + + public ServiceBuilder WithPrivate(bool priv) + { + _service.Private = priv; + return this; + } + + public ServiceBuilder WithVariables(TcaXmlField variables) + { + _service.Variables = variables; + return this; + } + + public ServiceBuilder WithStartup(ServiceStartup startup) + { + _service.Startup = startup; + return this; + } + + public ServiceBuilder WithPriority(ProcessPriorityClass priority) + { + _service.Priority = (int) priority; + return this; + } + + public ServiceBuilder WithAffinity(int affinity) + { + _service.Affinity = affinity; + return this; + } + + public ServiceBuilder WithNumaNode(int numaNode) + { + _service.NumaNode = numaNode; + return this; + } + + public ServiceBuilder WithBranded(bool branded) + { + _service.Branded = branded; + return this; + } + + public ServiceBuilder WithStartAfterCreated(bool startAfterCreation) + { + _extraData["StartAfterCreated"] = startAfterCreation; + return this; + } + + public ServiceBuilder WithScheduleDelete(bool scheduleDelete) + { + _extraData["ScheduleDelete"] = scheduleDelete; + return this; + } + + public ServiceBuilder WithDeleteTimeUtc(DateTime deletionTime) + { + _extraData["DeleteTimeUtc"] = deletionTime; + return this; + } + + public ServiceBuilder WithDeleteOwner(bool deleteOwner) + { + _extraData["DeleteOwner"] = deleteOwner; + return this; + } + + public ServiceBuilder WithUserPackageId(int userPackageId) + { + _service.UserPackageId = userPackageId; + return this; + } + + public ServiceBuilder WithGameSwitchingAllowedGames(string[] gameIds) + { + _service.GameSwitchingAllowedGames = gameIds; + return this; + } + + public ServiceBuilder WithBillingId(string billingId) + { + _service.BillingId = billingId; + return this; + } + + public ServiceBuilder WithCpuLimit(int cpuLimit) + { + _service.CpuLimit = cpuLimit; + return this; + } + + public ServiceBuilder WithVirtualMemoryLimitMb(int mb) + { + _extraData["VirtualMemoryLimitMB"] = mb; + return this; + } + + public ServiceBuilder WithMemoryLimitMb(int mb) + { + _service.MemoryLimitMB = mb; + return this; + } + + internal string GenerateRequestBody() + { + var jo = JObject.FromObject(_service, JsonSerializer.Create(Constants.IgnoreDefaultValues)); + foreach (var keyValuePair in _extraData) jo.Add(keyValuePair.Key, new JValue(keyValuePair.Value)); + _logger.Debug(jo.ToString()); + + return jo.ToString(); } } \ No newline at end of file diff --git a/TCAdminApiSharp/Entities/Service/ServiceQuery.cs b/TCAdminApiSharp/Entities/Service/ServiceQuery.cs new file mode 100644 index 0000000..ff5f208 --- /dev/null +++ b/TCAdminApiSharp/Entities/Service/ServiceQuery.cs @@ -0,0 +1,41 @@ +using System.Collections.Generic; +using Newtonsoft.Json; +using TCAdminApiSharp.Entities.Generic; + +namespace TCAdminApiSharp.Entities.Service; + +public class ServiceQuery +{ + [JsonProperty("Running")] + public bool Running { get; set; } + + [JsonProperty("Name")] + public string Name { get; set; } + + [JsonProperty("Map")] + public string Map { get; set; } + + [JsonProperty("Game")] + public string Game { get; set; } + + [JsonProperty("GameType")] + public string GameType { get; set; } + + [JsonProperty("MaxPlayers")] + public long MaxPlayers { get; set; } + + [JsonProperty("NumPlayers")] + public long NumPlayers { get; set; } + + [JsonProperty("MaxSpectators")] + public long MaxSpectators { get; set; } + + [JsonProperty("NumSpectators")] + public long NumSpectators { get; set; } + + [JsonProperty("Players", NullValueHandling = NullValueHandling.Ignore)] + public List Players { get; set; } + + [JsonProperty("Rules", NullValueHandling = NullValueHandling.Ignore)] + public TcaXmlField Rules { get; set; } +} \ No newline at end of file diff --git a/TCAdminApiSharp/Entities/Service/ServiceStartup.cs b/TCAdminApiSharp/Entities/Service/ServiceStartup.cs index db9e4d5..36f58e2 100644 --- a/TCAdminApiSharp/Entities/Service/ServiceStartup.cs +++ b/TCAdminApiSharp/Entities/Service/ServiceStartup.cs @@ -1,9 +1,8 @@ -namespace TCAdminApiSharp.Entities.Service +namespace TCAdminApiSharp.Entities.Service; + +public enum ServiceStartup { - public enum ServiceStartup - { - Automatic = 2, - Manual = 3, - Disabled = 4, - } + Automatic = 2, + Manual = 3, + Disabled = 4 } \ No newline at end of file diff --git a/TCAdminApiSharp/Entities/Service/ServiceStatus.cs b/TCAdminApiSharp/Entities/Service/ServiceStatus.cs index 8530687..6ed0e1c 100644 --- a/TCAdminApiSharp/Entities/Service/ServiceStatus.cs +++ b/TCAdminApiSharp/Entities/Service/ServiceStatus.cs @@ -1,17 +1,31 @@ -namespace TCAdminApiSharp.Entities.Service +using System; +using Newtonsoft.Json; + +namespace TCAdminApiSharp.Entities.Service; + +public class ServiceStatus { - public enum ServiceStatus - { - Processing = -3, // 0xFFFFFFFD - StartError = -2, // 0xFFFFFFFE - Unknown = -1, // 0xFFFFFFFF - Disabled = 0, - Stopped = 1, - Starting = 2, - Stopping = 3, - Running = 4, - Resuming = 5, - Pausing = 6, - Paused = 7, - } + [JsonProperty("StartTime")] + public DateTimeOffset StartTime { get; set; } + + [JsonProperty("ServiceStatus")] + public EServiceStatus Status { get; set; } + + [JsonProperty("ProcessId")] + public long ProcessId { get; set; } + + [JsonProperty("ServiceId")] + public long ServiceId { get; set; } + + [JsonProperty("BandwidthLastSecond")] + public long BandwidthLastSecond { get; set; } + + [JsonProperty("CpuLastSecond")] + public double CpuLastSecond { get; set; } + + [JsonProperty("MemoryLastSecond")] + public long MemoryLastSecond { get; set; } + + [JsonProperty("MemoryPercentageLastSecond")] + public double MemoryPercentageLastSecond { get; set; } } \ No newline at end of file diff --git a/TCAdminApiSharp/Entities/Task/Task.cs b/TCAdminApiSharp/Entities/Task/Task.cs index 905c712..4814be1 100644 --- a/TCAdminApiSharp/Entities/Task/Task.cs +++ b/TCAdminApiSharp/Entities/Task/Task.cs @@ -1,81 +1,76 @@ using System; using System.Collections.Generic; using System.Linq; +using System.Net.Http; +using System.Threading.Tasks; using Newtonsoft.Json; -using TCAdminApiSharp.Controllers; using TCAdminApiSharp.Entities.Generic; -using Microsoft.Extensions.DependencyInjection; -using RestSharp; -namespace TCAdminApiSharp.Entities.Task -{ - public class Task : ObjectBase - { - [JsonIgnore] public readonly TasksController TasksController = - TcaClient.ServiceProvider.GetService() ?? throw new InvalidOperationException(); - - [JsonProperty("TaskId")] public int TaskId { get; set; } +namespace TCAdminApiSharp.Entities.Task; - [JsonProperty("UserId")] public int UserId { get; set; } +public class Task : ObjectBase +{ + [JsonProperty("TaskId")] public int TaskId { get; set; } - [JsonProperty("UserName")] public string UserName { get; set; } + [JsonProperty("UserId")] public int UserId { get; set; } - [JsonProperty("ServerId")] public int ServerId { get; set; } + [JsonProperty("UserName")] public string UserName { get; set; } - [JsonProperty("Name")] public string Name { get; set; } + [JsonProperty("ServerId")] public int ServerId { get; set; } - [JsonProperty("Status")] public TaskStatus Status { get; set; } + [JsonProperty("Name")] public string Name { get; set; } - [JsonProperty("CurrentStepId")] public int CurrentStepId { get; set; } + [JsonProperty("Status")] public TaskStatus Status { get; set; } - [JsonProperty("LastRunTime")] public DateTime LastRunTime { get; set; } + [JsonProperty("CurrentStepId")] public int CurrentStepId { get; set; } - [JsonProperty("LastRunTimeUtc")] public DateTime LastRunTimeUtc { get; set; } + [JsonProperty("LastRunTime")] public DateTime LastRunTime { get; set; } - [JsonProperty("ScheduledTime")] public DateTime ScheduledTime { get; set; } + [JsonProperty("LastRunTimeUtc")] public DateTime LastRunTimeUtc { get; set; } - [JsonProperty("ScheduledTimeUtc")] public DateTime ScheduledTimeUtc { get; set; } + [JsonProperty("ScheduledTime")] public DateTime ScheduledTime { get; set; } - [JsonProperty("FilterTime")] public DateTime FilterTime { get; set; } + [JsonProperty("ScheduledTimeUtc")] public DateTime ScheduledTimeUtc { get; set; } - [JsonProperty("FilterTimeUtc")] public DateTime FilterTimeUtc { get; set; } + [JsonProperty("FilterTime")] public DateTime FilterTime { get; set; } - [JsonProperty("Enabled")] public bool Enabled { get; set; } + [JsonProperty("FilterTimeUtc")] public DateTime FilterTimeUtc { get; set; } - [JsonProperty("Source")] public string Source { get; set; } + [JsonProperty("Enabled")] public bool Enabled { get; set; } - [JsonProperty("SourceId")] public string SourceId { get; set; } + [JsonProperty("Source")] public string Source { get; set; } - [JsonProperty("RecurringTaskGuid")] public object RecurringTaskGuid { get; set; } + [JsonProperty("SourceId")] public string SourceId { get; set; } - [JsonProperty("RecurringTaskId")] public int RecurringTaskId { get; set; } + [JsonProperty("RecurringTaskGuid")] public object RecurringTaskGuid { get; set; } - [JsonProperty("TotalSteps")] public int TotalSteps { get; set; } + [JsonProperty("RecurringTaskId")] public int RecurringTaskId { get; set; } - [JsonProperty("RedirectUrl")] public string RedirectUrl { get; set; } + [JsonProperty("TotalSteps")] public int TotalSteps { get; set; } - [JsonIgnore] public IEnumerable Steps => (List) TasksController.GetTaskSteps(this.TaskId).Result; + [JsonProperty("RedirectUrl")] public string RedirectUrl { get; set; } - [JsonIgnore] - public TaskStep CurrentStep - { - get { return Steps.FirstOrDefault(x => x.StepId == this.CurrentStepId) ?? throw new InvalidOperationException(); } - } + public async System.Threading.Tasks.Task Start() + { + var request = TcaClient.TasksController.GenerateDefaultRequest( TaskId.ToString(), nameof(Start)); + request.Method = HttpMethod.Post; + await TcaClient.TasksController.ExecuteBaseResponseRequest(request); + } - public void Start() - { - var request = TasksController.GenerateDefaultRequest(); - request.Resource += $"start/{this.TaskId}"; - request.Method = Method.POST; - TasksController.ExecuteBaseResponseRequest(request); - } + public async System.Threading.Tasks.Task Cancel() + { + var request = TcaClient.TasksController.GenerateDefaultRequest(TaskId.ToString(), nameof(Cancel)); + request.Method = HttpMethod.Post; + await TcaClient.TasksController.ExecuteBaseResponseRequest(request); + } - public void Cancel() - { - var request = TasksController.GenerateDefaultRequest(); - request.Resource += $"cancel/{this.TaskId}"; - request.Method = Method.POST; - TasksController.ExecuteBaseResponseRequest(request); - } + public async Task> GetSteps() + { + return (await TcaClient.TasksController.GetTaskSteps(TaskId)).Result; + } + + public async Task GetCurrentStep() + { + return (await GetSteps()).First(x => x.StepId == CurrentStepId); } } \ No newline at end of file diff --git a/TCAdminApiSharp/Entities/Task/TaskStatus.cs b/TCAdminApiSharp/Entities/Task/TaskStatus.cs index c348d98..aa644f4 100644 --- a/TCAdminApiSharp/Entities/Task/TaskStatus.cs +++ b/TCAdminApiSharp/Entities/Task/TaskStatus.cs @@ -1,12 +1,11 @@ -namespace TCAdminApiSharp.Entities.Task +namespace TCAdminApiSharp.Entities.Task; + +public enum TaskStatus { - public enum TaskStatus - { - NotExecuted, - Executing, - Scheduled, - Completed, - Canceled, - TaskError, - } + NotExecuted, + Executing, + Scheduled, + Completed, + Canceled, + TaskError } \ No newline at end of file diff --git a/TCAdminApiSharp/Entities/Task/TaskStep.cs b/TCAdminApiSharp/Entities/Task/TaskStep.cs index 83d04ee..78765b8 100644 --- a/TCAdminApiSharp/Entities/Task/TaskStep.cs +++ b/TCAdminApiSharp/Entities/Task/TaskStep.cs @@ -1,51 +1,37 @@ using System; using System.Collections.Generic; using Newtonsoft.Json; +using TCAdminApiSharp.Entities.Generic; -namespace TCAdminApiSharp.Entities.Task +namespace TCAdminApiSharp.Entities.Task; + +public class TaskStep : ObjectBase { - public class TaskStep - { - [JsonProperty("ModuleId")] - public string ModuleId { get; set; } + [JsonProperty("ModuleId")] public string ModuleId { get; set; } - [JsonProperty("ProcessId")] - public int ProcessId { get; set; } + [JsonProperty("ProcessId")] public int ProcessId { get; set; } - [JsonProperty("TaskId")] - public int TaskId { get; set; } + [JsonProperty("TaskId")] public int TaskId { get; set; } - [JsonProperty("StepId")] - public int StepId { get; set; } + [JsonProperty("StepId")] public int StepId { get; set; } - [JsonProperty("ServerId")] - public int ServerId { get; set; } + [JsonProperty("ServerId")] public int ServerId { get; set; } - [JsonProperty("Log")] - public Dictionary Log { get; set; } + [JsonProperty("Log")] public Dictionary Log { get; set; } - [JsonProperty("DebugLog")] - public Dictionary DebugLog { get; set; } + [JsonProperty("DebugLog")] public Dictionary DebugLog { get; set; } - [JsonProperty("LastDebugLogKey")] - public DateTime LastDebugLogKey { get; set; } + [JsonProperty("LastDebugLogKey")] public DateTime LastDebugLogKey { get; set; } - [JsonProperty("LastLogKey")] - public DateTime LastLogKey { get; set; } + [JsonProperty("LastLogKey")] public DateTime LastLogKey { get; set; } - [JsonProperty("Name")] - public string Name { get; set; } + [JsonProperty("Name")] public string Name { get; set; } - [JsonProperty("LastLogItem")] - public string LastLogItem { get; set; } + [JsonProperty("LastLogItem")] public string LastLogItem { get; set; } - [JsonProperty("Arguments")] - public string Arguments { get; set; } + [JsonProperty("Arguments")] public string Arguments { get; set; } - [JsonProperty("ReturnValue")] - public string ReturnValue { get; set; } + [JsonProperty("ReturnValue")] public string ReturnValue { get; set; } - [JsonProperty("Progress")] - public int Progress { get; set; } - } + [JsonProperty("Progress")] public int Progress { get; set; } } \ No newline at end of file diff --git a/TCAdminApiSharp/Entities/User/User.cs b/TCAdminApiSharp/Entities/User/User.cs index 4040d22..0e02450 100644 --- a/TCAdminApiSharp/Entities/User/User.cs +++ b/TCAdminApiSharp/Entities/User/User.cs @@ -1,98 +1,140 @@ using System; +using System.Collections.Generic; +using System.Net.Http; +using System.Text; +using System.Threading.Tasks; using Newtonsoft.Json; -using TCAdminApiSharp.Controllers; +using TCAdminApiSharp.Entities.API; using TCAdminApiSharp.Entities.Generic; -using Microsoft.Extensions.DependencyInjection; +using TCAdminApiSharp.Helpers; -namespace TCAdminApiSharp.Entities.User +namespace TCAdminApiSharp.Entities.User; + +public class User : ObjectBase, IObjectBaseCrud { - public class User : ObjectBase, IObjectBaseCrud - { - [JsonIgnore] public readonly UsersController UsersController = - TcaClient.ServiceProvider.GetService() ?? throw new InvalidOperationException(); + [JsonProperty("UserId")] public int UserId { get; set; } - [JsonProperty("UserId")] public int UserId { get; set; } + [JsonProperty("UserName")] public string UserName { get; set; } - [JsonProperty("UserName")] public string UserName { get; set; } + [JsonProperty("RoleId")] public int RoleId { get; set; } - [JsonProperty("RoleId")] public int RoleId { get; set; } + [JsonProperty("OwnerId")] public int OwnerId { get; set; } - [JsonProperty("OwnerId")] public int OwnerId { get; set; } + [JsonProperty("RequiresTwoStepVerification")] + public bool RequiresTwoStepVerification { get; set; } - [JsonProperty("RequiresTwoStepVerification")] - public bool RequiresTwoStepVerification { get; set; } + [JsonProperty("FtpRequiresTwoStepVerification")] + public bool FtpRequiresTwoStepVerification { get; set; } - [JsonProperty("FtpRequiresTwoStepVerification")] - public bool FtpRequiresTwoStepVerification { get; set; } + [JsonProperty("FtpSkipTwoStepVerificationIfKnownIp")] + public bool FtpSkipTwoStepVerificationIfKnownIp { get; set; } - [JsonProperty("FtpSkipTwoStepVerificationIfKnownIp")] - public bool FtpSkipTwoStepVerificationIfKnownIp { get; set; } + [JsonProperty("TwoStepVerificationSecret")] + public object TwoStepVerificationSecret { get; set; } - [JsonProperty("TwoStepVerificationSecret")] - public object TwoStepVerificationSecret { get; set; } + [JsonProperty("Status")] public int Status { get; set; } - [JsonProperty("Status")] public int Status { get; set; } + [JsonProperty("LastLogin")] public DateTime LastLogin { get; set; } - [JsonProperty("LastLogin")] public DateTime LastLogin { get; set; } + [JsonProperty("LastLoginUtc")] public DateTime LastLoginUtc { get; set; } - [JsonProperty("LastLoginUtc")] public DateTime LastLoginUtc { get; set; } + [JsonProperty("LastLoginIp")] public string LastLoginIp { get; set; } - [JsonProperty("LastLoginIp")] public string LastLoginIp { get; set; } + [JsonProperty("BillingId")] public string BillingId { get; set; } - [JsonProperty("BillingId")] public string BillingId { get; set; } + [JsonProperty("BillingStatus")] public int BillingStatus { get; set; } - [JsonProperty("BillingStatus")] public int BillingStatus { get; set; } + [JsonProperty("DemoMode")] public bool DemoMode { get; set; } - [JsonProperty("DemoMode")] public bool DemoMode { get; set; } + [JsonProperty("IsSubUser")] public bool IsSubUser { get; set; } - [JsonProperty("IsSubUser")] public bool IsSubUser { get; set; } + [JsonProperty("SubUserOwnerId")] public int SubUserOwnerId { get; set; } - [JsonProperty("SubUserOwnerId")] public int SubUserOwnerId { get; set; } + [JsonProperty("ExternalId")] public string ExternalId { get; set; } - [JsonProperty("ExternalId")] public string ExternalId { get; set; } + [JsonProperty("FirstName")] public string FirstName { get; set; } - [JsonProperty("FirstName")] public string FirstName { get; set; } + [JsonProperty("LastName")] public string LastName { get; set; } - [JsonProperty("LastName")] public string LastName { get; set; } + [JsonProperty("FullName")] public string FullName { get; set; } - [JsonProperty("FullName")] public string FullName { get; set; } + [JsonProperty("AllAddress")] public string AllAddress { get; set; } - [JsonProperty("AllAddress")] public string AllAddress { get; set; } + [JsonProperty("Address1")] public string Address1 { get; set; } - [JsonProperty("Address1")] public string Address1 { get; set; } + [JsonProperty("Address2")] public string Address2 { get; set; } - [JsonProperty("Address2")] public string Address2 { get; set; } + [JsonProperty("Address3")] public string Address3 { get; set; } - [JsonProperty("Address3")] public string Address3 { get; set; } + [JsonProperty("City")] public string City { get; set; } - [JsonProperty("City")] public string City { get; set; } + [JsonProperty("State")] public string State { get; set; } - [JsonProperty("State")] public string State { get; set; } + [JsonProperty("Country")] public string Country { get; set; } - [JsonProperty("Country")] public string Country { get; set; } + [JsonProperty("Zip")] public string Zip { get; set; } - [JsonProperty("Zip")] public string Zip { get; set; } + [JsonProperty("HomePhone")] public string HomePhone { get; set; } - [JsonProperty("HomePhone")] public string HomePhone { get; set; } + [JsonProperty("MobilePhone")] public string MobilePhone { get; set; } - [JsonProperty("MobilePhone")] public string MobilePhone { get; set; } + [JsonProperty("Email1")] public string Email1 { get; set; } - [JsonProperty("Email1")] public string Email1 { get; set; } + [JsonProperty("Email2")] public string Email2 { get; set; } - [JsonProperty("Email2")] public string Email2 { get; set; } + [JsonProperty("TimeZoneId")] public string TimeZoneId { get; set; } - [JsonProperty("TimeZoneId")] public string TimeZoneId { get; set; } + [JsonProperty("UserType")] public UserType UserType { get; set; } + + public async Task SetPassword(string password) + { + var request = TcaClient.UsersController.GenerateDefaultRequest(UserId.ToString(), nameof(SetPassword)); + request.Method = HttpMethod.Post; + request.Content = new FormUrlEncodedContent(new[] + { new KeyValuePair(nameof(password), password) }); + return (await TcaClient.UsersController.ExecuteBaseResponseRequest(request)).Success; + } - [JsonProperty("UserType")] public UserType UserType { get; set; } + public async Task Update(Action action) + { + var service = new User(); + action(service); + var putJson = JsonConvert.SerializeObject(service, Constants.IgnoreDefaultValues); + var request = TcaClient.UsersController.GenerateDefaultRequest(UserId.ToString()); + request.Method = HttpMethod.Put; + request.Content = new StringContent(putJson, Encoding.UTF8, Constants.JsonContentType); + return (await TcaClient.UsersController.ExecuteBaseResponseRequest(request)).Success; + } - public void Update(Action action) + public Task Delete() + { + throw new NotImplementedException(); + } + + public async Task Suspend(bool recursive = true, bool suspendServices = true) + { + var request = TcaClient.UsersController.GenerateDefaultRequest(HttpMethod.Post, UserId.ToString(), nameof(Suspend)); + request.Content = new FormUrlEncodedContent(new KeyValuePair[] { - throw new NotImplementedException(); - } + new(nameof(recursive), recursive.ToString()), + new(nameof(suspendServices), suspendServices.ToString()) + }); + return (await TcaClient.UsersController.ExecuteBaseResponseRequest(request)).Success; + } - public void Delete() + public async Task Unsuspend(bool recursive = true, bool enableServices = true) + { + var request = TcaClient.UsersController.GenerateDefaultRequest(HttpMethod.Post, UserId.ToString(), nameof(Unsuspend)); + request.Content = new FormUrlEncodedContent(new KeyValuePair[] { - throw new NotImplementedException(); - } + new(nameof(recursive), recursive.ToString()), + new(nameof(enableServices), enableServices.ToString()) + }); + return (await TcaClient.UsersController.ExecuteBaseResponseRequest(request)).Success; + } + + public async Task> GetServices() + { + return await TcaClient.ServicesController.GetServicesByUserId(UserId); } } \ No newline at end of file diff --git a/TCAdminApiSharp/Entities/User/UserType.cs b/TCAdminApiSharp/Entities/User/UserType.cs index 2e043d0..a48b336 100644 --- a/TCAdminApiSharp/Entities/User/UserType.cs +++ b/TCAdminApiSharp/Entities/User/UserType.cs @@ -1,9 +1,8 @@ -namespace TCAdminApiSharp.Entities.User +namespace TCAdminApiSharp.Entities.User; + +public enum UserType { - public enum UserType - { - User = 1, - SubAdmin = 2, - Admin = 3, - } + User = 1, + SubAdmin = 2, + Admin = 3 } \ No newline at end of file diff --git a/TCAdminApiSharp/Exceptions/API/ApiRequestException.cs b/TCAdminApiSharp/Exceptions/API/ApiRequestException.cs deleted file mode 100644 index 6344c8f..0000000 --- a/TCAdminApiSharp/Exceptions/API/ApiRequestException.cs +++ /dev/null @@ -1,30 +0,0 @@ -using System; -using RestSharp; - -namespace TCAdminApiSharp.Exceptions.API -{ - public class ApiRequestException : Exception - { - public readonly RestRequest RestRequest; - - internal ApiRequestException(RestRequest restRequest) - { - this.RestRequest = restRequest; - } - - internal ApiRequestException(RestRequest restRequest, string? message) : base(message) - { - this.RestRequest = restRequest; - } - - internal ApiRequestException(RestRequest restRequest, string? message, Exception? innerException) : base(message, innerException) - { - this.RestRequest = restRequest; - } - - internal ApiRequestException(RestRequest restRequest, Exception? innerException) : base(null, innerException) - { - this.RestRequest = restRequest; - } - } -} \ No newline at end of file diff --git a/TCAdminApiSharp/Exceptions/API/ApiResponseException.cs b/TCAdminApiSharp/Exceptions/API/ApiResponseException.cs index 60762b1..53a16ab 100644 --- a/TCAdminApiSharp/Exceptions/API/ApiResponseException.cs +++ b/TCAdminApiSharp/Exceptions/API/ApiResponseException.cs @@ -1,30 +1,36 @@ using System; -using RestSharp; -using TCAdminApiSharp.Entities; +using System.Net.Http; +using Newtonsoft.Json; using TCAdminApiSharp.Entities.API; -namespace TCAdminApiSharp.Exceptions.API +namespace TCAdminApiSharp.Exceptions.API; + +public class ApiResponseException : Exception { - public class ApiResponseException : Exception - { - public readonly IRestResponse RestResponse; - public readonly ErrorResponse ErrorResponse; + public readonly HttpResponseMessage HttpResponseMessage; + public readonly BaseResponse ExceptionResponse; - internal ApiResponseException() - { - - } + internal ApiResponseException() + { + } - internal ApiResponseException(IRestResponse restResponse) : this() - { - RestResponse = restResponse; - ErrorResponse = new ErrorResponse(restResponse); - } + internal ApiResponseException(HttpResponseMessage httpResponseMessage) : this() + { + this.HttpResponseMessage = httpResponseMessage; + var readAsStringAsync = HttpResponseMessage.Content.ReadAsStringAsync().GetAwaiter().GetResult(); + ExceptionResponse = JsonConvert.DeserializeObject>(readAsStringAsync); + } - internal ApiResponseException(IRestResponse restResponse, string message) : base(message) - { - RestResponse = restResponse; - ErrorResponse = new ErrorResponse(restResponse); - } + internal ApiResponseException(HttpResponseMessage httpResponseMessage, string message) : base(message) + { + this.HttpResponseMessage = httpResponseMessage; + var readAsStringAsync = HttpResponseMessage.Content.ReadAsStringAsync().GetAwaiter().GetResult(); + ExceptionResponse = JsonConvert.DeserializeObject>(readAsStringAsync); + } + + internal ApiResponseException(HttpResponseMessage httpResponseMessage, BaseResponse exceptionResponse) : base(exceptionResponse.Message) + { + this.HttpResponseMessage = httpResponseMessage; + ExceptionResponse = exceptionResponse; } } \ No newline at end of file diff --git a/TCAdminApiSharp/Exceptions/NotFoundException.cs b/TCAdminApiSharp/Exceptions/NotFoundException.cs deleted file mode 100644 index 13450bc..0000000 --- a/TCAdminApiSharp/Exceptions/NotFoundException.cs +++ /dev/null @@ -1,22 +0,0 @@ -using System; - -namespace TCAdminApiSharp.Exceptions -{ - public class NotFoundException : Exception - { - public readonly Type Type; - public readonly int[] Ids; - - public NotFoundException(Type type, params int[] ids) : base($"The {type.FullName} could not be found with ids: [{string.Join(", ", ids)}]") - { - this.Type = type; - Ids = ids; - } - - public NotFoundException(Type type, Exception innerException, int[] ids) : base($"The {type.FullName} could not be found", innerException) - { - this.Type = type; - Ids = ids; - } - } -} \ No newline at end of file diff --git a/TCAdminApiSharp/Helpers/Constants.cs b/TCAdminApiSharp/Helpers/Constants.cs index 6fa42e9..c561b0d 100644 --- a/TCAdminApiSharp/Helpers/Constants.cs +++ b/TCAdminApiSharp/Helpers/Constants.cs @@ -1,15 +1,20 @@ using Newtonsoft.Json; -namespace TCAdminApiSharp.Helpers +namespace TCAdminApiSharp.Helpers; + +internal static class Constants { - internal static class Constants + public const string JsonContentType = "application/json"; + + public static readonly JsonSerializerSettings IgnoreDefaultValues = new() + { + NullValueHandling = NullValueHandling.Ignore, + DefaultValueHandling = DefaultValueHandling.Ignore, + ReferenceLoopHandling = ReferenceLoopHandling.Ignore + }; + + public static readonly JsonSerializerSettings IgnoreReferenceLoop = new() { - public const string JsonContentType = "application/json"; - - public static readonly JsonSerializerSettings IgnoreDefaultValues = new() - { - NullValueHandling = NullValueHandling.Ignore, - DefaultValueHandling = DefaultValueHandling.Ignore - }; - } + ReferenceLoopHandling = ReferenceLoopHandling.Ignore + }; } \ No newline at end of file diff --git a/TCAdminApiSharp/Querying/IQueryOperation.cs b/TCAdminApiSharp/Querying/IQueryOperation.cs new file mode 100644 index 0000000..b10b642 --- /dev/null +++ b/TCAdminApiSharp/Querying/IQueryOperation.cs @@ -0,0 +1,9 @@ +using System.Net.Http; + +namespace TCAdminApiSharp.Querying; + +public interface IQueryOperation +{ + string JsonKey { get; set; } + void ModifyRequest(HttpRequestMessage request); +} \ No newline at end of file diff --git a/TCAdminApiSharp/Querying/Operations/FilterList.cs b/TCAdminApiSharp/Querying/Operations/FilterList.cs new file mode 100644 index 0000000..e044afb --- /dev/null +++ b/TCAdminApiSharp/Querying/Operations/FilterList.cs @@ -0,0 +1,60 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Net.Http; +using Microsoft.AspNetCore.WebUtilities; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; +using TCAdminApiSharp.Querying.Structs; + +namespace TCAdminApiSharp.Querying.Operations; + +public class FilterList : List, IQueryOperation +{ + [JsonIgnore] + public string JsonKey { get; set; } = "Fields"; + + public FilterList() + { + } + + public FilterList(params string[] where) + { + foreach (var filterInfo in where) + { + Add(filterInfo); + } + } + + public FilterList(FilterInfo where) + { + Add(where); + } + + public FilterList(params FilterInfo[] where) + { + foreach (var filterInfo in @where) + { + Add(filterInfo); + } + } + + public void Add(string column) + { + Add(new FilterInfo + { + Column = column + }); + } + + public JToken GenerateQuery() + { + var temp = this.Aggregate("(", (current, info) => current + $"[{info.Column}]") + ")"; + return new JValue(temp); + } + + public void ModifyRequest(HttpRequestMessage request) + { + request.RequestUri = new Uri(QueryHelpers.AddQueryString(request.RequestUri.ToString(), JsonKey, GenerateQuery().ToString())); + } +} \ No newline at end of file diff --git a/TCAdminApiSharp/Querying/Operations/OrderList.cs b/TCAdminApiSharp/Querying/Operations/OrderList.cs new file mode 100644 index 0000000..bab5d8a --- /dev/null +++ b/TCAdminApiSharp/Querying/Operations/OrderList.cs @@ -0,0 +1,55 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Net.Http; +using Microsoft.AspNetCore.WebUtilities; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; +using TCAdminApiSharp.Querying.Operators; +using TCAdminApiSharp.Querying.Structs; + +namespace TCAdminApiSharp.Querying.Operations; + +public class OrderList : List, IQueryOperation +{ + [JsonIgnore] public string JsonKey { get; set; } = "Order"; + + public OrderList() + { + } + + public OrderList(string field, OrderOperator @operator) + { + Add(field, @operator); + } + + public void Add(string column, OrderOperator @operator) + { + Add(new OrderInfo + { + Column = column, + Operator = @operator + }); + } + + public JToken GenerateQuery() + { + return JToken.FromObject(this); + } + + public void ModifyRequest(HttpRequestMessage request) + { + JObject jObject = new(); + var dictionary = QueryHelpers.ParseQuery(request.RequestUri.ToString()); + var queryInfoExists = dictionary.Any(x => x.Key == "queryInfo"); + if (queryInfoExists) + { + jObject = JsonConvert.DeserializeObject(dictionary.FirstOrDefault(x => x.Key == "queryInfo").Value.ToString()!); + } + + jObject[JsonKey] = GenerateQuery(); + request.RequestUri = + new Uri(QueryHelpers.AddQueryString(request.RequestUri.ToString(), "queryInfo", jObject.ToString())); + + } +} \ No newline at end of file diff --git a/TCAdminApiSharp/Querying/Operations/WhereList.cs b/TCAdminApiSharp/Querying/Operations/WhereList.cs new file mode 100644 index 0000000..33f09e9 --- /dev/null +++ b/TCAdminApiSharp/Querying/Operations/WhereList.cs @@ -0,0 +1,114 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Net.Http; +using System.Runtime.CompilerServices; +using Microsoft.AspNetCore.WebUtilities; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; +using TCAdminApiSharp.Querying.Operators; +using TCAdminApiSharp.Querying.Structs; + +namespace TCAdminApiSharp.Querying.Operations; + +public class WhereList : List, IQueryOperation +{ + [System.Text.Json.Serialization.JsonIgnore] public string JsonKey { get; set; } = "Where"; + [System.Text.Json.Serialization.JsonIgnore] public WhereOperator WhereOperator { get; set; } + + public WhereList() + { + WhereOperator = WhereOperator.And; + } + + public WhereList(WhereInfo where) + { + WhereOperator = WhereOperator.And; + Add(where); + } + + public WhereList(string column, object value) + { + WhereOperator = WhereOperator.And; + Add(column, ColumnOperator.Equal, RuntimeHelpers.GetObjectValue(value)); + } + + public WhereList(string column, ColumnOperator @operator, object value) + { + WhereOperator = WhereOperator.And; + Add(new WhereInfo + { + Column = column, + ColumnOperator = @operator, + ColumnValue = RuntimeHelpers.GetObjectValue(value) + }); + } + + public void Add(string column, object value) + { + Add(column, ColumnOperator.Equal, RuntimeHelpers.GetObjectValue(value)); + } + + public void Add(string column, ColumnOperator @operator, object value) + { + Add(new WhereInfo + { + Column = column, + ColumnOperator = @operator, + ColumnValue = value + }); + } + + public JToken GenerateQuery() + { + var temp = "("; + foreach (var info in this) + { + var tempColumnName = info.Column; + if (!tempColumnName.StartsWith("[") && !tempColumnName.EndsWith("]")) + { + tempColumnName = $"[{info.Column}]"; + } + + temp += $"{tempColumnName} {ConvertColumnOperator(info.ColumnOperator)} '{info.ColumnValue}'"; + if (!this.Last().Equals(info)) + // Add where operator + temp += $" {WhereOperator.ToString().ToUpper()} "; + } + + temp += ")"; + return new JValue(temp); + } + + public void ModifyRequest(HttpRequestMessage request) + { + JObject jObject = new(); + var dictionary = QueryHelpers.ParseQuery(request.RequestUri.ToString()); + var queryInfoExists = dictionary.Any(x => x.Key == "queryInfo"); + if (queryInfoExists) + { + jObject = JsonConvert.DeserializeObject(dictionary.FirstOrDefault(x => x.Key == "queryInfo").Value.ToString()!); + } + + jObject[JsonKey] = GenerateQuery(); + var addQueryString = QueryHelpers.AddQueryString(request.RequestUri.ToString(), "queryInfo", jObject.ToString()); + request.RequestUri = + new Uri(addQueryString, UriKind.RelativeOrAbsolute); + } + + public static string ConvertColumnOperator(ColumnOperator columnOperator) + { + return columnOperator switch + { + ColumnOperator.Equal => "=", + ColumnOperator.NotEqual => "<>", + ColumnOperator.GreaterThan => ">", + ColumnOperator.GreaterOrEqualTo => ">=", + ColumnOperator.LowerThan => "<", + ColumnOperator.LowerOrEqualTo => "<=", + ColumnOperator.Like => "LIKE", + ColumnOperator.NotLike => "NOT LIKE", + _ => throw new ArgumentOutOfRangeException(nameof(columnOperator), columnOperator, null) + }; + } +} \ No newline at end of file diff --git a/TCAdminApiSharp/Querying/Operators/ColumnOperator.cs b/TCAdminApiSharp/Querying/Operators/ColumnOperator.cs new file mode 100644 index 0000000..a6b783e --- /dev/null +++ b/TCAdminApiSharp/Querying/Operators/ColumnOperator.cs @@ -0,0 +1,13 @@ +namespace TCAdminApiSharp.Querying.Operators; + +public enum ColumnOperator +{ + Equal, + NotEqual, + GreaterThan, + GreaterOrEqualTo, + LowerThan, + LowerOrEqualTo, + Like, + NotLike +} \ No newline at end of file diff --git a/TCAdminApiSharp/Querying/Operators/OrderOperator.cs b/TCAdminApiSharp/Querying/Operators/OrderOperator.cs new file mode 100644 index 0000000..dbd7d7d --- /dev/null +++ b/TCAdminApiSharp/Querying/Operators/OrderOperator.cs @@ -0,0 +1,7 @@ +namespace TCAdminApiSharp.Querying.Operators; + +public enum OrderOperator +{ + Ascending, + Descending +} \ No newline at end of file diff --git a/TCAdminApiSharp/Querying/Operators/WhereOperator.cs b/TCAdminApiSharp/Querying/Operators/WhereOperator.cs new file mode 100644 index 0000000..4684da5 --- /dev/null +++ b/TCAdminApiSharp/Querying/Operators/WhereOperator.cs @@ -0,0 +1,7 @@ +namespace TCAdminApiSharp.Querying.Operators; + +public enum WhereOperator +{ + And, + Or +} \ No newline at end of file diff --git a/TCAdminApiSharp/Querying/QueryableInfo.cs b/TCAdminApiSharp/Querying/QueryableInfo.cs new file mode 100644 index 0000000..b776bee --- /dev/null +++ b/TCAdminApiSharp/Querying/QueryableInfo.cs @@ -0,0 +1,38 @@ +using System.Collections.Generic; +using System.Net.Http; +using Newtonsoft.Json; + +namespace TCAdminApiSharp.Querying; + +public class QueryableInfo +{ + [JsonProperty("RowCount")] public int RowCount { get; set; } + + [JsonProperty("Offset")] public int Offset { get; set; } + + [JsonIgnore] public List QueryOperations { get; set; } = new(); + + public QueryableInfo() + { + } + + public QueryableInfo(int rowCount, int offset, IQueryOperation queryOperation) + { + RowCount = rowCount; + Offset = offset; + QueryOperations.Add(queryOperation); + } + + public QueryableInfo(params IQueryOperation[] queryOperations) + { + foreach (var queryOperation in queryOperations) QueryOperations.Add(queryOperation); + } + + public void BuildQuery(HttpRequestMessage request) + { + foreach (var queryOperation in QueryOperations) + { + queryOperation.ModifyRequest(request); + } + } +} \ No newline at end of file diff --git a/TCAdminApiSharp/Querying/Structs/FilterInfo.cs b/TCAdminApiSharp/Querying/Structs/FilterInfo.cs new file mode 100644 index 0000000..6c101f9 --- /dev/null +++ b/TCAdminApiSharp/Querying/Structs/FilterInfo.cs @@ -0,0 +1,11 @@ +namespace TCAdminApiSharp.Querying.Structs; + +public struct FilterInfo +{ + public string Column; + + public FilterInfo(string column) + { + Column = column; + } +} \ No newline at end of file diff --git a/TCAdminApiSharp/Querying/Structs/OrderInfo.cs b/TCAdminApiSharp/Querying/Structs/OrderInfo.cs new file mode 100644 index 0000000..bd831e4 --- /dev/null +++ b/TCAdminApiSharp/Querying/Structs/OrderInfo.cs @@ -0,0 +1,13 @@ +using Newtonsoft.Json; +using Newtonsoft.Json.Converters; +using TCAdminApiSharp.Querying.Operators; + +namespace TCAdminApiSharp.Querying.Structs; + +public struct OrderInfo +{ + [JsonProperty("Field")] public string Column; + + [JsonProperty("Direction")] [JsonConverter(typeof(StringEnumConverter))] + public OrderOperator Operator; +} \ No newline at end of file diff --git a/TCAdminApiSharp/Querying/Structs/WhereInfo.cs b/TCAdminApiSharp/Querying/Structs/WhereInfo.cs new file mode 100644 index 0000000..f30af32 --- /dev/null +++ b/TCAdminApiSharp/Querying/Structs/WhereInfo.cs @@ -0,0 +1,14 @@ +using Newtonsoft.Json; +using Newtonsoft.Json.Converters; +using TCAdminApiSharp.Querying.Operators; + +namespace TCAdminApiSharp.Querying.Structs; + +public struct WhereInfo +{ + public string Column; + public object ColumnValue; + + [JsonConverter(typeof(StringEnumConverter))] + public ColumnOperator ColumnOperator; +} \ No newline at end of file diff --git a/TCAdminApiSharp/TCAdminApiSharp.csproj b/TCAdminApiSharp/TCAdminApiSharp.csproj index 6f2e1ef..a223473 100644 --- a/TCAdminApiSharp/TCAdminApiSharp.csproj +++ b/TCAdminApiSharp/TCAdminApiSharp.csproj @@ -1,28 +1,34 @@ - net5.0 + net6.0 enable - true TCAdminAPISharp Alex Redding A C# Wrapper for the TCAdmin REST API. https://github.com/TotalControlAdmin/TCAdminApiSharp - https://opensource.org/licenses/MIT - https://avatars3.githubusercontent.com/u/67070230?s=200&v=4 + TC_LOGO_SMALL.png https://github.com/TotalControlAdmin/TCAdminApiSharp TCAdmin, Wrapper, Rest, Api - 1.0.0 - 1.0.0 + 2.0.0 + $(AssemblyVersion) + + $(AssemblyVersion) + $(VersionPrefix)-$(VersionSuffix)-$(BuildNumber) + $(VersionPrefix) + + + + + + + + + - - - - - - + diff --git a/TCAdminApiSharp/TC_LOGO_SMALL.png b/TCAdminApiSharp/TC_LOGO_SMALL.png new file mode 100644 index 0000000..b391e3c Binary files /dev/null and b/TCAdminApiSharp/TC_LOGO_SMALL.png differ diff --git a/TCAdminApiSharp/TcaClient.cs b/TCAdminApiSharp/TcaClient.cs index 71cd820..ef09b89 100644 --- a/TCAdminApiSharp/TcaClient.cs +++ b/TCAdminApiSharp/TcaClient.cs @@ -1,68 +1,69 @@ using System; -using Microsoft.Extensions.DependencyInjection; -using RestSharp; +using System.Net.Http; +using System.Threading.Tasks; using Serilog; using Serilog.Events; using TCAdminApiSharp.Controllers; -// ReSharper disable NotAccessedField.Global +using TCAdminApiSharp.Helpers; -namespace TCAdminApiSharp +namespace TCAdminApiSharp; + +public class TcaClient : IDisposable { - public class TcaClient + public readonly string Host; + private readonly string _apiKey; + public readonly ServicesController ServicesController; + public readonly ServersController ServersController; + public readonly UsersController UsersController; + public readonly TasksController TasksController; + public readonly TcaClientSettings Settings; + internal readonly HttpClient HttpClient; + private int? _myUserId; + + public TcaClient(string host, string apiKey, TcaClientSettings? clientSettings = null) { - public readonly string Host; - private readonly string _apiKey; - internal static ServiceProvider ServiceProvider; - internal readonly RestClient RestClient; - public readonly ServicesController ServicesController; - public readonly UsersController UsersController; - public readonly TasksController TasksController; + clientSettings ??= TcaClientSettings.Default; + SetupDefaultLogger(clientSettings.MinimumLogLevel); + if (string.IsNullOrEmpty(host)) throw new ArgumentException("Parameter is null/empty", nameof(host)); + if (string.IsNullOrEmpty(apiKey)) throw new ArgumentException("Parameter is null/empty", nameof(apiKey)); - public TcaClient(string host, string apiKey, LogEventLevel minimumLogLevel = LogEventLevel.Information) - { - SetupDefaultLogger(minimumLogLevel); - CreateHostBuilder(); - if (string.IsNullOrEmpty(host)) - { - throw new ArgumentException("Parameter is null/empty", nameof(host)); - } - if (string.IsNullOrEmpty(apiKey)) - { - throw new ArgumentException("Parameter is null/empty", nameof(apiKey)); - } + Settings = clientSettings; + Host = host; + _apiKey = apiKey; - Host = host; - _apiKey = apiKey; + HttpClient = new HttpClient(); + HttpClient.BaseAddress = new Uri(Host); + HttpClient.DefaultRequestHeaders.Add("api_key", _apiKey); + HttpClient.DefaultRequestHeaders.Add("accept", Constants.JsonContentType); - RestClient = new RestClient(Host); - RestClient.AddDefaultHeader("api_key", apiKey); - - ServicesController = ServiceProvider.GetService() ?? throw new InvalidOperationException(); - UsersController = ServiceProvider.GetService() ?? throw new InvalidOperationException(); - TasksController = ServiceProvider.GetService() ?? throw new InvalidOperationException(); - } + ServicesController = new ServicesController(this); + ServersController = new ServersController(this); + UsersController = new UsersController(this); + TasksController = new TasksController(this); + } - internal int GetTokenUserId() + internal async Task GetTokenUserId() + { + if (_myUserId == null) { - return int.Parse(this._apiKey.Split('#')[0]); + var me = await UsersController.GetMe(); + _myUserId = me.UserId; } - private void CreateHostBuilder() - { - ServiceProvider = new ServiceCollection() - .AddTransient(_ => this) - .AddScoped() - .AddScoped() - .AddScoped() - .BuildServiceProvider(); - } + return _myUserId.Value; + } - private static void SetupDefaultLogger(LogEventLevel logEventLevel) - { - Log.Logger = new LoggerConfiguration() - .MinimumLevel.Is(logEventLevel) - .WriteTo.Console(outputTemplate: "[{Timestamp:HH:mm:ss} {Level:u3}] {Message:lj}{NewLine}{Exception}") - .CreateLogger(); - } + private static void SetupDefaultLogger(LogEventLevel logEventLevel) + { + Log.Logger = new LoggerConfiguration() + .MinimumLevel.Is(logEventLevel) + .WriteTo.Console(outputTemplate: "[{Timestamp:HH:mm:ss} {Level:u3}] {Message:lj}{NewLine}{Exception}") + .CreateLogger(); + } + + public void Dispose() + { + HttpClient.Dispose(); + GC.SuppressFinalize(this); } } \ No newline at end of file diff --git a/TCAdminApiSharp/TcaClientSettings.cs b/TCAdminApiSharp/TcaClientSettings.cs new file mode 100644 index 0000000..dc36912 --- /dev/null +++ b/TCAdminApiSharp/TcaClientSettings.cs @@ -0,0 +1,18 @@ +using Serilog.Events; + +namespace TCAdminApiSharp; + +public class TcaClientSettings +{ + public LogEventLevel MinimumLogLevel { get; set; } = LogEventLevel.Information; + + public bool ThrowOnApiResponseStatusNonComplete { get; set; } + + public static TcaClientSettings Default => new(); + + public static TcaClientSettings Debug => new() + { + MinimumLogLevel = LogEventLevel.Debug, + ThrowOnApiResponseStatusNonComplete = true + }; +} \ No newline at end of file