From 7a4a0bd4bdaf709bf66de97f0a597127512e7cd4 Mon Sep 17 00:00:00 2001 From: Dakroach Date: Sat, 30 May 2026 23:25:22 -0700 Subject: [PATCH] feat: Enhance ServerTemplatesUpdateEndpoint with additional request fields and validation rules feat: Expand PlayersApi with new endpoints for better player management feat: Update ServerApi to include new instance-related endpoints feat: Add new endpoints to ServiceAccountsApi for improved service account management fix: Update TokensRotateEndpoint and TokensStoreEndpoint to include new validation rules feat: Introduce ControlPlaneHttpClient for handling HTTP requests to the control plane feat: Implement PathBuilder for dynamic URI resolution feat: Add PlayerEntitlement and PlayerSessionProfile models for player data handling feat: Create server-related models including HeartbeatPayload, PresenceState, and ReadinessState feat: Develop RegistrationPayload and ServerInstance models for server management feat: Add ServerProfile model to encapsulate server instance details refactor: Update network class to include builder method for ControlPlaneClient chore: Update manifest.json for plugin metadata and dependencies --- .gitignore | 3 +- build.gradle | 14 +- gradle.properties | 2 +- .../kewwbec/network/ControlPlaneClient.java | 69 ++++++++ .../net/kewwbec/network/NetworkPlugin.java | 63 +++++++ .../net/kewwbec/network/auth/ApiToken.java | 25 +++ .../kewwbec/network/client/PlayersClient.java | 29 ++++ .../network/client/PresenceClient.java | 40 +++++ .../kewwbec/network/client/ServerClient.java | 18 ++ .../kewwbec/network/errors/AuthException.java | 14 ++ .../network/errors/ControlPlaneException.java | 11 ++ .../network/errors/NotFoundException.java | 7 + .../network/errors/RemoteException.java | 14 ++ .../network/errors/ValidationException.java | 17 ++ .../generated/api/v1/ControlPlaneApiV1.java | 46 +++++- .../v1/infrastructure/InfrastructureApi.java | 5 + .../ServerInstancesPresenceIndexEndpoint.java | 2 +- .../ServerTemplatesStoreEndpoint.java | 2 +- .../ServerTemplatesUpdateEndpoint.java | 2 +- .../generated/api/v1/players/PlayersApi.java | 92 ++++++++++- .../generated/api/v1/server/ServerApi.java | 15 ++ .../serviceaccounts/ServiceAccountsApi.java | 22 ++- .../serviceaccounts/TokensRotateEndpoint.java | 2 +- .../serviceaccounts/TokensStoreEndpoint.java | 2 +- .../generated/api/v1/social/SocialApi.java | 10 ++ .../network/http/ControlPlaneHttpClient.java | 155 ++++++++++++++++++ .../net/kewwbec/network/http/PathBuilder.java | 19 +++ .../models/players/PlayerEntitlement.java | 49 ++++++ .../models/players/PlayerSessionProfile.java | 97 +++++++++++ .../models/server/HeartbeatPayload.java | 31 ++++ .../network/models/server/PresenceState.java | 16 ++ .../network/models/server/ReadinessState.java | 18 ++ .../models/server/RegistrationPayload.java | 37 +++++ .../network/models/server/ServerInstance.java | 67 ++++++++ .../network/models/server/ServerProfile.java | 32 ++++ .../java/net/kewwbec/network/network.java | 10 +- src/main/resources/manifest.json | 24 ++- 37 files changed, 1047 insertions(+), 34 deletions(-) create mode 100644 src/main/java/net/kewwbec/network/ControlPlaneClient.java create mode 100644 src/main/java/net/kewwbec/network/NetworkPlugin.java create mode 100644 src/main/java/net/kewwbec/network/auth/ApiToken.java create mode 100644 src/main/java/net/kewwbec/network/client/PlayersClient.java create mode 100644 src/main/java/net/kewwbec/network/client/PresenceClient.java create mode 100644 src/main/java/net/kewwbec/network/client/ServerClient.java create mode 100644 src/main/java/net/kewwbec/network/errors/AuthException.java create mode 100644 src/main/java/net/kewwbec/network/errors/ControlPlaneException.java create mode 100644 src/main/java/net/kewwbec/network/errors/NotFoundException.java create mode 100644 src/main/java/net/kewwbec/network/errors/RemoteException.java create mode 100644 src/main/java/net/kewwbec/network/errors/ValidationException.java create mode 100644 src/main/java/net/kewwbec/network/http/ControlPlaneHttpClient.java create mode 100644 src/main/java/net/kewwbec/network/http/PathBuilder.java create mode 100644 src/main/java/net/kewwbec/network/models/players/PlayerEntitlement.java create mode 100644 src/main/java/net/kewwbec/network/models/players/PlayerSessionProfile.java create mode 100644 src/main/java/net/kewwbec/network/models/server/HeartbeatPayload.java create mode 100644 src/main/java/net/kewwbec/network/models/server/PresenceState.java create mode 100644 src/main/java/net/kewwbec/network/models/server/ReadinessState.java create mode 100644 src/main/java/net/kewwbec/network/models/server/RegistrationPayload.java create mode 100644 src/main/java/net/kewwbec/network/models/server/ServerInstance.java create mode 100644 src/main/java/net/kewwbec/network/models/server/ServerProfile.java diff --git a/.gitignore b/.gitignore index ed12b28..0fa0562 100644 --- a/.gitignore +++ b/.gitignore @@ -61,4 +61,5 @@ desktop.ini # Template specific libs/HytaleServer.jar buildSrc/ -.github/ \ No newline at end of file +.github/ +src/main/java/net/kewwbec/network/generated/ \ No newline at end of file diff --git a/build.gradle b/build.gradle index e1ecb6b..e99ef87 100644 --- a/build.gradle +++ b/build.gradle @@ -47,14 +47,18 @@ javadoc { // Adds the Hytale server as a build dependency, allowing you to reference and // compile against their code without bundling it. When a local install is -// present, we still use its jar for launching the server in IDE run configs. +// present we compile and run against that jar directly so there is no dependency +// on the Hytale Maven repositories. In CI (no local install) the Maven artifact +// is used together with an explicit Gson dep (bundled in the server at runtime). dependencies { - compileOnly("com.hypixel.hytale:Server:$hytale_build") if (hasHytaleHome) { - runtimeOnly(files("$hytaleHome/install/$patchline/package/game/latest/Server/HytaleServer.jar")) + def serverJar = files("$hytaleHome/install/$patchline/package/game/latest/Server/HytaleServer.jar") + compileOnly(serverJar) + runtimeOnly(serverJar) + } else { + compileOnly("com.hypixel.hytale:Server:$hytale_build") + compileOnly("com.google.gson:gson:2.11.0") } - - // Your dependencies here } repositories { diff --git a/gradle.properties b/gradle.properties index ba33300..a486b58 100644 --- a/gradle.properties +++ b/gradle.properties @@ -3,7 +3,7 @@ version=0.0.2 # The group ID used for maven publishing. Usually the same as your package name # but not the same as your plugin group! -maven_group=org.example +maven_group=net.kewwbec # The version of Java used by your plugin. The game is built on Java 21 but # actually runs on Java 25. diff --git a/src/main/java/net/kewwbec/network/ControlPlaneClient.java b/src/main/java/net/kewwbec/network/ControlPlaneClient.java new file mode 100644 index 0000000..8ccc052 --- /dev/null +++ b/src/main/java/net/kewwbec/network/ControlPlaneClient.java @@ -0,0 +1,69 @@ +package net.kewwbec.network; + +import net.kewwbec.network.auth.ApiToken; +import net.kewwbec.network.client.PlayersClient; +import net.kewwbec.network.client.PresenceClient; +import net.kewwbec.network.client.ServerClient; +import net.kewwbec.network.http.ControlPlaneHttpClient; + +import java.time.Duration; + +public final class ControlPlaneClient { + private final ControlPlaneHttpClient http; + private final PresenceClient presence; + private final ServerClient server; + private final PlayersClient players; + + private ControlPlaneClient(Builder builder) { + this.http = new ControlPlaneHttpClient(builder.baseUrl, builder.token, builder.connectTimeout); + this.presence = new PresenceClient(http); + this.server = new ServerClient(http); + this.players = new PlayersClient(http); + } + + public static Builder builder() { + return new Builder(); + } + + public PresenceClient presence() { return presence; } + public ServerClient server() { return server; } + public PlayersClient players() { return players; } + + public static final class Builder { + private String baseUrl; + private ApiToken token; + private Duration connectTimeout = Duration.ofSeconds(5); + + private Builder() {} + + public Builder baseUrl(String baseUrl) { + this.baseUrl = baseUrl; + return this; + } + + public Builder token(String token) { + this.token = ApiToken.of(token); + return this; + } + + public Builder token(ApiToken token) { + this.token = token; + return this; + } + + public Builder connectTimeout(Duration timeout) { + this.connectTimeout = timeout; + return this; + } + + public ControlPlaneClient build() { + if (baseUrl == null || baseUrl.isBlank()) { + throw new IllegalStateException("baseUrl must be set"); + } + if (token == null) { + throw new IllegalStateException("token must be set"); + } + return new ControlPlaneClient(this); + } + } +} diff --git a/src/main/java/net/kewwbec/network/NetworkPlugin.java b/src/main/java/net/kewwbec/network/NetworkPlugin.java new file mode 100644 index 0000000..56f1ec0 --- /dev/null +++ b/src/main/java/net/kewwbec/network/NetworkPlugin.java @@ -0,0 +1,63 @@ +package net.kewwbec.network; + +/** + * Plugin entry point for core-network. + * + * Call {@link #configure(String, String)} once during server startup (e.g. from + * your plugin's onLoad/onEnable equivalent) before any other plugin calls + * {@link #client()}. The base URL and token come from your server's environment + * or plugin config. + * + * Dependent plugins declare this plugin in their manifest Dependencies block: + * "Dependencies": { "core-network": "*" } + */ +public final class NetworkPlugin { + private static volatile ControlPlaneClient instance; + + private NetworkPlugin() {} + + /** + * Initialise the shared {@link ControlPlaneClient}. Must be called once + * before any plugin calls {@link #client()}. + * + * @param baseUrl control-plane base URL, e.g. {@code https://cp.internal} + * @param token Sanctum bearer token issued to this server instance + */ + public static void configure(String baseUrl, String token) { + instance = ControlPlaneClient.builder() + .baseUrl(baseUrl) + .token(token) + .build(); + } + + /** + * Initialise with a pre-built client (useful for testing or custom config). + */ + public static void configure(ControlPlaneClient client) { + if (client == null) throw new IllegalArgumentException("client must not be null"); + instance = client; + } + + /** + * Returns the shared {@link ControlPlaneClient}. + * + * @throws IllegalStateException if {@link #configure} has not been called yet + */ + public static ControlPlaneClient client() { + ControlPlaneClient c = instance; + if (c == null) { + throw new IllegalStateException( + "NetworkPlugin has not been configured. " + + "Call NetworkPlugin.configure(baseUrl, token) during plugin startup." + ); + } + return c; + } + + /** + * Returns {@code true} if the client has been configured. + */ + public static boolean isConfigured() { + return instance != null; + } +} diff --git a/src/main/java/net/kewwbec/network/auth/ApiToken.java b/src/main/java/net/kewwbec/network/auth/ApiToken.java new file mode 100644 index 0000000..abcde14 --- /dev/null +++ b/src/main/java/net/kewwbec/network/auth/ApiToken.java @@ -0,0 +1,25 @@ +package net.kewwbec.network.auth; + +public final class ApiToken { + private final String value; + + private ApiToken(String value) { + if (value == null || value.isBlank()) { + throw new IllegalArgumentException("API token must not be blank"); + } + this.value = value; + } + + public static ApiToken of(String value) { + return new ApiToken(value); + } + + public String value() { + return value; + } + + @Override + public String toString() { + return "ApiToken[***]"; + } +} diff --git a/src/main/java/net/kewwbec/network/client/PlayersClient.java b/src/main/java/net/kewwbec/network/client/PlayersClient.java new file mode 100644 index 0000000..6877a16 --- /dev/null +++ b/src/main/java/net/kewwbec/network/client/PlayersClient.java @@ -0,0 +1,29 @@ +package net.kewwbec.network.client; + +import net.kewwbec.network.errors.ControlPlaneException; +import net.kewwbec.network.generated.api.v1.players.EntitlementsIndexEndpoint; +import net.kewwbec.network.generated.api.v1.players.SessionProfileEndpoint; +import net.kewwbec.network.http.ControlPlaneHttpClient; +import net.kewwbec.network.http.PathBuilder; +import net.kewwbec.network.models.players.PlayerEntitlement; +import net.kewwbec.network.models.players.PlayerSessionProfile; + +import java.util.List; + +public final class PlayersClient { + private final ControlPlaneHttpClient http; + + public PlayersClient(ControlPlaneHttpClient http) { + this.http = http; + } + + public PlayerSessionProfile getSessionProfile(String playerId) throws ControlPlaneException { + String uri = PathBuilder.resolve(SessionProfileEndpoint.VALUE.uri(), "player", playerId); + return http.get(uri, PlayerSessionProfile.class); + } + + public List getEntitlements(String playerId) throws ControlPlaneException { + String uri = PathBuilder.resolve(EntitlementsIndexEndpoint.VALUE.uri(), "player", playerId); + return http.getList(uri, PlayerEntitlement.class); + } +} diff --git a/src/main/java/net/kewwbec/network/client/PresenceClient.java b/src/main/java/net/kewwbec/network/client/PresenceClient.java new file mode 100644 index 0000000..7d55994 --- /dev/null +++ b/src/main/java/net/kewwbec/network/client/PresenceClient.java @@ -0,0 +1,40 @@ +package net.kewwbec.network.client; + +import net.kewwbec.network.errors.ControlPlaneException; +import net.kewwbec.network.generated.api.v1.server.InstancesHeartbeatEndpoint; +import net.kewwbec.network.generated.api.v1.server.InstancesRegisterEndpoint; +import net.kewwbec.network.generated.api.v1.server.InstancesShutdownEndpoint; +import net.kewwbec.network.http.ControlPlaneHttpClient; +import net.kewwbec.network.http.PathBuilder; +import net.kewwbec.network.models.server.HeartbeatPayload; +import net.kewwbec.network.models.server.RegistrationPayload; + +public final class PresenceClient { + private final ControlPlaneHttpClient http; + + public PresenceClient(ControlPlaneHttpClient http) { + this.http = http; + } + + public void register(String instanceId, RegistrationPayload payload) throws ControlPlaneException { + String uri = PathBuilder.resolve(InstancesRegisterEndpoint.VALUE.uri(), "instance", instanceId); + http.post(uri, payload); + } + + public void heartbeat(String instanceId, HeartbeatPayload payload) throws ControlPlaneException { + String uri = PathBuilder.resolve(InstancesHeartbeatEndpoint.VALUE.uri(), "instance", instanceId); + http.post(uri, payload); + } + + public void shutdown(String instanceId) throws ControlPlaneException { + shutdown(instanceId, null); + } + + public void shutdown(String instanceId, String reason) throws ControlPlaneException { + String uri = PathBuilder.resolve(InstancesShutdownEndpoint.VALUE.uri(), "instance", instanceId); + ShutdownBody body = reason != null ? new ShutdownBody(reason) : null; + http.post(uri, body); + } + + private record ShutdownBody(String reason) {} +} diff --git a/src/main/java/net/kewwbec/network/client/ServerClient.java b/src/main/java/net/kewwbec/network/client/ServerClient.java new file mode 100644 index 0000000..34148d2 --- /dev/null +++ b/src/main/java/net/kewwbec/network/client/ServerClient.java @@ -0,0 +1,18 @@ +package net.kewwbec.network.client; + +import net.kewwbec.network.errors.ControlPlaneException; +import net.kewwbec.network.generated.api.v1.server.ProfileEndpoint; +import net.kewwbec.network.http.ControlPlaneHttpClient; +import net.kewwbec.network.models.server.ServerProfile; + +public final class ServerClient { + private final ControlPlaneHttpClient http; + + public ServerClient(ControlPlaneHttpClient http) { + this.http = http; + } + + public ServerProfile currentProfile() throws ControlPlaneException { + return http.get(ProfileEndpoint.VALUE.uri(), ServerProfile.class); + } +} diff --git a/src/main/java/net/kewwbec/network/errors/AuthException.java b/src/main/java/net/kewwbec/network/errors/AuthException.java new file mode 100644 index 0000000..dbdbf51 --- /dev/null +++ b/src/main/java/net/kewwbec/network/errors/AuthException.java @@ -0,0 +1,14 @@ +package net.kewwbec.network.errors; + +public final class AuthException extends ControlPlaneException { + private final int statusCode; + + public AuthException(int statusCode, String message) { + super("Auth failure (" + statusCode + "): " + message); + this.statusCode = statusCode; + } + + public int statusCode() { + return statusCode; + } +} diff --git a/src/main/java/net/kewwbec/network/errors/ControlPlaneException.java b/src/main/java/net/kewwbec/network/errors/ControlPlaneException.java new file mode 100644 index 0000000..00cd80c --- /dev/null +++ b/src/main/java/net/kewwbec/network/errors/ControlPlaneException.java @@ -0,0 +1,11 @@ +package net.kewwbec.network.errors; + +public class ControlPlaneException extends Exception { + public ControlPlaneException(String message) { + super(message); + } + + public ControlPlaneException(String message, Throwable cause) { + super(message, cause); + } +} diff --git a/src/main/java/net/kewwbec/network/errors/NotFoundException.java b/src/main/java/net/kewwbec/network/errors/NotFoundException.java new file mode 100644 index 0000000..de3e326 --- /dev/null +++ b/src/main/java/net/kewwbec/network/errors/NotFoundException.java @@ -0,0 +1,7 @@ +package net.kewwbec.network.errors; + +public final class NotFoundException extends ControlPlaneException { + public NotFoundException(String message) { + super("Not found: " + message); + } +} diff --git a/src/main/java/net/kewwbec/network/errors/RemoteException.java b/src/main/java/net/kewwbec/network/errors/RemoteException.java new file mode 100644 index 0000000..8f16836 --- /dev/null +++ b/src/main/java/net/kewwbec/network/errors/RemoteException.java @@ -0,0 +1,14 @@ +package net.kewwbec.network.errors; + +public final class RemoteException extends ControlPlaneException { + private final int statusCode; + + public RemoteException(int statusCode, String message) { + super("Remote error (" + statusCode + "): " + message); + this.statusCode = statusCode; + } + + public int statusCode() { + return statusCode; + } +} diff --git a/src/main/java/net/kewwbec/network/errors/ValidationException.java b/src/main/java/net/kewwbec/network/errors/ValidationException.java new file mode 100644 index 0000000..a273c0c --- /dev/null +++ b/src/main/java/net/kewwbec/network/errors/ValidationException.java @@ -0,0 +1,17 @@ +package net.kewwbec.network.errors; + +import java.util.Collections; +import java.util.Map; + +public final class ValidationException extends ControlPlaneException { + private final Map errors; + + public ValidationException(String message, Map errors) { + super("Validation failed: " + message); + this.errors = Collections.unmodifiableMap(errors); + } + + public Map errors() { + return errors; + } +} diff --git a/src/main/java/net/kewwbec/network/generated/api/v1/ControlPlaneApiV1.java b/src/main/java/net/kewwbec/network/generated/api/v1/ControlPlaneApiV1.java index 25a44e2..8982974 100644 --- a/src/main/java/net/kewwbec/network/generated/api/v1/ControlPlaneApiV1.java +++ b/src/main/java/net/kewwbec/network/generated/api/v1/ControlPlaneApiV1.java @@ -1,26 +1,34 @@ package net.kewwbec.network.generated.api.v1; import net.kewwbec.network.generated.api.v1.announcements.AnnouncementsApi; +import net.kewwbec.network.generated.api.v1.assets.AssetsApi; import net.kewwbec.network.generated.api.v1.audit.AuditApi; +import net.kewwbec.network.generated.api.v1.entitlements.EntitlementsApi; +import net.kewwbec.network.generated.api.v1.gamepermissions.GamePermissionsApi; +import net.kewwbec.network.generated.api.v1.gameplay.GameplayApi; import net.kewwbec.network.generated.api.v1.health.HealthApi; +import net.kewwbec.network.generated.api.v1.hub.HubApi; import net.kewwbec.network.generated.api.v1.infrastructure.InfrastructureApi; import net.kewwbec.network.generated.api.v1.integrations.IntegrationsApi; import net.kewwbec.network.generated.api.v1.moderation.ModerationApi; import net.kewwbec.network.generated.api.v1.players.PlayersApi; import net.kewwbec.network.generated.api.v1.plugins.PluginsApi; +import net.kewwbec.network.generated.api.v1.progression.ProgressionApi; +import net.kewwbec.network.generated.api.v1.rewards.RewardsApi; import net.kewwbec.network.generated.api.v1.server.ServerApi; import net.kewwbec.network.generated.api.v1.serviceaccounts.ServiceAccountsApi; import net.kewwbec.network.generated.api.v1.social.SocialApi; import net.kewwbec.network.generated.api.v1.support.SupportApi; +import net.kewwbec.network.generated.api.v1.worlds.WorldsApi; public final class ControlPlaneApiV1 { public static final ControlPlaneApiV1 INSTANCE = new ControlPlaneApiV1(); private static final String API_VERSION = "v1"; private static final String BASE_PATH = "/api/v1"; - private static final String FINGERPRINT = "4dfbb2630cab5693fcc6f310408442201b6a4881f60a582d04fc2d6d05c45420"; - private static final int DOMAIN_COUNT = 12; - private static final int ENDPOINT_COUNT = 69; + private static final String FINGERPRINT = "4627923de5907196aabfc8de361f6e168f139a0476a206a5367fb5550b9dedbc"; + private static final int DOMAIN_COUNT = 20; + private static final int ENDPOINT_COUNT = 136; private ControlPlaneApiV1() { } @@ -49,14 +57,34 @@ public final class ControlPlaneApiV1 { return AnnouncementsApi.INSTANCE; } + public AssetsApi assets() { + return AssetsApi.INSTANCE; + } + public AuditApi audit() { return AuditApi.INSTANCE; } + public EntitlementsApi entitlements() { + return EntitlementsApi.INSTANCE; + } + + public GamePermissionsApi gamePermissions() { + return GamePermissionsApi.INSTANCE; + } + + public GameplayApi gameplay() { + return GameplayApi.INSTANCE; + } + public HealthApi health() { return HealthApi.INSTANCE; } + public HubApi hub() { + return HubApi.INSTANCE; + } + public InfrastructureApi infrastructure() { return InfrastructureApi.INSTANCE; } @@ -77,6 +105,14 @@ public final class ControlPlaneApiV1 { return PluginsApi.INSTANCE; } + public ProgressionApi progression() { + return ProgressionApi.INSTANCE; + } + + public RewardsApi rewards() { + return RewardsApi.INSTANCE; + } + public ServerApi server() { return ServerApi.INSTANCE; } @@ -92,4 +128,8 @@ public final class ControlPlaneApiV1 { public SupportApi support() { return SupportApi.INSTANCE; } + + public WorldsApi worlds() { + return WorldsApi.INSTANCE; + } } diff --git a/src/main/java/net/kewwbec/network/generated/api/v1/infrastructure/InfrastructureApi.java b/src/main/java/net/kewwbec/network/generated/api/v1/infrastructure/InfrastructureApi.java index 8f8c015..80abd9c 100644 --- a/src/main/java/net/kewwbec/network/generated/api/v1/infrastructure/InfrastructureApi.java +++ b/src/main/java/net/kewwbec/network/generated/api/v1/infrastructure/InfrastructureApi.java @@ -7,6 +7,7 @@ public final class InfrastructureApi { public static final InfrastructureApi INSTANCE = new InfrastructureApi(); private static final List ENDPOINTS = List.of( + ServerInstancesDestinationValidationEndpoint.VALUE, ServerInstancesPresenceIndexEndpoint.VALUE, ServerTemplatesIndexEndpoint.VALUE, ServerTemplatesShowEndpoint.VALUE, @@ -39,6 +40,10 @@ public final class InfrastructureApi { throw new IllegalArgumentException("Unknown route: " + routeName); } + public ApiEndpoint serverInstancesDestinationValidation() { + return ServerInstancesDestinationValidationEndpoint.VALUE; + } + public ApiEndpoint serverInstancesPresenceIndex() { return ServerInstancesPresenceIndexEndpoint.VALUE; } diff --git a/src/main/java/net/kewwbec/network/generated/api/v1/infrastructure/ServerInstancesPresenceIndexEndpoint.java b/src/main/java/net/kewwbec/network/generated/api/v1/infrastructure/ServerInstancesPresenceIndexEndpoint.java index 53879df..95998a1 100644 --- a/src/main/java/net/kewwbec/network/generated/api/v1/infrastructure/ServerInstancesPresenceIndexEndpoint.java +++ b/src/main/java/net/kewwbec/network/generated/api/v1/infrastructure/ServerInstancesPresenceIndexEndpoint.java @@ -18,7 +18,7 @@ public final class ServerInstancesPresenceIndexEndpoint { List.of("presence.read"), List.of("api", "auth:sanctum", "service.abilities:presence.read"), List.of(), - new RequestDescriptor("App\\Domains\\Infrastructure\\Http\\Requests\\ListServerPresenceRequest", "query", List.of(new RequestField("region", List.of(new RuleDescriptor("string", null, "sometimes"), new RuleDescriptor("string", null, "string"), new RuleDescriptor("string", null, "max:100"))), new RequestField("template", List.of(new RuleDescriptor("string", null, "sometimes"), new RuleDescriptor("string", null, "string"), new RuleDescriptor("string", null, "max:150"))), new RequestField("category", List.of(new RuleDescriptor("string", null, "sometimes"), new RuleDescriptor("string", null, "string"), new RuleDescriptor("string", null, "max:100"))), new RequestField("status", List.of(new RuleDescriptor("string", null, "sometimes"), new RuleDescriptor("string", null, "string"), new RuleDescriptor("object", "Illuminate\\Validation\\Rules\\In", "in:\"provisioning\",\"starting\",\"running\",\"draining\",\"stopped\",\"unhealthy\""))), new RequestField("presence_state", List.of(new RuleDescriptor("string", null, "sometimes"), new RuleDescriptor("string", null, "string"), new RuleDescriptor("object", "Illuminate\\Validation\\Rules\\In", "in:\"online\",\"missing\",\"any\""))), new RequestField("has_capacity", List.of(new RuleDescriptor("string", null, "sometimes"), new RuleDescriptor("string", null, "boolean"))), new RequestField("limit", List.of(new RuleDescriptor("string", null, "sometimes"), new RuleDescriptor("string", null, "integer"), new RuleDescriptor("string", null, "min:1"), new RuleDescriptor("string", null, "max:100"))))), + new RequestDescriptor("App\\Domains\\Infrastructure\\Http\\Requests\\ListServerPresenceRequest", "query", List.of(new RequestField("region", List.of(new RuleDescriptor("string", null, "sometimes"), new RuleDescriptor("string", null, "string"), new RuleDescriptor("string", null, "max:100"))), new RequestField("template", List.of(new RuleDescriptor("string", null, "sometimes"), new RuleDescriptor("string", null, "string"), new RuleDescriptor("string", null, "max:150"))), new RequestField("category", List.of(new RuleDescriptor("string", null, "sometimes"), new RuleDescriptor("string", null, "string"), new RuleDescriptor("string", null, "max:100"))), new RequestField("status", List.of(new RuleDescriptor("string", null, "sometimes"), new RuleDescriptor("string", null, "string"), new RuleDescriptor("object", "Illuminate\\Validation\\Rules\\In", "in:\"provisioning\",\"starting\",\"running\",\"draining\",\"stopped\",\"unhealthy\""))), new RequestField("presence_state", List.of(new RuleDescriptor("string", null, "sometimes"), new RuleDescriptor("string", null, "string"), new RuleDescriptor("object", "Illuminate\\Validation\\Rules\\In", "in:\"online\",\"missing\",\"any\""))), new RequestField("has_capacity", List.of(new RuleDescriptor("string", null, "sometimes"), new RuleDescriptor("string", null, "boolean"))), new RequestField("accepting_players", List.of(new RuleDescriptor("string", null, "sometimes"), new RuleDescriptor("string", null, "boolean"))), new RequestField("limit", List.of(new RuleDescriptor("string", null, "sometimes"), new RuleDescriptor("string", null, "integer"), new RuleDescriptor("string", null, "min:1"), new RuleDescriptor("string", null, "max:100"))))), new ResponseDescriptor("json_resource", new TypeDescriptor("Illuminate\\Http\\Resources\\Json\\AnonymousResourceCollection", false, false)) ) ; diff --git a/src/main/java/net/kewwbec/network/generated/api/v1/infrastructure/ServerTemplatesStoreEndpoint.java b/src/main/java/net/kewwbec/network/generated/api/v1/infrastructure/ServerTemplatesStoreEndpoint.java index 5f16dde..0cc03ca 100644 --- a/src/main/java/net/kewwbec/network/generated/api/v1/infrastructure/ServerTemplatesStoreEndpoint.java +++ b/src/main/java/net/kewwbec/network/generated/api/v1/infrastructure/ServerTemplatesStoreEndpoint.java @@ -18,7 +18,7 @@ public final class ServerTemplatesStoreEndpoint { List.of("server-templates.write"), List.of("api", "auth:sanctum", "service.abilities:server-templates.write"), List.of(), - new RequestDescriptor("App\\Domains\\Infrastructure\\Http\\Requests\\StoreServerTemplateRequest", "body", List.of(new RequestField("region_key", List.of(new RuleDescriptor("string", null, "required"), new RuleDescriptor("string", null, "string"), new RuleDescriptor("string", null, "exists:regions,key"))), new RequestField("key", List.of(new RuleDescriptor("string", null, "required"), new RuleDescriptor("string", null, "string"), new RuleDescriptor("string", null, "max:150"), new RuleDescriptor("string", null, "regex:/^[a-z0-9._-]+$/"), new RuleDescriptor("string", null, "unique:server_templates,key"))), new RequestField("name", List.of(new RuleDescriptor("string", null, "required"), new RuleDescriptor("string", null, "string"), new RuleDescriptor("string", null, "max:120"))), new RequestField("category", List.of(new RuleDescriptor("string", null, "required"), new RuleDescriptor("string", null, "string"), new RuleDescriptor("string", null, "max:100"))), new RequestField("lifecycle_strategy", List.of(new RuleDescriptor("string", null, "required"), new RuleDescriptor("string", null, "string"), new RuleDescriptor("object", "Illuminate\\Validation\\Rules\\In", "in:\"manual\",\"static\",\"elastic\""))), new RequestField("version", List.of(new RuleDescriptor("string", null, "nullable"), new RuleDescriptor("string", null, "string"), new RuleDescriptor("string", null, "max:80"))), new RequestField("max_players", List.of(new RuleDescriptor("string", null, "required"), new RuleDescriptor("string", null, "integer"), new RuleDescriptor("string", null, "min:0"))), new RequestField("is_active", List.of(new RuleDescriptor("string", null, "sometimes"), new RuleDescriptor("string", null, "boolean"))), new RequestField("metadata", List.of(new RuleDescriptor("string", null, "nullable"), new RuleDescriptor("string", null, "array"))))), + new RequestDescriptor("App\\Domains\\Infrastructure\\Http\\Requests\\StoreServerTemplateRequest", "body", List.of(new RequestField("region_key", List.of(new RuleDescriptor("string", null, "required"), new RuleDescriptor("string", null, "string"), new RuleDescriptor("string", null, "exists:regions,key"))), new RequestField("key", List.of(new RuleDescriptor("string", null, "required"), new RuleDescriptor("string", null, "string"), new RuleDescriptor("string", null, "max:150"), new RuleDescriptor("string", null, "regex:/^[a-z0-9._-]+$/"), new RuleDescriptor("string", null, "unique:server_templates,key"))), new RequestField("name", List.of(new RuleDescriptor("string", null, "required"), new RuleDescriptor("string", null, "string"), new RuleDescriptor("string", null, "max:120"))), new RequestField("category", List.of(new RuleDescriptor("string", null, "required"), new RuleDescriptor("string", null, "string"), new RuleDescriptor("string", null, "max:100"))), new RequestField("lifecycle_strategy", List.of(new RuleDescriptor("string", null, "required"), new RuleDescriptor("string", null, "string"), new RuleDescriptor("object", "Illuminate\\Validation\\Rules\\In", "in:\"manual\",\"static\",\"elastic\""))), new RequestField("version", List.of(new RuleDescriptor("string", null, "nullable"), new RuleDescriptor("string", null, "string"), new RuleDescriptor("string", null, "max:80"))), new RequestField("max_players", List.of(new RuleDescriptor("string", null, "required"), new RuleDescriptor("string", null, "integer"), new RuleDescriptor("string", null, "min:0"))), new RequestField("is_active", List.of(new RuleDescriptor("string", null, "sometimes"), new RuleDescriptor("string", null, "boolean"))), new RequestField("startup_world_key", List.of(new RuleDescriptor("string", null, "nullable"), new RuleDescriptor("string", null, "string"), new RuleDescriptor("string", null, "max:150"), new RuleDescriptor("string", null, "exists:worlds,key"))), new RequestField("asset_pack_keys", List.of(new RuleDescriptor("string", null, "sometimes"), new RuleDescriptor("string", null, "array"))), new RequestField("asset_pack_keys.*", List.of(new RuleDescriptor("string", null, "required"), new RuleDescriptor("string", null, "string"), new RuleDescriptor("string", null, "distinct"), new RuleDescriptor("string", null, "exists:asset_packs,key"))), new RequestField("metadata", List.of(new RuleDescriptor("string", null, "nullable"), new RuleDescriptor("string", null, "array"))))), new ResponseDescriptor("json_response", new TypeDescriptor("Illuminate\\Http\\JsonResponse", false, false)) ) ; diff --git a/src/main/java/net/kewwbec/network/generated/api/v1/infrastructure/ServerTemplatesUpdateEndpoint.java b/src/main/java/net/kewwbec/network/generated/api/v1/infrastructure/ServerTemplatesUpdateEndpoint.java index ec2f117..511e5f4 100644 --- a/src/main/java/net/kewwbec/network/generated/api/v1/infrastructure/ServerTemplatesUpdateEndpoint.java +++ b/src/main/java/net/kewwbec/network/generated/api/v1/infrastructure/ServerTemplatesUpdateEndpoint.java @@ -18,7 +18,7 @@ public final class ServerTemplatesUpdateEndpoint { List.of("server-templates.write"), List.of("api", "auth:sanctum", "service.abilities:server-templates.write"), List.of(new RouteParameter("serverTemplate", new TypeDescriptor("App\\Domains\\Infrastructure\\Models\\ServerTemplate", false, false))), - new RequestDescriptor("App\\Domains\\Infrastructure\\Http\\Requests\\UpdateServerTemplateRequest", "body", List.of(new RequestField("region_key", List.of(new RuleDescriptor("string", null, "sometimes"), new RuleDescriptor("string", null, "string"), new RuleDescriptor("string", null, "exists:regions,key"))), new RequestField("key", List.of(new RuleDescriptor("string", null, "sometimes"), new RuleDescriptor("string", null, "string"), new RuleDescriptor("string", null, "max:150"), new RuleDescriptor("string", null, "regex:/^[a-z0-9._-]+$/"), new RuleDescriptor("object", "Illuminate\\Validation\\Rules\\Unique", "unique:server_templates,key,NULL,id"))), new RequestField("name", List.of(new RuleDescriptor("string", null, "sometimes"), new RuleDescriptor("string", null, "string"), new RuleDescriptor("string", null, "max:120"))), new RequestField("category", List.of(new RuleDescriptor("string", null, "sometimes"), new RuleDescriptor("string", null, "string"), new RuleDescriptor("string", null, "max:100"))), new RequestField("lifecycle_strategy", List.of(new RuleDescriptor("string", null, "sometimes"), new RuleDescriptor("string", null, "string"), new RuleDescriptor("object", "Illuminate\\Validation\\Rules\\In", "in:\"manual\",\"static\",\"elastic\""))), new RequestField("version", List.of(new RuleDescriptor("string", null, "nullable"), new RuleDescriptor("string", null, "string"), new RuleDescriptor("string", null, "max:80"))), new RequestField("max_players", List.of(new RuleDescriptor("string", null, "sometimes"), new RuleDescriptor("string", null, "integer"), new RuleDescriptor("string", null, "min:0"))), new RequestField("is_active", List.of(new RuleDescriptor("string", null, "sometimes"), new RuleDescriptor("string", null, "boolean"))), new RequestField("metadata", List.of(new RuleDescriptor("string", null, "nullable"), new RuleDescriptor("string", null, "array"))))), + new RequestDescriptor("App\\Domains\\Infrastructure\\Http\\Requests\\UpdateServerTemplateRequest", "body", List.of(new RequestField("region_key", List.of(new RuleDescriptor("string", null, "sometimes"), new RuleDescriptor("string", null, "string"), new RuleDescriptor("string", null, "exists:regions,key"))), new RequestField("key", List.of(new RuleDescriptor("string", null, "sometimes"), new RuleDescriptor("string", null, "string"), new RuleDescriptor("string", null, "max:150"), new RuleDescriptor("string", null, "regex:/^[a-z0-9._-]+$/"), new RuleDescriptor("object", "Illuminate\\Validation\\Rules\\Unique", "unique:server_templates,key,NULL,id"))), new RequestField("name", List.of(new RuleDescriptor("string", null, "sometimes"), new RuleDescriptor("string", null, "string"), new RuleDescriptor("string", null, "max:120"))), new RequestField("category", List.of(new RuleDescriptor("string", null, "sometimes"), new RuleDescriptor("string", null, "string"), new RuleDescriptor("string", null, "max:100"))), new RequestField("lifecycle_strategy", List.of(new RuleDescriptor("string", null, "sometimes"), new RuleDescriptor("string", null, "string"), new RuleDescriptor("object", "Illuminate\\Validation\\Rules\\In", "in:\"manual\",\"static\",\"elastic\""))), new RequestField("version", List.of(new RuleDescriptor("string", null, "nullable"), new RuleDescriptor("string", null, "string"), new RuleDescriptor("string", null, "max:80"))), new RequestField("max_players", List.of(new RuleDescriptor("string", null, "sometimes"), new RuleDescriptor("string", null, "integer"), new RuleDescriptor("string", null, "min:0"))), new RequestField("is_active", List.of(new RuleDescriptor("string", null, "sometimes"), new RuleDescriptor("string", null, "boolean"))), new RequestField("startup_world_key", List.of(new RuleDescriptor("string", null, "nullable"), new RuleDescriptor("string", null, "string"), new RuleDescriptor("string", null, "max:150"), new RuleDescriptor("string", null, "exists:worlds,key"))), new RequestField("asset_pack_keys", List.of(new RuleDescriptor("string", null, "sometimes"), new RuleDescriptor("string", null, "array"))), new RequestField("asset_pack_keys.*", List.of(new RuleDescriptor("string", null, "required"), new RuleDescriptor("string", null, "string"), new RuleDescriptor("string", null, "distinct"), new RuleDescriptor("string", null, "exists:asset_packs,key"))), new RequestField("metadata", List.of(new RuleDescriptor("string", null, "nullable"), new RuleDescriptor("string", null, "array"))))), new ResponseDescriptor("json_response", new TypeDescriptor("Illuminate\\Http\\JsonResponse", false, false)) ) ; diff --git a/src/main/java/net/kewwbec/network/generated/api/v1/players/PlayersApi.java b/src/main/java/net/kewwbec/network/generated/api/v1/players/PlayersApi.java index f11d042..1b4d16a 100644 --- a/src/main/java/net/kewwbec/network/generated/api/v1/players/PlayersApi.java +++ b/src/main/java/net/kewwbec/network/generated/api/v1/players/PlayersApi.java @@ -7,12 +7,30 @@ public final class PlayersApi { public static final PlayersApi INSTANCE = new PlayersApi(); private static final List ENDPOINTS = List.of( + AuthorizationPermissionSnapshotEndpoint.VALUE, + BalanceTransactionsIndexEndpoint.VALUE, + BalanceTransactionsStoreEndpoint.VALUE, + BalancesIndexEndpoint.VALUE, + CatalogEmotesIndexEndpoint.VALUE, + EntitlementsIndexEndpoint.VALUE, + EntitlementsRevokeEndpoint.VALUE, + EntitlementsStoreEndpoint.VALUE, + GamePermissionsShowEndpoint.VALUE, + GameplayAttemptsIndexEndpoint.VALUE, + GameplayStatsShowEndpoint.VALUE, + ModerationSanctionSnapshotEndpoint.VALUE, NotificationsIndexEndpoint.VALUE, NotificationsReadEndpoint.VALUE, NotificationsStoreEndpoint.VALUE, + PresenceEndpoint.VALUE, SessionProfileEndpoint.VALUE, SocialGraphEndpoint.VALUE, - WebsiteProfileEndpoint.VALUE + SocialPrivacyUpdateEndpoint.VALUE, + VisibilityUpdateEndpoint.VALUE, + WebsiteProfileEndpoint.VALUE, + XpLedgerIndexEndpoint.VALUE, + XpLedgerStoreEndpoint.VALUE, + XpProgressIndexEndpoint.VALUE ); private PlayersApi() { @@ -40,6 +58,54 @@ public final class PlayersApi { throw new IllegalArgumentException("Unknown route: " + routeName); } + public ApiEndpoint authorizationPermissionSnapshot() { + return AuthorizationPermissionSnapshotEndpoint.VALUE; + } + + public ApiEndpoint balanceTransactionsIndex() { + return BalanceTransactionsIndexEndpoint.VALUE; + } + + public ApiEndpoint balanceTransactionsStore() { + return BalanceTransactionsStoreEndpoint.VALUE; + } + + public ApiEndpoint balancesIndex() { + return BalancesIndexEndpoint.VALUE; + } + + public ApiEndpoint catalogEmotesIndex() { + return CatalogEmotesIndexEndpoint.VALUE; + } + + public ApiEndpoint entitlementsIndex() { + return EntitlementsIndexEndpoint.VALUE; + } + + public ApiEndpoint entitlementsRevoke() { + return EntitlementsRevokeEndpoint.VALUE; + } + + public ApiEndpoint entitlementsStore() { + return EntitlementsStoreEndpoint.VALUE; + } + + public ApiEndpoint gamePermissionsShow() { + return GamePermissionsShowEndpoint.VALUE; + } + + public ApiEndpoint gameplayAttemptsIndex() { + return GameplayAttemptsIndexEndpoint.VALUE; + } + + public ApiEndpoint gameplayStatsShow() { + return GameplayStatsShowEndpoint.VALUE; + } + + public ApiEndpoint moderationSanctionSnapshot() { + return ModerationSanctionSnapshotEndpoint.VALUE; + } + public ApiEndpoint notificationsIndex() { return NotificationsIndexEndpoint.VALUE; } @@ -52,6 +118,10 @@ public final class PlayersApi { return NotificationsStoreEndpoint.VALUE; } + public ApiEndpoint presence() { + return PresenceEndpoint.VALUE; + } + public ApiEndpoint sessionProfile() { return SessionProfileEndpoint.VALUE; } @@ -60,7 +130,27 @@ public final class PlayersApi { return SocialGraphEndpoint.VALUE; } + public ApiEndpoint socialPrivacyUpdate() { + return SocialPrivacyUpdateEndpoint.VALUE; + } + + public ApiEndpoint visibilityUpdate() { + return VisibilityUpdateEndpoint.VALUE; + } + public ApiEndpoint websiteProfile() { return WebsiteProfileEndpoint.VALUE; } + + public ApiEndpoint xpLedgerIndex() { + return XpLedgerIndexEndpoint.VALUE; + } + + public ApiEndpoint xpLedgerStore() { + return XpLedgerStoreEndpoint.VALUE; + } + + public ApiEndpoint xpProgressIndex() { + return XpProgressIndexEndpoint.VALUE; + } } diff --git a/src/main/java/net/kewwbec/network/generated/api/v1/server/ServerApi.java b/src/main/java/net/kewwbec/network/generated/api/v1/server/ServerApi.java index 1cd50e3..5381a71 100644 --- a/src/main/java/net/kewwbec/network/generated/api/v1/server/ServerApi.java +++ b/src/main/java/net/kewwbec/network/generated/api/v1/server/ServerApi.java @@ -7,8 +7,11 @@ public final class ServerApi { public static final ServerApi INSTANCE = new ServerApi(); private static final List ENDPOINTS = List.of( + InstancesAssetPacksVersionsAcknowledgeEndpoint.VALUE, + InstancesGameplayAttemptsStoreEndpoint.VALUE, InstancesHeartbeatEndpoint.VALUE, InstancesMatchesResultsStoreEndpoint.VALUE, + InstancesPlayersPresenceStoreEndpoint.VALUE, InstancesRegisterEndpoint.VALUE, InstancesShutdownEndpoint.VALUE, ProfileEndpoint.VALUE @@ -39,6 +42,14 @@ public final class ServerApi { throw new IllegalArgumentException("Unknown route: " + routeName); } + public ApiEndpoint instancesAssetPacksVersionsAcknowledge() { + return InstancesAssetPacksVersionsAcknowledgeEndpoint.VALUE; + } + + public ApiEndpoint instancesGameplayAttemptsStore() { + return InstancesGameplayAttemptsStoreEndpoint.VALUE; + } + public ApiEndpoint instancesHeartbeat() { return InstancesHeartbeatEndpoint.VALUE; } @@ -47,6 +58,10 @@ public final class ServerApi { return InstancesMatchesResultsStoreEndpoint.VALUE; } + public ApiEndpoint instancesPlayersPresenceStore() { + return InstancesPlayersPresenceStoreEndpoint.VALUE; + } + public ApiEndpoint instancesRegister() { return InstancesRegisterEndpoint.VALUE; } diff --git a/src/main/java/net/kewwbec/network/generated/api/v1/serviceaccounts/ServiceAccountsApi.java b/src/main/java/net/kewwbec/network/generated/api/v1/serviceaccounts/ServiceAccountsApi.java index 01da44d..895af1a 100644 --- a/src/main/java/net/kewwbec/network/generated/api/v1/serviceaccounts/ServiceAccountsApi.java +++ b/src/main/java/net/kewwbec/network/generated/api/v1/serviceaccounts/ServiceAccountsApi.java @@ -7,10 +7,14 @@ public final class ServiceAccountsApi { public static final ServiceAccountsApi INSTANCE = new ServiceAccountsApi(); private static final List ENDPOINTS = List.of( + IndexEndpoint.VALUE, + ShowEndpoint.VALUE, + StoreEndpoint.VALUE, TokensDestroyEndpoint.VALUE, TokensIndexEndpoint.VALUE, TokensRotateEndpoint.VALUE, - TokensStoreEndpoint.VALUE + TokensStoreEndpoint.VALUE, + UpdateEndpoint.VALUE ); private ServiceAccountsApi() { @@ -38,6 +42,18 @@ public final class ServiceAccountsApi { throw new IllegalArgumentException("Unknown route: " + routeName); } + public ApiEndpoint index() { + return IndexEndpoint.VALUE; + } + + public ApiEndpoint show() { + return ShowEndpoint.VALUE; + } + + public ApiEndpoint store() { + return StoreEndpoint.VALUE; + } + public ApiEndpoint tokensDestroy() { return TokensDestroyEndpoint.VALUE; } @@ -53,4 +69,8 @@ public final class ServiceAccountsApi { public ApiEndpoint tokensStore() { return TokensStoreEndpoint.VALUE; } + + public ApiEndpoint update() { + return UpdateEndpoint.VALUE; + } } diff --git a/src/main/java/net/kewwbec/network/generated/api/v1/serviceaccounts/TokensRotateEndpoint.java b/src/main/java/net/kewwbec/network/generated/api/v1/serviceaccounts/TokensRotateEndpoint.java index 46145ba..9adacac 100644 --- a/src/main/java/net/kewwbec/network/generated/api/v1/serviceaccounts/TokensRotateEndpoint.java +++ b/src/main/java/net/kewwbec/network/generated/api/v1/serviceaccounts/TokensRotateEndpoint.java @@ -18,7 +18,7 @@ public final class TokensRotateEndpoint { List.of("service-accounts.tokens.manage"), List.of("api", "auth:sanctum", "service.abilities:service-accounts.tokens.manage"), List.of(new RouteParameter("serviceAccount", new TypeDescriptor("App\\Domains\\Authorization\\Models\\ServiceAccount", false, false))), - new RequestDescriptor("App\\Domains\\Authorization\\Http\\Requests\\IssueServiceAccountTokenRequest", "body", List.of(new RequestField("name", List.of(new RuleDescriptor("string", null, "required"), new RuleDescriptor("string", null, "string"), new RuleDescriptor("string", null, "max:255"))), new RequestField("abilities", List.of(new RuleDescriptor("string", null, "required"), new RuleDescriptor("string", null, "array"), new RuleDescriptor("string", null, "min:1"))), new RequestField("abilities.*", List.of(new RuleDescriptor("string", null, "required"), new RuleDescriptor("string", null, "string"), new RuleDescriptor("object", "Illuminate\\Validation\\Rules\\In", "in:\"announcements.read\",\"audit-events.read\",\"configs.read\",\"integrations.read\",\"integrations.write\",\"matches.result.write\",\"moderation.cases.read\",\"moderation.cases.write\",\"notifications.read\",\"notifications.write\",\"plugins.deploy.write\",\"plugins.read\",\"presence.read\",\"players.website-profile.read\",\"players.session-profile.read\",\"presence.write\",\"rewards.request\",\"social.read\",\"social.write\",\"service-accounts.tokens.manage\",\"server-instance.heartbeat.write\",\"server.profile.read\",\"server-templates.read\",\"server-templates.write\",\"support.issues.read\",\"support.issues.write\""))), new RequestField("expires_in_minutes", List.of(new RuleDescriptor("string", null, "nullable"), new RuleDescriptor("string", null, "integer"), new RuleDescriptor("string", null, "min:1"), new RuleDescriptor("string", null, "max:10080"))))), + new RequestDescriptor("App\\Domains\\Authorization\\Http\\Requests\\IssueServiceAccountTokenRequest", "body", List.of(new RequestField("name", List.of(new RuleDescriptor("string", null, "required"), new RuleDescriptor("string", null, "string"), new RuleDescriptor("string", null, "max:255"))), new RequestField("abilities", List.of(new RuleDescriptor("string", null, "required"), new RuleDescriptor("string", null, "array"), new RuleDescriptor("string", null, "min:1"))), new RequestField("abilities.*", List.of(new RuleDescriptor("string", null, "required"), new RuleDescriptor("string", null, "string"), new RuleDescriptor("object", "Illuminate\\Validation\\Rules\\In", "in:\"allocation.read\",\"announcements.read\",\"asset-packs.read\",\"asset-packs.write\",\"audit-events.read\",\"catalog.read\",\"catalog.write\",\"hub-live-ops.read\",\"hub-live-ops.write\",\"authorization.runtime.read\",\"configs.read\",\"entitlements.read\",\"entitlements.write\",\"game-permissions.read\",\"game-permissions.write\",\"gameplay.results.read\",\"gameplay.stats.read\",\"gameplay.results.write\",\"integrations.read\",\"integrations.write\",\"matches.result.write\",\"moderation.cases.read\",\"moderation.cases.write\",\"moderation.runtime.read\",\"notifications.read\",\"notifications.write\",\"plugins.deploy.write\",\"plugins.read\",\"presence.read\",\"players.visibility.write\",\"players.balances.read\",\"players.balances.write\",\"players.website-profile.read\",\"players.session-profile.read\",\"players.xp-ledger.read\",\"players.xp-ledger.write\",\"presence.write\",\"rewards.read\",\"rewards.write\",\"rewards.request\",\"social.read\",\"social.write\",\"service-accounts.manage\",\"service-accounts.tokens.manage\",\"server-instance.heartbeat.write\",\"server.profile.read\",\"server-templates.read\",\"server-templates.write\",\"support.issues.read\",\"support.issues.write\",\"worlds.read\",\"worlds.write\""))), new RequestField("expires_in_minutes", List.of(new RuleDescriptor("string", null, "nullable"), new RuleDescriptor("string", null, "integer"), new RuleDescriptor("string", null, "min:1"), new RuleDescriptor("string", null, "max:10080"))))), new ResponseDescriptor("json_response", new TypeDescriptor("Illuminate\\Http\\JsonResponse", false, false)) ) ; diff --git a/src/main/java/net/kewwbec/network/generated/api/v1/serviceaccounts/TokensStoreEndpoint.java b/src/main/java/net/kewwbec/network/generated/api/v1/serviceaccounts/TokensStoreEndpoint.java index f5fe326..e1e16a1 100644 --- a/src/main/java/net/kewwbec/network/generated/api/v1/serviceaccounts/TokensStoreEndpoint.java +++ b/src/main/java/net/kewwbec/network/generated/api/v1/serviceaccounts/TokensStoreEndpoint.java @@ -18,7 +18,7 @@ public final class TokensStoreEndpoint { List.of("service-accounts.tokens.manage"), List.of("api", "auth:sanctum", "service.abilities:service-accounts.tokens.manage"), List.of(new RouteParameter("serviceAccount", new TypeDescriptor("App\\Domains\\Authorization\\Models\\ServiceAccount", false, false))), - new RequestDescriptor("App\\Domains\\Authorization\\Http\\Requests\\IssueServiceAccountTokenRequest", "body", List.of(new RequestField("name", List.of(new RuleDescriptor("string", null, "required"), new RuleDescriptor("string", null, "string"), new RuleDescriptor("string", null, "max:255"))), new RequestField("abilities", List.of(new RuleDescriptor("string", null, "required"), new RuleDescriptor("string", null, "array"), new RuleDescriptor("string", null, "min:1"))), new RequestField("abilities.*", List.of(new RuleDescriptor("string", null, "required"), new RuleDescriptor("string", null, "string"), new RuleDescriptor("object", "Illuminate\\Validation\\Rules\\In", "in:\"announcements.read\",\"audit-events.read\",\"configs.read\",\"integrations.read\",\"integrations.write\",\"matches.result.write\",\"moderation.cases.read\",\"moderation.cases.write\",\"notifications.read\",\"notifications.write\",\"plugins.deploy.write\",\"plugins.read\",\"presence.read\",\"players.website-profile.read\",\"players.session-profile.read\",\"presence.write\",\"rewards.request\",\"social.read\",\"social.write\",\"service-accounts.tokens.manage\",\"server-instance.heartbeat.write\",\"server.profile.read\",\"server-templates.read\",\"server-templates.write\",\"support.issues.read\",\"support.issues.write\""))), new RequestField("expires_in_minutes", List.of(new RuleDescriptor("string", null, "nullable"), new RuleDescriptor("string", null, "integer"), new RuleDescriptor("string", null, "min:1"), new RuleDescriptor("string", null, "max:10080"))))), + new RequestDescriptor("App\\Domains\\Authorization\\Http\\Requests\\IssueServiceAccountTokenRequest", "body", List.of(new RequestField("name", List.of(new RuleDescriptor("string", null, "required"), new RuleDescriptor("string", null, "string"), new RuleDescriptor("string", null, "max:255"))), new RequestField("abilities", List.of(new RuleDescriptor("string", null, "required"), new RuleDescriptor("string", null, "array"), new RuleDescriptor("string", null, "min:1"))), new RequestField("abilities.*", List.of(new RuleDescriptor("string", null, "required"), new RuleDescriptor("string", null, "string"), new RuleDescriptor("object", "Illuminate\\Validation\\Rules\\In", "in:\"allocation.read\",\"announcements.read\",\"asset-packs.read\",\"asset-packs.write\",\"audit-events.read\",\"catalog.read\",\"catalog.write\",\"hub-live-ops.read\",\"hub-live-ops.write\",\"authorization.runtime.read\",\"configs.read\",\"entitlements.read\",\"entitlements.write\",\"game-permissions.read\",\"game-permissions.write\",\"gameplay.results.read\",\"gameplay.stats.read\",\"gameplay.results.write\",\"integrations.read\",\"integrations.write\",\"matches.result.write\",\"moderation.cases.read\",\"moderation.cases.write\",\"moderation.runtime.read\",\"notifications.read\",\"notifications.write\",\"plugins.deploy.write\",\"plugins.read\",\"presence.read\",\"players.visibility.write\",\"players.balances.read\",\"players.balances.write\",\"players.website-profile.read\",\"players.session-profile.read\",\"players.xp-ledger.read\",\"players.xp-ledger.write\",\"presence.write\",\"rewards.read\",\"rewards.write\",\"rewards.request\",\"social.read\",\"social.write\",\"service-accounts.manage\",\"service-accounts.tokens.manage\",\"server-instance.heartbeat.write\",\"server.profile.read\",\"server-templates.read\",\"server-templates.write\",\"support.issues.read\",\"support.issues.write\",\"worlds.read\",\"worlds.write\""))), new RequestField("expires_in_minutes", List.of(new RuleDescriptor("string", null, "nullable"), new RuleDescriptor("string", null, "integer"), new RuleDescriptor("string", null, "min:1"), new RuleDescriptor("string", null, "max:10080"))))), new ResponseDescriptor("json_response", new TypeDescriptor("Illuminate\\Http\\JsonResponse", false, false)) ) ; diff --git a/src/main/java/net/kewwbec/network/generated/api/v1/social/SocialApi.java b/src/main/java/net/kewwbec/network/generated/api/v1/social/SocialApi.java index bf7a7f4..edefa84 100644 --- a/src/main/java/net/kewwbec/network/generated/api/v1/social/SocialApi.java +++ b/src/main/java/net/kewwbec/network/generated/api/v1/social/SocialApi.java @@ -7,6 +7,8 @@ public final class SocialApi { public static final SocialApi INSTANCE = new SocialApi(); private static final List ENDPOINTS = List.of( + BlocksRemoveEndpoint.VALUE, + BlocksStoreEndpoint.VALUE, FriendshipsAcceptEndpoint.VALUE, FriendshipsStoreEndpoint.VALUE, GuildInvitesAcceptEndpoint.VALUE, @@ -54,6 +56,14 @@ public final class SocialApi { throw new IllegalArgumentException("Unknown route: " + routeName); } + public ApiEndpoint blocksRemove() { + return BlocksRemoveEndpoint.VALUE; + } + + public ApiEndpoint blocksStore() { + return BlocksStoreEndpoint.VALUE; + } + public ApiEndpoint friendshipsAccept() { return FriendshipsAcceptEndpoint.VALUE; } diff --git a/src/main/java/net/kewwbec/network/http/ControlPlaneHttpClient.java b/src/main/java/net/kewwbec/network/http/ControlPlaneHttpClient.java new file mode 100644 index 0000000..0682cea --- /dev/null +++ b/src/main/java/net/kewwbec/network/http/ControlPlaneHttpClient.java @@ -0,0 +1,155 @@ +package net.kewwbec.network.http; + +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; +import com.google.gson.JsonParser; +import com.google.gson.reflect.TypeToken; + +import java.lang.reflect.Type; +import net.kewwbec.network.auth.ApiToken; +import net.kewwbec.network.errors.AuthException; +import net.kewwbec.network.errors.ControlPlaneException; +import net.kewwbec.network.errors.NotFoundException; +import net.kewwbec.network.errors.RemoteException; +import net.kewwbec.network.errors.ValidationException; + +import java.io.IOException; +import java.net.URI; +import java.net.http.HttpClient; +import java.net.http.HttpRequest; +import java.net.http.HttpResponse; +import java.time.Duration; +import java.util.HashMap; +import java.util.Map; + +public final class ControlPlaneHttpClient { + private static final Gson GSON = new GsonBuilder().create(); + + private final HttpClient httpClient; + private final String baseUrl; + private final ApiToken token; + + public ControlPlaneHttpClient(String baseUrl, ApiToken token, Duration timeout) { + this.baseUrl = baseUrl.endsWith("/") ? baseUrl.substring(0, baseUrl.length() - 1) : baseUrl; + this.token = token; + this.httpClient = HttpClient.newBuilder() + .connectTimeout(timeout) + .build(); + } + + public JsonObject get(String uri) throws ControlPlaneException { + HttpRequest request = HttpRequest.newBuilder() + .uri(URI.create(baseUrl + uri)) + .header("Authorization", "Bearer " + token.value()) + .header("Accept", "application/json") + .GET() + .timeout(Duration.ofSeconds(10)) + .build(); + return send(request); + } + + public JsonObject post(String uri, Object body) throws ControlPlaneException { + String json = body != null ? GSON.toJson(body) : "{}"; + HttpRequest request = HttpRequest.newBuilder() + .uri(URI.create(baseUrl + uri)) + .header("Authorization", "Bearer " + token.value()) + .header("Content-Type", "application/json") + .header("Accept", "application/json") + .POST(HttpRequest.BodyPublishers.ofString(json)) + .timeout(Duration.ofSeconds(10)) + .build(); + return send(request); + } + + public T get(String uri, Class responseType) throws ControlPlaneException { + JsonObject body = get(uri); + return GSON.fromJson(extractData(body), responseType); + } + + public java.util.List getList(String uri, Class elementType) throws ControlPlaneException { + JsonObject body = get(uri); + Type listType = TypeToken.getParameterized(java.util.List.class, elementType).getType(); + return GSON.fromJson(extractData(body), listType); + } + + public T post(String uri, Object requestBody, Class responseType) throws ControlPlaneException { + JsonObject body = post(uri, requestBody); + return GSON.fromJson(extractData(body), responseType); + } + + private JsonObject send(HttpRequest request) throws ControlPlaneException { + HttpResponse response; + try { + response = httpClient.send(request, HttpResponse.BodyHandlers.ofString()); + } catch (IOException e) { + throw new ControlPlaneException("Network error communicating with control plane", e); + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + throw new ControlPlaneException("Request interrupted", e); + } + + int status = response.statusCode(); + String responseBody = response.body(); + + if (status >= 200 && status < 300) { + if (responseBody == null || responseBody.isBlank()) { + return new JsonObject(); + } + JsonElement element = JsonParser.parseString(responseBody); + return element.isJsonObject() ? element.getAsJsonObject() : new JsonObject(); + } + + if (status == 401 || status == 403) { + throw new AuthException(status, parseMessage(responseBody)); + } + if (status == 404) { + throw new NotFoundException(parseMessage(responseBody)); + } + if (status == 422) { + throw new ValidationException(parseMessage(responseBody), parseErrors(responseBody)); + } + if (status >= 500) { + throw new RemoteException(status, parseMessage(responseBody)); + } + + throw new ControlPlaneException("Unexpected response status " + status + ": " + responseBody); + } + + private JsonElement extractData(JsonObject envelope) { + if (envelope.has("data")) { + return envelope.get("data"); + } + return envelope; + } + + private String parseMessage(String body) { + try { + JsonObject obj = JsonParser.parseString(body).getAsJsonObject(); + if (obj.has("message")) { + return obj.get("message").getAsString(); + } + } catch (Exception ignored) {} + return body; + } + + private Map parseErrors(String body) { + Map errors = new HashMap<>(); + try { + JsonObject obj = JsonParser.parseString(body).getAsJsonObject(); + if (obj.has("errors")) { + JsonObject errObj = obj.getAsJsonObject("errors"); + for (String key : errObj.keySet()) { + com.google.gson.JsonArray arr = errObj.getAsJsonArray(key); + String[] messages = new String[arr.size()]; + for (int i = 0; i < arr.size(); i++) { + messages[i] = arr.get(i).getAsString(); + } + errors.put(key, messages); + } + } + } catch (Exception ignored) {} + return errors; + } +} diff --git a/src/main/java/net/kewwbec/network/http/PathBuilder.java b/src/main/java/net/kewwbec/network/http/PathBuilder.java new file mode 100644 index 0000000..f96133c --- /dev/null +++ b/src/main/java/net/kewwbec/network/http/PathBuilder.java @@ -0,0 +1,19 @@ +package net.kewwbec.network.http; + +import java.util.Map; + +public final class PathBuilder { + private PathBuilder() {} + + public static String resolve(String uriTemplate, Map params) { + String result = uriTemplate; + for (Map.Entry entry : params.entrySet()) { + result = result.replace("{" + entry.getKey() + "}", entry.getValue()); + } + return result; + } + + public static String resolve(String uriTemplate, String paramName, String paramValue) { + return uriTemplate.replace("{" + paramName + "}", paramValue); + } +} diff --git a/src/main/java/net/kewwbec/network/models/players/PlayerEntitlement.java b/src/main/java/net/kewwbec/network/models/players/PlayerEntitlement.java new file mode 100644 index 0000000..68af40c --- /dev/null +++ b/src/main/java/net/kewwbec/network/models/players/PlayerEntitlement.java @@ -0,0 +1,49 @@ +package net.kewwbec.network.models.players; + +import com.google.gson.annotations.SerializedName; + +public final class PlayerEntitlement { + private String id; + private String status; + + @SerializedName("source_type") + private String sourceType; + + @SerializedName("granted_at") + private String grantedAt; + + @SerializedName("expires_at") + private String expiresAt; + + @SerializedName("revoked_at") + private String revokedAt; + + @SerializedName("revoked_reason") + private String revokedReason; + + private EntitlementDefinition definition; + + public String id() { return id; } + public String status() { return status; } + public String sourceType() { return sourceType; } + public String grantedAt() { return grantedAt; } + public String expiresAt() { return expiresAt; } + public String revokedAt() { return revokedAt; } + public String revokedReason() { return revokedReason; } + public EntitlementDefinition definition() { return definition; } + + public boolean isActive() { return "active".equals(status); } + public boolean isRevoked() { return "revoked".equals(status); } + + public static final class EntitlementDefinition { + private String id; + private String key; + private String type; + private String name; + + public String id() { return id; } + public String key() { return key; } + public String type() { return type; } + public String name() { return name; } + } +} diff --git a/src/main/java/net/kewwbec/network/models/players/PlayerSessionProfile.java b/src/main/java/net/kewwbec/network/models/players/PlayerSessionProfile.java new file mode 100644 index 0000000..5ac3924 --- /dev/null +++ b/src/main/java/net/kewwbec/network/models/players/PlayerSessionProfile.java @@ -0,0 +1,97 @@ +package net.kewwbec.network.models.players; + +import com.google.gson.annotations.SerializedName; + +import java.util.List; + +public final class PlayerSessionProfile { + private String id; + + @SerializedName("current_name") + private String currentName; + + @SerializedName("display_name") + private String displayName; + + private String status; + + @SerializedName("game_identity") + private GameIdentity gameIdentity; + + private List entitlements; + + @SerializedName("last_seen_at") + private String lastSeenAt; + + private SocialSummary social; + + public String id() { return id; } + public String currentName() { return currentName; } + public String displayName() { return displayName; } + public String status() { return status; } + public GameIdentity gameIdentity() { return gameIdentity; } + public List entitlements() { return entitlements != null ? entitlements : List.of(); } + public String lastSeenAt() { return lastSeenAt; } + public SocialSummary social() { return social; } + + public static final class GameIdentity { + private String provider; + + @SerializedName("player_id") + private String playerId; + + public String provider() { return provider; } + public String playerId() { return playerId; } + } + + public static final class SocialSummary { + @SerializedName("friends_count") + private int friendsCount; + + private GuildSummary guild; + private PartySummary party; + + public int friendsCount() { return friendsCount; } + public GuildSummary guild() { return guild; } + public PartySummary party() { return party; } + + public boolean isInGuild() { return guild != null; } + public boolean isInParty() { return party != null; } + } + + public static final class GuildSummary { + private String id; + private String slug; + private String name; + private String tag; + private String role; + + @SerializedName("member_count") + private int memberCount; + + public String id() { return id; } + public String slug() { return slug; } + public String name() { return name; } + public String tag() { return tag; } + public String role() { return role; } + public int memberCount() { return memberCount; } + } + + public static final class PartySummary { + private String id; + + @SerializedName("member_count") + private int memberCount; + + @SerializedName("max_members") + private int maxMembers; + + @SerializedName("is_leader") + private boolean isLeader; + + public String id() { return id; } + public int memberCount() { return memberCount; } + public int maxMembers() { return maxMembers; } + public boolean isLeader() { return isLeader; } + } +} diff --git a/src/main/java/net/kewwbec/network/models/server/HeartbeatPayload.java b/src/main/java/net/kewwbec/network/models/server/HeartbeatPayload.java new file mode 100644 index 0000000..082aa57 --- /dev/null +++ b/src/main/java/net/kewwbec/network/models/server/HeartbeatPayload.java @@ -0,0 +1,31 @@ +package net.kewwbec.network.models.server; + +import com.google.gson.annotations.SerializedName; + +public final class HeartbeatPayload { + private final String status; + + @SerializedName("current_players") + private final int currentPlayers; + + @SerializedName("max_players") + private final int maxPlayers; + + private HeartbeatPayload(String status, int currentPlayers, int maxPlayers) { + this.status = status; + this.currentPlayers = currentPlayers; + this.maxPlayers = maxPlayers; + } + + public static HeartbeatPayload running(int currentPlayers, int maxPlayers) { + return new HeartbeatPayload("running", currentPlayers, maxPlayers); + } + + public static HeartbeatPayload draining(int currentPlayers, int maxPlayers) { + return new HeartbeatPayload("draining", currentPlayers, maxPlayers); + } + + public String status() { return status; } + public int currentPlayers() { return currentPlayers; } + public int maxPlayers() { return maxPlayers; } +} diff --git a/src/main/java/net/kewwbec/network/models/server/PresenceState.java b/src/main/java/net/kewwbec/network/models/server/PresenceState.java new file mode 100644 index 0000000..0897b9b --- /dev/null +++ b/src/main/java/net/kewwbec/network/models/server/PresenceState.java @@ -0,0 +1,16 @@ +package net.kewwbec.network.models.server; + +public enum PresenceState { + LIVE, + STALE, + UNKNOWN; + + public static PresenceState fromString(String value) { + if (value == null) return UNKNOWN; + return switch (value.toLowerCase()) { + case "live" -> LIVE; + case "stale" -> STALE; + default -> UNKNOWN; + }; + } +} diff --git a/src/main/java/net/kewwbec/network/models/server/ReadinessState.java b/src/main/java/net/kewwbec/network/models/server/ReadinessState.java new file mode 100644 index 0000000..e5fabd3 --- /dev/null +++ b/src/main/java/net/kewwbec/network/models/server/ReadinessState.java @@ -0,0 +1,18 @@ +package net.kewwbec.network.models.server; + +public enum ReadinessState { + READY, + DRAINING, + STALE, + UNKNOWN; + + public static ReadinessState fromString(String value) { + if (value == null) return UNKNOWN; + return switch (value.toLowerCase()) { + case "ready" -> READY; + case "draining" -> DRAINING; + case "stale" -> STALE; + default -> UNKNOWN; + }; + } +} diff --git a/src/main/java/net/kewwbec/network/models/server/RegistrationPayload.java b/src/main/java/net/kewwbec/network/models/server/RegistrationPayload.java new file mode 100644 index 0000000..3c2ab4d --- /dev/null +++ b/src/main/java/net/kewwbec/network/models/server/RegistrationPayload.java @@ -0,0 +1,37 @@ +package net.kewwbec.network.models.server; + +import com.google.gson.annotations.SerializedName; + +public final class RegistrationPayload { + private final String status; + private final String host; + private final int port; + + @SerializedName("current_players") + private final int currentPlayers; + + @SerializedName("max_players") + private final int maxPlayers; + + private RegistrationPayload(String status, String host, int port, int currentPlayers, int maxPlayers) { + this.status = status; + this.host = host; + this.port = port; + this.currentPlayers = currentPlayers; + this.maxPlayers = maxPlayers; + } + + public static RegistrationPayload starting(String host, int port, int maxPlayers) { + return new RegistrationPayload("starting", host, port, 0, maxPlayers); + } + + public static RegistrationPayload running(String host, int port, int currentPlayers, int maxPlayers) { + return new RegistrationPayload("running", host, port, currentPlayers, maxPlayers); + } + + public String status() { return status; } + public String host() { return host; } + public int port() { return port; } + public int currentPlayers() { return currentPlayers; } + public int maxPlayers() { return maxPlayers; } +} diff --git a/src/main/java/net/kewwbec/network/models/server/ServerInstance.java b/src/main/java/net/kewwbec/network/models/server/ServerInstance.java new file mode 100644 index 0000000..642d702 --- /dev/null +++ b/src/main/java/net/kewwbec/network/models/server/ServerInstance.java @@ -0,0 +1,67 @@ +package net.kewwbec.network.models.server; + +import com.google.gson.annotations.SerializedName; + +public final class ServerInstance { + private String id; + private String slug; + private String status; + private String host; + private int port; + + @SerializedName("current_players") + private int currentPlayers; + + @SerializedName("max_players") + private int maxPlayers; + + @SerializedName("available_slots") + private int availableSlots; + + @SerializedName("has_capacity") + private boolean hasCapacity; + + @SerializedName("presence_state") + private String presenceStateRaw; + + @SerializedName("readiness_state") + private String readinessStateRaw; + + @SerializedName("accepting_players") + private boolean acceptingPlayers; + + @SerializedName("last_heartbeat_at") + private String lastHeartbeatAt; + + public String id() { return id; } + public String slug() { return slug; } + public String status() { return status; } + public String host() { return host; } + public int port() { return port; } + public int currentPlayers() { return currentPlayers; } + public int maxPlayers() { return maxPlayers; } + public int availableSlots() { return availableSlots; } + public boolean hasCapacity() { return hasCapacity; } + public boolean acceptingPlayers() { return acceptingPlayers; } + public String lastHeartbeatAt() { return lastHeartbeatAt; } + + public PresenceState presenceState() { + return PresenceState.fromString(presenceStateRaw); + } + + public ReadinessState readinessState() { + return ReadinessState.fromString(readinessStateRaw); + } + + public boolean isReady() { + return readinessState() == ReadinessState.READY; + } + + public boolean isDraining() { + return readinessState() == ReadinessState.DRAINING; + } + + public boolean isStale() { + return readinessState() == ReadinessState.STALE || presenceState() == PresenceState.STALE; + } +} diff --git a/src/main/java/net/kewwbec/network/models/server/ServerProfile.java b/src/main/java/net/kewwbec/network/models/server/ServerProfile.java new file mode 100644 index 0000000..70df1ff --- /dev/null +++ b/src/main/java/net/kewwbec/network/models/server/ServerProfile.java @@ -0,0 +1,32 @@ +package net.kewwbec.network.models.server; + +import com.google.gson.annotations.SerializedName; + +public final class ServerProfile { + @SerializedName("service_account") + private ServiceAccountSummary serviceAccount; + + @SerializedName("server_instance") + private ServerInstance serverInstance; + + public ServiceAccountSummary serviceAccount() { return serviceAccount; } + public ServerInstance serverInstance() { return serverInstance; } + + public boolean hasInstance() { return serverInstance != null; } + + public static final class ServiceAccountSummary { + private String id; + private String key; + private String name; + private String type; + + @SerializedName("last_used_at") + private String lastUsedAt; + + public String id() { return id; } + public String key() { return key; } + public String name() { return name; } + public String type() { return type; } + public String lastUsedAt() { return lastUsedAt; } + } +} diff --git a/src/main/java/net/kewwbec/network/network.java b/src/main/java/net/kewwbec/network/network.java index 3853bf9..f654390 100644 --- a/src/main/java/net/kewwbec/network/network.java +++ b/src/main/java/net/kewwbec/network/network.java @@ -3,7 +3,11 @@ package net.kewwbec.network; import net.kewwbec.network.generated.api.v1.ControlPlaneApiV1; public class network { - public ControlPlaneApiV1 controlPlane() { - return ControlPlaneApiV1.INSTANCE; - } + public ControlPlaneApiV1 controlPlane() { + return ControlPlaneApiV1.INSTANCE; + } + + public static ControlPlaneClient.Builder builder() { + return ControlPlaneClient.builder(); + } } diff --git a/src/main/resources/manifest.json b/src/main/resources/manifest.json index c39edab..f512551 100644 --- a/src/main/resources/manifest.json +++ b/src/main/resources/manifest.json @@ -1,22 +1,18 @@ { - "Group": "Example", - "Name": "ExamplePlugin", + "Group": "net.kewwbec", + "Name": "core-network", "Version": "0.0.2", - "Description": "An example plugin for HyTale!", + "Description": "KweebecNetwork control-plane SDK for Hytale server plugins", "Authors": [ { - "Name": "It's you!" + "Name": "KweebecNetwork" } ], - "Website": "example.org", + "Website": "https://kewwbec.net", "ServerVersion": "2026.02.17-255364b8e", - "Dependencies": { - - }, - "OptionalDependencies": { - - }, + "Dependencies": {}, + "OptionalDependencies": {}, "DisabledByDefault": false, - "Main": "org.example.plugin.ExamplePlugin", - "IncludesAssetPack": true -} \ No newline at end of file + "Main": "net.kewwbec.network.NetworkPlugin", + "IncludesAssetPack": false +}