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