SessionServiceClient class

Пакет: com.hypixel.hytale.server.core.auth

Файл: com/hypixel/hytale/server/core/auth/SessionServiceClient.java

Поля (51)

МодификаторыТипИмя
public static final BuilderCodec<SessionServiceClient.AccessTokenResponse> CODEC
public static final BuilderCodec<SessionServiceClient.AuthGrantResponse> CODEC
public static final BuilderCodec<SessionServiceClient.GameProfile> CODEC
public static final BuilderCodec<SessionServiceClient.GameSessionResponse> CODEC
public static final BuilderCodec<SessionServiceClient.JwkKey> CODEC
public static final BuilderCodec<SessionServiceClient.JwksResponse> CODEC
public static final BuilderCodec<SessionServiceClient.LauncherDataResponse> CODEC
final HytaleLogger LOGGER
public String accessToken
public String alg
public String authorizationGrant
public String crv
public String e
public String expiresAt
public String identityToken
public SessionServiceClient.JwkKey[] keys
public String kid
public String kty
public String n
public UUID owner
public SessionServiceClient.GameProfile[] profiles
public String sessionToken
public String use
public String username
public UUID uuid
HttpRequest var1
HttpResponse var2
HttpRequest var2
HttpRequest var2
HttpRequest var2
SessionServiceClient.JwksResponse var3
HttpResponse var3
String var3
HttpResponse var3
HttpResponse var3
String var4
String var4
SessionServiceClient.LauncherDataResponse var4
HttpRequest var4
int var4
HttpRequest var5
HttpRequest var5
HttpResponse var5
SessionServiceClient.GameSessionResponse var5
HttpResponse var6
HttpResponse var6
SessionServiceClient.GameSessionResponse var6
SessionServiceClient.AuthGrantResponse var7
SessionServiceClient.AccessTokenResponse var7
public String x
public String y

Методы (23)

МодификаторыВозвратСигнатура
public AccessTokenResponsepublic AccessTokenResponse()
public AuthGrantResponsepublic AuthGrantResponse()
public GameProfilepublic GameProfile()
public GameSessionResponsepublic GameSessionResponse()
abstract throw new IllegalArgumentExceptionthrow new IllegalArgumentException("Session Service URL cannot be null or empty")
public JwkKeypublic JwkKey()
public JwksResponsepublic JwksResponse()
public LauncherDataResponsepublic LauncherDataResponse()
static String escapeJsonStringString escapeJsonString(String var0)
public CompletableFuture<String> exchangeAuthGrantForTokenAsyncCompletableFuture<String> exchangeAuthGrantForTokenAsync(@Nonnull String var1, @Nonnull String var2, @Nonnull String var3)
static <T> KeyedCodec<T> externalKey<T> KeyedCodec<T> externalKey(String var0, Codec<T> var1)
public Instant getExpiresAtInstantpublic Instant getExpiresAtInstant()
if if(var7 != null && var7.authorizationGrant != null)
if if(var7 != null && var7.accessToken != null)
if if(var3 != null && var3.keys != null && var3.keys.length != 0)
if if(var4 != null && var4.profiles != null)
if if(var6 != null && var6.identityToken != null)
if if(var4 != 200)
if if(var5 != null && var5.identityToken != null)
if if(this.expiresAt == null)
public CompletableFuture<SessionServiceClient.GameSessionResponse> refreshSessionAsyncCompletableFuture<SessionServiceClient.GameSessionResponse> refreshSessionAsync(@Nonnull String var1)
public CompletableFuture<String> requestAuthorizationGrantAsyncCompletableFuture<String> requestAuthorizationGrantAsync(@Nonnull String var1, @Nonnull String var2, @Nonnull String var3)
public void terminateSessionvoid terminateSession(@Nonnull String var1)

Исходный код

Показать/скрыть
class="kw">package com.hypixel.hytale.server.core.auth;

class="kw">import com.hypixel.hytale.codec.Codec;
class="kw">import com.hypixel.hytale.codec.EmptyExtraInfo;
class="kw">import com.hypixel.hytale.codec.KeyedCodec;
class="kw">import com.hypixel.hytale.codec.builder.BuilderCodec;
class="kw">import com.hypixel.hytale.codec.codecs.array.ArrayCodec;
class="kw">import com.hypixel.hytale.codec.util.RawJsonReader;
class="kw">import com.hypixel.hytale.logger.HytaleLogger;
class="kw">import com.hypixel.hytale.server.core.util.ServiceHttpClientFactory;
class="kw">import com.hypixel.hytale.sneakythrow.SneakyThrow;
class="kw">import java.io.IOException;
class="kw">import java.net.URI;
class="kw">import java.net.http.HttpClient;
class="kw">import java.net.http.HttpRequest;
class="kw">import java.net.http.HttpResponse;
class="kw">import java.net.http.HttpRequest.BodyPublishers;
class="kw">import java.net.http.HttpResponse.BodyHandlers;
class="kw">import java.time.Instant;
class="kw">import java.util.UUID;
class="kw">import java.util.concurrent.CompletableFuture;
class="kw">import java.util.concurrent.ExecutorService;
class="kw">import java.util.concurrent.Executors;
class="kw">import java.util.logging.Level;
class="kw">import javax.annotation.Nonnull;
class="kw">import javax.annotation.Nullable;

class="kw">public class SessionServiceClient {
   class="kw">private class="kw">static class="kw">final HytaleLogger LOGGER = HytaleLogger.forEnclosingClass();
   class="kw">private class="kw">static class="kw">final ExecutorService HTTP_EXECUTOR = Executors.newVirtualThreadPerTaskExecutor();
   class="kw">private class="kw">final HttpClient httpClient;
   class="kw">private class="kw">final String sessionServiceUrl;

   class="kw">public SessionServiceClient(@Nonnull String var1) {
      if (var1 != null && !var1.isEmpty()) {
         this.sessionServiceUrl = var1.endsWith("/") ? var1.substring(0, var1.length() - 1) : var1;
         this.httpClient = ServiceHttpClientFactory.create(AuthConfig.HTTP_TIMEOUT);
         LOGGER.at(Level.INFO).log("Session Service client initialized for: %s", this.sessionServiceUrl);
      } else {
         throw new IllegalArgumentException("Session Service URL cannot be null or empty");
      }
   }

   class="kw">public CompletableFuture<String> requestAuthorizationGrantAsync(@Nonnull String var1, @Nonnull String var2, @Nonnull String var3) {
      class="kw">return CompletableFuture.supplyAsync(
         () -> {
            try {
               String var4 = String.format("{\"identityToken\":\"%s\",\"aud\":\"%s\"}", escapeJsonString(var1), escapeJsonString(var2));
               HttpRequest var5 = HttpRequest.newBuilder()
                  .uri(URI.create(this.sessionServiceUrl + "/server-join/auth-grant"))
                  .header("Content-Type", "application/json")
                  .header("Accept", "application/json")
                  .header("Authorization", "Bearer " + var3)
                  .header("User-Agent", AuthConfig.USER_AGENT)
                  .timeout(AuthConfig.HTTP_TIMEOUT)
                  .POST(BodyPublishers.ofString(var4))
                  .build();
               LOGGER.at(Level.INFO).log("Requesting authorization grant with identity token, aud='%s'", var2);
               HttpResponse var6 = this.httpClient.send(var5, BodyHandlers.ofString());
               if (var6.statusCode() != 200) {
                  LOGGER.at(Level.WARNING).log("Failed to request authorization grant: HTTP %d - %s", var6.statusCode(), var6.body());
                  class="kw">return null;
               } else {
                  SessionServiceClient.AuthGrantResponse var7 = SessionServiceClient.AuthGrantResponse.CODEC
                     .decodeJson(new RawJsonReader(var6.body().toCharArray()), EmptyExtraInfo.EMPTY);
                  if (var7 != null && var7.authorizationGrant != null) {
                     LOGGER.at(Level.INFO).log("Successfully obtained authorization grant");
                     class="kw">return var7.authorizationGrant;
                  } else {
                     LOGGER.at(Level.WARNING).log("Session Service response missing authorizationGrant field");
                     class="kw">return null;
                  }
               }
            } catch (IOException var8) {
               LOGGER.at(Level.WARNING).log("IO error while requesting authorization grant: %s", var8.getMessage());
               class="kw">return null;
            } catch (InterruptedException var9) {
               LOGGER.at(Level.WARNING).log("Request interrupted while obtaining authorization grant");
               Thread.currentThread().interrupt();
               class="kw">return null;
            } catch (Exception var10) {
               LOGGER.at(Level.WARNING).log("Unexpected error requesting authorization grant: %s", var10.getMessage());
               class="kw">return null;
            }
         },
         HTTP_EXECUTOR
      );
   }

   class="kw">public CompletableFuture<String> exchangeAuthGrantForTokenAsync(@Nonnull String var1, @Nonnull String var2, @Nonnull String var3) {
      class="kw">return CompletableFuture.supplyAsync(
         () -> {
            try {
               String var4 = String.format("{\"authorizationGrant\":\"%s\",\"x509Fingerprint\":\"%s\"}", escapeJsonString(var1), escapeJsonString(var2));
               HttpRequest var5 = HttpRequest.newBuilder()
                  .uri(URI.create(this.sessionServiceUrl + "/server-join/auth-token"))
                  .header("Content-Type", "application/json")
                  .header("Accept", "application/json")
                  .header("Authorization", "Bearer " + var3)
                  .header("User-Agent", AuthConfig.USER_AGENT)
                  .timeout(AuthConfig.HTTP_TIMEOUT)
                  .POST(BodyPublishers.ofString(var4))
                  .build();
               LOGGER.at(Level.INFO).log("Exchanging authorization grant for access token");
               LOGGER.at(Level.FINE).log("Using bearer token (first 20 chars): %s...", var3.length() > 20 ? var3.substring(0, 20) : var3);
               LOGGER.at(Level.FINE).log("Request body: %s", var4);
               HttpResponse var6 = this.httpClient.send(var5, BodyHandlers.ofString());
               if (var6.statusCode() != 200) {
                  LOGGER.at(Level.WARNING).log("Failed to exchange auth grant: HTTP %d - %s", var6.statusCode(), var6.body());
                  class="kw">return null;
               } else {
                  SessionServiceClient.AccessTokenResponse var7 = SessionServiceClient.AccessTokenResponse.CODEC
                     .decodeJson(new RawJsonReader(var6.body().toCharArray()), EmptyExtraInfo.EMPTY);
                  if (var7 != null && var7.accessToken != null) {
                     LOGGER.at(Level.INFO).log("Successfully obtained access token");
                     class="kw">return var7.accessToken;
                  } else {
                     LOGGER.at(Level.WARNING).log("Session Service response missing accessToken field");
                     class="kw">return null;
                  }
               }
            } catch (IOException var8) {
               LOGGER.at(Level.WARNING).log("IO error while exchanging auth grant: %s", var8.getMessage());
               class="kw">return null;
            } catch (InterruptedException var9) {
               LOGGER.at(Level.WARNING).log("Request interrupted while exchanging auth grant");
               Thread.currentThread().interrupt();
               class="kw">return null;
            } catch (Exception var10) {
               LOGGER.at(Level.WARNING).log("Unexpected error exchanging auth grant: %s", var10.getMessage());
               class="kw">return null;
            }
         },
         HTTP_EXECUTOR
      );
   }

   @Nullable
   class="kw">public SessionServiceClient.JwksResponse getJwks() {
      try {
         HttpRequest var1 = HttpRequest.newBuilder()
            .uri(URI.create(this.sessionServiceUrl + "/.well-known/jwks.json"))
            .header("Accept", "application/json")
            .header("User-Agent", AuthConfig.USER_AGENT)
            .timeout(AuthConfig.HTTP_TIMEOUT)
            .GET()
            .build();
         LOGGER.at(Level.FINE).log("Fetching JWKS from Session Service");
         HttpResponse var2 = this.httpClient.send(var1, BodyHandlers.ofString());
         if (var2.statusCode() != 200) {
            LOGGER.at(Level.WARNING).log("Failed to fetch JWKS: HTTP %d - %s", var2.statusCode(), var2.body());
            class="kw">return null;
         } else {
            SessionServiceClient.JwksResponse var3 = SessionServiceClient.JwksResponse.CODEC
               .decodeJson(new RawJsonReader(var2.body().toCharArray()), EmptyExtraInfo.EMPTY);
            if (var3 != null && var3.keys != null && var3.keys.length != 0) {
               LOGGER.at(Level.INFO).log("Successfully fetched JWKS with %d keys", var3.keys.length);
               class="kw">return var3;
            } else {
               LOGGER.at(Level.WARNING).log("Session Service returned invalid JWKS (no keys)");
               class="kw">return null;
            }
         }
      } catch (IOException var4) {
         LOGGER.at(Level.WARNING).log("IO error while fetching JWKS: %s", var4.getMessage());
         class="kw">return null;
      } catch (InterruptedException var5) {
         LOGGER.at(Level.WARNING).log("Request interrupted while fetching JWKS");
         Thread.currentThread().interrupt();
         class="kw">return null;
      } catch (Exception var6) {
         LOGGER.at(Level.WARNING).log("Unexpected error fetching JWKS: %s", var6.getMessage());
         class="kw">return null;
      }
   }

   @Nullable
   class="kw">public SessionServiceClient.GameProfile[] getGameProfiles(@Nonnull String var1) {
      try {
         HttpRequest var2 = HttpRequest.newBuilder()
            .uri(URI.create("https://account-data.hytale.com/my-account/get-profiles"))
            .header("Accept", "application/json")
            .header("Authorization", "Bearer " + var1)
            .header("User-Agent", AuthConfig.USER_AGENT)
            .timeout(AuthConfig.HTTP_TIMEOUT)
            .GET()
            .build();
         LOGGER.at(Level.INFO).log("Fetching game profiles...");
         HttpResponse var3 = this.httpClient.send(var2, BodyHandlers.ofString());
         if (var3.statusCode() != 200) {
            LOGGER.at(Level.WARNING).log("Failed to fetch profiles: HTTP %d - %s", var3.statusCode(), var3.body());
            class="kw">return null;
         } else {
            SessionServiceClient.LauncherDataResponse var4 = SessionServiceClient.LauncherDataResponse.CODEC
               .decodeJson(new RawJsonReader(var3.body().toCharArray()), EmptyExtraInfo.EMPTY);
            if (var4 != null && var4.profiles != null) {
               LOGGER.at(Level.INFO).log("Found %d game profile(s)", var4.profiles.length);
               class="kw">return var4.profiles;
            } else {
               LOGGER.at(Level.WARNING).log("Account Data returned invalid response");
               class="kw">return null;
            }
         }
      } catch (IOException var5) {
         LOGGER.at(Level.WARNING).log("IO error while fetching profiles: %s", var5.getMessage());
         class="kw">return null;
      } catch (InterruptedException var6) {
         LOGGER.at(Level.WARNING).log("Request interrupted while fetching profiles");
         Thread.currentThread().interrupt();
         class="kw">return null;
      } catch (Exception var7) {
         LOGGER.at(Level.WARNING).log("Unexpected error fetching profiles: %s", var7.getMessage());
         class="kw">return null;
      }
   }

   @Nullable
   class="kw">public SessionServiceClient.GameSessionResponse createGameSession(@Nonnull String var1, @Nonnull UUID var2) {
      try {
         String var3 = String.format("{\"uuid\":\"%s\"}", var2.toString());
         HttpRequest var4 = HttpRequest.newBuilder()
            .uri(URI.create(this.sessionServiceUrl + "/game-session/new"))
            .header("Content-Type", "application/json")
            .header("Authorization", "Bearer " + var1)
            .header("User-Agent", AuthConfig.USER_AGENT)
            .timeout(AuthConfig.HTTP_TIMEOUT)
            .POST(BodyPublishers.ofString(var3))
            .build();
         LOGGER.at(Level.INFO).log("Creating game session...");
         HttpResponse var5 = this.httpClient.send(var4, BodyHandlers.ofString());
         if (var5.statusCode() != 200 && var5.statusCode() != 201) {
            LOGGER.at(Level.WARNING).log("Failed to create game session: HTTP %d - %s", var5.statusCode(), var5.body());
            class="kw">return null;
         } else {
            SessionServiceClient.GameSessionResponse var6 = SessionServiceClient.GameSessionResponse.CODEC
               .decodeJson(new RawJsonReader(var5.body().toCharArray()), EmptyExtraInfo.EMPTY);
            if (var6 != null && var6.identityToken != null) {
               LOGGER.at(Level.INFO).log("Successfully created game session");
               class="kw">return var6;
            } else {
               LOGGER.at(Level.WARNING).log("Session Service returned invalid response");
               class="kw">return null;
            }
         }
      } catch (IOException var7) {
         LOGGER.at(Level.WARNING).log("IO error while creating session: %s", var7.getMessage());
         class="kw">return null;
      } catch (InterruptedException var8) {
         LOGGER.at(Level.WARNING).log("Request interrupted while creating session");
         Thread.currentThread().interrupt();
         class="kw">return null;
      } catch (Exception var9) {
         LOGGER.at(Level.WARNING).log("Unexpected error creating session: %s", var9.getMessage());
         class="kw">return null;
      }
   }

   class="kw">public CompletableFuture<SessionServiceClient.GameSessionResponse> refreshSessionAsync(@Nonnull String var1) {
      class="kw">return CompletableFuture.supplyAsync(
         () -> {
            try {
               HttpRequest var2 = HttpRequest.newBuilder()
                  .uri(URI.create(this.sessionServiceUrl + "/game-session/refresh"))
                  .header("Accept", "application/json")
                  .header("Authorization", "Bearer " + var1)
                  .header("User-Agent", AuthConfig.USER_AGENT)
                  .timeout(AuthConfig.HTTP_TIMEOUT)
                  .POST(BodyPublishers.noBody())
                  .build();
               LOGGER.at(Level.INFO).log("Refreshing game session...");
               HttpResponse var3 = this.httpClient.send(var2, BodyHandlers.ofString());
               int var4 = var3.statusCode();
               if (var4 != 200) {
                  LOGGER.at(Level.WARNING).log("Failed to refresh session: HTTP %d - %s", var4, var3.body());
                  if (!AuthConfig.isRejectedStatusCode(var4)) {
                     throw new HttpResponseException(var4, var3.body());
                  } else {
                     class="kw">return null;
                  }
               } else {
                  SessionServiceClient.GameSessionResponse var5 = SessionServiceClient.GameSessionResponse.CODEC
                     .decodeJson(new RawJsonReader(var3.body().toCharArray()), EmptyExtraInfo.EMPTY);
                  if (var5 != null && var5.identityToken != null) {
                     LOGGER.at(Level.INFO).log("Successfully refreshed game session");
                     class="kw">return var5;
                  } else {
                     LOGGER.at(Level.WARNING).log("Session Service returned invalid response (missing identity token)");
                     class="kw">return null;
                  }
               }
            } catch (IOException var6) {
               LOGGER.at(Level.WARNING).log("IO error while refreshing session: %s", var6.getMessage());
               throw SneakyThrow.sneakyThrow(var6);
            } catch (InterruptedException var7) {
               LOGGER.at(Level.WARNING).log("Request interrupted while refreshing session");
               Thread.currentThread().interrupt();
               class="kw">return null;
            } catch (Exception var8) {
               LOGGER.at(Level.WARNING).log("Unexpected error refreshing session: %s", var8.getMessage());
               class="kw">return null;
            }
         },
         HTTP_EXECUTOR
      );
   }

   class="kw">public void terminateSession(@Nonnull String var1) {
      if (var1 != null && !var1.isEmpty()) {
         try {
            HttpRequest var2 = HttpRequest.newBuilder()
               .uri(URI.create(this.sessionServiceUrl + "/game-session"))
               .header("Authorization", "Bearer " + var1)
               .header("User-Agent", AuthConfig.USER_AGENT)
               .timeout(AuthConfig.HTTP_TIMEOUT)
               .DELETE()
               .build();
            LOGGER.at(Level.INFO).log("Terminating game session...");
            HttpResponse var3 = this.httpClient.send(var2, BodyHandlers.ofString());
            if (var3.statusCode() != 200 && var3.statusCode() != 204) {
               LOGGER.at(Level.WARNING).log("Failed to terminate session: HTTP %d - %s", var3.statusCode(), var3.body());
            } else {
               LOGGER.at(Level.INFO).log("Game session terminated");
            }
         } catch (IOException var4) {
            LOGGER.at(Level.WARNING).log("IO error while terminating session: %s", var4.getMessage());
         } catch (InterruptedException var5) {
            LOGGER.at(Level.WARNING).log("Request interrupted while terminating session");
            Thread.currentThread().interrupt();
         } catch (Exception var6) {
            LOGGER.at(Level.WARNING).log("Error terminating session: %s", var6.getMessage());
         }
      }
   }

   class="kw">private class="kw">static String escapeJsonString(String var0) {
      class="kw">return var0 == null ? "" : var0.replace("\\", "\\\\").replace("\"", "\\\"").replace("\n", "\\n").replace("\r", "\\r").replace("\t", "\\t");
   }

   class="kw">private class="kw">static <T> KeyedCodec<T> externalKey(String var0, Codec<T> var1) {
      class="kw">return new KeyedCodec<>(var0, var1, false, true);
   }

   class="kw">public class="kw">static class AccessTokenResponse {
      class="kw">public String accessToken;
      class="kw">public class="kw">static class="kw">final BuilderCodec<SessionServiceClient.AccessTokenResponse> CODEC = BuilderCodec.builder(
            SessionServiceClient.AccessTokenResponse.class, SessionServiceClient.AccessTokenResponse::new
         )
         .append(SessionServiceClient.externalKey("accessToken", Codec.STRING), (var0, var1) -> var0.accessToken = var1, var0 -> var0.accessToken)
         .add()
         .build();

      class="kw">public AccessTokenResponse() {
      }
   }

   class="kw">public class="kw">static class AuthGrantResponse {
      class="kw">public String authorizationGrant;
      class="kw">public class="kw">static class="kw">final BuilderCodec<SessionServiceClient.AuthGrantResponse> CODEC = BuilderCodec.builder(
            SessionServiceClient.AuthGrantResponse.class, SessionServiceClient.AuthGrantResponse::new
         )
         .append(
            SessionServiceClient.externalKey("authorizationGrant", Codec.STRING),
            (var0, var1) -> var0.authorizationGrant = var1,
            var0 -> var0.authorizationGrant
         )
         .add()
         .build();

      class="kw">public AuthGrantResponse() {
      }
   }

   class="kw">public class="kw">static class GameProfile {
      class="kw">public UUID uuid;
      class="kw">public String username;
      class="kw">public class="kw">static class="kw">final BuilderCodec<SessionServiceClient.GameProfile> CODEC = BuilderCodec.builder(
            SessionServiceClient.GameProfile.class, SessionServiceClient.GameProfile::new
         )
         .append(SessionServiceClient.externalKey("uuid", Codec.UUID_STRING), (var0, var1) -> var0.uuid = var1, var0 -> var0.uuid)
         .add()
         .append(SessionServiceClient.externalKey("username", Codec.STRING), (var0, var1) -> var0.username = var1, var0 -> var0.username)
         .add()
         .build();

      class="kw">public GameProfile() {
      }
   }

   class="kw">public class="kw">static class GameSessionResponse {
      class="kw">public String sessionToken;
      class="kw">public String identityToken;
      class="kw">public String expiresAt;
      class="kw">public class="kw">static class="kw">final BuilderCodec<SessionServiceClient.GameSessionResponse> CODEC = BuilderCodec.builder(
            SessionServiceClient.GameSessionResponse.class, SessionServiceClient.GameSessionResponse::new
         )
         .append(SessionServiceClient.externalKey("sessionToken", Codec.STRING), (var0, var1) -> var0.sessionToken = var1, var0 -> var0.sessionToken)
         .add()
         .append(SessionServiceClient.externalKey("identityToken", Codec.STRING), (var0, var1) -> var0.identityToken = var1, var0 -> var0.identityToken)
         .add()
         .append(SessionServiceClient.externalKey("expiresAt", Codec.STRING), (var0, var1) -> var0.expiresAt = var1, var0 -> var0.expiresAt)
         .add()
         .build();

      class="kw">public GameSessionResponse() {
      }

      @Nullable
      class="kw">public Instant getExpiresAtInstant() {
         if (this.expiresAt == null) {
            class="kw">return null;
         }

         try {
            class="kw">return Instant.parse(this.expiresAt);
         } catch (Exception var2) {
            class="kw">return null;
         }
      }
   }

   class="kw">public class="kw">static class JwkKey {
      class="kw">public String kty;
      class="kw">public String alg;
      class="kw">public String use;
      class="kw">public String kid;
      class="kw">public String crv;
      class="kw">public String x;
      class="kw">public String y;
      class="kw">public String n;
      class="kw">public String e;
      class="kw">public class="kw">static class="kw">final BuilderCodec<SessionServiceClient.JwkKey> CODEC = BuilderCodec.builder(
            SessionServiceClient.JwkKey.class, SessionServiceClient.JwkKey::new
         )
         .append(SessionServiceClient.externalKey("kty", Codec.STRING), (var0, var1) -> var0.kty = var1, var0 -> var0.kty)
         .add()
         .append(SessionServiceClient.externalKey("alg", Codec.STRING), (var0, var1) -> var0.alg = var1, var0 -> var0.alg)
         .add()
         .append(SessionServiceClient.externalKey("use", Codec.STRING), (var0, var1) -> var0.use = var1, var0 -> var0.use)
         .add()
         .append(SessionServiceClient.externalKey("kid", Codec.STRING), (var0, var1) -> var0.kid = var1, var0 -> var0.kid)
         .add()
         .append(SessionServiceClient.externalKey("crv", Codec.STRING), (var0, var1) -> var0.crv = var1, var0 -> var0.crv)
         .add()
         .append(SessionServiceClient.externalKey("x", Codec.STRING), (var0, var1) -> var0.x = var1, var0 -> var0.x)
         .add()
         .append(SessionServiceClient.externalKey("y", Codec.STRING), (var0, var1) -> var0.y = var1, var0 -> var0.y)
         .add()
         .append(SessionServiceClient.externalKey("n", Codec.STRING), (var0, var1) -> var0.n = var1, var0 -> var0.n)
         .add()
         .append(SessionServiceClient.externalKey("e", Codec.STRING), (var0, var1) -> var0.e = var1, var0 -> var0.e)
         .add()
         .build();

      class="kw">public JwkKey() {
      }
   }

   class="kw">public class="kw">static class JwksResponse {
      class="kw">public SessionServiceClient.JwkKey[] keys;
      class="kw">public class="kw">static class="kw">final BuilderCodec<SessionServiceClient.JwksResponse> CODEC = BuilderCodec.builder(
            SessionServiceClient.JwksResponse.class, SessionServiceClient.JwksResponse::new
         )
         .append(
            SessionServiceClient.externalKey("keys", new ArrayCodec<>(SessionServiceClient.JwkKey.CODEC, SessionServiceClient.JwkKey[]::new)),
            (var0, var1) -> var0.keys = var1,
            var0 -> var0.keys
         )
         .add()
         .build();

      class="kw">public JwksResponse() {
      }
   }

   class="kw">public class="kw">static class LauncherDataResponse {
      class="kw">public UUID owner;
      class="kw">public SessionServiceClient.GameProfile[] profiles;
      class="kw">public class="kw">static class="kw">final BuilderCodec<SessionServiceClient.LauncherDataResponse> CODEC = BuilderCodec.builder(
            SessionServiceClient.LauncherDataResponse.class, SessionServiceClient.LauncherDataResponse::new
         )
         .append(SessionServiceClient.externalKey("owner", Codec.UUID_STRING), (var0, var1) -> var0.owner = var1, var0 -> var0.owner)
         .add()
         .append(
            SessionServiceClient.externalKey("profiles", new ArrayCodec<>(SessionServiceClient.GameProfile.CODEC, SessionServiceClient.GameProfile[]::new)),
            (var0, var1) -> var0.profiles = var1,
            var0 -> var0.profiles
         )
         .add()
         .build();

      class="kw">public LauncherDataResponse() {
      }
   }
}