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
This commit is contained in:
+2
-1
@@ -61,4 +61,5 @@ desktop.ini
|
||||
# Template specific
|
||||
libs/HytaleServer.jar
|
||||
buildSrc/
|
||||
.github/
|
||||
.github/
|
||||
src/main/java/net/kewwbec/network/generated/
|
||||
+9
-5
@@ -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 {
|
||||
|
||||
+1
-1
@@ -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.
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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[***]";
|
||||
}
|
||||
}
|
||||
@@ -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<PlayerEntitlement> getEntitlements(String playerId) throws ControlPlaneException {
|
||||
String uri = PathBuilder.resolve(EntitlementsIndexEndpoint.VALUE.uri(), "player", playerId);
|
||||
return http.getList(uri, PlayerEntitlement.class);
|
||||
}
|
||||
}
|
||||
@@ -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) {}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
package net.kewwbec.network.errors;
|
||||
|
||||
public final class NotFoundException extends ControlPlaneException {
|
||||
public NotFoundException(String message) {
|
||||
super("Not found: " + message);
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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<String, String[]> errors;
|
||||
|
||||
public ValidationException(String message, Map<String, String[]> errors) {
|
||||
super("Validation failed: " + message);
|
||||
this.errors = Collections.unmodifiableMap(errors);
|
||||
}
|
||||
|
||||
public Map<String, String[]> errors() {
|
||||
return errors;
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
+5
@@ -7,6 +7,7 @@ public final class InfrastructureApi {
|
||||
public static final InfrastructureApi INSTANCE = new InfrastructureApi();
|
||||
|
||||
private static final List<ApiEndpoint> 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;
|
||||
}
|
||||
|
||||
+1
-1
@@ -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))
|
||||
)
|
||||
;
|
||||
|
||||
+1
-1
@@ -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))
|
||||
)
|
||||
;
|
||||
|
||||
+1
-1
@@ -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))
|
||||
)
|
||||
;
|
||||
|
||||
@@ -7,12 +7,30 @@ public final class PlayersApi {
|
||||
public static final PlayersApi INSTANCE = new PlayersApi();
|
||||
|
||||
private static final List<ApiEndpoint> 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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,8 +7,11 @@ public final class ServerApi {
|
||||
public static final ServerApi INSTANCE = new ServerApi();
|
||||
|
||||
private static final List<ApiEndpoint> 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;
|
||||
}
|
||||
|
||||
+21
-1
@@ -7,10 +7,14 @@ public final class ServiceAccountsApi {
|
||||
public static final ServiceAccountsApi INSTANCE = new ServiceAccountsApi();
|
||||
|
||||
private static final List<ApiEndpoint> 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;
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -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))
|
||||
)
|
||||
;
|
||||
|
||||
+1
-1
@@ -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))
|
||||
)
|
||||
;
|
||||
|
||||
@@ -7,6 +7,8 @@ public final class SocialApi {
|
||||
public static final SocialApi INSTANCE = new SocialApi();
|
||||
|
||||
private static final List<ApiEndpoint> 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;
|
||||
}
|
||||
|
||||
@@ -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> T get(String uri, Class<T> responseType) throws ControlPlaneException {
|
||||
JsonObject body = get(uri);
|
||||
return GSON.fromJson(extractData(body), responseType);
|
||||
}
|
||||
|
||||
public <T> java.util.List<T> getList(String uri, Class<T> 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> T post(String uri, Object requestBody, Class<T> responseType) throws ControlPlaneException {
|
||||
JsonObject body = post(uri, requestBody);
|
||||
return GSON.fromJson(extractData(body), responseType);
|
||||
}
|
||||
|
||||
private JsonObject send(HttpRequest request) throws ControlPlaneException {
|
||||
HttpResponse<String> 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<String, String[]> parseErrors(String body) {
|
||||
Map<String, String[]> 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;
|
||||
}
|
||||
}
|
||||
@@ -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<String, String> params) {
|
||||
String result = uriTemplate;
|
||||
for (Map.Entry<String, String> 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);
|
||||
}
|
||||
}
|
||||
@@ -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; }
|
||||
}
|
||||
}
|
||||
@@ -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<PlayerEntitlement> 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<PlayerEntitlement> 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; }
|
||||
}
|
||||
}
|
||||
@@ -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; }
|
||||
}
|
||||
@@ -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;
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -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; }
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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; }
|
||||
}
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
"Main": "net.kewwbec.network.NetworkPlugin",
|
||||
"IncludesAssetPack": false
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user