From 783f7dad56084a32f683fcf8ab61ca08e7c46bd8 Mon Sep 17 00:00:00 2001 From: Eicy Date: Sun, 6 Apr 2025 18:24:27 +0800 Subject: [PATCH] it works --- .idea/.idea.Pterodactyl.NETSDK/.idea/vcs.xml | 4 +- Pterodactyl.NETSDK/Application.cs | 312 +++++ Pterodactyl.NETSDK/Client.cs | 124 ++ .../Exceptions/PterodactylApiException.cs | 3 + Pterodactyl.NETSDK/GlobalUsings.cs | 1 + Pterodactyl.NETSDK/Helper/HttpHelper.cs | 43 + .../Models/Application/Locations/Location.cs | 10 + .../Application/Locations/LocationResponse.cs | 8 + .../Models/Application/Nests/Eggs/Egg.cs | 15 + .../Application/Nests/Eggs/EggConfig.cs | 11 + .../Application/Nests/Eggs/EggResponse.cs | 8 + .../Application/Nests/Eggs/EggScript.cs | 9 + .../Application/Nests/Eggs/FileConfig.cs | 7 + .../Application/Nests/Eggs/LogConfig.cs | 7 + .../Models/Application/Nests/Nest.cs | 12 + .../Models/Application/Nests/NestResponse.cs | 8 + .../Models/Application/Nodes/Node.cs | 31 + .../Models/Application/Nodes/NodeApiConfig.cs | 8 + .../Application/Nodes/NodeConfiguration.cs | 12 + .../Models/Application/Nodes/NodeResponse.cs | 8 + .../Application/Nodes/NodeSftpConfig.cs | 6 + .../Models/Application/Nodes/NodeSslConfig.cs | 8 + .../Application/Nodes/NodeSystemConfig.cs | 7 + .../Application/Servers/ContainerDetails.cs | 12 + .../Servers/ContainerExtensions.cs | 11 + .../Models/Application/Servers/Server.cs | 24 + .../Application/Servers/ServerDatabase.cs | 14 + .../Servers/ServerDatabaseResponse.cs | 8 + .../Application/Servers/ServerResponse.cs | 7 + .../Application/Servers/StartupConfig.cs | 7 + .../Models/Application/Users/User.cs | 28 + .../Models/Application/Users/UserResponse.cs | 7 + .../Models/Client/Account/Account.cs | 12 + .../Models/Client/Account/AccountResponse.cs | 7 + .../Models/Client/Account/ApiKey.cs | 14 + .../Client/Account/ApiKeyCreateResponse.cs | 8 + .../Models/Client/Account/ApiKeyResponse.cs | 8 + .../Models/Client/Account/ApiKeyWithSecret.cs | 6 + .../Models/Client/Account/TwoFactorDetails.cs | 6 + .../Account/TwoFactorDetailsResponse.cs | 7 + .../Client/Account/TwoFactorEnableResponse.cs | 9 + .../Models/Client/Servers/AllocationList.cs | 10 + .../Models/Client/Servers/ResourceStats.cs | 10 + .../Models/Client/Servers/ResourceUsage.cs | 8 + .../Models/Client/Servers/Server.cs | 30 + .../Client/Servers/ServerRelationships.cs | 6 + .../Models/Client/Servers/ServerResponse.cs | 8 + .../Models/Client/Servers/SftpDetails.cs | 8 + .../Client/Servers/WebSocketCredentials.cs | 8 + .../Client/Servers/WebSocketResponse.cs | 6 + .../Models/Common/Allocations/Allocation.cs | 10 + .../Common/Allocations/AllocationResponse.cs | 7 + .../Common/Allocations/AllocationSettings.cs | 8 + .../Models/Common/PaginatedResult.cs | 10 + .../Models/Common/PaginationDetails.cs | 10 + .../Models/Common/PaginationMeta.cs | 6 + .../Models/Common/ServerFeatureLimits.cs | 8 + .../Models/Common/ServerLimits.cs | 10 + Pterodactyl.NETSDK/Pterodactyl.NETSDK.csproj | 1 + Pterodactyl.NETSDK/PterodactylClient.cs | 1026 +---------------- .../Request/DatabaseCreateRequest.cs | 8 + .../Request/LocationCreateRequest.cs | 7 + .../Request/LocationUpdateRequest.cs | 5 + .../Request/NodeCreateRequest.cs | 22 + .../Request/NodeUpdateRequest.cs | 8 + .../Request/ServerCreateRequest.cs | 20 + .../Request/ServerDetailsUpdateRequest.cs | 9 + .../Request/UserCreateRequest.cs | 11 + .../Request/UserUpdateRequest.cs | 6 + 69 files changed, 1127 insertions(+), 1016 deletions(-) create mode 100644 Pterodactyl.NETSDK/Application.cs create mode 100644 Pterodactyl.NETSDK/Client.cs create mode 100644 Pterodactyl.NETSDK/Exceptions/PterodactylApiException.cs create mode 100644 Pterodactyl.NETSDK/GlobalUsings.cs create mode 100644 Pterodactyl.NETSDK/Helper/HttpHelper.cs create mode 100644 Pterodactyl.NETSDK/Models/Application/Locations/Location.cs create mode 100644 Pterodactyl.NETSDK/Models/Application/Locations/LocationResponse.cs create mode 100644 Pterodactyl.NETSDK/Models/Application/Nests/Eggs/Egg.cs create mode 100644 Pterodactyl.NETSDK/Models/Application/Nests/Eggs/EggConfig.cs create mode 100644 Pterodactyl.NETSDK/Models/Application/Nests/Eggs/EggResponse.cs create mode 100644 Pterodactyl.NETSDK/Models/Application/Nests/Eggs/EggScript.cs create mode 100644 Pterodactyl.NETSDK/Models/Application/Nests/Eggs/FileConfig.cs create mode 100644 Pterodactyl.NETSDK/Models/Application/Nests/Eggs/LogConfig.cs create mode 100644 Pterodactyl.NETSDK/Models/Application/Nests/Nest.cs create mode 100644 Pterodactyl.NETSDK/Models/Application/Nests/NestResponse.cs create mode 100644 Pterodactyl.NETSDK/Models/Application/Nodes/Node.cs create mode 100644 Pterodactyl.NETSDK/Models/Application/Nodes/NodeApiConfig.cs create mode 100644 Pterodactyl.NETSDK/Models/Application/Nodes/NodeConfiguration.cs create mode 100644 Pterodactyl.NETSDK/Models/Application/Nodes/NodeResponse.cs create mode 100644 Pterodactyl.NETSDK/Models/Application/Nodes/NodeSftpConfig.cs create mode 100644 Pterodactyl.NETSDK/Models/Application/Nodes/NodeSslConfig.cs create mode 100644 Pterodactyl.NETSDK/Models/Application/Nodes/NodeSystemConfig.cs create mode 100644 Pterodactyl.NETSDK/Models/Application/Servers/ContainerDetails.cs create mode 100644 Pterodactyl.NETSDK/Models/Application/Servers/ContainerExtensions.cs create mode 100644 Pterodactyl.NETSDK/Models/Application/Servers/Server.cs create mode 100644 Pterodactyl.NETSDK/Models/Application/Servers/ServerDatabase.cs create mode 100644 Pterodactyl.NETSDK/Models/Application/Servers/ServerDatabaseResponse.cs create mode 100644 Pterodactyl.NETSDK/Models/Application/Servers/ServerResponse.cs create mode 100644 Pterodactyl.NETSDK/Models/Application/Servers/StartupConfig.cs create mode 100644 Pterodactyl.NETSDK/Models/Application/Users/User.cs create mode 100644 Pterodactyl.NETSDK/Models/Application/Users/UserResponse.cs create mode 100644 Pterodactyl.NETSDK/Models/Client/Account/Account.cs create mode 100644 Pterodactyl.NETSDK/Models/Client/Account/AccountResponse.cs create mode 100644 Pterodactyl.NETSDK/Models/Client/Account/ApiKey.cs create mode 100644 Pterodactyl.NETSDK/Models/Client/Account/ApiKeyCreateResponse.cs create mode 100644 Pterodactyl.NETSDK/Models/Client/Account/ApiKeyResponse.cs create mode 100644 Pterodactyl.NETSDK/Models/Client/Account/ApiKeyWithSecret.cs create mode 100644 Pterodactyl.NETSDK/Models/Client/Account/TwoFactorDetails.cs create mode 100644 Pterodactyl.NETSDK/Models/Client/Account/TwoFactorDetailsResponse.cs create mode 100644 Pterodactyl.NETSDK/Models/Client/Account/TwoFactorEnableResponse.cs create mode 100644 Pterodactyl.NETSDK/Models/Client/Servers/AllocationList.cs create mode 100644 Pterodactyl.NETSDK/Models/Client/Servers/ResourceStats.cs create mode 100644 Pterodactyl.NETSDK/Models/Client/Servers/ResourceUsage.cs create mode 100644 Pterodactyl.NETSDK/Models/Client/Servers/Server.cs create mode 100644 Pterodactyl.NETSDK/Models/Client/Servers/ServerRelationships.cs create mode 100644 Pterodactyl.NETSDK/Models/Client/Servers/ServerResponse.cs create mode 100644 Pterodactyl.NETSDK/Models/Client/Servers/SftpDetails.cs create mode 100644 Pterodactyl.NETSDK/Models/Client/Servers/WebSocketCredentials.cs create mode 100644 Pterodactyl.NETSDK/Models/Client/Servers/WebSocketResponse.cs create mode 100644 Pterodactyl.NETSDK/Models/Common/Allocations/Allocation.cs create mode 100644 Pterodactyl.NETSDK/Models/Common/Allocations/AllocationResponse.cs create mode 100644 Pterodactyl.NETSDK/Models/Common/Allocations/AllocationSettings.cs create mode 100644 Pterodactyl.NETSDK/Models/Common/PaginatedResult.cs create mode 100644 Pterodactyl.NETSDK/Models/Common/PaginationDetails.cs create mode 100644 Pterodactyl.NETSDK/Models/Common/PaginationMeta.cs create mode 100644 Pterodactyl.NETSDK/Models/Common/ServerFeatureLimits.cs create mode 100644 Pterodactyl.NETSDK/Models/Common/ServerLimits.cs create mode 100644 Pterodactyl.NETSDK/Request/DatabaseCreateRequest.cs create mode 100644 Pterodactyl.NETSDK/Request/LocationCreateRequest.cs create mode 100644 Pterodactyl.NETSDK/Request/LocationUpdateRequest.cs create mode 100644 Pterodactyl.NETSDK/Request/NodeCreateRequest.cs create mode 100644 Pterodactyl.NETSDK/Request/NodeUpdateRequest.cs create mode 100644 Pterodactyl.NETSDK/Request/ServerCreateRequest.cs create mode 100644 Pterodactyl.NETSDK/Request/ServerDetailsUpdateRequest.cs create mode 100644 Pterodactyl.NETSDK/Request/UserCreateRequest.cs create mode 100644 Pterodactyl.NETSDK/Request/UserUpdateRequest.cs diff --git a/.idea/.idea.Pterodactyl.NETSDK/.idea/vcs.xml b/.idea/.idea.Pterodactyl.NETSDK/.idea/vcs.xml index d843f34..94a25f7 100644 --- a/.idea/.idea.Pterodactyl.NETSDK/.idea/vcs.xml +++ b/.idea/.idea.Pterodactyl.NETSDK/.idea/vcs.xml @@ -1,4 +1,6 @@ - + + + \ No newline at end of file diff --git a/Pterodactyl.NETSDK/Application.cs b/Pterodactyl.NETSDK/Application.cs new file mode 100644 index 0000000..6f0ed1c --- /dev/null +++ b/Pterodactyl.NETSDK/Application.cs @@ -0,0 +1,312 @@ +using System.Text; +using System.Text.Json; +using System.Web; +using Pterodactyl.NETSDK.Helper; +using Pterodactyl.NETSDK.Models.Application.Locations; +using Pterodactyl.NETSDK.Models.Application.Nests; +using Pterodactyl.NETSDK.Models.Application.Nests.Eggs; +using Pterodactyl.NETSDK.Models.Application.Nodes; +using Pterodactyl.NETSDK.Models.Application.Servers; +using Pterodactyl.NETSDK.Models.Application.Users; +using Pterodactyl.NETSDK.Models.Common; +using Pterodactyl.NETSDK.Models.Common.Allocations; +using Pterodactyl.NETSDK.Request; + +namespace Pterodactyl.NETSDK; + +public class Application(string baseUrl, string apiKey) : PterodactylClient(baseUrl, apiKey) +{ + #region Application API + + #region Users + + public async Task> ListUsers() + { + var response = await HttpClient.GetAsync($"{BaseUrl}/api/application/users"); + var result = await HttpHelper.HandleResponse>(response); + return result?.Data.Select(r => r.User).ToList() ?? []; + } + + public async Task GetUser(int userId) + { + var response = await HttpClient.GetAsync($"{BaseUrl}/api/application/users/{userId}"); + var result = await HttpHelper.HandleResponse(response); + return result?.User; + } + + public async Task GetUserByExternalId(string externalId) + { + var response = await HttpClient.GetAsync($"{BaseUrl}/api/application/users/external/{externalId}"); + var result = await HttpHelper.HandleResponse(response); + return result?.User; + } + + public async Task CreateUser(UserCreateRequest request) + { + var content = new StringContent(JsonSerializer.Serialize(request), Encoding.UTF8, "application/json"); + var response = await HttpClient.PostAsync($"{BaseUrl}/api/application/users", content); + var result = await HttpHelper.HandleResponse(response); + return result?.User; + } + + public async Task UpdateUser(int userId, Action updateAction) + { + var currentUser = await GetUser(userId); + + var request = new UserUpdateRequest + { + Email = currentUser?.Email, + Username = currentUser?.Username, + FirstName = currentUser?.FirstName, + LastName = currentUser?.LastName, + Language = currentUser?.Language + }; + + updateAction(request); + + var content = new StringContent(JsonSerializer.Serialize(request), Encoding.UTF8, "application/json"); + var response = await HttpClient.PatchAsync($"{BaseUrl}/api/application/users/{userId}", content); + var result = await HttpHelper.HandleResponse(response); + return result?.User; + } + + public async Task DeleteUser(int userId) + { + var response = await HttpClient.DeleteAsync($"{BaseUrl}/api/application/users/{userId}"); + await HttpHelper.HandleResponse(response); + } + + #endregion + + #region Nodes + + public async Task?> ListNodes() + { + var response = await HttpClient.GetAsync($"{BaseUrl}/api/application/nodes"); + var result = await HttpHelper.HandleResponse>(response); + + return result?.Data.Select(n => n.Node).ToList() ?? []; + } + + public async Task GetNode(int nodeId) + { + var response = await HttpClient.GetAsync($"{BaseUrl}/api/application/nodes/{nodeId}"); + var result = await HttpHelper.HandleResponse(response); + return result?.Node; + } + + public async Task GetNodeConfiguration(int nodeId) + { + var response = await HttpClient.GetAsync($"{BaseUrl}/api/application/nodes/{nodeId}/configuration"); + return await HttpHelper.HandleResponse(response); + } + + + public async Task CreateNode(NodeCreateRequest request) + { + var content = new StringContent(JsonSerializer.Serialize(request), Encoding.UTF8, "application/json"); + var response = await HttpClient.PostAsync($"{BaseUrl}/api/application/nodes", content); + var result = await HttpHelper.HandleResponse(response); + return result?.Node; + } + + public async Task UpdateNode(int nodeId, NodeUpdateRequest request) + { + var content = new StringContent(JsonSerializer.Serialize(request), Encoding.UTF8, "application/json"); + var response = await HttpClient.PatchAsync($"{BaseUrl}/api/application/nodes/{nodeId}", content); + var result = await HttpHelper.HandleResponse(response); + return result?.Node; + } + + public async Task DeleteNode(int nodeId) + { + var response = await HttpClient.DeleteAsync($"{BaseUrl}/api/application/nodes/{nodeId}"); + await HttpHelper.HandleResponse(response); + } + + public async Task?> GetNodeAllocations(int nodeId) + { + var response = await HttpClient.GetAsync($"{BaseUrl}/api/application/nodes/{nodeId}/allocations"); + var result = await HttpHelper.HandleResponse>(response); + return result?.Data.Select(r => r.Allocation).ToList(); + } + + #endregion + + #region Servers + + public async Task?> ListServers() + { + var response = await HttpClient.GetAsync($"{BaseUrl}/api/application/servers"); + var result = await HttpHelper.HandleResponse>(response); + + return result?.Data.Select(r => r.Server).ToList() ?? []; + } + + public async Task GetServer(int serverId) + { + var response = await HttpClient.GetAsync($"{BaseUrl}/api/application/servers/{serverId}"); + var result = await HttpHelper.HandleResponse(response); + return result?.Server; + } + + public async Task GetServerByExternalId(string externalId) + { + var response = await HttpClient.GetAsync($"{BaseUrl}/api/application/servers/external/{externalId}"); + var result = await HttpHelper.HandleResponse(response); + return result?.Server; + } + + public async Task CreateServer(ServerCreateRequest request) + { + var content = new StringContent(JsonSerializer.Serialize(request), Encoding.UTF8, "application/json"); + var response = await HttpClient.PostAsync($"{BaseUrl}/api/application/servers", content); + var result = await HttpHelper.HandleResponse(response); + return result?.Server; + } + + public async Task UpdateServerDetails(int serverId, + ServerDetailsUpdateRequest request) + { + var content = new StringContent(JsonSerializer.Serialize(request), Encoding.UTF8, "application/json"); + var response = + await HttpClient.PatchAsync($"{BaseUrl}/api/application/servers/{serverId}/details", content); + var result = await HttpHelper.HandleResponse(response); + return result?.Server; + } + + public async Task SuspendServer(int serverId) + { + var response = await HttpClient.PostAsync($"{BaseUrl}/api/application/servers/{serverId}/suspend", null); + await HttpHelper.HandleResponse(response); + } + + public async Task UnSuspendServer(int serverId) + { + var response = await HttpClient.PostAsync($"{BaseUrl}/api/application/servers/{serverId}/unsuspend", null); + await HttpHelper.HandleResponse(response); + } + + public async Task ReinstallServer(int serverId) + { + var response = await HttpClient.PostAsync($"{BaseUrl}/api/application/servers/{serverId}/reinstall", null); + await HttpHelper.HandleResponse(response); + } + + public async Task DeleteServer(int serverId, bool force = false) + { + var url = $"{BaseUrl}/api/application/servers/{serverId}" + (force ? "/force" : ""); + var response = await HttpClient.DeleteAsync(url); + await HttpHelper.HandleResponse(response); + } + + #endregion + + #region Locations + + public async Task?> ListLocations() + { + var response = await HttpClient.GetAsync($"{BaseUrl}/api/application/locations"); + var result = await HttpHelper.HandleResponse>(response); + return result?.Data.Select(r => r.Location).ToList() ?? []; + } + + public async Task CreateLocation(LocationCreateRequest request) + { + var content = new StringContent(JsonSerializer.Serialize(request), Encoding.UTF8, "application/json"); + var response = await HttpClient.PostAsync($"{BaseUrl}/api/application/locations", content); + var result = await HttpHelper.HandleResponse(response); + return result?.Location; + } + + public async Task UpdateLocation(int locationId, LocationUpdateRequest request) + { + var content = new StringContent(JsonSerializer.Serialize(request), Encoding.UTF8, "application/json"); + var response = await HttpClient.PatchAsync($"{BaseUrl}/api/application/locations/{locationId}", content); + var result = await HttpHelper.HandleResponse(response); + return result?.Location; + } + + public async Task DeleteLocation(int locationId) + { + var response = await HttpClient.DeleteAsync($"{BaseUrl}/api/application/locations/{locationId}"); + await HttpHelper.HandleResponse(response); + } + + #endregion + + #region Databases 一般弃用 暂不进行适配 + + public async Task?> ListServerDatabases(int serverId) + { + var response = await HttpClient.GetAsync($"{BaseUrl}/api/application/servers/{serverId}/databases"); + return await HttpHelper.HandleResponse>(response); + } + + public async Task CreateServerDatabase(int serverId, DatabaseCreateRequest request) + { + var content = new StringContent(JsonSerializer.Serialize(request), Encoding.UTF8, "application/json"); + var response = + await HttpClient.PostAsync($"{BaseUrl}/api/application/servers/{serverId}/databases", content); + return await HttpHelper.HandleResponse(response); + } + + public async Task ResetDatabasePassword(int serverId, int databaseId) + { + var response = await HttpClient.PostAsync( + $"{BaseUrl}/api/application/servers/{serverId}/databases/{databaseId}/reset-password", null); + await HttpHelper.HandleResponse(response); + } + + public async Task DeleteServerDatabase(int serverId, int databaseId) + { + var response = await HttpClient.DeleteAsync( + $"{BaseUrl}/api/application/servers/{serverId}/databases/{databaseId}"); + await HttpHelper.HandleResponse(response); + } + + #endregion + + #region Nests + + public async Task?> ListNests() + { + var response = await HttpClient.GetAsync($"{BaseUrl}/api/application/nests"); + var result = await HttpHelper.HandleResponse>(response); + return result?.Data.Select(n => n.Nest).ToList() ?? []; + } + + public async Task GetNest(int nestId) + { + var response = await HttpClient.GetAsync($"{BaseUrl}/api/application/nests/{nestId}"); + var result = await HttpHelper.HandleResponse(response); + return result?.Nest; + } + + public async Task> ListNestEggs(int nestId, bool includeNest = false, bool includeServers = false) + { + var includes = new List(); + if (includeNest) includes.Add("nest"); + if (includeServers) includes.Add("servers"); + + var query = includes.Any() + ? $"?include={string.Join(",", includes)}" + : string.Empty; + + var response = await HttpClient.GetAsync($"{BaseUrl}/api/application/nests/{nestId}/eggs{query}"); + var result = await HttpHelper.HandleResponse>(response); + + return result?.Data.Select(r => r.Egg).ToList() ?? []; + } + + public async Task GetEgg(int nestId, int eggId) + { + var response = await HttpClient.GetAsync($"{BaseUrl}/api/application/nests/{nestId}/eggs/{eggId}"); + var result = await HttpHelper.HandleResponse(response); + return result?.Egg; + } + + #endregion + + #endregion +} \ No newline at end of file diff --git a/Pterodactyl.NETSDK/Client.cs b/Pterodactyl.NETSDK/Client.cs new file mode 100644 index 0000000..dba5610 --- /dev/null +++ b/Pterodactyl.NETSDK/Client.cs @@ -0,0 +1,124 @@ +using System.Text; +using System.Text.Json; +using Pterodactyl.NETSDK.Helper; +using Pterodactyl.NETSDK.Models.Client.Account; +using Pterodactyl.NETSDK.Models.Client.Servers; +using Pterodactyl.NETSDK.Models.Common; + +namespace Pterodactyl.NETSDK; + +public class Client(string baseUrl, string apiKey) : PterodactylClient(baseUrl, apiKey) +{ + public async Task> ListServers() + { + var response = await HttpClient.GetAsync($"{BaseUrl}/api/client"); + var result = await HttpHelper.HandleResponse>(response); + return result?.Data.Select(r => r.Server).ToList() ?? []; + } + + public async Task GetAccountDetails() + { + var response = await HttpClient.GetAsync($"{BaseUrl}/api/client/account"); + var result = await HttpHelper.HandleResponse(response); + return result?.Account; + } + + public async Task GetTwoFactorDetails() + { + var response = await HttpClient.GetAsync($"{BaseUrl}/api/client/account/two-factor"); + var result = await HttpHelper.HandleResponse(response); + return result?.TwoFactorDetails; + } + + public async Task EnableTwoFactor(string code) + { + var content = new StringContent(JsonSerializer.Serialize(new { code }), Encoding.UTF8, "application/json"); + var response = await HttpClient.PostAsync($"{BaseUrl}/api/client/account/two-factor", content); + return await HttpHelper.HandleResponse(response); + } + + public async Task DisableTwoFactor(string password) + { + var requestBody = new { password }; + var content = new StringContent(JsonSerializer.Serialize(requestBody), Encoding.UTF8, "application/json"); + + var request = new HttpRequestMessage(HttpMethod.Delete, $"{BaseUrl}/api/client/account/two-factor") + { + Content = content + }; + + var response = await HttpClient.SendAsync(request); + + await HttpHelper.HandleResponse(response); + } + + public async Task UpdateEmail(string email, string password) + { + var content = new StringContent(JsonSerializer.Serialize(new { email, password }), Encoding.UTF8, + "application/json"); + var response = await HttpClient.PutAsync($"{BaseUrl}/api/client/account/email", content); + await HttpHelper.HandleResponse(response); + } + + public async Task UpdatePassword(string currentPassword, string newPassword, string confirmPassword) + { + var content = new StringContent(JsonSerializer.Serialize(new + { + current_password = currentPassword, + password = newPassword, + password_confirmation = confirmPassword + }), Encoding.UTF8, "application/json"); + + var response = await HttpClient.PutAsync($"{BaseUrl}/api/client/account/password", content); + await HttpHelper.HandleResponse(response); + } + + public async Task?> ListApiKeys() + { + var response = await HttpClient.GetAsync($"{BaseUrl}/api/client/account/api-keys"); + var result = await HttpHelper.HandleResponse>(response); + return result?.Data.Select(r => r.ApiKey).ToList(); + } + + public async Task CreateApiKey(string description, List? allowedIps = null) + { + var content = new StringContent(JsonSerializer.Serialize(new + { + description, + allowed_ips = allowedIps ?? [] + }), Encoding.UTF8, "application/json"); + + var response = await HttpClient.PostAsync($"{BaseUrl}/api/client/account/api-keys", content); + var result = await HttpHelper.HandleResponse(response); + return result?.ApiKeyWithSecret; + } + + public async Task DeleteApiKey(string identifier) + { + var response = await HttpClient.DeleteAsync($"{BaseUrl}/api/client/account/api-keys/{identifier}"); + await HttpHelper.HandleResponse(response); + } + + public async Task GetServerDetails(string serverId) + { + var response = await HttpClient.GetAsync($"{BaseUrl}/api/client/servers/{serverId}"); + var result = await HttpHelper.HandleResponse(response); + return result?.Server; + } + + public async Task SendCommand(string serverId, string command) + { + var content = new StringContent(JsonSerializer.Serialize(new { command }), Encoding.UTF8, + "application/json"); + var response = await HttpClient.PostAsync($"{BaseUrl}/api/client/servers/{serverId}/command", content); + await HttpHelper.HandleResponse(response); + } + + public async Task GetWebSocketCredentials(string serverId) + { + var response = await HttpClient.GetAsync( + $"{BaseUrl}/api/client/servers/{serverId}/websocket" + ); + return (await HttpHelper.HandleResponse(response))?.Data; + } +} \ No newline at end of file diff --git a/Pterodactyl.NETSDK/Exceptions/PterodactylApiException.cs b/Pterodactyl.NETSDK/Exceptions/PterodactylApiException.cs new file mode 100644 index 0000000..c85f900 --- /dev/null +++ b/Pterodactyl.NETSDK/Exceptions/PterodactylApiException.cs @@ -0,0 +1,3 @@ +namespace Pterodactyl.NETSDK.Exceptions; + +public class PterodactylApiException(string message) : Exception(message); \ No newline at end of file diff --git a/Pterodactyl.NETSDK/GlobalUsings.cs b/Pterodactyl.NETSDK/GlobalUsings.cs new file mode 100644 index 0000000..886a4e4 --- /dev/null +++ b/Pterodactyl.NETSDK/GlobalUsings.cs @@ -0,0 +1 @@ +global using System.Text.Json.Serialization; \ No newline at end of file diff --git a/Pterodactyl.NETSDK/Helper/HttpHelper.cs b/Pterodactyl.NETSDK/Helper/HttpHelper.cs new file mode 100644 index 0000000..94254f9 --- /dev/null +++ b/Pterodactyl.NETSDK/Helper/HttpHelper.cs @@ -0,0 +1,43 @@ +using System.Text.Json; +using Pterodactyl.NETSDK.Exceptions; + +namespace Pterodactyl.NETSDK.Helper; + +internal static class HttpHelper +{ + public static async Task HandleResponse(HttpResponseMessage response) + { + var content = await response.Content.ReadAsStringAsync(); + + if (!response.IsSuccessStatusCode) + throw new PterodactylApiException( + $"API请求失败,状态码: {response.StatusCode}" + + response.StatusCode + + content + ); + + try + { + return JsonSerializer.Deserialize(content); + } + catch (JsonException ex) + { + throw new PterodactylApiException( + $"JSON解析失败: {ex.Message}" + + response.StatusCode + + content + + ex + ); + } + } + + public static async Task HandleResponse(HttpResponseMessage response) + { + if (!response.IsSuccessStatusCode) + { + var errorContent = await response.Content.ReadAsStringAsync(); + throw new PterodactylApiException( + $"API request failed with status code {response.StatusCode}: {errorContent}"); + } + } +} \ No newline at end of file diff --git a/Pterodactyl.NETSDK/Models/Application/Locations/Location.cs b/Pterodactyl.NETSDK/Models/Application/Locations/Location.cs new file mode 100644 index 0000000..005cf0b --- /dev/null +++ b/Pterodactyl.NETSDK/Models/Application/Locations/Location.cs @@ -0,0 +1,10 @@ +namespace Pterodactyl.NETSDK.Models.Application.Locations; + +public class Location +{ + [JsonPropertyName("id")] public int Id { get; set; } + [JsonPropertyName("short")] public string? ShortCode { get; set; } + [JsonPropertyName("long")] public string? LongName { get; set; } + [JsonPropertyName("created_at")] public DateTime CreatedAt { get; set; } + [JsonPropertyName("updated_at")] public DateTime UpdatedAt { get; set; } +} \ No newline at end of file diff --git a/Pterodactyl.NETSDK/Models/Application/Locations/LocationResponse.cs b/Pterodactyl.NETSDK/Models/Application/Locations/LocationResponse.cs new file mode 100644 index 0000000..d4577f2 --- /dev/null +++ b/Pterodactyl.NETSDK/Models/Application/Locations/LocationResponse.cs @@ -0,0 +1,8 @@ +namespace Pterodactyl.NETSDK.Models.Application.Locations; + +public class LocationResponse +{ + [JsonPropertyName("object")] public string? ObjectType { get; set; } + + [JsonPropertyName("attributes")] public Location? Location { get; set; } +} \ No newline at end of file diff --git a/Pterodactyl.NETSDK/Models/Application/Nests/Eggs/Egg.cs b/Pterodactyl.NETSDK/Models/Application/Nests/Eggs/Egg.cs new file mode 100644 index 0000000..65516b0 --- /dev/null +++ b/Pterodactyl.NETSDK/Models/Application/Nests/Eggs/Egg.cs @@ -0,0 +1,15 @@ +namespace Pterodactyl.NETSDK.Models.Application.Nests.Eggs; + +public class Egg +{ + [JsonPropertyName("id")] public int Id { get; set; } + [JsonPropertyName("uuid")] public string? Uuid { get; set; } + [JsonPropertyName("name")] public string? Name { get; set; } + [JsonPropertyName("description")] public string? Description { get; set; } + [JsonPropertyName("docker_image")] public string? DockerImage { get; set; } + [JsonPropertyName("config")] public EggConfig? Config { get; set; } + [JsonPropertyName("startup")] public string? StartupCommand { get; set; } + [JsonPropertyName("script")] public EggScript? Script { get; set; } + [JsonPropertyName("created_at")] public DateTime CreatedAt { get; set; } + [JsonPropertyName("updated_at")] public DateTime UpdatedAt { get; set; } +} \ No newline at end of file diff --git a/Pterodactyl.NETSDK/Models/Application/Nests/Eggs/EggConfig.cs b/Pterodactyl.NETSDK/Models/Application/Nests/Eggs/EggConfig.cs new file mode 100644 index 0000000..2f5ad69 --- /dev/null +++ b/Pterodactyl.NETSDK/Models/Application/Nests/Eggs/EggConfig.cs @@ -0,0 +1,11 @@ +using Pterodactyl.NETSDK.Models.Application.Servers; + +namespace Pterodactyl.NETSDK.Models.Application.Nests.Eggs; + +public class EggConfig +{ + [JsonPropertyName("files")] public Dictionary? Files { get; set; } + [JsonPropertyName("startup")] public StartupConfig? Startup { get; set; } + [JsonPropertyName("stop")] public string? StopSign { get; set; } + [JsonPropertyName("logs")] public List? Logs { get; set; } +} \ No newline at end of file diff --git a/Pterodactyl.NETSDK/Models/Application/Nests/Eggs/EggResponse.cs b/Pterodactyl.NETSDK/Models/Application/Nests/Eggs/EggResponse.cs new file mode 100644 index 0000000..b586ad0 --- /dev/null +++ b/Pterodactyl.NETSDK/Models/Application/Nests/Eggs/EggResponse.cs @@ -0,0 +1,8 @@ +namespace Pterodactyl.NETSDK.Models.Application.Nests.Eggs; + +public class EggResponse +{ + [JsonPropertyName("object")] public string? ObjectType { get; set; } + + [JsonPropertyName("attributes")] public Egg? Egg { get; set; } +} \ No newline at end of file diff --git a/Pterodactyl.NETSDK/Models/Application/Nests/Eggs/EggScript.cs b/Pterodactyl.NETSDK/Models/Application/Nests/Eggs/EggScript.cs new file mode 100644 index 0000000..95322ac --- /dev/null +++ b/Pterodactyl.NETSDK/Models/Application/Nests/Eggs/EggScript.cs @@ -0,0 +1,9 @@ +namespace Pterodactyl.NETSDK.Models.Application.Nests.Eggs; + +public class EggScript +{ + [JsonPropertyName("privileged")] public bool Privileged { get; set; } + [JsonPropertyName("install")] public string? InstallScript { get; set; } + [JsonPropertyName("entry")] public string? EntryPoint { get; set; } + [JsonPropertyName("container")] public string? ContainerImage { get; set; } +} \ No newline at end of file diff --git a/Pterodactyl.NETSDK/Models/Application/Nests/Eggs/FileConfig.cs b/Pterodactyl.NETSDK/Models/Application/Nests/Eggs/FileConfig.cs new file mode 100644 index 0000000..d0b3ebd --- /dev/null +++ b/Pterodactyl.NETSDK/Models/Application/Nests/Eggs/FileConfig.cs @@ -0,0 +1,7 @@ +namespace Pterodactyl.NETSDK.Models.Application.Nests.Eggs; + +public class FileConfig +{ + [JsonPropertyName("parser")] public string? Parser { get; set; } + [JsonPropertyName("find")] public Dictionary? FindReplace { get; set; } +} \ No newline at end of file diff --git a/Pterodactyl.NETSDK/Models/Application/Nests/Eggs/LogConfig.cs b/Pterodactyl.NETSDK/Models/Application/Nests/Eggs/LogConfig.cs new file mode 100644 index 0000000..a3321c9 --- /dev/null +++ b/Pterodactyl.NETSDK/Models/Application/Nests/Eggs/LogConfig.cs @@ -0,0 +1,7 @@ +namespace Pterodactyl.NETSDK.Models.Application.Nests.Eggs; + +public class LogConfig +{ + [JsonPropertyName("custom")] public bool IsCustom { get; set; } + [JsonPropertyName("location")] public string? Location { get; set; } +} \ No newline at end of file diff --git a/Pterodactyl.NETSDK/Models/Application/Nests/Nest.cs b/Pterodactyl.NETSDK/Models/Application/Nests/Nest.cs new file mode 100644 index 0000000..878c5b5 --- /dev/null +++ b/Pterodactyl.NETSDK/Models/Application/Nests/Nest.cs @@ -0,0 +1,12 @@ +namespace Pterodactyl.NETSDK.Models.Application.Nests; + +public class Nest +{ + [JsonPropertyName("id")] public int Id { get; set; } + [JsonPropertyName("uuid")] public string? Uuid { get; set; } + [JsonPropertyName("author")] public string? Author { get; set; } + [JsonPropertyName("name")] public string? Name { get; set; } + [JsonPropertyName("description")] public string? Description { get; set; } + [JsonPropertyName("created_at")] public DateTime CreatedAt { get; set; } + [JsonPropertyName("updated_at")] public DateTime UpdatedAt { get; set; } +} \ No newline at end of file diff --git a/Pterodactyl.NETSDK/Models/Application/Nests/NestResponse.cs b/Pterodactyl.NETSDK/Models/Application/Nests/NestResponse.cs new file mode 100644 index 0000000..1ccae7a --- /dev/null +++ b/Pterodactyl.NETSDK/Models/Application/Nests/NestResponse.cs @@ -0,0 +1,8 @@ +namespace Pterodactyl.NETSDK.Models.Application.Nests; + +public class NestResponse +{ + [JsonPropertyName("object")] public string? ObjectType { get; set; } + + [JsonPropertyName("attributes")] public Nest? Nest { get; set; } +} \ No newline at end of file diff --git a/Pterodactyl.NETSDK/Models/Application/Nodes/Node.cs b/Pterodactyl.NETSDK/Models/Application/Nodes/Node.cs new file mode 100644 index 0000000..cd65d3d --- /dev/null +++ b/Pterodactyl.NETSDK/Models/Application/Nodes/Node.cs @@ -0,0 +1,31 @@ +namespace Pterodactyl.NETSDK.Models.Application.Nodes; + +public class Node +{ + [JsonPropertyName("id")] public int Id { get; set; } + [JsonPropertyName("uuid")] public string? Uuid { get; set; } + [JsonPropertyName("public")] public bool Public { get; set; } + [JsonPropertyName("name")] public string? Name { get; set; } + [JsonPropertyName("description")] public string? Description { get; set; } + [JsonPropertyName("location_id")] public int LocationId { get; set; } + [JsonPropertyName("fqdn")] public string? Fqdn { get; set; } + [JsonPropertyName("scheme")] public string? Scheme { get; set; } + [JsonPropertyName("behind_proxy")] public bool BehindProxy { get; set; } + [JsonPropertyName("maintenance_mode")] public bool MaintenanceMode { get; set; } + [JsonPropertyName("memory")] public int Memory { get; set; } + + [JsonPropertyName("memory_overallocate")] + public int MemoryOverallocate { get; set; } + + [JsonPropertyName("disk")] public int Disk { get; set; } + + [JsonPropertyName("disk_overallocate")] + public int DiskOverallocate { get; set; } + + [JsonPropertyName("upload_size")] public int UploadSize { get; set; } + [JsonPropertyName("daemon_listen")] public int DaemonListen { get; set; } + [JsonPropertyName("daemon_sftp")] public int DaemonSftp { get; set; } + [JsonPropertyName("daemon_base")] public string? DaemonBase { get; set; } + [JsonPropertyName("created_at")] public DateTime CreatedAt { get; set; } + [JsonPropertyName("updated_at")] public DateTime UpdatedAt { get; set; } +} \ No newline at end of file diff --git a/Pterodactyl.NETSDK/Models/Application/Nodes/NodeApiConfig.cs b/Pterodactyl.NETSDK/Models/Application/Nodes/NodeApiConfig.cs new file mode 100644 index 0000000..14462c1 --- /dev/null +++ b/Pterodactyl.NETSDK/Models/Application/Nodes/NodeApiConfig.cs @@ -0,0 +1,8 @@ +namespace Pterodactyl.NETSDK.Models.Application.Nodes; + +public class NodeApiConfig +{ + [JsonPropertyName("host")] public string? Host { get; set; } + [JsonPropertyName("port")] public int Port { get; set; } + [JsonPropertyName("ssl")] public NodeSslConfig? Ssl { get; set; } +} \ No newline at end of file diff --git a/Pterodactyl.NETSDK/Models/Application/Nodes/NodeConfiguration.cs b/Pterodactyl.NETSDK/Models/Application/Nodes/NodeConfiguration.cs new file mode 100644 index 0000000..92f44f4 --- /dev/null +++ b/Pterodactyl.NETSDK/Models/Application/Nodes/NodeConfiguration.cs @@ -0,0 +1,12 @@ +namespace Pterodactyl.NETSDK.Models.Application.Nodes; + +public class NodeConfiguration +{ + [JsonPropertyName("debug")] public bool Debug { get; set; } + [JsonPropertyName("uuid")] public string? Uuid { get; set; } + [JsonPropertyName("token_id")] public string? TokenId { get; set; } + [JsonPropertyName("token")] public string? Token { get; set; } + [JsonPropertyName("api")] public NodeApiConfig? Api { get; set; } + [JsonPropertyName("system")] public NodeSystemConfig? System { get; set; } + [JsonPropertyName("remote")] public string? Remote { get; set; } +} \ No newline at end of file diff --git a/Pterodactyl.NETSDK/Models/Application/Nodes/NodeResponse.cs b/Pterodactyl.NETSDK/Models/Application/Nodes/NodeResponse.cs new file mode 100644 index 0000000..7645ad8 --- /dev/null +++ b/Pterodactyl.NETSDK/Models/Application/Nodes/NodeResponse.cs @@ -0,0 +1,8 @@ +namespace Pterodactyl.NETSDK.Models.Application.Nodes; + +public class NodeResponse +{ + [JsonPropertyName("object")] public string? ObjectType { get; set; } + + [JsonPropertyName("attributes")] public Node? Node { get; set; } +} \ No newline at end of file diff --git a/Pterodactyl.NETSDK/Models/Application/Nodes/NodeSftpConfig.cs b/Pterodactyl.NETSDK/Models/Application/Nodes/NodeSftpConfig.cs new file mode 100644 index 0000000..64b12e6 --- /dev/null +++ b/Pterodactyl.NETSDK/Models/Application/Nodes/NodeSftpConfig.cs @@ -0,0 +1,6 @@ +namespace Pterodactyl.NETSDK.Models.Application.Nodes; + +public class NodeSftpConfig +{ + [JsonPropertyName("bind_port")] public int Port { get; set; } +} \ No newline at end of file diff --git a/Pterodactyl.NETSDK/Models/Application/Nodes/NodeSslConfig.cs b/Pterodactyl.NETSDK/Models/Application/Nodes/NodeSslConfig.cs new file mode 100644 index 0000000..7dd3e51 --- /dev/null +++ b/Pterodactyl.NETSDK/Models/Application/Nodes/NodeSslConfig.cs @@ -0,0 +1,8 @@ +namespace Pterodactyl.NETSDK.Models.Application.Nodes; + +public class NodeSslConfig +{ + [JsonPropertyName("enabled")] public bool Enabled { get; set; } + [JsonPropertyName("cert")] public string? Certificate { get; set; } + [JsonPropertyName("key")] public string? Key { get; set; } +} \ No newline at end of file diff --git a/Pterodactyl.NETSDK/Models/Application/Nodes/NodeSystemConfig.cs b/Pterodactyl.NETSDK/Models/Application/Nodes/NodeSystemConfig.cs new file mode 100644 index 0000000..f933e6c --- /dev/null +++ b/Pterodactyl.NETSDK/Models/Application/Nodes/NodeSystemConfig.cs @@ -0,0 +1,7 @@ +namespace Pterodactyl.NETSDK.Models.Application.Nodes; + +public class NodeSystemConfig +{ + [JsonPropertyName("data")] public string? DataPath { get; set; } + [JsonPropertyName("sftp")] public NodeSftpConfig? Sftp { get; set; } +} \ No newline at end of file diff --git a/Pterodactyl.NETSDK/Models/Application/Servers/ContainerDetails.cs b/Pterodactyl.NETSDK/Models/Application/Servers/ContainerDetails.cs new file mode 100644 index 0000000..94122a7 --- /dev/null +++ b/Pterodactyl.NETSDK/Models/Application/Servers/ContainerDetails.cs @@ -0,0 +1,12 @@ +namespace Pterodactyl.NETSDK.Models.Application.Servers; + +public class ContainerDetails +{ + [JsonPropertyName("startup_command")] public string? StartupCommand { get; set; } + + [JsonPropertyName("image")] public string? Image { get; set; } + + [JsonPropertyName("installed")] public int Installed { get; set; } + + [JsonPropertyName("environment")] public Dictionary? Environment { get; set; } +} \ No newline at end of file diff --git a/Pterodactyl.NETSDK/Models/Application/Servers/ContainerExtensions.cs b/Pterodactyl.NETSDK/Models/Application/Servers/ContainerExtensions.cs new file mode 100644 index 0000000..38206b9 --- /dev/null +++ b/Pterodactyl.NETSDK/Models/Application/Servers/ContainerExtensions.cs @@ -0,0 +1,11 @@ +namespace Pterodactyl.NETSDK.Models.Application.Servers; + +public static class ContainerExtensions +{ + public static T? GetEnvironmentValue(Dictionary env, string key) + { + if (env.TryGetValue(key, out var value) && value is T typedValue) return typedValue; + + return default; + } +} \ No newline at end of file diff --git a/Pterodactyl.NETSDK/Models/Application/Servers/Server.cs b/Pterodactyl.NETSDK/Models/Application/Servers/Server.cs new file mode 100644 index 0000000..a674608 --- /dev/null +++ b/Pterodactyl.NETSDK/Models/Application/Servers/Server.cs @@ -0,0 +1,24 @@ +using Pterodactyl.NETSDK.Models.Common; + +namespace Pterodactyl.NETSDK.Models.Application.Servers; + +public class Server +{ + [JsonPropertyName("id")] public int Id { get; set; } + [JsonPropertyName("identifier")] public string? Identifier { get; set; } + [JsonPropertyName("external_id")] public string? ExternalId { get; set; } + [JsonPropertyName("uuid")] public string? Uuid { get; set; } + [JsonPropertyName("name")] public string? Name { get; set; } + [JsonPropertyName("description")] public string? Description { get; set; } + [JsonPropertyName("suspended")] public bool IsSuspended { get; set; } + [JsonPropertyName("limits")] public ServerLimits? Limits { get; set; } + [JsonPropertyName("feature_limits")] public ServerFeatureLimits? FeatureLimits { get; set; } + [JsonPropertyName("user")] public int User { get; set; } + [JsonPropertyName("node")] public int Node { get; set; } + [JsonPropertyName("allocation")] public int Allocation { get; set; } + [JsonPropertyName("nest")] public int Nest { get; set; } + [JsonPropertyName("egg")] public int Egg { get; set; } + [JsonPropertyName("container")] public ContainerDetails? Container { get; set; } + [JsonPropertyName("updated_at")] public DateTime? UpdateAt { get; set; } + [JsonPropertyName("created_at")] public DateTime? CreatedAt { get; set; } +} \ No newline at end of file diff --git a/Pterodactyl.NETSDK/Models/Application/Servers/ServerDatabase.cs b/Pterodactyl.NETSDK/Models/Application/Servers/ServerDatabase.cs new file mode 100644 index 0000000..5ac61f6 --- /dev/null +++ b/Pterodactyl.NETSDK/Models/Application/Servers/ServerDatabase.cs @@ -0,0 +1,14 @@ +namespace Pterodactyl.NETSDK.Models.Application.Servers; + +public class ServerDatabase +{ + [JsonPropertyName("id")] public int Id { get; set; } + [JsonPropertyName("server")] public int ServerId { get; set; } + [JsonPropertyName("host")] public int HostId { get; set; } + [JsonPropertyName("database")] public string? DatabaseName { get; set; } + [JsonPropertyName("username")] public string? Username { get; set; } + [JsonPropertyName("remote")] public string? RemoteAccess { get; set; } + [JsonPropertyName("max_connections")] public int MaxConnections { get; set; } + [JsonPropertyName("created_at")] public DateTime CreatedAt { get; set; } + [JsonPropertyName("updated_at")] public DateTime UpdatedAt { get; set; } +} \ No newline at end of file diff --git a/Pterodactyl.NETSDK/Models/Application/Servers/ServerDatabaseResponse.cs b/Pterodactyl.NETSDK/Models/Application/Servers/ServerDatabaseResponse.cs new file mode 100644 index 0000000..06de5c5 --- /dev/null +++ b/Pterodactyl.NETSDK/Models/Application/Servers/ServerDatabaseResponse.cs @@ -0,0 +1,8 @@ +namespace Pterodactyl.NETSDK.Models.Application.Servers; + +public class ServerDatabaseResponse +{ + [JsonPropertyName("object")] public string? ObjectType { get; set; } + + [JsonPropertyName("attributes")] public ServerDatabase? ServerDatabase { get; set; } +} \ No newline at end of file diff --git a/Pterodactyl.NETSDK/Models/Application/Servers/ServerResponse.cs b/Pterodactyl.NETSDK/Models/Application/Servers/ServerResponse.cs new file mode 100644 index 0000000..4a98d1c --- /dev/null +++ b/Pterodactyl.NETSDK/Models/Application/Servers/ServerResponse.cs @@ -0,0 +1,7 @@ +namespace Pterodactyl.NETSDK.Models.Application.Servers; + +public class ServerResponse +{ + [JsonPropertyName("object")] public string? ObjectType { get; set; } + [JsonPropertyName("attributes")] public Server? Server { get; set; } +} \ No newline at end of file diff --git a/Pterodactyl.NETSDK/Models/Application/Servers/StartupConfig.cs b/Pterodactyl.NETSDK/Models/Application/Servers/StartupConfig.cs new file mode 100644 index 0000000..9ca86c8 --- /dev/null +++ b/Pterodactyl.NETSDK/Models/Application/Servers/StartupConfig.cs @@ -0,0 +1,7 @@ +namespace Pterodactyl.NETSDK.Models.Application.Servers; + +public class StartupConfig +{ + [JsonPropertyName("done")] public string? CompletionExpression { get; set; } + [JsonPropertyName("userInteraction")] public List? UserInteractions { get; set; } +} \ No newline at end of file diff --git a/Pterodactyl.NETSDK/Models/Application/Users/User.cs b/Pterodactyl.NETSDK/Models/Application/Users/User.cs new file mode 100644 index 0000000..0a946f9 --- /dev/null +++ b/Pterodactyl.NETSDK/Models/Application/Users/User.cs @@ -0,0 +1,28 @@ +namespace Pterodactyl.NETSDK.Models.Application.Users; + +public class User +{ + [JsonPropertyName("id")] public int Id { get; set; } + + [JsonPropertyName("external_id")] public string? ExternalId { get; set; } + + [JsonPropertyName("uuid")] public string? Uuid { get; set; } + + [JsonPropertyName("username")] public string? Username { get; set; } + + [JsonPropertyName("email")] public string? Email { get; set; } + + [JsonPropertyName("first_name")] public string? FirstName { get; set; } + + [JsonPropertyName("last_name")] public string? LastName { get; set; } + + [JsonPropertyName("language")] public string? Language { get; set; } + + [JsonPropertyName("root_admin")] public bool IsRootAdmin { get; set; } + + [JsonPropertyName("2fa")] public bool TwoFactorEnabled { get; set; } + + [JsonPropertyName("created_at")] public DateTime CreatedAt { get; set; } + + [JsonPropertyName("updated_at")] public DateTime UpdatedAt { get; set; } +} \ No newline at end of file diff --git a/Pterodactyl.NETSDK/Models/Application/Users/UserResponse.cs b/Pterodactyl.NETSDK/Models/Application/Users/UserResponse.cs new file mode 100644 index 0000000..b477d82 --- /dev/null +++ b/Pterodactyl.NETSDK/Models/Application/Users/UserResponse.cs @@ -0,0 +1,7 @@ +namespace Pterodactyl.NETSDK.Models.Application.Users; + +public class UserResponse +{ + [JsonPropertyName("object")] public string? ObjectType { get; set; } + [JsonPropertyName("attributes")] public User? User { get; set; } +} \ No newline at end of file diff --git a/Pterodactyl.NETSDK/Models/Client/Account/Account.cs b/Pterodactyl.NETSDK/Models/Client/Account/Account.cs new file mode 100644 index 0000000..a169444 --- /dev/null +++ b/Pterodactyl.NETSDK/Models/Client/Account/Account.cs @@ -0,0 +1,12 @@ +namespace Pterodactyl.NETSDK.Models.Client.Account; + +public class Account +{ + [JsonPropertyName("id")] public int Id { get; set; } + [JsonPropertyName("admin")] public bool Admin { get; set; } + [JsonPropertyName("username")] public string? Username { get; set; } + [JsonPropertyName("email")] public string? Email { get; set; } + [JsonPropertyName("first_name")] public string? FirstName { get; set; } + [JsonPropertyName("last_name")] public string? LastName { get; set; } + [JsonPropertyName("language")] public string? Language { get; set; } +} \ No newline at end of file diff --git a/Pterodactyl.NETSDK/Models/Client/Account/AccountResponse.cs b/Pterodactyl.NETSDK/Models/Client/Account/AccountResponse.cs new file mode 100644 index 0000000..9dea1f6 --- /dev/null +++ b/Pterodactyl.NETSDK/Models/Client/Account/AccountResponse.cs @@ -0,0 +1,7 @@ +namespace Pterodactyl.NETSDK.Models.Client.Account; + +public class AccountResponse +{ + [JsonPropertyName("object")] public string? ObjectType { get; set; } + [JsonPropertyName("attributes")] public Account? Account { get; set; } +} \ No newline at end of file diff --git a/Pterodactyl.NETSDK/Models/Client/Account/ApiKey.cs b/Pterodactyl.NETSDK/Models/Client/Account/ApiKey.cs new file mode 100644 index 0000000..93aaecf --- /dev/null +++ b/Pterodactyl.NETSDK/Models/Client/Account/ApiKey.cs @@ -0,0 +1,14 @@ +namespace Pterodactyl.NETSDK.Models.Client.Account; + +public class ApiKey +{ + [JsonPropertyName("identifier")] public string? Identifier { get; set; } + + [JsonPropertyName("description")] public string? Description { get; set; } + + [JsonPropertyName("allowed_ips")] public List? AllowedIps { get; set; } + + [JsonPropertyName("last_used_at")] public DateTime? LastUsedAt { get; set; } + + [JsonPropertyName("created_at")] public DateTime CreatedAt { get; set; } +} \ No newline at end of file diff --git a/Pterodactyl.NETSDK/Models/Client/Account/ApiKeyCreateResponse.cs b/Pterodactyl.NETSDK/Models/Client/Account/ApiKeyCreateResponse.cs new file mode 100644 index 0000000..1c214c8 --- /dev/null +++ b/Pterodactyl.NETSDK/Models/Client/Account/ApiKeyCreateResponse.cs @@ -0,0 +1,8 @@ +namespace Pterodactyl.NETSDK.Models.Client.Account; + +public class ApiKeyCreateResponse +{ + [JsonPropertyName("object")] public string? ObjectType { get; set; } + + [JsonPropertyName("attributes")] public ApiKeyWithSecret? ApiKeyWithSecret { get; set; } +} \ No newline at end of file diff --git a/Pterodactyl.NETSDK/Models/Client/Account/ApiKeyResponse.cs b/Pterodactyl.NETSDK/Models/Client/Account/ApiKeyResponse.cs new file mode 100644 index 0000000..2e592d3 --- /dev/null +++ b/Pterodactyl.NETSDK/Models/Client/Account/ApiKeyResponse.cs @@ -0,0 +1,8 @@ +namespace Pterodactyl.NETSDK.Models.Client.Account; + +public class ApiKeyResponse +{ + [JsonPropertyName("object")] public string? ObjectType { get; set; } + + [JsonPropertyName("attributes")] public ApiKey? ApiKey { get; set; } +} \ No newline at end of file diff --git a/Pterodactyl.NETSDK/Models/Client/Account/ApiKeyWithSecret.cs b/Pterodactyl.NETSDK/Models/Client/Account/ApiKeyWithSecret.cs new file mode 100644 index 0000000..5d11dd1 --- /dev/null +++ b/Pterodactyl.NETSDK/Models/Client/Account/ApiKeyWithSecret.cs @@ -0,0 +1,6 @@ +namespace Pterodactyl.NETSDK.Models.Client.Account; + +public class ApiKeyWithSecret : ApiKey +{ + [JsonPropertyName("token")] public string? SecretToken { get; set; } +} \ No newline at end of file diff --git a/Pterodactyl.NETSDK/Models/Client/Account/TwoFactorDetails.cs b/Pterodactyl.NETSDK/Models/Client/Account/TwoFactorDetails.cs new file mode 100644 index 0000000..84fc6f6 --- /dev/null +++ b/Pterodactyl.NETSDK/Models/Client/Account/TwoFactorDetails.cs @@ -0,0 +1,6 @@ +namespace Pterodactyl.NETSDK.Models.Client.Account; + +public class TwoFactorDetails +{ + [JsonPropertyName("image_url_data")] public string? ImageUrlData { get; set; } +} \ No newline at end of file diff --git a/Pterodactyl.NETSDK/Models/Client/Account/TwoFactorDetailsResponse.cs b/Pterodactyl.NETSDK/Models/Client/Account/TwoFactorDetailsResponse.cs new file mode 100644 index 0000000..eca784a --- /dev/null +++ b/Pterodactyl.NETSDK/Models/Client/Account/TwoFactorDetailsResponse.cs @@ -0,0 +1,7 @@ +namespace Pterodactyl.NETSDK.Models.Client.Account; + +public class TwoFactorDetailsResponse +{ + [JsonPropertyName("object")] public string? ObjectType { get; set; } + [JsonPropertyName("attributes")] public TwoFactorDetails? TwoFactorDetails { get; set; } +} \ No newline at end of file diff --git a/Pterodactyl.NETSDK/Models/Client/Account/TwoFactorEnableResponse.cs b/Pterodactyl.NETSDK/Models/Client/Account/TwoFactorEnableResponse.cs new file mode 100644 index 0000000..f0aa4dc --- /dev/null +++ b/Pterodactyl.NETSDK/Models/Client/Account/TwoFactorEnableResponse.cs @@ -0,0 +1,9 @@ +namespace Pterodactyl.NETSDK.Models.Client.Account; + +public class TwoFactorEnableResponse +{ + [JsonPropertyName("tokens")] public List? Tokens { get; set; } + [JsonPropertyName("allowed_ips")] public List? AllowedIps { get; set; } + [JsonPropertyName("last_used_at")] public DateTime? LastUsedAt { get; set; } + [JsonPropertyName("created_at")] public DateTime CreatedAt { get; set; } +} \ No newline at end of file diff --git a/Pterodactyl.NETSDK/Models/Client/Servers/AllocationList.cs b/Pterodactyl.NETSDK/Models/Client/Servers/AllocationList.cs new file mode 100644 index 0000000..9509f24 --- /dev/null +++ b/Pterodactyl.NETSDK/Models/Client/Servers/AllocationList.cs @@ -0,0 +1,10 @@ +using Pterodactyl.NETSDK.Models.Common.Allocations; + +namespace Pterodactyl.NETSDK.Models.Client.Servers; + +public class AllocationList +{ + [JsonPropertyName("object")] public string? ObjectType { get; set; } + + [JsonPropertyName("data")] public List? Data { get; set; } +} \ No newline at end of file diff --git a/Pterodactyl.NETSDK/Models/Client/Servers/ResourceStats.cs b/Pterodactyl.NETSDK/Models/Client/Servers/ResourceStats.cs new file mode 100644 index 0000000..988b181 --- /dev/null +++ b/Pterodactyl.NETSDK/Models/Client/Servers/ResourceStats.cs @@ -0,0 +1,10 @@ +namespace Pterodactyl.NETSDK.Models.Client.Servers; + +public class ResourceStats +{ + [JsonPropertyName("memory_bytes")] public long MemoryBytes { get; set; } + [JsonPropertyName("cpu_absolute")] public long CpuAbsolute { get; set; } + [JsonPropertyName("disk_bytes")] public long DiskBytes { get; set; } + [JsonPropertyName("network_rx_bytes")] public long NetworkRxBytes { get; set; } + [JsonPropertyName("network_tx_bytes")] public long NetworkTxBytes { get; set; } +} \ No newline at end of file diff --git a/Pterodactyl.NETSDK/Models/Client/Servers/ResourceUsage.cs b/Pterodactyl.NETSDK/Models/Client/Servers/ResourceUsage.cs new file mode 100644 index 0000000..ff29de9 --- /dev/null +++ b/Pterodactyl.NETSDK/Models/Client/Servers/ResourceUsage.cs @@ -0,0 +1,8 @@ +namespace Pterodactyl.NETSDK.Models.Client.Servers; + +public class ResourceUsage +{ + [JsonPropertyName("current_state")] public string? CurrentState { get; set; } + [JsonPropertyName("is_suspended")] public bool IsSuspended { get; set; } + [JsonPropertyName("resources")] public ResourceStats? Resources { get; set; } +} \ No newline at end of file diff --git a/Pterodactyl.NETSDK/Models/Client/Servers/Server.cs b/Pterodactyl.NETSDK/Models/Client/Servers/Server.cs new file mode 100644 index 0000000..2f11467 --- /dev/null +++ b/Pterodactyl.NETSDK/Models/Client/Servers/Server.cs @@ -0,0 +1,30 @@ +using Pterodactyl.NETSDK.Models.Common; + +namespace Pterodactyl.NETSDK.Models.Client.Servers; + +public class Server +{ + [JsonPropertyName("server_owner")] public bool IsServerOwner { get; set; } + + [JsonPropertyName("identifier")] public string? Identifier { get; set; } + + [JsonPropertyName("uuid")] public string? Uuid { get; set; } + + [JsonPropertyName("name")] public string? Name { get; set; } + + [JsonPropertyName("node")] public string? NodeName { get; set; } + + [JsonPropertyName("sftp_details")] public SftpDetails? SftpDetails { get; set; } + + [JsonPropertyName("description")] public string? Description { get; set; } + + [JsonPropertyName("limits")] public ServerLimits? Limits { get; set; } + + [JsonPropertyName("feature_limits")] public ServerFeatureLimits? FeatureLimits { get; set; } + + [JsonPropertyName("is_suspended")] public bool IsSuspended { get; set; } + + [JsonPropertyName("is_installing")] public bool IsInstalling { get; set; } + + [JsonPropertyName("relationships")] public ServerRelationships? Relationships { get; set; } +} \ No newline at end of file diff --git a/Pterodactyl.NETSDK/Models/Client/Servers/ServerRelationships.cs b/Pterodactyl.NETSDK/Models/Client/Servers/ServerRelationships.cs new file mode 100644 index 0000000..eb3e7fb --- /dev/null +++ b/Pterodactyl.NETSDK/Models/Client/Servers/ServerRelationships.cs @@ -0,0 +1,6 @@ +namespace Pterodactyl.NETSDK.Models.Client.Servers; + +public class ServerRelationships +{ + [JsonPropertyName("allocations")] public AllocationList? Allocations { get; set; } +} \ No newline at end of file diff --git a/Pterodactyl.NETSDK/Models/Client/Servers/ServerResponse.cs b/Pterodactyl.NETSDK/Models/Client/Servers/ServerResponse.cs new file mode 100644 index 0000000..759a721 --- /dev/null +++ b/Pterodactyl.NETSDK/Models/Client/Servers/ServerResponse.cs @@ -0,0 +1,8 @@ +namespace Pterodactyl.NETSDK.Models.Client.Servers; + +public class ServerResponse +{ + [JsonPropertyName("object")] public string? ObjectType { get; set; } + + [JsonPropertyName("attributes")] public Server? Server { get; set; } +} \ No newline at end of file diff --git a/Pterodactyl.NETSDK/Models/Client/Servers/SftpDetails.cs b/Pterodactyl.NETSDK/Models/Client/Servers/SftpDetails.cs new file mode 100644 index 0000000..97debb3 --- /dev/null +++ b/Pterodactyl.NETSDK/Models/Client/Servers/SftpDetails.cs @@ -0,0 +1,8 @@ +namespace Pterodactyl.NETSDK.Models.Client.Servers; + +public class SftpDetails +{ + [JsonPropertyName("ip")] public string? Ip { get; set; } + + [JsonPropertyName("port")] public int Port { get; set; } +} \ No newline at end of file diff --git a/Pterodactyl.NETSDK/Models/Client/Servers/WebSocketCredentials.cs b/Pterodactyl.NETSDK/Models/Client/Servers/WebSocketCredentials.cs new file mode 100644 index 0000000..e6f3fa5 --- /dev/null +++ b/Pterodactyl.NETSDK/Models/Client/Servers/WebSocketCredentials.cs @@ -0,0 +1,8 @@ +namespace Pterodactyl.NETSDK.Models.Client.Servers; + +public class WebSocketCredentials +{ + [JsonPropertyName("token")] public string? Token { get; set; } + + [JsonPropertyName("socket")] public string? SocketUrl { get; set; } +} \ No newline at end of file diff --git a/Pterodactyl.NETSDK/Models/Client/Servers/WebSocketResponse.cs b/Pterodactyl.NETSDK/Models/Client/Servers/WebSocketResponse.cs new file mode 100644 index 0000000..f543d75 --- /dev/null +++ b/Pterodactyl.NETSDK/Models/Client/Servers/WebSocketResponse.cs @@ -0,0 +1,6 @@ +namespace Pterodactyl.NETSDK.Models.Client.Servers; + +public class WebSocketResponse +{ + [JsonPropertyName("data")] public WebSocketCredentials? Data { get; set; } +} \ No newline at end of file diff --git a/Pterodactyl.NETSDK/Models/Common/Allocations/Allocation.cs b/Pterodactyl.NETSDK/Models/Common/Allocations/Allocation.cs new file mode 100644 index 0000000..3df5383 --- /dev/null +++ b/Pterodactyl.NETSDK/Models/Common/Allocations/Allocation.cs @@ -0,0 +1,10 @@ +namespace Pterodactyl.NETSDK.Models.Common.Allocations; + +public class Allocation +{ + [JsonPropertyName("id")] public int Id { get; set; } + [JsonPropertyName("ip")] public string? Ip { get; set; } + [JsonPropertyName("port")] public int Port { get; set; } + [JsonPropertyName("notes")] public string? Notes { get; set; } + [JsonPropertyName("is_default")] public bool IsDefault { get; set; } +} \ No newline at end of file diff --git a/Pterodactyl.NETSDK/Models/Common/Allocations/AllocationResponse.cs b/Pterodactyl.NETSDK/Models/Common/Allocations/AllocationResponse.cs new file mode 100644 index 0000000..aff8a84 --- /dev/null +++ b/Pterodactyl.NETSDK/Models/Common/Allocations/AllocationResponse.cs @@ -0,0 +1,7 @@ +namespace Pterodactyl.NETSDK.Models.Common.Allocations; + +public class AllocationResponse +{ + [JsonPropertyName("object")] public string? ObjectType { get; set; } + [JsonPropertyName("attributes")] public Allocation? Allocation { get; set; } +} \ No newline at end of file diff --git a/Pterodactyl.NETSDK/Models/Common/Allocations/AllocationSettings.cs b/Pterodactyl.NETSDK/Models/Common/Allocations/AllocationSettings.cs new file mode 100644 index 0000000..07a3ccb --- /dev/null +++ b/Pterodactyl.NETSDK/Models/Common/Allocations/AllocationSettings.cs @@ -0,0 +1,8 @@ +namespace Pterodactyl.NETSDK.Models.Common.Allocations; + +public class AllocationSettings +{ + [JsonPropertyName("default")] public int DefaultAllocation { get; set; } + + [JsonPropertyName("additional")] public List AdditionalAllocations { get; set; } = new(); +} \ No newline at end of file diff --git a/Pterodactyl.NETSDK/Models/Common/PaginatedResult.cs b/Pterodactyl.NETSDK/Models/Common/PaginatedResult.cs new file mode 100644 index 0000000..fe12808 --- /dev/null +++ b/Pterodactyl.NETSDK/Models/Common/PaginatedResult.cs @@ -0,0 +1,10 @@ +namespace Pterodactyl.NETSDK.Models.Common; + +public class PaginatedResult +{ + [JsonPropertyName("object")] public string? ObjectType { get; set; } + + [JsonPropertyName("data")] public List? Data { get; set; } + + [JsonPropertyName("meta")] public PaginationMeta? Meta { get; set; } +} \ No newline at end of file diff --git a/Pterodactyl.NETSDK/Models/Common/PaginationDetails.cs b/Pterodactyl.NETSDK/Models/Common/PaginationDetails.cs new file mode 100644 index 0000000..712b1c1 --- /dev/null +++ b/Pterodactyl.NETSDK/Models/Common/PaginationDetails.cs @@ -0,0 +1,10 @@ +namespace Pterodactyl.NETSDK.Models.Common; + +public class PaginationDetails +{ + [JsonPropertyName("total")] public int Total { get; set; } + [JsonPropertyName("count")] public int Count { get; set; } + [JsonPropertyName("per_page")] public int PerPage { get; set; } + [JsonPropertyName("current_page")] public int CurrentPage { get; set; } + [JsonPropertyName("total_pages")] public int TotalPages { get; set; } +} \ No newline at end of file diff --git a/Pterodactyl.NETSDK/Models/Common/PaginationMeta.cs b/Pterodactyl.NETSDK/Models/Common/PaginationMeta.cs new file mode 100644 index 0000000..ba26ef8 --- /dev/null +++ b/Pterodactyl.NETSDK/Models/Common/PaginationMeta.cs @@ -0,0 +1,6 @@ +namespace Pterodactyl.NETSDK.Models.Common; + +public class PaginationMeta +{ + [JsonPropertyName("pagination")] public PaginationDetails? Pagination { get; set; } +} \ No newline at end of file diff --git a/Pterodactyl.NETSDK/Models/Common/ServerFeatureLimits.cs b/Pterodactyl.NETSDK/Models/Common/ServerFeatureLimits.cs new file mode 100644 index 0000000..6b23616 --- /dev/null +++ b/Pterodactyl.NETSDK/Models/Common/ServerFeatureLimits.cs @@ -0,0 +1,8 @@ +namespace Pterodactyl.NETSDK.Models.Common; + +public class ServerFeatureLimits +{ + [JsonPropertyName("databases")] public int Databases { get; set; } + [JsonPropertyName("allocations")] public int Allocations { get; set; } + [JsonPropertyName("backups")] public int Backups { get; set; } +} \ No newline at end of file diff --git a/Pterodactyl.NETSDK/Models/Common/ServerLimits.cs b/Pterodactyl.NETSDK/Models/Common/ServerLimits.cs new file mode 100644 index 0000000..80ff610 --- /dev/null +++ b/Pterodactyl.NETSDK/Models/Common/ServerLimits.cs @@ -0,0 +1,10 @@ +namespace Pterodactyl.NETSDK.Models.Common; + +public class ServerLimits +{ + [JsonPropertyName("memory")] public int Memory { get; set; } + [JsonPropertyName("swap")] public int Swap { get; set; } + [JsonPropertyName("disk")] public int Disk { get; set; } + [JsonPropertyName("io")] public int Io { get; set; } + [JsonPropertyName("cpu")] public int Cpu { get; set; } +} \ No newline at end of file diff --git a/Pterodactyl.NETSDK/Pterodactyl.NETSDK.csproj b/Pterodactyl.NETSDK/Pterodactyl.NETSDK.csproj index 3a63532..04368a4 100644 --- a/Pterodactyl.NETSDK/Pterodactyl.NETSDK.csproj +++ b/Pterodactyl.NETSDK/Pterodactyl.NETSDK.csproj @@ -4,6 +4,7 @@ net8.0 enable enable + Library diff --git a/Pterodactyl.NETSDK/PterodactylClient.cs b/Pterodactyl.NETSDK/PterodactylClient.cs index c62fcf8..ec60197 100644 --- a/Pterodactyl.NETSDK/PterodactylClient.cs +++ b/Pterodactyl.NETSDK/PterodactylClient.cs @@ -1,1024 +1,20 @@ using System.Net.Http.Headers; -using System.Text; -using System.Text.Json; -using System.Text.Json.Serialization; -using System.Web; -// ReSharper disable CheckNamespace -// ReSharper disable ClassNeverInstantiated.Global -// ReSharper disable UnusedAutoPropertyAccessor.Global -// ReSharper disable UnusedMember.Global -// ReSharper disable MemberHidesStaticFromOuterClass -// ReSharper disable CollectionNeverUpdated.Global - -// ReSharper disable MemberCanBePrivate.Global namespace Pterodactyl.NETSDK; -public class PterodactylClient +public abstract class PterodactylClient { - private readonly HttpClient _httpClient; - private readonly string _baseUrl; - // ReSharper disable once PrivateFieldCanBeConvertedToLocalVariable - private readonly string _apiKey; + protected readonly HttpClient HttpClient; + protected readonly string BaseUrl; + protected readonly string ApiKey; - public PterodactylClient(string baseUrl, string apiKey) + protected PterodactylClient(string baseUrl, string apiKey) { - _baseUrl = baseUrl.TrimEnd('/'); - _apiKey = apiKey; - _httpClient = new HttpClient(); - _httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", _apiKey); - _httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); - _httpClient.DefaultRequestHeaders.Add("Accept", "Application/vnd.pterodactyl.v1+json"); + BaseUrl = baseUrl.TrimEnd('/'); + ApiKey = apiKey; + HttpClient = new HttpClient(); + HttpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", ApiKey); + HttpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); + HttpClient.DefaultRequestHeaders.Add("Accept", "Application/vnd.pterodactyl.v1+json"); } - - #region Client API - - public async Task> ListServersAsyncClient() - { - var servers = new List(); - var page = 1; - var hasMore = true; - - while (hasMore) - { - var response = await _httpClient.GetAsync($"{_baseUrl}/api/application/servers?page={page}"); - var result = await HandleResponse>(response); - - servers.AddRange(result?.Data.Select(r => r.Server) ?? Array.Empty()); - - if (result != null) hasMore = result.Meta.Pagination.CurrentPage < result.Meta.Pagination.TotalPages; - page++; - } - - return servers; - } - - public async Task GetAccountDetailsAsync() - { - var response = await _httpClient.GetAsync($"{_baseUrl}/api/client/account"); - return await HandleResponse(response); - } - - public async Task GetTwoFactorDetailsAsync() - { - var response = await _httpClient.GetAsync($"{_baseUrl}/api/client/account/two-factor"); - return await HandleResponse(response); - } - - public async Task EnableTwoFactorAsync(string code) - { - var content = new StringContent(JsonSerializer.Serialize(new { code }), Encoding.UTF8, "application/json"); - var response = await _httpClient.PostAsync($"{_baseUrl}/api/client/account/two-factor", content); - return await HandleResponse(response); - } - - public async Task DisableTwoFactorAsync(string password) - { - var requestBody = new { password }; - var content = new StringContent(JsonSerializer.Serialize(requestBody), Encoding.UTF8, "application/json"); - - var request = new HttpRequestMessage(HttpMethod.Delete, $"{_baseUrl}/api/client/account/two-factor") - { - Content = content - }; - - var response = await _httpClient.SendAsync(request); - - await HandleResponse(response); - } - - public async Task UpdateEmailAsync(string email, string password) - { - var content = new StringContent(JsonSerializer.Serialize(new { email, password }), Encoding.UTF8, - "application/json"); - var response = await _httpClient.PutAsync($"{_baseUrl}/api/client/account/email", content); - await HandleResponse(response); - } - - public async Task UpdatePasswordAsync(string currentPassword, string newPassword, string confirmPassword) - { - var content = new StringContent(JsonSerializer.Serialize(new - { - current_password = currentPassword, - password = newPassword, - password_confirmation = confirmPassword - }), Encoding.UTF8, "application/json"); - - var response = await _httpClient.PutAsync($"{_baseUrl}/api/client/account/password", content); - await HandleResponse(response); - } - - public async Task?> ListApiKeysAsync() - { - var response = await _httpClient.GetAsync($"{_baseUrl}/api/client/account/api-keys"); - var result = await HandleResponse>(response); - return result?.Data.Select(r => r.ApiKey).ToList(); - } - - public async Task CreateApiKeyAsync(string description, List? allowedIps = null) - { - var content = new StringContent(JsonSerializer.Serialize(new - { - description, - allowed_ips = allowedIps ?? [] - }), Encoding.UTF8, "application/json"); - - var response = await _httpClient.PostAsync($"{_baseUrl}/api/client/account/api-keys", content); - var result = await HandleResponse(response); - return result?.ApiKeyWithSecret; - } - - public async Task DeleteApiKeyAsync(string identifier) - { - var response = await _httpClient.DeleteAsync($"{_baseUrl}/api/client/account/api-keys/{identifier}"); - await HandleResponse(response); - } - - public async Task GetServerDetailsAsync(string serverId) - { - var response = await _httpClient.GetAsync($"{_baseUrl}/api/client/servers/{serverId}"); - return await HandleResponse(response); - } - - public async Task SendCommandAsync(string serverId, string command) - { - var content = new StringContent(JsonSerializer.Serialize(new { command }), Encoding.UTF8, - "application/json"); - var response = await _httpClient.PostAsync($"{_baseUrl}/api/client/servers/{serverId}/command", content); - await HandleResponse(response); - } - - #endregion - - #region Application API - - #region Users - - public async Task?> ListUsersAsync(int page = 1, int perPage = 50) - { - var query = HttpUtility.ParseQueryString(string.Empty); - query["page"] = page.ToString(); - query["per_page"] = perPage.ToString(); - - var response = await _httpClient.GetAsync($"{_baseUrl}/api/application/users?{query}"); - return await HandleResponse>(response); - } - - public async Task GetUserAsync(int userId) - { - var response = await _httpClient.GetAsync($"{_baseUrl}/api/application/users/{userId}"); - var result = await HandleResponse(response); - return result?.User; - } - - public async Task GetUserByExternalIdAsync(string externalId) - { - var response = await _httpClient.GetAsync($"{_baseUrl}/api/application/users/external/{externalId}"); - var result = await HandleResponse(response); - return result?.User; - } - - public async Task CreateUserAsync(UserCreateRequest request) - { - var content = new StringContent(JsonSerializer.Serialize(request), Encoding.UTF8, "application/json"); - var response = await _httpClient.PostAsync($"{_baseUrl}/api/application/users", content); - var result = await HandleResponse(response); - return result?.User; - } - - public async Task UpdateUserAsync(int userId, Action updateAction) - { - var currentUser = await GetUserAsync(userId); - - var request = new UserUpdateRequest - { - Email = currentUser?.Email, - Username = currentUser?.Username, - FirstName = currentUser?.FirstName, - LastName = currentUser?.LastName, - Language = currentUser?.Language - }; - - updateAction(request); - - var content = new StringContent(JsonSerializer.Serialize(request), Encoding.UTF8, "application/json"); - var response = await _httpClient.PatchAsync($"{_baseUrl}/api/application/users/{userId}", content); - var result = await HandleResponse(response); - return result?.User; - } - - public async Task DeleteUserAsync(int userId) - { - var response = await _httpClient.DeleteAsync($"{_baseUrl}/api/application/users/{userId}"); - await HandleResponse(response); - } - - #endregion - - #region Nodes - - public async Task?> ListNodesAsync(int page = 1, int perPage = 50) - { - var response = - await _httpClient.GetAsync($"{_baseUrl}/api/application/nodes?page={page}&per_page={perPage}"); - return await HandleResponse>(response); - } - - public async Task GetNodeAsync(int nodeId) - { - var response = await _httpClient.GetAsync($"{_baseUrl}/api/application/nodes/{nodeId}"); - return await HandleResponse(response); - } - - public async Task GetNodeConfigurationAsync(int nodeId) - { - var response = await _httpClient.GetAsync($"{_baseUrl}/api/application/nodes/{nodeId}/configuration"); - return await HandleResponse(response); - } - - - public async Task CreateNodeAsync(NodeCreateRequest request) - { - var content = new StringContent(JsonSerializer.Serialize(request), Encoding.UTF8, "application/json"); - var response = await _httpClient.PostAsync($"{_baseUrl}/api/application/nodes", content); - return await HandleResponse(response); - } - - public async Task UpdateNodeAsync(int nodeId, NodeUpdateRequest request) - { - var content = new StringContent(JsonSerializer.Serialize(request), Encoding.UTF8, "application/json"); - var response = await _httpClient.PatchAsync($"{_baseUrl}/api/application/nodes/{nodeId}", content); - return await HandleResponse(response); - } - - public async Task DeleteNodeAsync(int nodeId) - { - var response = await _httpClient.DeleteAsync($"{_baseUrl}/api/application/nodes/{nodeId}"); - await HandleResponse(response); - } - - public async Task?> GetNodeAllocationsAsync(int nodeId) - { - var response = await _httpClient.GetAsync($"{_baseUrl}/api/application/nodes/{nodeId}/allocations"); - var result = await HandleResponse>(response); - return result?.Data.Select(r => r.Allocation).ToList(); - } - - #endregion - - #region Servers - - public async Task?> ListServersAsync(int page = 1, int perPage = 50) - { - var response = - await _httpClient.GetAsync($"{_baseUrl}/api/application/servers?page={page}&per_page={perPage}"); - return await HandleResponse>(response); - } - - public async Task GetServerAsync(int serverId) - { - var response = await _httpClient.GetAsync($"{_baseUrl}/api/application/servers/{serverId}"); - var result = await HandleResponse(response); - return result?.Server; - } - - public async Task GetServerByExternalIdAsync(string externalId) - { - var response = await _httpClient.GetAsync($"{_baseUrl}/api/application/servers/external/{externalId}"); - var result = await HandleResponse(response); - return result?.Server; - } - - public async Task CreateServerAsync(ServerCreateRequest request) - { - var content = new StringContent(JsonSerializer.Serialize(request), Encoding.UTF8, "application/json"); - var response = await _httpClient.PostAsync($"{_baseUrl}/api/application/servers", content); - var result = await HandleResponse(response); - return result?.ApplicationServer; - } - - public async Task UpdateServerDetailsAsync(int serverId, ServerDetailsUpdateRequest request) - { - var content = new StringContent(JsonSerializer.Serialize(request), Encoding.UTF8, "application/json"); - var response = - await _httpClient.PatchAsync($"{_baseUrl}/api/application/servers/{serverId}/details", content); - return await HandleResponse(response); - } - - public async Task SuspendServerAsync(int serverId) - { - var response = await _httpClient.PostAsync($"{_baseUrl}/api/application/servers/{serverId}/suspend", null); - await HandleResponse(response); - } - - public async Task DeleteServerAsync(int serverId, bool force = false) - { - var url = $"{_baseUrl}/api/application/servers/{serverId}" + (force ? "/force" : ""); - var response = await _httpClient.DeleteAsync(url); - await HandleResponse(response); - } - - #endregion - - #region Locations - - public async Task?> ListLocationsAsync(int page = 1, int perPage = 50) - { - var response = await _httpClient.GetAsync( - $"{_baseUrl}/api/application/locations?page={page}&per_page={perPage}" - ); - return await HandleResponse>(response); - } - - public async Task CreateLocationAsync(LocationCreateRequest request) - { - var content = new StringContent(JsonSerializer.Serialize(request), Encoding.UTF8, "application/json"); - var response = await _httpClient.PostAsync($"{_baseUrl}/api/application/locations", content); - var result = await HandleResponse(response); - return result?.Location; - } - - public async Task UpdateLocationAsync(int locationId, LocationUpdateRequest request) - { - var content = new StringContent(JsonSerializer.Serialize(request), Encoding.UTF8, "application/json"); - var response = await _httpClient.PatchAsync($"{_baseUrl}/api/application/locations/{locationId}", content); - var result = await HandleResponse(response); - return result?.Location; - } - - public async Task DeleteLocationAsync(int locationId) - { - var response = await _httpClient.DeleteAsync($"{_baseUrl}/api/application/locations/{locationId}"); - await HandleResponse(response); - } - - #endregion - - #region Databases 一般弃用 - - public async Task?> ListServerDatabasesAsync(int serverId) - { - var response = await _httpClient.GetAsync($"{_baseUrl}/api/application/servers/{serverId}/databases"); - return await HandleResponse>(response); - } - - public async Task CreateServerDatabaseAsync(int serverId, DatabaseCreateRequest request) - { - var content = new StringContent(JsonSerializer.Serialize(request), Encoding.UTF8, "application/json"); - var response = - await _httpClient.PostAsync($"{_baseUrl}/api/application/servers/{serverId}/databases", content); - return await HandleResponse(response); - } - - public async Task ResetDatabasePasswordAsync(int serverId, int databaseId) - { - var response = await _httpClient.PostAsync( - $"{_baseUrl}/api/application/servers/{serverId}/databases/{databaseId}/reset-password", null); - await HandleResponse(response); - } - - public async Task DeleteServerDatabaseAsync(int serverId, int databaseId) - { - var response = await _httpClient.DeleteAsync( - $"{_baseUrl}/api/application/servers/{serverId}/databases/{databaseId}"); - await HandleResponse(response); - } - - #endregion - - #region Nests - - public async Task?> ListNestsAsync(int page = 1, int perPage = 50) - { - var response = await _httpClient.GetAsync( - $"{_baseUrl}/api/application/nests?page={page}&per_page={perPage}" - ); - return await HandleResponse>(response); - } - - public async Task GetNestAsync(int nestId) - { - var response = await _httpClient.GetAsync($"{_baseUrl}/api/application/nests/{nestId}"); - var result = await HandleResponse(response); - return result?.Nest; - } - - public async Task?> ListNestEggsAsync(int nestId) - { - var response = await _httpClient.GetAsync($"{_baseUrl}/api/application/nests/{nestId}/eggs"); - return await HandleResponse>(response); - } - - public async Task GetEggAsync(int nestId, int eggId) - { - var response = await _httpClient.GetAsync($"{_baseUrl}/api/application/nests/{nestId}/eggs/{eggId}"); - var result = await HandleResponse(response); - return result?.Egg; - } - - #endregion - - #endregion - - #region Helper Methods - - private async Task HandleResponse(HttpResponseMessage response) - { - var content = await response.Content.ReadAsStringAsync(); - - if (!response.IsSuccessStatusCode) - { - throw new PterodactylApiException( - $"API请求失败,状态码: {response.StatusCode}" + - response.StatusCode + - content - ); - } - - try - { - return JsonSerializer.Deserialize(content); - } - catch (JsonException ex) - { - throw new PterodactylApiException( - $"JSON解析失败: {ex.Message}" + - response.StatusCode + - content + - ex - ); - } - } - - private async Task HandleResponse(HttpResponseMessage response) - { - if (!response.IsSuccessStatusCode) - { - var errorContent = await response.Content.ReadAsStringAsync(); - throw new PterodactylApiException( - $"API request failed with status code {response.StatusCode}: {errorContent}"); - } - } - - #endregion - - #region Models - - #region Client Models - - public class Server - { - [JsonPropertyName("identifier")] public string? Identifier { get; set; } - [JsonPropertyName("uuid")] public string? Uuid { get; set; } - [JsonPropertyName("name")] public string? Name { get; set; } - [JsonPropertyName("description")] public string? Description { get; set; } - [JsonPropertyName("is_suspended")] public bool IsSuspended { get; set; } - [JsonPropertyName("is_installing")] public bool IsInstalling { get; set; } - [JsonPropertyName("limits")] public ServerLimits? Limits { get; set; } - [JsonPropertyName("feature_limits")] public ServerFeatureLimits? FeatureLimits { get; set; } - } - - public class ServerLimits - { - [JsonPropertyName("memory")] public int Memory { get; set; } - [JsonPropertyName("swap")] public int Swap { get; set; } - [JsonPropertyName("disk")] public int Disk { get; set; } - [JsonPropertyName("io")] public int Io { get; set; } - [JsonPropertyName("cpu")] public int Cpu { get; set; } - } - - public class ServerFeatureLimits - { - [JsonPropertyName("databases")] public int Databases { get; set; } - [JsonPropertyName("allocations")] public int Allocations { get; set; } - [JsonPropertyName("backups")] public int Backups { get; set; } - } - - public class Account - { - [JsonPropertyName("id")] public int Id { get; set; } - [JsonPropertyName("admin")] public bool Admin { get; set; } - [JsonPropertyName("username")] public string? Username { get; set; } - [JsonPropertyName("email")] public string? Email { get; set; } - [JsonPropertyName("first_name")] public string? FirstName { get; set; } - [JsonPropertyName("last_name")] public string? LastName { get; set; } - [JsonPropertyName("language")] public string? Language { get; set; } - } - - public class TwoFactorDetails - { - [JsonPropertyName("image_url_data")] public string? ImageUrlData { get; set; } - } - - public class TwoFactorEnableResponse - { - [JsonPropertyName("tokens")] public List? Tokens { get; set; } - [JsonPropertyName("allowed_ips")] public List? AllowedIps { get; set; } - [JsonPropertyName("last_used_at")] public DateTime? LastUsedAt { get; set; } - [JsonPropertyName("created_at")] public DateTime CreatedAt { get; set; } - } - - public class ApiKeyCreateResponse - { - [JsonPropertyName("object")] public string? ObjectType { get; set; } - - [JsonPropertyName("attributes")] public ApiKeyWithSecret? ApiKeyWithSecret { get; set; } - } - - public class ApiKeyWithSecret : ApiKey - { - [JsonPropertyName("token")] public string? SecretToken { get; set; } - } - - public class WebSocketDetails - { - [JsonPropertyName("token")] public string? Token { get; set; } - [JsonPropertyName("socket")] public string? Socket { get; set; } - } - - public class ResourceUsage - { - [JsonPropertyName("current_state")] public string? CurrentState { get; set; } - [JsonPropertyName("is_suspended")] public bool IsSuspended { get; set; } - [JsonPropertyName("resources")] public ResourceStats? Resources { get; set; } - } - - public class ResourceStats - { - [JsonPropertyName("memory_bytes")] public long MemoryBytes { get; set; } - [JsonPropertyName("cpu_absolute")] public long CpuAbsolute { get; set; } - [JsonPropertyName("disk_bytes")] public long DiskBytes { get; set; } - [JsonPropertyName("network_rx_bytes")] public long NetworkRxBytes { get; set; } - [JsonPropertyName("network_tx_bytes")] public long NetworkTxBytes { get; set; } - } - - public class Database - { - [JsonPropertyName("id")] public string? Id { get; set; } - [JsonPropertyName("host")] public DatabaseHost? Host { get; set; } - [JsonPropertyName("name")] public string? Name { get; set; } - [JsonPropertyName("username")] public string? Username { get; set; } - [JsonPropertyName("connections_from")] public string? ConnectionsFrom { get; set; } - [JsonPropertyName("max_connections")] public int MaxConnections { get; set; } - [JsonPropertyName("password")] public DatabasePassword? Password { get; set; } - } - - public class DatabaseHost - { - [JsonPropertyName("address")] public string? Address { get; set; } - [JsonPropertyName("port")] public int Port { get; set; } - } - - public class DatabasePassword - { - [JsonPropertyName("password")] public string? Password { get; set; } - } - - public class FileObject - { - [JsonPropertyName("name")] public string? Name { get; set; } - [JsonPropertyName("mode")] public string? Mode { get; set; } - [JsonPropertyName("size")] public long Size { get; set; } - [JsonPropertyName("is_file")] public bool IsFile { get; set; } - [JsonPropertyName("is_symlink")] public bool IsSymlink { get; set; } - [JsonPropertyName("is_editable")] public bool IsEditable { get; set; } - [JsonPropertyName("mimetype")] public string? Mimetype { get; set; } - [JsonPropertyName("created_at")] public DateTime CreatedAt { get; set; } - [JsonPropertyName("modified_at")] public DateTime ModifiedAt { get; set; } - } - - public class ApiKeyResponse - { - [JsonPropertyName("object")] public string? ObjectType { get; set; } - - [JsonPropertyName("attributes")] public ApiKey? ApiKey { get; set; } - } - - public class ApiKey - { - [JsonPropertyName("identifier")] public string? Identifier { get; set; } - - [JsonPropertyName("description")] public string? Description { get; set; } - - [JsonPropertyName("allowed_ips")] public List? AllowedIps { get; set; } - - [JsonPropertyName("last_used_at")] public DateTime? LastUsedAt { get; set; } - - [JsonPropertyName("created_at")] public DateTime CreatedAt { get; set; } - } - - public class SignedUrl - { - [JsonPropertyName("url")] public string? Url { get; set; } - } - - #endregion - - #region Application Models - - public class ApplicationServerResponse - { - [JsonPropertyName("object")] public string? ObjectType { get; set; } - - [JsonPropertyName("attributes")] public ApplicationServer? ApplicationServer { get; set; } - } - - public class ApplicationServer - { - [JsonPropertyName("id")] public int Id { get; set; } - [JsonPropertyName("external_id")] public string? ExternalId { get; set; } - [JsonPropertyName("uuid")] public string? Uuid { get; set; } - [JsonPropertyName("identifier")] public string? Identifier { get; set; } - [JsonPropertyName("name")] public string? Name { get; set; } - [JsonPropertyName("description")] public string? Description { get; set; } - [JsonPropertyName("suspended")] public bool IsSuspended { get; set; } - [JsonPropertyName("limits")] public ApplicationServerLimits? Limits { get; set; } - [JsonPropertyName("feature_limits")] public ApplicationFeatureLimits? FeatureLimits { get; set; } - [JsonPropertyName("user")] public int UserId { get; set; } - [JsonPropertyName("node")] public int NodeId { get; set; } - [JsonPropertyName("allocation")] public int AllocationId { get; set; } - [JsonPropertyName("nest")] public int NestId { get; set; } - [JsonPropertyName("egg")] public int EggId { get; set; } - [JsonPropertyName("container")] public ContainerDetails? Container { get; set; } - [JsonPropertyName("created_at")] public DateTime CreatedAt { get; set; } - [JsonPropertyName("updated_at")] public DateTime UpdatedAt { get; set; } - } - - public class ApplicationServerLimits - { - [JsonPropertyName("memory")] public int Memory { get; set; } - [JsonPropertyName("swap")] public int Swap { get; set; } - [JsonPropertyName("disk")] public int Disk { get; set; } - [JsonPropertyName("io")] public int Io { get; set; } - [JsonPropertyName("cpu")] public int Cpu { get; set; } - } - - public class ApplicationFeatureLimits - { - [JsonPropertyName("databases")] public int Databases { get; set; } - [JsonPropertyName("backups")] public int Backups { get; set; } - } - - public class ContainerDetails - { - [JsonPropertyName("startup_command")] public string? StartupCommand { get; set; } - - [JsonPropertyName("image")] public string? Image { get; set; } - - [JsonPropertyName("installed")] public int Installed { get; set; } - - [JsonPropertyName("environment")] public Dictionary? Environment { get; set; } - } - - public static class ContainerExtensions - { - public static T? GetEnvironmentValue(Dictionary env, string key) - { - if (env.TryGetValue(key, out var value) && value is T typedValue) - { - return typedValue; - } - - return default; - } - } - - public class NodeConfiguration - { - [JsonPropertyName("debug")] public bool Debug { get; set; } - [JsonPropertyName("uuid")] public string? Uuid { get; set; } - [JsonPropertyName("token")] public string? Token { get; set; } - [JsonPropertyName("api")] public NodeApiConfig? Api { get; set; } - [JsonPropertyName("system")] public NodeSystemConfig? System { get; set; } - } - - public class NodeApiConfig - { - [JsonPropertyName("host")] public string? Host { get; set; } - [JsonPropertyName("port")] public int Port { get; set; } - [JsonPropertyName("ssl")] public NodeSslConfig? Ssl { get; set; } - } - - public class NodeSslConfig - { - [JsonPropertyName("enabled")] public bool Enabled { get; set; } - [JsonPropertyName("cert")] public string? Certificate { get; set; } - [JsonPropertyName("key")] public string? Key { get; set; } - } - - public class NodeSystemConfig - { - [JsonPropertyName("data")] public string? DataPath { get; set; } - [JsonPropertyName("sftp")] public NodeSftpConfig? Sftp { get; set; } - } - - public class NodeSftpConfig - { - [JsonPropertyName("bind_port")] public int Port { get; set; } - } - - public class LocationResponse - { - [JsonPropertyName("object")] public string? ObjectType { get; set; } - - [JsonPropertyName("attributes")] public Location? Location { get; set; } - } - - public class Location - { - [JsonPropertyName("id")] public int Id { get; set; } - [JsonPropertyName("short")] public string? ShortCode { get; set; } - [JsonPropertyName("long")] public string? LongName { get; set; } - [JsonPropertyName("created_at")] public DateTime CreatedAt { get; set; } - [JsonPropertyName("updated_at")] public DateTime UpdatedAt { get; set; } - } - - public class ServerDatabase - { - [JsonPropertyName("id")] public int Id { get; set; } - [JsonPropertyName("server")] public int ServerId { get; set; } - [JsonPropertyName("host")] public int HostId { get; set; } - [JsonPropertyName("database")] public string? DatabaseName { get; set; } - [JsonPropertyName("username")] public string? Username { get; set; } - [JsonPropertyName("remote")] public string? RemoteAccess { get; set; } - [JsonPropertyName("max_connections")] public int MaxConnections { get; set; } - [JsonPropertyName("created_at")] public DateTime CreatedAt { get; set; } - [JsonPropertyName("updated_at")] public DateTime UpdatedAt { get; set; } - } - - public class UserResponse - { - [JsonPropertyName("object")] public string? ObjectType { get; set; } - [JsonPropertyName("attributes")] public ApplicationUser? ApplicationUser { get; set; } - } - - public class SingleUserResponse - { - [JsonPropertyName("object")] public string? ObjectType { get; set; } - - [JsonPropertyName("attributes")] public ApplicationUser? User { get; set; } - } - - public class ApplicationUser - { - [JsonPropertyName("id")] public int Id { get; set; } - - [JsonPropertyName("external_id")] public string? ExternalId { get; set; } - - [JsonPropertyName("uuid")] public string? Uuid { get; set; } - - [JsonPropertyName("username")] public string? Username { get; set; } - - [JsonPropertyName("email")] public string? Email { get; set; } - - [JsonPropertyName("first_name")] public string? FirstName { get; set; } - - [JsonPropertyName("last_name")] public string? LastName { get; set; } - - [JsonPropertyName("language")] public string? Language { get; set; } - - [JsonPropertyName("root_admin")] public bool IsRootAdmin { get; set; } - - [JsonPropertyName("2fa")] public bool TwoFactorEnabled { get; set; } - - [JsonPropertyName("created_at")] public DateTime CreatedAt { get; set; } - - [JsonPropertyName("updated_at")] public DateTime UpdatedAt { get; set; } - } - - public class Nest - { - [JsonPropertyName("id")] public int Id { get; set; } - [JsonPropertyName("uuid")] public string? Uuid { get; set; } - [JsonPropertyName("author")] public string? Author { get; set; } - [JsonPropertyName("name")] public string? Name { get; set; } - [JsonPropertyName("description")] public string? Description { get; set; } - [JsonPropertyName("created_at")] public DateTime CreatedAt { get; set; } - [JsonPropertyName("updated_at")] public DateTime UpdatedAt { get; set; } - } - - public class NestResponse - { - [JsonPropertyName("object")] public string? ObjectType { get; set; } - - [JsonPropertyName("attributes")] public Nest? Nest { get; set; } - } - - public class EggResponse - { - [JsonPropertyName("object")] public string? ObjectType { get; set; } - - [JsonPropertyName("attributes")] public Egg? Egg { get; set; } - } - - public class Egg - { - [JsonPropertyName("id")] public int Id { get; set; } - [JsonPropertyName("uuid")] public string? Uuid { get; set; } - [JsonPropertyName("name")] public string? Name { get; set; } - [JsonPropertyName("description")] public string? Description { get; set; } - [JsonPropertyName("docker_image")] public string? DockerImage { get; set; } - [JsonPropertyName("config")] public EggConfig? Config { get; set; } - [JsonPropertyName("startup")] public string? StartupCommand { get; set; } - [JsonPropertyName("script")] public EggScript? Script { get; set; } - [JsonPropertyName("created_at")] public DateTime CreatedAt { get; set; } - [JsonPropertyName("updated_at")] public DateTime UpdatedAt { get; set; } - } - - public class EggConfig - { - [JsonPropertyName("files")] public Dictionary? Files { get; set; } - [JsonPropertyName("startup")] public StartupConfig? Startup { get; set; } - [JsonPropertyName("stop")] public string? StopCommand { get; set; } - [JsonPropertyName("logs")] public List? Logs { get; set; } - } - - public class LogConfig - { - [JsonPropertyName("custom")] public bool IsCustom { get; set; } - [JsonPropertyName("location")] public string? Location { get; set; } - } - - public class FileConfig - { - [JsonPropertyName("parser")] public string? Parser { get; set; } - [JsonPropertyName("find")] public Dictionary? FindReplace { get; set; } - } - - public class StartupConfig - { - [JsonPropertyName("done")] public string? CompletionExpression { get; set; } - [JsonPropertyName("userInteraction")] public List? UserInteractions { get; set; } - } - - - public class EggScript - { - [JsonPropertyName("privileged")] public bool Privileged { get; set; } - [JsonPropertyName("install")] public string? InstallScript { get; set; } - [JsonPropertyName("entry")] public string? EntryPoint { get; set; } - [JsonPropertyName("container")] public string? ContainerImage { get; set; } - } - - public class PaginatedResult - { - [JsonPropertyName("object")] public string? ObjectType { get; set; } - - [JsonPropertyName("data")] public List? Data { get; set; } - - [JsonPropertyName("meta")] public PaginationMeta? Meta { get; set; } - } - - public class PaginationMeta - { - [JsonPropertyName("pagination")] public PaginationDetails? Pagination { get; set; } - } - - public class PaginationDetails - { - [JsonPropertyName("total")] public int Total { get; set; } - [JsonPropertyName("count")] public int Count { get; set; } - [JsonPropertyName("per_page")] public int PerPage { get; set; } - [JsonPropertyName("current_page")] public int CurrentPage { get; set; } - [JsonPropertyName("total_pages")] public int TotalPages { get; set; } - } - - public class Node - { - [JsonPropertyName("id")] public int Id { get; set; } - [JsonPropertyName("uuid")] public string? Uuid { get; set; } - [JsonPropertyName("name")] public string? Name { get; set; } - [JsonPropertyName("description")] public string? Description { get; set; } - [JsonPropertyName("location_id")] public int LocationId { get; set; } - [JsonPropertyName("fqdn")] public string? Fqdn { get; set; } - [JsonPropertyName("memory")] public int Memory { get; set; } - [JsonPropertyName("disk")] public int Disk { get; set; } - [JsonPropertyName("upload_size")] public int UploadSize { get; set; } - [JsonPropertyName("daemon_base")] public string? DaemonBase { get; set; } - [JsonPropertyName("created_at")] public DateTime CreatedAt { get; set; } - [JsonPropertyName("updated_at")] public DateTime UpdatedAt { get; set; } - } - - public class Allocation - { - [JsonPropertyName("id")] public int Id { get; set; } - [JsonPropertyName("ip")] public string? Ip { get; set; } - [JsonPropertyName("port")] public int Port { get; set; } - [JsonPropertyName("notes")] public string? Notes { get; set; } - [JsonPropertyName("assigned")] public bool IsAssigned { get; set; } - } - - public class AllocationResponse - { - [JsonPropertyName("object")] public string? ObjectType { get; set; } - [JsonPropertyName("attributes")] public Allocation? Allocation { get; set; } - } - - #endregion - - #region Request Models - - public class UserCreateRequest - { - [JsonPropertyName("email")] public string? Email { get; set; } - [JsonPropertyName("username")] public string? Username { get; set; } - [JsonPropertyName("first_name")] public string? FirstName { get; set; } - [JsonPropertyName("last_name")] public string? LastName { get; set; } - [JsonPropertyName("password")] public string? Password { get; set; } - [JsonPropertyName("root_admin")] public bool IsRootAdmin { get; set; } - } - - public class UserUpdateRequest : UserCreateRequest - { - [JsonPropertyName("language")] public string? Language { get; set; } - } - - public class NodeCreateRequest - { - [JsonPropertyName("name")] public string? Name { get; set; } - [JsonPropertyName("location_id")] public int LocationId { get; set; } - [JsonPropertyName("fqdn")] public string? Fqdn { get; set; } - [JsonPropertyName("scheme")] public string? Scheme { get; set; } - [JsonPropertyName("memory")] public int Memory { get; set; } - - [JsonPropertyName("memory_overallocate")] - public int MemoryOverallocation { get; set; } - - [JsonPropertyName("disk")] public int Disk { get; set; } - - [JsonPropertyName("disk_overallocate")] - public int DiskOverallocation { get; set; } - - [JsonPropertyName("upload_size")] public int UploadSize { get; set; } - [JsonPropertyName("daemon_sftp")] public int SftpPort { get; set; } - [JsonPropertyName("daemon_listen")] public int DaemonPort { get; set; } - } - - public class NodeUpdateRequest : NodeCreateRequest - { - [JsonPropertyName("description")] public string? Description { get; set; } - [JsonPropertyName("behind_proxy")] public bool BehindProxy { get; set; } - [JsonPropertyName("maintenance_mode")] public bool MaintenanceMode { get; set; } - } - - public class ServerCreateRequest - { - [JsonPropertyName("name")] public string? Name { get; set; } - [JsonPropertyName("user")] public int UserId { get; set; } - [JsonPropertyName("egg")] public int EggId { get; set; } - [JsonPropertyName("node")] public int NodeId { get; set; } - - [JsonPropertyName("allocation")] public AllocationSettings Allocation { get; set; } = new(); - - [JsonPropertyName("docker_image")] public string? DockerImage { get; set; } - [JsonPropertyName("startup")] public string? StartupCommand { get; set; } - [JsonPropertyName("environment")] public Dictionary? Environment { get; set; } - [JsonPropertyName("limits")] public ApplicationServerLimits? Limits { get; set; } - [JsonPropertyName("feature_limits")] public ApplicationFeatureLimits? FeatureLimits { get; set; } - } - - public class AllocationSettings - { - [JsonPropertyName("default")] public int DefaultAllocation { get; set; } - - [JsonPropertyName("additional")] public List AdditionalAllocations { get; set; } = new List(); - } - - public class ServerDetailsUpdateRequest - { - [JsonPropertyName("name")] public string? Name { get; set; } - [JsonPropertyName("user")] public int UserId { get; set; } - [JsonPropertyName("external_id")] public string? ExternalId { get; set; } - [JsonPropertyName("description")] public string? Description { get; set; } - } - - public class ServerResponse - { - [JsonPropertyName("object")] public string? ObjectType { get; set; } - - [JsonPropertyName("attributes")] public Server? Server { get; set; } - } - - public class LocationCreateRequest - { - [JsonPropertyName("short")] public string? ShortCode { get; set; } - [JsonPropertyName("long")] public string? LongName { get; set; } - } - - public class LocationUpdateRequest : LocationCreateRequest - { - } - - public class DatabaseCreateRequest - { - [JsonPropertyName("database")] public string? DatabaseName { get; set; } - [JsonPropertyName("remote")] public string? RemoteAccess { get; set; } - [JsonPropertyName("host")] public int HostId { get; set; } - } - - #endregion - - #endregion - - public class PterodactylApiException(string message) : Exception(message); } \ No newline at end of file diff --git a/Pterodactyl.NETSDK/Request/DatabaseCreateRequest.cs b/Pterodactyl.NETSDK/Request/DatabaseCreateRequest.cs new file mode 100644 index 0000000..393926a --- /dev/null +++ b/Pterodactyl.NETSDK/Request/DatabaseCreateRequest.cs @@ -0,0 +1,8 @@ +namespace Pterodactyl.NETSDK.Request; + +public class DatabaseCreateRequest +{ + [JsonPropertyName("database")] public string? DatabaseName { get; set; } + [JsonPropertyName("remote")] public string? RemoteAccess { get; set; } + [JsonPropertyName("host")] public int HostId { get; set; } +} \ No newline at end of file diff --git a/Pterodactyl.NETSDK/Request/LocationCreateRequest.cs b/Pterodactyl.NETSDK/Request/LocationCreateRequest.cs new file mode 100644 index 0000000..401c204 --- /dev/null +++ b/Pterodactyl.NETSDK/Request/LocationCreateRequest.cs @@ -0,0 +1,7 @@ +namespace Pterodactyl.NETSDK.Request; + +public class LocationCreateRequest +{ + [JsonPropertyName("short")] public string? ShortCode { get; set; } + [JsonPropertyName("long")] public string? LongName { get; set; } +} \ No newline at end of file diff --git a/Pterodactyl.NETSDK/Request/LocationUpdateRequest.cs b/Pterodactyl.NETSDK/Request/LocationUpdateRequest.cs new file mode 100644 index 0000000..6c5c6f3 --- /dev/null +++ b/Pterodactyl.NETSDK/Request/LocationUpdateRequest.cs @@ -0,0 +1,5 @@ +namespace Pterodactyl.NETSDK.Request; + +public class LocationUpdateRequest : LocationCreateRequest +{ +} \ No newline at end of file diff --git a/Pterodactyl.NETSDK/Request/NodeCreateRequest.cs b/Pterodactyl.NETSDK/Request/NodeCreateRequest.cs new file mode 100644 index 0000000..ca483aa --- /dev/null +++ b/Pterodactyl.NETSDK/Request/NodeCreateRequest.cs @@ -0,0 +1,22 @@ +namespace Pterodactyl.NETSDK.Request; + +public class NodeCreateRequest +{ + [JsonPropertyName("name")] public string? Name { get; set; } + [JsonPropertyName("location_id")] public int LocationId { get; set; } + [JsonPropertyName("fqdn")] public string? Fqdn { get; set; } + [JsonPropertyName("scheme")] public string? Scheme { get; set; } + [JsonPropertyName("memory")] public int Memory { get; set; } + + [JsonPropertyName("memory_overallocate")] + public int MemoryOverallocation { get; set; } + + [JsonPropertyName("disk")] public int Disk { get; set; } + + [JsonPropertyName("disk_overallocate")] + public int DiskOverallocation { get; set; } + + [JsonPropertyName("upload_size")] public int UploadSize { get; set; } + [JsonPropertyName("daemon_sftp")] public int SftpPort { get; set; } + [JsonPropertyName("daemon_listen")] public int DaemonPort { get; set; } +} \ No newline at end of file diff --git a/Pterodactyl.NETSDK/Request/NodeUpdateRequest.cs b/Pterodactyl.NETSDK/Request/NodeUpdateRequest.cs new file mode 100644 index 0000000..e3ff1af --- /dev/null +++ b/Pterodactyl.NETSDK/Request/NodeUpdateRequest.cs @@ -0,0 +1,8 @@ +namespace Pterodactyl.NETSDK.Request; + +public class NodeUpdateRequest : NodeCreateRequest +{ + [JsonPropertyName("description")] public string? Description { get; set; } + [JsonPropertyName("behind_proxy")] public bool BehindProxy { get; set; } + [JsonPropertyName("maintenance_mode")] public bool MaintenanceMode { get; set; } +} \ No newline at end of file diff --git a/Pterodactyl.NETSDK/Request/ServerCreateRequest.cs b/Pterodactyl.NETSDK/Request/ServerCreateRequest.cs new file mode 100644 index 0000000..5981a00 --- /dev/null +++ b/Pterodactyl.NETSDK/Request/ServerCreateRequest.cs @@ -0,0 +1,20 @@ +using Pterodactyl.NETSDK.Models.Common; +using Pterodactyl.NETSDK.Models.Common.Allocations; + +namespace Pterodactyl.NETSDK.Request; + +public class ServerCreateRequest +{ + [JsonPropertyName("name")] public string? Name { get; set; } + [JsonPropertyName("user")] public int UserId { get; set; } + [JsonPropertyName("egg")] public int EggId { get; set; } + [JsonPropertyName("node")] public int NodeId { get; set; } + + [JsonPropertyName("allocation")] public AllocationSettings Allocation { get; set; } = new(); + + [JsonPropertyName("docker_image")] public string? DockerImage { get; set; } + [JsonPropertyName("startup")] public string? StartupCommand { get; set; } + [JsonPropertyName("environment")] public Dictionary? Environment { get; set; } + [JsonPropertyName("limits")] public ServerLimits? Limits { get; set; } + [JsonPropertyName("feature_limits")] public ServerFeatureLimits? FeatureLimits { get; set; } +} \ No newline at end of file diff --git a/Pterodactyl.NETSDK/Request/ServerDetailsUpdateRequest.cs b/Pterodactyl.NETSDK/Request/ServerDetailsUpdateRequest.cs new file mode 100644 index 0000000..e5433a0 --- /dev/null +++ b/Pterodactyl.NETSDK/Request/ServerDetailsUpdateRequest.cs @@ -0,0 +1,9 @@ +namespace Pterodactyl.NETSDK.Request; + +public class ServerDetailsUpdateRequest +{ + [JsonPropertyName("name")] public string? Name { get; set; } + [JsonPropertyName("user")] public int UserId { get; set; } + [JsonPropertyName("external_id")] public string? ExternalId { get; set; } + [JsonPropertyName("description")] public string? Description { get; set; } +} \ No newline at end of file diff --git a/Pterodactyl.NETSDK/Request/UserCreateRequest.cs b/Pterodactyl.NETSDK/Request/UserCreateRequest.cs new file mode 100644 index 0000000..95342d5 --- /dev/null +++ b/Pterodactyl.NETSDK/Request/UserCreateRequest.cs @@ -0,0 +1,11 @@ +namespace Pterodactyl.NETSDK.Request; + +public class UserCreateRequest +{ + [JsonPropertyName("email")] public string? Email { get; set; } + [JsonPropertyName("username")] public string? Username { get; set; } + [JsonPropertyName("first_name")] public string? FirstName { get; set; } + [JsonPropertyName("last_name")] public string? LastName { get; set; } + [JsonPropertyName("password")] public string? Password { get; set; } + [JsonPropertyName("root_admin")] public bool IsRootAdmin { get; set; } +} \ No newline at end of file diff --git a/Pterodactyl.NETSDK/Request/UserUpdateRequest.cs b/Pterodactyl.NETSDK/Request/UserUpdateRequest.cs new file mode 100644 index 0000000..2f4fc7e --- /dev/null +++ b/Pterodactyl.NETSDK/Request/UserUpdateRequest.cs @@ -0,0 +1,6 @@ +namespace Pterodactyl.NETSDK.Request; + +public class UserUpdateRequest : UserCreateRequest +{ + [JsonPropertyName("language")] public string? Language { get; set; } +} \ No newline at end of file