// 
// Decompiled by Procyon v0.6.0
// 

package com.hypixel.hytale.server.core.auth;

import com.hypixel.hytale.codec.codecs.array.ArrayCodec;
import java.time.Instant;
import com.hypixel.hytale.codec.builder.BuilderCodec;
import com.hypixel.hytale.codec.KeyedCodec;
import com.hypixel.hytale.codec.Codec;
import java.util.UUID;
import javax.annotation.Nullable;
import java.io.IOException;
import com.hypixel.hytale.codec.ExtraInfo;
import com.hypixel.hytale.codec.EmptyExtraInfo;
import com.hypixel.hytale.codec.util.RawJsonReader;
import java.net.http.HttpResponse;
import java.net.URI;
import java.net.http.HttpRequest;
import java.util.concurrent.CompletableFuture;
import java.util.logging.Level;
import javax.annotation.Nonnull;
import java.net.http.HttpClient;
import java.time.Duration;
import com.hypixel.hytale.logger.HytaleLogger;

public class SessionServiceClient
{
    private static final HytaleLogger LOGGER;
    private static final Duration REQUEST_TIMEOUT;
    private final HttpClient httpClient;
    private final String sessionServiceUrl;
    
    public SessionServiceClient(@Nonnull final String sessionServiceUrl) {
        if (sessionServiceUrl == null || sessionServiceUrl.isEmpty()) {
            throw new IllegalArgumentException("Session Service URL cannot be null or empty");
        }
        this.sessionServiceUrl = (sessionServiceUrl.endsWith("/") ? sessionServiceUrl.substring(0, sessionServiceUrl.length() - 1) : sessionServiceUrl);
        this.httpClient = HttpClient.newBuilder().connectTimeout(SessionServiceClient.REQUEST_TIMEOUT).build();
        SessionServiceClient.LOGGER.at(Level.INFO).log("Session Service client initialized for: %s", this.sessionServiceUrl);
    }
    
    public CompletableFuture<String> requestAuthorizationGrantAsync(@Nonnull final String identityToken, @Nonnull final String serverAudience, @Nonnull final String bearerToken) {
        return CompletableFuture.supplyAsync(() -> {
            try {
                final String jsonBody = String.format("{\"identityToken\":\"%s\",\"aud\":\"%s\"}", escapeJsonString(identityToken), escapeJsonString(serverAudience));
                final HttpRequest request = HttpRequest.newBuilder().uri(URI.create(this.sessionServiceUrl + "/server-join/auth-grant")).header("Content-Type", "application/json").header("Accept", "application/json").header("Authorization", "Bearer " + bearerToken).header("User-Agent", AuthConfig.USER_AGENT).timeout(SessionServiceClient.REQUEST_TIMEOUT).POST(HttpRequest.BodyPublishers.ofString(jsonBody)).build();
                SessionServiceClient.LOGGER.at(Level.INFO).log("Requesting authorization grant with identity token, aud='%s'", serverAudience);
                final HttpResponse<String> response = this.httpClient.send(request, HttpResponse.BodyHandlers.ofString());
                if (response.statusCode() != 200) {
                    SessionServiceClient.LOGGER.at(Level.WARNING).log("Failed to request authorization grant: HTTP %d - %s", response.statusCode(), response.body());
                    return null;
                }
                else {
                    final AuthGrantResponse authGrantResponse = AuthGrantResponse.CODEC.decodeJson(new RawJsonReader(response.body().toCharArray()), EmptyExtraInfo.EMPTY);
                    if (authGrantResponse == null || authGrantResponse.authorizationGrant == null) {
                        SessionServiceClient.LOGGER.at(Level.WARNING).log("Session Service response missing authorizationGrant field");
                        return null;
                    }
                    else {
                        SessionServiceClient.LOGGER.at(Level.INFO).log("Successfully obtained authorization grant");
                        return authGrantResponse.authorizationGrant;
                    }
                }
            }
            catch (final IOException e) {
                SessionServiceClient.LOGGER.at(Level.WARNING).log("IO error while requesting authorization grant: %s", e.getMessage());
                return null;
            }
            catch (final InterruptedException e2) {
                SessionServiceClient.LOGGER.at(Level.WARNING).log("Request interrupted while obtaining authorization grant");
                Thread.currentThread().interrupt();
                return null;
            }
            catch (final Exception e3) {
                SessionServiceClient.LOGGER.at(Level.WARNING).log("Unexpected error requesting authorization grant: %s", e3.getMessage());
                return null;
            }
        });
    }
    
    public CompletableFuture<String> exchangeAuthGrantForTokenAsync(@Nonnull final String authorizationGrant, @Nonnull final String x509Fingerprint, @Nonnull final String bearerToken) {
        return CompletableFuture.supplyAsync(() -> {
            try {
                final String jsonBody = String.format("{\"authorizationGrant\":\"%s\",\"x509Fingerprint\":\"%s\"}", escapeJsonString(authorizationGrant), escapeJsonString(x509Fingerprint));
                final HttpRequest request = HttpRequest.newBuilder().uri(URI.create(this.sessionServiceUrl + "/server-join/auth-token")).header("Content-Type", "application/json").header("Accept", "application/json").header("Authorization", "Bearer " + bearerToken).header("User-Agent", AuthConfig.USER_AGENT).timeout(SessionServiceClient.REQUEST_TIMEOUT).POST(HttpRequest.BodyPublishers.ofString(jsonBody)).build();
                SessionServiceClient.LOGGER.at(Level.INFO).log("Exchanging authorization grant for access token");
                SessionServiceClient.LOGGER.at(Level.FINE).log("Using bearer token (first 20 chars): %s...", (bearerToken.length() > 20) ? bearerToken.substring(0, 20) : bearerToken);
                SessionServiceClient.LOGGER.at(Level.FINE).log("Request body: %s", jsonBody);
                final HttpResponse<String> response = this.httpClient.send(request, HttpResponse.BodyHandlers.ofString());
                if (response.statusCode() != 200) {
                    SessionServiceClient.LOGGER.at(Level.WARNING).log("Failed to exchange auth grant: HTTP %d - %s", response.statusCode(), response.body());
                    return null;
                }
                else {
                    final AccessTokenResponse tokenResponse = AccessTokenResponse.CODEC.decodeJson(new RawJsonReader(response.body().toCharArray()), EmptyExtraInfo.EMPTY);
                    if (tokenResponse == null || tokenResponse.accessToken == null) {
                        SessionServiceClient.LOGGER.at(Level.WARNING).log("Session Service response missing accessToken field");
                        return null;
                    }
                    else {
                        SessionServiceClient.LOGGER.at(Level.INFO).log("Successfully obtained access token");
                        return tokenResponse.accessToken;
                    }
                }
            }
            catch (final IOException e) {
                SessionServiceClient.LOGGER.at(Level.WARNING).log("IO error while exchanging auth grant: %s", e.getMessage());
                return null;
            }
            catch (final InterruptedException e2) {
                SessionServiceClient.LOGGER.at(Level.WARNING).log("Request interrupted while exchanging auth grant");
                Thread.currentThread().interrupt();
                return null;
            }
            catch (final Exception e3) {
                SessionServiceClient.LOGGER.at(Level.WARNING).log("Unexpected error exchanging auth grant: %s", e3.getMessage());
                return null;
            }
        });
    }
    
    @Nullable
    public JwksResponse getJwks() {
        try {
            final HttpRequest request = HttpRequest.newBuilder().uri(URI.create(this.sessionServiceUrl + "/.well-known/jwks.json")).header("Accept", "application/json").header("User-Agent", AuthConfig.USER_AGENT).timeout(SessionServiceClient.REQUEST_TIMEOUT).GET().build();
            SessionServiceClient.LOGGER.at(Level.FINE).log("Fetching JWKS from Session Service");
            final HttpResponse<String> response = this.httpClient.send(request, HttpResponse.BodyHandlers.ofString());
            if (response.statusCode() != 200) {
                SessionServiceClient.LOGGER.at(Level.WARNING).log("Failed to fetch JWKS: HTTP %d - %s", response.statusCode(), response.body());
                return null;
            }
            final JwksResponse jwks = JwksResponse.CODEC.decodeJson(new RawJsonReader(response.body().toCharArray()), EmptyExtraInfo.EMPTY);
            if (jwks == null || jwks.keys == null || jwks.keys.length == 0) {
                SessionServiceClient.LOGGER.at(Level.WARNING).log("Session Service returned invalid JWKS (no keys)");
                return null;
            }
            SessionServiceClient.LOGGER.at(Level.INFO).log("Successfully fetched JWKS with %d keys", jwks.keys.length);
            return jwks;
        }
        catch (final IOException e) {
            SessionServiceClient.LOGGER.at(Level.WARNING).log("IO error while fetching JWKS: %s", e.getMessage());
            return null;
        }
        catch (final InterruptedException e2) {
            SessionServiceClient.LOGGER.at(Level.WARNING).log("Request interrupted while fetching JWKS");
            Thread.currentThread().interrupt();
            return null;
        }
        catch (final Exception e3) {
            SessionServiceClient.LOGGER.at(Level.WARNING).log("Unexpected error fetching JWKS: %s", e3.getMessage());
            return null;
        }
    }
    
    @Nullable
    public GameProfile[] getGameProfiles(@Nonnull final String oauthAccessToken) {
        try {
            final HttpRequest request = HttpRequest.newBuilder().uri(URI.create("https://account-data.hytale.com/my-account/get-profiles")).header("Accept", "application/json").header("Authorization", "Bearer " + oauthAccessToken).header("User-Agent", AuthConfig.USER_AGENT).timeout(SessionServiceClient.REQUEST_TIMEOUT).GET().build();
            SessionServiceClient.LOGGER.at(Level.INFO).log("Fetching game profiles...");
            final HttpResponse<String> response = this.httpClient.send(request, HttpResponse.BodyHandlers.ofString());
            if (response.statusCode() != 200) {
                SessionServiceClient.LOGGER.at(Level.WARNING).log("Failed to fetch profiles: HTTP %d - %s", response.statusCode(), response.body());
                return null;
            }
            final LauncherDataResponse data = LauncherDataResponse.CODEC.decodeJson(new RawJsonReader(response.body().toCharArray()), EmptyExtraInfo.EMPTY);
            if (data == null || data.profiles == null) {
                SessionServiceClient.LOGGER.at(Level.WARNING).log("Account Data returned invalid response");
                return null;
            }
            SessionServiceClient.LOGGER.at(Level.INFO).log("Found %d game profile(s)", data.profiles.length);
            return data.profiles;
        }
        catch (final IOException e) {
            SessionServiceClient.LOGGER.at(Level.WARNING).log("IO error while fetching profiles: %s", e.getMessage());
            return null;
        }
        catch (final InterruptedException e2) {
            SessionServiceClient.LOGGER.at(Level.WARNING).log("Request interrupted while fetching profiles");
            Thread.currentThread().interrupt();
            return null;
        }
        catch (final Exception e3) {
            SessionServiceClient.LOGGER.at(Level.WARNING).log("Unexpected error fetching profiles: %s", e3.getMessage());
            return null;
        }
    }
    
    public GameSessionResponse createGameSession(@Nonnull final String oauthAccessToken, @Nonnull final UUID profileUuid) {
        try {
            final String body = String.format("{\"uuid\":\"%s\"}", profileUuid.toString());
            final HttpRequest request = HttpRequest.newBuilder().uri(URI.create(this.sessionServiceUrl + "/game-session/new")).header("Content-Type", "application/json").header("Authorization", "Bearer " + oauthAccessToken).header("User-Agent", AuthConfig.USER_AGENT).timeout(SessionServiceClient.REQUEST_TIMEOUT).POST(HttpRequest.BodyPublishers.ofString(body)).build();
            SessionServiceClient.LOGGER.at(Level.INFO).log("Creating game session...");
            final HttpResponse<String> response = this.httpClient.send(request, HttpResponse.BodyHandlers.ofString());
            if (response.statusCode() != 200 && response.statusCode() != 201) {
                SessionServiceClient.LOGGER.at(Level.WARNING).log("Failed to create game session: HTTP %d - %s", response.statusCode(), response.body());
                return null;
            }
            final GameSessionResponse sessionResponse = GameSessionResponse.CODEC.decodeJson(new RawJsonReader(response.body().toCharArray()), EmptyExtraInfo.EMPTY);
            if (sessionResponse == null || sessionResponse.identityToken == null) {
                SessionServiceClient.LOGGER.at(Level.WARNING).log("Session Service returned invalid response");
                return null;
            }
            SessionServiceClient.LOGGER.at(Level.INFO).log("Successfully created game session");
            return sessionResponse;
        }
        catch (final IOException e) {
            SessionServiceClient.LOGGER.at(Level.WARNING).log("IO error while creating session: %s", e.getMessage());
            return null;
        }
        catch (final InterruptedException e2) {
            SessionServiceClient.LOGGER.at(Level.WARNING).log("Request interrupted while creating session");
            Thread.currentThread().interrupt();
            return null;
        }
        catch (final Exception e3) {
            SessionServiceClient.LOGGER.at(Level.WARNING).log("Unexpected error creating session: %s", e3.getMessage());
            return null;
        }
    }
    
    public CompletableFuture<GameSessionResponse> refreshSessionAsync(@Nonnull final String sessionToken) {
        return CompletableFuture.supplyAsync(() -> {
            try {
                final HttpRequest request = HttpRequest.newBuilder().uri(URI.create(this.sessionServiceUrl + "/game-session/refresh")).header("Accept", "application/json").header("Authorization", "Bearer " + sessionToken).header("User-Agent", AuthConfig.USER_AGENT).timeout(SessionServiceClient.REQUEST_TIMEOUT).POST(HttpRequest.BodyPublishers.noBody()).build();
                SessionServiceClient.LOGGER.at(Level.INFO).log("Refreshing game session...");
                final HttpResponse<String> response = this.httpClient.send(request, HttpResponse.BodyHandlers.ofString());
                if (response.statusCode() != 200) {
                    SessionServiceClient.LOGGER.at(Level.WARNING).log("Failed to refresh session: HTTP %d - %s", response.statusCode(), response.body());
                    return null;
                }
                else {
                    final GameSessionResponse sessionResponse = GameSessionResponse.CODEC.decodeJson(new RawJsonReader(response.body().toCharArray()), EmptyExtraInfo.EMPTY);
                    if (sessionResponse == null || sessionResponse.identityToken == null) {
                        SessionServiceClient.LOGGER.at(Level.WARNING).log("Session Service returned invalid response (missing identity token)");
                        return null;
                    }
                    else {
                        SessionServiceClient.LOGGER.at(Level.INFO).log("Successfully refreshed game session");
                        return sessionResponse;
                    }
                }
            }
            catch (final IOException e) {
                SessionServiceClient.LOGGER.at(Level.WARNING).log("IO error while refreshing session: %s", e.getMessage());
                return null;
            }
            catch (final InterruptedException e2) {
                SessionServiceClient.LOGGER.at(Level.WARNING).log("Request interrupted while refreshing session");
                Thread.currentThread().interrupt();
                return null;
            }
            catch (final Exception e3) {
                SessionServiceClient.LOGGER.at(Level.WARNING).log("Unexpected error refreshing session: %s", e3.getMessage());
                return null;
            }
        });
    }
    
    public void terminateSession(@Nonnull final String sessionToken) {
        if (sessionToken == null || sessionToken.isEmpty()) {
            return;
        }
        try {
            final HttpRequest request = HttpRequest.newBuilder().uri(URI.create(this.sessionServiceUrl + "/game-session")).header("Authorization", "Bearer " + sessionToken).header("User-Agent", AuthConfig.USER_AGENT).timeout(SessionServiceClient.REQUEST_TIMEOUT).DELETE().build();
            SessionServiceClient.LOGGER.at(Level.INFO).log("Terminating game session...");
            final HttpResponse<String> response = this.httpClient.send(request, HttpResponse.BodyHandlers.ofString());
            if (response.statusCode() == 200 || response.statusCode() == 204) {
                SessionServiceClient.LOGGER.at(Level.INFO).log("Game session terminated");
            }
            else {
                SessionServiceClient.LOGGER.at(Level.WARNING).log("Failed to terminate session: HTTP %d - %s", response.statusCode(), response.body());
            }
        }
        catch (final IOException e) {
            SessionServiceClient.LOGGER.at(Level.WARNING).log("IO error while terminating session: %s", e.getMessage());
        }
        catch (final InterruptedException e2) {
            SessionServiceClient.LOGGER.at(Level.WARNING).log("Request interrupted while terminating session");
            Thread.currentThread().interrupt();
        }
        catch (final Exception e3) {
            SessionServiceClient.LOGGER.at(Level.WARNING).log("Error terminating session: %s", e3.getMessage());
        }
    }
    
    private static String escapeJsonString(final String value) {
        if (value == null) {
            return "";
        }
        return value.replace("\\", "\\\\").replace("\"", "\\\"").replace("\n", "\\n").replace("\r", "\\r").replace("\t", "\\t");
    }
    
    private static <T> KeyedCodec<T> externalKey(final String key, final Codec<T> codec) {
        return new KeyedCodec<T>(key, codec, false, true);
    }
    
    static {
        LOGGER = HytaleLogger.forEnclosingClass();
        REQUEST_TIMEOUT = Duration.ofSeconds(5L);
    }
    
    public static class AuthGrantResponse
    {
        public String authorizationGrant;
        public static final BuilderCodec<AuthGrantResponse> CODEC;
        
        static {
            CODEC = BuilderCodec.builder(AuthGrantResponse.class, AuthGrantResponse::new).append((KeyedCodec<String>)SessionServiceClient.externalKey("authorizationGrant", (Codec<FieldType>)Codec.STRING), (r, v) -> r.authorizationGrant = v, r -> r.authorizationGrant).add().build();
        }
    }
    
    public static class AccessTokenResponse
    {
        public String accessToken;
        public static final BuilderCodec<AccessTokenResponse> CODEC;
        
        static {
            CODEC = BuilderCodec.builder(AccessTokenResponse.class, AccessTokenResponse::new).append((KeyedCodec<String>)SessionServiceClient.externalKey("accessToken", (Codec<FieldType>)Codec.STRING), (r, v) -> r.accessToken = v, r -> r.accessToken).add().build();
        }
    }
    
    public static class GameSessionResponse
    {
        public String sessionToken;
        public String identityToken;
        public String expiresAt;
        public static final BuilderCodec<GameSessionResponse> CODEC;
        
        public Instant getExpiresAtInstant() {
            if (this.expiresAt == null) {
                return null;
            }
            try {
                return Instant.parse(this.expiresAt);
            }
            catch (final Exception e) {
                return null;
            }
        }
        
        static {
            // 
            // This method could not be decompiled.
            // 
            // Original Bytecode:
            // 
            //     2: invokedynamic   BootstrapMethod #0, get:()Ljava/util/function/Supplier;
            //     7: invokestatic    com/hypixel/hytale/codec/builder/BuilderCodec.builder:(Ljava/lang/Class;Ljava/util/function/Supplier;)Lcom/hypixel/hytale/codec/builder/BuilderCodec$Builder;
            //    10: ldc             "sessionToken"
            //    12: getstatic       com/hypixel/hytale/codec/Codec.STRING:Lcom/hypixel/hytale/codec/codecs/simple/StringCodec;
            //    15: invokestatic    com/hypixel/hytale/server/core/auth/SessionServiceClient.externalKey:(Ljava/lang/String;Lcom/hypixel/hytale/codec/Codec;)Lcom/hypixel/hytale/codec/KeyedCodec;
            //    18: invokedynamic   BootstrapMethod #1, accept:()Ljava/util/function/BiConsumer;
            //    23: invokedynamic   BootstrapMethod #2, apply:()Ljava/util/function/Function;
            //    28: invokevirtual   com/hypixel/hytale/codec/builder/BuilderCodec$Builder.append:(Lcom/hypixel/hytale/codec/KeyedCodec;Ljava/util/function/BiConsumer;Ljava/util/function/Function;)Lcom/hypixel/hytale/codec/builder/BuilderField$FieldBuilder;
            //    31: invokevirtual   com/hypixel/hytale/codec/builder/BuilderField$FieldBuilder.add:()Lcom/hypixel/hytale/codec/builder/BuilderCodec$BuilderBase;
            //    34: checkcast       Lcom/hypixel/hytale/codec/builder/BuilderCodec$Builder;
            //    37: ldc             "identityToken"
            //    39: getstatic       com/hypixel/hytale/codec/Codec.STRING:Lcom/hypixel/hytale/codec/codecs/simple/StringCodec;
            //    42: invokestatic    com/hypixel/hytale/server/core/auth/SessionServiceClient.externalKey:(Ljava/lang/String;Lcom/hypixel/hytale/codec/Codec;)Lcom/hypixel/hytale/codec/KeyedCodec;
            //    45: invokedynamic   BootstrapMethod #3, accept:()Ljava/util/function/BiConsumer;
            //    50: invokedynamic   BootstrapMethod #4, apply:()Ljava/util/function/Function;
            //    55: invokevirtual   com/hypixel/hytale/codec/builder/BuilderCodec$Builder.append:(Lcom/hypixel/hytale/codec/KeyedCodec;Ljava/util/function/BiConsumer;Ljava/util/function/Function;)Lcom/hypixel/hytale/codec/builder/BuilderField$FieldBuilder;
            //    58: invokevirtual   com/hypixel/hytale/codec/builder/BuilderField$FieldBuilder.add:()Lcom/hypixel/hytale/codec/builder/BuilderCodec$BuilderBase;
            //    61: checkcast       Lcom/hypixel/hytale/codec/builder/BuilderCodec$Builder;
            //    64: ldc             "expiresAt"
            //    66: getstatic       com/hypixel/hytale/codec/Codec.STRING:Lcom/hypixel/hytale/codec/codecs/simple/StringCodec;
            //    69: invokestatic    com/hypixel/hytale/server/core/auth/SessionServiceClient.externalKey:(Ljava/lang/String;Lcom/hypixel/hytale/codec/Codec;)Lcom/hypixel/hytale/codec/KeyedCodec;
            //    72: invokedynamic   BootstrapMethod #5, accept:()Ljava/util/function/BiConsumer;
            //    77: invokedynamic   BootstrapMethod #6, apply:()Ljava/util/function/Function;
            //    82: invokevirtual   com/hypixel/hytale/codec/builder/BuilderCodec$Builder.append:(Lcom/hypixel/hytale/codec/KeyedCodec;Ljava/util/function/BiConsumer;Ljava/util/function/Function;)Lcom/hypixel/hytale/codec/builder/BuilderField$FieldBuilder;
            //    85: invokevirtual   com/hypixel/hytale/codec/builder/BuilderField$FieldBuilder.add:()Lcom/hypixel/hytale/codec/builder/BuilderCodec$BuilderBase;
            //    88: checkcast       Lcom/hypixel/hytale/codec/builder/BuilderCodec$Builder;
            //    91: invokevirtual   com/hypixel/hytale/codec/builder/BuilderCodec$Builder.build:()Lcom/hypixel/hytale/codec/builder/BuilderCodec;
            //    94: putstatic       com/hypixel/hytale/server/core/auth/SessionServiceClient$GameSessionResponse.CODEC:Lcom/hypixel/hytale/codec/builder/BuilderCodec;
            //    97: return         
            // 
            // The error that occurred was:
            // 
            // java.lang.UnsupportedOperationException: The requested operation is not supported.
            //     at com.strobel.util.ContractUtils.unsupported(ContractUtils.java:27)
            //     at com.strobel.assembler.metadata.TypeReference.getRawType(TypeReference.java:284)
            //     at com.strobel.assembler.metadata.TypeReference.getRawType(TypeReference.java:279)
            //     at com.strobel.assembler.metadata.TypeReference.makeGenericType(TypeReference.java:154)
            //     at com.strobel.assembler.metadata.TypeSubstitutionVisitor.visitParameterizedType(TypeSubstitutionVisitor.java:225)
            //     at com.strobel.assembler.metadata.TypeSubstitutionVisitor.visitParameterizedType(TypeSubstitutionVisitor.java:25)
            //     at com.strobel.assembler.metadata.ParameterizedType.accept(ParameterizedType.java:103)
            //     at com.strobel.assembler.metadata.TypeSubstitutionVisitor.visit(TypeSubstitutionVisitor.java:40)
            //     at com.strobel.assembler.metadata.TypeSubstitutionVisitor.visitParameterizedType(TypeSubstitutionVisitor.java:211)
            //     at com.strobel.assembler.metadata.TypeSubstitutionVisitor.visitParameterizedType(TypeSubstitutionVisitor.java:25)
            //     at com.strobel.assembler.metadata.ParameterizedType.accept(ParameterizedType.java:103)
            //     at com.strobel.assembler.metadata.TypeSubstitutionVisitor.visit(TypeSubstitutionVisitor.java:40)
            //     at com.strobel.assembler.metadata.TypeSubstitutionVisitor.visitMethod(TypeSubstitutionVisitor.java:314)
            //     at com.strobel.decompiler.ast.TypeAnalysis.inferCall(TypeAnalysis.java:2611)
            //     at com.strobel.decompiler.ast.TypeAnalysis.doInferTypeForExpression(TypeAnalysis.java:1040)
            //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:815)
            //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:790)
            //     at com.strobel.decompiler.ast.TypeAnalysis.inferCall(TypeAnalysis.java:2689)
            //     at com.strobel.decompiler.ast.TypeAnalysis.doInferTypeForExpression(TypeAnalysis.java:1040)
            //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:815)
            //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:782)
            //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:778)
            //     at com.strobel.decompiler.ast.TypeAnalysis.doInferTypeForExpression(TypeAnalysis.java:1510)
            //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:815)
            //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:790)
            //     at com.strobel.decompiler.ast.TypeAnalysis.inferCall(TypeAnalysis.java:2689)
            //     at com.strobel.decompiler.ast.TypeAnalysis.doInferTypeForExpression(TypeAnalysis.java:1040)
            //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:815)
            //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:790)
            //     at com.strobel.decompiler.ast.TypeAnalysis.inferCall(TypeAnalysis.java:2689)
            //     at com.strobel.decompiler.ast.TypeAnalysis.doInferTypeForExpression(TypeAnalysis.java:1040)
            //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:815)
            //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:782)
            //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:778)
            //     at com.strobel.decompiler.ast.TypeAnalysis.doInferTypeForExpression(TypeAnalysis.java:1510)
            //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:815)
            //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:790)
            //     at com.strobel.decompiler.ast.TypeAnalysis.inferCall(TypeAnalysis.java:2689)
            //     at com.strobel.decompiler.ast.TypeAnalysis.doInferTypeForExpression(TypeAnalysis.java:1040)
            //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:815)
            //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:782)
            //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:778)
            //     at com.strobel.decompiler.ast.TypeAnalysis.doInferTypeForExpression(TypeAnalysis.java:1083)
            //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:815)
            //     at com.strobel.decompiler.ast.TypeAnalysis.runInference(TypeAnalysis.java:684)
            //     at com.strobel.decompiler.ast.TypeAnalysis.runInference(TypeAnalysis.java:667)
            //     at com.strobel.decompiler.ast.TypeAnalysis.runInference(TypeAnalysis.java:373)
            //     at com.strobel.decompiler.ast.TypeAnalysis.run(TypeAnalysis.java:95)
            //     at com.strobel.decompiler.ast.AstOptimizer.optimize(AstOptimizer.java:344)
            //     at com.strobel.decompiler.ast.AstOptimizer.optimize(AstOptimizer.java:42)
            //     at com.strobel.decompiler.languages.java.ast.AstMethodBodyBuilder.createMethodBody(AstMethodBodyBuilder.java:206)
            //     at com.strobel.decompiler.languages.java.ast.AstMethodBodyBuilder.createMethodBody(AstMethodBodyBuilder.java:93)
            //     at com.strobel.decompiler.languages.java.ast.AstBuilder.createMethodBody(AstBuilder.java:868)
            //     at com.strobel.decompiler.languages.java.ast.AstBuilder.createMethod(AstBuilder.java:761)
            //     at com.strobel.decompiler.languages.java.ast.AstBuilder.addTypeMembers(AstBuilder.java:638)
            //     at com.strobel.decompiler.languages.java.ast.AstBuilder.createTypeCore(AstBuilder.java:605)
            //     at com.strobel.decompiler.languages.java.ast.AstBuilder.createTypeNoCache(AstBuilder.java:195)
            //     at com.strobel.decompiler.languages.java.ast.AstBuilder.addTypeMembers(AstBuilder.java:662)
            //     at com.strobel.decompiler.languages.java.ast.AstBuilder.createTypeCore(AstBuilder.java:605)
            //     at com.strobel.decompiler.languages.java.ast.AstBuilder.createTypeNoCache(AstBuilder.java:195)
            //     at com.strobel.decompiler.languages.java.ast.AstBuilder.createType(AstBuilder.java:162)
            //     at com.strobel.decompiler.languages.java.ast.AstBuilder.addType(AstBuilder.java:137)
            //     at com.strobel.decompiler.languages.java.JavaLanguage.buildAst(JavaLanguage.java:71)
            //     at com.strobel.decompiler.languages.java.JavaLanguage.decompileType(JavaLanguage.java:59)
            //     at com.strobel.decompiler.DecompilerDriver.decompileType(DecompilerDriver.java:333)
            //     at com.strobel.decompiler.DecompilerDriver.decompileJar(DecompilerDriver.java:254)
            //     at com.strobel.decompiler.DecompilerDriver.main(DecompilerDriver.java:129)
            // 
            throw new IllegalStateException("An error occurred while decompiling this method.");
        }
    }
    
    public static class JwksResponse
    {
        public JwkKey[] keys;
        public static final BuilderCodec<JwksResponse> CODEC;
        
        static {
            // 
            // This method could not be decompiled.
            // 
            // Original Bytecode:
            // 
            //     2: invokedynamic   BootstrapMethod #0, get:()Ljava/util/function/Supplier;
            //     7: invokestatic    com/hypixel/hytale/codec/builder/BuilderCodec.builder:(Ljava/lang/Class;Ljava/util/function/Supplier;)Lcom/hypixel/hytale/codec/builder/BuilderCodec$Builder;
            //    10: ldc             "keys"
            //    12: new             Lcom/hypixel/hytale/codec/codecs/array/ArrayCodec;
            //    15: dup            
            //    16: getstatic       com/hypixel/hytale/server/core/auth/SessionServiceClient$JwkKey.CODEC:Lcom/hypixel/hytale/codec/builder/BuilderCodec;
            //    19: invokedynamic   BootstrapMethod #1, apply:()Ljava/util/function/IntFunction;
            //    24: invokespecial   com/hypixel/hytale/codec/codecs/array/ArrayCodec.<init>:(Lcom/hypixel/hytale/codec/Codec;Ljava/util/function/IntFunction;)V
            //    27: invokestatic    com/hypixel/hytale/server/core/auth/SessionServiceClient.externalKey:(Ljava/lang/String;Lcom/hypixel/hytale/codec/Codec;)Lcom/hypixel/hytale/codec/KeyedCodec;
            //    30: invokedynamic   BootstrapMethod #2, accept:()Ljava/util/function/BiConsumer;
            //    35: invokedynamic   BootstrapMethod #3, apply:()Ljava/util/function/Function;
            //    40: invokevirtual   com/hypixel/hytale/codec/builder/BuilderCodec$Builder.append:(Lcom/hypixel/hytale/codec/KeyedCodec;Ljava/util/function/BiConsumer;Ljava/util/function/Function;)Lcom/hypixel/hytale/codec/builder/BuilderField$FieldBuilder;
            //    43: invokevirtual   com/hypixel/hytale/codec/builder/BuilderField$FieldBuilder.add:()Lcom/hypixel/hytale/codec/builder/BuilderCodec$BuilderBase;
            //    46: checkcast       Lcom/hypixel/hytale/codec/builder/BuilderCodec$Builder;
            //    49: invokevirtual   com/hypixel/hytale/codec/builder/BuilderCodec$Builder.build:()Lcom/hypixel/hytale/codec/builder/BuilderCodec;
            //    52: putstatic       com/hypixel/hytale/server/core/auth/SessionServiceClient$JwksResponse.CODEC:Lcom/hypixel/hytale/codec/builder/BuilderCodec;
            //    55: return         
            // 
            // The error that occurred was:
            // 
            // java.lang.UnsupportedOperationException: The requested operation is not supported.
            //     at com.strobel.util.ContractUtils.unsupported(ContractUtils.java:27)
            //     at com.strobel.assembler.metadata.TypeReference.getRawType(TypeReference.java:284)
            //     at com.strobel.assembler.metadata.TypeReference.getRawType(TypeReference.java:279)
            //     at com.strobel.assembler.metadata.TypeReference.makeGenericType(TypeReference.java:154)
            //     at com.strobel.assembler.metadata.TypeSubstitutionVisitor.visitParameterizedType(TypeSubstitutionVisitor.java:225)
            //     at com.strobel.assembler.metadata.TypeSubstitutionVisitor.visitParameterizedType(TypeSubstitutionVisitor.java:25)
            //     at com.strobel.assembler.metadata.ParameterizedType.accept(ParameterizedType.java:103)
            //     at com.strobel.assembler.metadata.TypeSubstitutionVisitor.visit(TypeSubstitutionVisitor.java:40)
            //     at com.strobel.assembler.metadata.TypeSubstitutionVisitor.visitParameterizedType(TypeSubstitutionVisitor.java:211)
            //     at com.strobel.assembler.metadata.TypeSubstitutionVisitor.visitParameterizedType(TypeSubstitutionVisitor.java:25)
            //     at com.strobel.assembler.metadata.ParameterizedType.accept(ParameterizedType.java:103)
            //     at com.strobel.assembler.metadata.TypeSubstitutionVisitor.visit(TypeSubstitutionVisitor.java:40)
            //     at com.strobel.assembler.metadata.TypeSubstitutionVisitor.visitMethod(TypeSubstitutionVisitor.java:314)
            //     at com.strobel.decompiler.ast.TypeAnalysis.inferCall(TypeAnalysis.java:2611)
            //     at com.strobel.decompiler.ast.TypeAnalysis.doInferTypeForExpression(TypeAnalysis.java:1040)
            //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:815)
            //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:782)
            //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:778)
            //     at com.strobel.decompiler.ast.TypeAnalysis.inferCall(TypeAnalysis.java:2483)
            //     at com.strobel.decompiler.ast.TypeAnalysis.doInferTypeForExpression(TypeAnalysis.java:1040)
            //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:815)
            //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:782)
            //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:778)
            //     at com.strobel.decompiler.ast.TypeAnalysis.doInferTypeForExpression(TypeAnalysis.java:1510)
            //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:815)
            //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:782)
            //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:778)
            //     at com.strobel.decompiler.ast.TypeAnalysis.inferCall(TypeAnalysis.java:2483)
            //     at com.strobel.decompiler.ast.TypeAnalysis.doInferTypeForExpression(TypeAnalysis.java:1040)
            //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:815)
            //     at com.strobel.decompiler.ast.TypeAnalysis.runInference(TypeAnalysis.java:684)
            //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypesForVariables(TypeAnalysis.java:593)
            //     at com.strobel.decompiler.ast.TypeAnalysis.runInference(TypeAnalysis.java:405)
            //     at com.strobel.decompiler.ast.TypeAnalysis.run(TypeAnalysis.java:95)
            //     at com.strobel.decompiler.ast.AstOptimizer.optimize(AstOptimizer.java:109)
            //     at com.strobel.decompiler.ast.AstOptimizer.optimize(AstOptimizer.java:42)
            //     at com.strobel.decompiler.languages.java.ast.AstMethodBodyBuilder.createMethodBody(AstMethodBodyBuilder.java:206)
            //     at com.strobel.decompiler.languages.java.ast.AstMethodBodyBuilder.createMethodBody(AstMethodBodyBuilder.java:93)
            //     at com.strobel.decompiler.languages.java.ast.AstBuilder.createMethodBody(AstBuilder.java:868)
            //     at com.strobel.decompiler.languages.java.ast.AstBuilder.createMethod(AstBuilder.java:761)
            //     at com.strobel.decompiler.languages.java.ast.AstBuilder.addTypeMembers(AstBuilder.java:638)
            //     at com.strobel.decompiler.languages.java.ast.AstBuilder.createTypeCore(AstBuilder.java:605)
            //     at com.strobel.decompiler.languages.java.ast.AstBuilder.createTypeNoCache(AstBuilder.java:195)
            //     at com.strobel.decompiler.languages.java.ast.AstBuilder.addTypeMembers(AstBuilder.java:662)
            //     at com.strobel.decompiler.languages.java.ast.AstBuilder.createTypeCore(AstBuilder.java:605)
            //     at com.strobel.decompiler.languages.java.ast.AstBuilder.createTypeNoCache(AstBuilder.java:195)
            //     at com.strobel.decompiler.languages.java.ast.AstBuilder.createType(AstBuilder.java:162)
            //     at com.strobel.decompiler.languages.java.ast.AstBuilder.addType(AstBuilder.java:137)
            //     at com.strobel.decompiler.languages.java.JavaLanguage.buildAst(JavaLanguage.java:71)
            //     at com.strobel.decompiler.languages.java.JavaLanguage.decompileType(JavaLanguage.java:59)
            //     at com.strobel.decompiler.DecompilerDriver.decompileType(DecompilerDriver.java:333)
            //     at com.strobel.decompiler.DecompilerDriver.decompileJar(DecompilerDriver.java:254)
            //     at com.strobel.decompiler.DecompilerDriver.main(DecompilerDriver.java:129)
            // 
            throw new IllegalStateException("An error occurred while decompiling this method.");
        }
    }
    
    public static class JwkKey
    {
        public String kty;
        public String alg;
        public String use;
        public String kid;
        public String crv;
        public String x;
        public String y;
        public String n;
        public String e;
        public static final BuilderCodec<JwkKey> CODEC;
        
        static {
            // 
            // This method could not be decompiled.
            // 
            // Original Bytecode:
            // 
            //     2: invokedynamic   BootstrapMethod #0, get:()Ljava/util/function/Supplier;
            //     7: invokestatic    com/hypixel/hytale/codec/builder/BuilderCodec.builder:(Ljava/lang/Class;Ljava/util/function/Supplier;)Lcom/hypixel/hytale/codec/builder/BuilderCodec$Builder;
            //    10: ldc             "kty"
            //    12: getstatic       com/hypixel/hytale/codec/Codec.STRING:Lcom/hypixel/hytale/codec/codecs/simple/StringCodec;
            //    15: invokestatic    com/hypixel/hytale/server/core/auth/SessionServiceClient.externalKey:(Ljava/lang/String;Lcom/hypixel/hytale/codec/Codec;)Lcom/hypixel/hytale/codec/KeyedCodec;
            //    18: invokedynamic   BootstrapMethod #1, accept:()Ljava/util/function/BiConsumer;
            //    23: invokedynamic   BootstrapMethod #2, apply:()Ljava/util/function/Function;
            //    28: invokevirtual   com/hypixel/hytale/codec/builder/BuilderCodec$Builder.append:(Lcom/hypixel/hytale/codec/KeyedCodec;Ljava/util/function/BiConsumer;Ljava/util/function/Function;)Lcom/hypixel/hytale/codec/builder/BuilderField$FieldBuilder;
            //    31: invokevirtual   com/hypixel/hytale/codec/builder/BuilderField$FieldBuilder.add:()Lcom/hypixel/hytale/codec/builder/BuilderCodec$BuilderBase;
            //    34: checkcast       Lcom/hypixel/hytale/codec/builder/BuilderCodec$Builder;
            //    37: ldc             "alg"
            //    39: getstatic       com/hypixel/hytale/codec/Codec.STRING:Lcom/hypixel/hytale/codec/codecs/simple/StringCodec;
            //    42: invokestatic    com/hypixel/hytale/server/core/auth/SessionServiceClient.externalKey:(Ljava/lang/String;Lcom/hypixel/hytale/codec/Codec;)Lcom/hypixel/hytale/codec/KeyedCodec;
            //    45: invokedynamic   BootstrapMethod #3, accept:()Ljava/util/function/BiConsumer;
            //    50: invokedynamic   BootstrapMethod #4, apply:()Ljava/util/function/Function;
            //    55: invokevirtual   com/hypixel/hytale/codec/builder/BuilderCodec$Builder.append:(Lcom/hypixel/hytale/codec/KeyedCodec;Ljava/util/function/BiConsumer;Ljava/util/function/Function;)Lcom/hypixel/hytale/codec/builder/BuilderField$FieldBuilder;
            //    58: invokevirtual   com/hypixel/hytale/codec/builder/BuilderField$FieldBuilder.add:()Lcom/hypixel/hytale/codec/builder/BuilderCodec$BuilderBase;
            //    61: checkcast       Lcom/hypixel/hytale/codec/builder/BuilderCodec$Builder;
            //    64: ldc             "use"
            //    66: getstatic       com/hypixel/hytale/codec/Codec.STRING:Lcom/hypixel/hytale/codec/codecs/simple/StringCodec;
            //    69: invokestatic    com/hypixel/hytale/server/core/auth/SessionServiceClient.externalKey:(Ljava/lang/String;Lcom/hypixel/hytale/codec/Codec;)Lcom/hypixel/hytale/codec/KeyedCodec;
            //    72: invokedynamic   BootstrapMethod #5, accept:()Ljava/util/function/BiConsumer;
            //    77: invokedynamic   BootstrapMethod #6, apply:()Ljava/util/function/Function;
            //    82: invokevirtual   com/hypixel/hytale/codec/builder/BuilderCodec$Builder.append:(Lcom/hypixel/hytale/codec/KeyedCodec;Ljava/util/function/BiConsumer;Ljava/util/function/Function;)Lcom/hypixel/hytale/codec/builder/BuilderField$FieldBuilder;
            //    85: invokevirtual   com/hypixel/hytale/codec/builder/BuilderField$FieldBuilder.add:()Lcom/hypixel/hytale/codec/builder/BuilderCodec$BuilderBase;
            //    88: checkcast       Lcom/hypixel/hytale/codec/builder/BuilderCodec$Builder;
            //    91: ldc             "kid"
            //    93: getstatic       com/hypixel/hytale/codec/Codec.STRING:Lcom/hypixel/hytale/codec/codecs/simple/StringCodec;
            //    96: invokestatic    com/hypixel/hytale/server/core/auth/SessionServiceClient.externalKey:(Ljava/lang/String;Lcom/hypixel/hytale/codec/Codec;)Lcom/hypixel/hytale/codec/KeyedCodec;
            //    99: invokedynamic   BootstrapMethod #7, accept:()Ljava/util/function/BiConsumer;
            //   104: invokedynamic   BootstrapMethod #8, apply:()Ljava/util/function/Function;
            //   109: invokevirtual   com/hypixel/hytale/codec/builder/BuilderCodec$Builder.append:(Lcom/hypixel/hytale/codec/KeyedCodec;Ljava/util/function/BiConsumer;Ljava/util/function/Function;)Lcom/hypixel/hytale/codec/builder/BuilderField$FieldBuilder;
            //   112: invokevirtual   com/hypixel/hytale/codec/builder/BuilderField$FieldBuilder.add:()Lcom/hypixel/hytale/codec/builder/BuilderCodec$BuilderBase;
            //   115: checkcast       Lcom/hypixel/hytale/codec/builder/BuilderCodec$Builder;
            //   118: ldc             "crv"
            //   120: getstatic       com/hypixel/hytale/codec/Codec.STRING:Lcom/hypixel/hytale/codec/codecs/simple/StringCodec;
            //   123: invokestatic    com/hypixel/hytale/server/core/auth/SessionServiceClient.externalKey:(Ljava/lang/String;Lcom/hypixel/hytale/codec/Codec;)Lcom/hypixel/hytale/codec/KeyedCodec;
            //   126: invokedynamic   BootstrapMethod #9, accept:()Ljava/util/function/BiConsumer;
            //   131: invokedynamic   BootstrapMethod #10, apply:()Ljava/util/function/Function;
            //   136: invokevirtual   com/hypixel/hytale/codec/builder/BuilderCodec$Builder.append:(Lcom/hypixel/hytale/codec/KeyedCodec;Ljava/util/function/BiConsumer;Ljava/util/function/Function;)Lcom/hypixel/hytale/codec/builder/BuilderField$FieldBuilder;
            //   139: invokevirtual   com/hypixel/hytale/codec/builder/BuilderField$FieldBuilder.add:()Lcom/hypixel/hytale/codec/builder/BuilderCodec$BuilderBase;
            //   142: checkcast       Lcom/hypixel/hytale/codec/builder/BuilderCodec$Builder;
            //   145: ldc             "x"
            //   147: getstatic       com/hypixel/hytale/codec/Codec.STRING:Lcom/hypixel/hytale/codec/codecs/simple/StringCodec;
            //   150: invokestatic    com/hypixel/hytale/server/core/auth/SessionServiceClient.externalKey:(Ljava/lang/String;Lcom/hypixel/hytale/codec/Codec;)Lcom/hypixel/hytale/codec/KeyedCodec;
            //   153: invokedynamic   BootstrapMethod #11, accept:()Ljava/util/function/BiConsumer;
            //   158: invokedynamic   BootstrapMethod #12, apply:()Ljava/util/function/Function;
            //   163: invokevirtual   com/hypixel/hytale/codec/builder/BuilderCodec$Builder.append:(Lcom/hypixel/hytale/codec/KeyedCodec;Ljava/util/function/BiConsumer;Ljava/util/function/Function;)Lcom/hypixel/hytale/codec/builder/BuilderField$FieldBuilder;
            //   166: invokevirtual   com/hypixel/hytale/codec/builder/BuilderField$FieldBuilder.add:()Lcom/hypixel/hytale/codec/builder/BuilderCodec$BuilderBase;
            //   169: checkcast       Lcom/hypixel/hytale/codec/builder/BuilderCodec$Builder;
            //   172: ldc             "y"
            //   174: getstatic       com/hypixel/hytale/codec/Codec.STRING:Lcom/hypixel/hytale/codec/codecs/simple/StringCodec;
            //   177: invokestatic    com/hypixel/hytale/server/core/auth/SessionServiceClient.externalKey:(Ljava/lang/String;Lcom/hypixel/hytale/codec/Codec;)Lcom/hypixel/hytale/codec/KeyedCodec;
            //   180: invokedynamic   BootstrapMethod #13, accept:()Ljava/util/function/BiConsumer;
            //   185: invokedynamic   BootstrapMethod #14, apply:()Ljava/util/function/Function;
            //   190: invokevirtual   com/hypixel/hytale/codec/builder/BuilderCodec$Builder.append:(Lcom/hypixel/hytale/codec/KeyedCodec;Ljava/util/function/BiConsumer;Ljava/util/function/Function;)Lcom/hypixel/hytale/codec/builder/BuilderField$FieldBuilder;
            //   193: invokevirtual   com/hypixel/hytale/codec/builder/BuilderField$FieldBuilder.add:()Lcom/hypixel/hytale/codec/builder/BuilderCodec$BuilderBase;
            //   196: checkcast       Lcom/hypixel/hytale/codec/builder/BuilderCodec$Builder;
            //   199: ldc             "n"
            //   201: getstatic       com/hypixel/hytale/codec/Codec.STRING:Lcom/hypixel/hytale/codec/codecs/simple/StringCodec;
            //   204: invokestatic    com/hypixel/hytale/server/core/auth/SessionServiceClient.externalKey:(Ljava/lang/String;Lcom/hypixel/hytale/codec/Codec;)Lcom/hypixel/hytale/codec/KeyedCodec;
            //   207: invokedynamic   BootstrapMethod #15, accept:()Ljava/util/function/BiConsumer;
            //   212: invokedynamic   BootstrapMethod #16, apply:()Ljava/util/function/Function;
            //   217: invokevirtual   com/hypixel/hytale/codec/builder/BuilderCodec$Builder.append:(Lcom/hypixel/hytale/codec/KeyedCodec;Ljava/util/function/BiConsumer;Ljava/util/function/Function;)Lcom/hypixel/hytale/codec/builder/BuilderField$FieldBuilder;
            //   220: invokevirtual   com/hypixel/hytale/codec/builder/BuilderField$FieldBuilder.add:()Lcom/hypixel/hytale/codec/builder/BuilderCodec$BuilderBase;
            //   223: checkcast       Lcom/hypixel/hytale/codec/builder/BuilderCodec$Builder;
            //   226: ldc             "e"
            //   228: getstatic       com/hypixel/hytale/codec/Codec.STRING:Lcom/hypixel/hytale/codec/codecs/simple/StringCodec;
            //   231: invokestatic    com/hypixel/hytale/server/core/auth/SessionServiceClient.externalKey:(Ljava/lang/String;Lcom/hypixel/hytale/codec/Codec;)Lcom/hypixel/hytale/codec/KeyedCodec;
            //   234: invokedynamic   BootstrapMethod #17, accept:()Ljava/util/function/BiConsumer;
            //   239: invokedynamic   BootstrapMethod #18, apply:()Ljava/util/function/Function;
            //   244: invokevirtual   com/hypixel/hytale/codec/builder/BuilderCodec$Builder.append:(Lcom/hypixel/hytale/codec/KeyedCodec;Ljava/util/function/BiConsumer;Ljava/util/function/Function;)Lcom/hypixel/hytale/codec/builder/BuilderField$FieldBuilder;
            //   247: invokevirtual   com/hypixel/hytale/codec/builder/BuilderField$FieldBuilder.add:()Lcom/hypixel/hytale/codec/builder/BuilderCodec$BuilderBase;
            //   250: checkcast       Lcom/hypixel/hytale/codec/builder/BuilderCodec$Builder;
            //   253: invokevirtual   com/hypixel/hytale/codec/builder/BuilderCodec$Builder.build:()Lcom/hypixel/hytale/codec/builder/BuilderCodec;
            //   256: putstatic       com/hypixel/hytale/server/core/auth/SessionServiceClient$JwkKey.CODEC:Lcom/hypixel/hytale/codec/builder/BuilderCodec;
            //   259: return         
            // 
            // The error that occurred was:
            // 
            // java.lang.UnsupportedOperationException: The requested operation is not supported.
            //     at com.strobel.util.ContractUtils.unsupported(ContractUtils.java:27)
            //     at com.strobel.assembler.metadata.TypeReference.getRawType(TypeReference.java:284)
            //     at com.strobel.assembler.metadata.TypeReference.getRawType(TypeReference.java:279)
            //     at com.strobel.assembler.metadata.TypeReference.makeGenericType(TypeReference.java:154)
            //     at com.strobel.assembler.metadata.TypeSubstitutionVisitor.visitClassType(TypeSubstitutionVisitor.java:267)
            //     at com.strobel.assembler.metadata.TypeSubstitutionVisitor.visitClassType(TypeSubstitutionVisitor.java:25)
            //     at com.strobel.assembler.metadata.TypeDefinition.accept(TypeDefinition.java:189)
            //     at com.strobel.assembler.metadata.TypeSubstitutionVisitor.visit(TypeSubstitutionVisitor.java:40)
            //     at com.strobel.assembler.metadata.TypeSubstitutionVisitor.visitMethod(TypeSubstitutionVisitor.java:324)
            //     at com.strobel.decompiler.ast.TypeAnalysis.inferCall(TypeAnalysis.java:2586)
            //     at com.strobel.decompiler.ast.TypeAnalysis.doInferTypeForExpression(TypeAnalysis.java:1040)
            //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:815)
            //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:790)
            //     at com.strobel.decompiler.ast.TypeAnalysis.inferCall(TypeAnalysis.java:2689)
            //     at com.strobel.decompiler.ast.TypeAnalysis.doInferTypeForExpression(TypeAnalysis.java:1040)
            //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:815)
            //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:782)
            //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:778)
            //     at com.strobel.decompiler.ast.TypeAnalysis.doInferTypeForExpression(TypeAnalysis.java:1510)
            //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:815)
            //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:790)
            //     at com.strobel.decompiler.ast.TypeAnalysis.inferCall(TypeAnalysis.java:2689)
            //     at com.strobel.decompiler.ast.TypeAnalysis.doInferTypeForExpression(TypeAnalysis.java:1040)
            //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:815)
            //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:790)
            //     at com.strobel.decompiler.ast.TypeAnalysis.inferCall(TypeAnalysis.java:2689)
            //     at com.strobel.decompiler.ast.TypeAnalysis.doInferTypeForExpression(TypeAnalysis.java:1040)
            //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:815)
            //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:782)
            //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:778)
            //     at com.strobel.decompiler.ast.TypeAnalysis.doInferTypeForExpression(TypeAnalysis.java:1510)
            //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:815)
            //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:790)
            //     at com.strobel.decompiler.ast.TypeAnalysis.inferCall(TypeAnalysis.java:2689)
            //     at com.strobel.decompiler.ast.TypeAnalysis.doInferTypeForExpression(TypeAnalysis.java:1040)
            //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:815)
            //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:790)
            //     at com.strobel.decompiler.ast.TypeAnalysis.inferCall(TypeAnalysis.java:2689)
            //     at com.strobel.decompiler.ast.TypeAnalysis.doInferTypeForExpression(TypeAnalysis.java:1040)
            //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:815)
            //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:782)
            //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:778)
            //     at com.strobel.decompiler.ast.TypeAnalysis.doInferTypeForExpression(TypeAnalysis.java:1510)
            //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:815)
            //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:790)
            //     at com.strobel.decompiler.ast.TypeAnalysis.inferCall(TypeAnalysis.java:2689)
            //     at com.strobel.decompiler.ast.TypeAnalysis.doInferTypeForExpression(TypeAnalysis.java:1040)
            //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:815)
            //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:790)
            //     at com.strobel.decompiler.ast.TypeAnalysis.inferCall(TypeAnalysis.java:2689)
            //     at com.strobel.decompiler.ast.TypeAnalysis.doInferTypeForExpression(TypeAnalysis.java:1040)
            //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:815)
            //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:782)
            //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:778)
            //     at com.strobel.decompiler.ast.TypeAnalysis.doInferTypeForExpression(TypeAnalysis.java:1510)
            //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:815)
            //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:790)
            //     at com.strobel.decompiler.ast.TypeAnalysis.inferCall(TypeAnalysis.java:2689)
            //     at com.strobel.decompiler.ast.TypeAnalysis.doInferTypeForExpression(TypeAnalysis.java:1040)
            //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:815)
            //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:790)
            //     at com.strobel.decompiler.ast.TypeAnalysis.inferCall(TypeAnalysis.java:2689)
            //     at com.strobel.decompiler.ast.TypeAnalysis.doInferTypeForExpression(TypeAnalysis.java:1040)
            //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:815)
            //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:782)
            //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:778)
            //     at com.strobel.decompiler.ast.TypeAnalysis.doInferTypeForExpression(TypeAnalysis.java:1510)
            //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:815)
            //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:790)
            //     at com.strobel.decompiler.ast.TypeAnalysis.inferCall(TypeAnalysis.java:2689)
            //     at com.strobel.decompiler.ast.TypeAnalysis.doInferTypeForExpression(TypeAnalysis.java:1040)
            //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:815)
            //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:790)
            //     at com.strobel.decompiler.ast.TypeAnalysis.inferCall(TypeAnalysis.java:2689)
            //     at com.strobel.decompiler.ast.TypeAnalysis.doInferTypeForExpression(TypeAnalysis.java:1040)
            //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:815)
            //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:782)
            //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:778)
            //     at com.strobel.decompiler.ast.TypeAnalysis.doInferTypeForExpression(TypeAnalysis.java:1510)
            //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:815)
            //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:782)
            //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:778)
            //     at com.strobel.decompiler.ast.TypeAnalysis.inferCall(TypeAnalysis.java:2483)
            //     at com.strobel.decompiler.ast.TypeAnalysis.doInferTypeForExpression(TypeAnalysis.java:1040)
            //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:815)
            //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:782)
            //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:778)
            //     at com.strobel.decompiler.ast.TypeAnalysis.inferCall(TypeAnalysis.java:2483)
            //     at com.strobel.decompiler.ast.TypeAnalysis.doInferTypeForExpression(TypeAnalysis.java:1040)
            //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:815)
            //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:782)
            //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:778)
            //     at com.strobel.decompiler.ast.TypeAnalysis.doInferTypeForExpression(TypeAnalysis.java:1510)
            //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:815)
            //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:782)
            //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:778)
            //     at com.strobel.decompiler.ast.TypeAnalysis.inferCall(TypeAnalysis.java:2483)
            //     at com.strobel.decompiler.ast.TypeAnalysis.doInferTypeForExpression(TypeAnalysis.java:1040)
            //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:815)
            //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:782)
            //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:778)
            //     at com.strobel.decompiler.ast.TypeAnalysis.inferCall(TypeAnalysis.java:2483)
            //     at com.strobel.decompiler.ast.TypeAnalysis.doInferTypeForExpression(TypeAnalysis.java:1040)
            //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:815)
            //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:782)
            //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:778)
            //     at com.strobel.decompiler.ast.TypeAnalysis.doInferTypeForExpression(TypeAnalysis.java:1510)
            //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:815)
            //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:782)
            //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:778)
            //     at com.strobel.decompiler.ast.TypeAnalysis.inferCall(TypeAnalysis.java:2483)
            //     at com.strobel.decompiler.ast.TypeAnalysis.doInferTypeForExpression(TypeAnalysis.java:1040)
            //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:815)
            //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:782)
            //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:778)
            //     at com.strobel.decompiler.ast.TypeAnalysis.doInferTypeForExpression(TypeAnalysis.java:1083)
            //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:815)
            //     at com.strobel.decompiler.ast.TypeAnalysis.runInference(TypeAnalysis.java:684)
            //     at com.strobel.decompiler.ast.TypeAnalysis.runInference(TypeAnalysis.java:667)
            //     at com.strobel.decompiler.ast.TypeAnalysis.runInference(TypeAnalysis.java:373)
            //     at com.strobel.decompiler.ast.TypeAnalysis.run(TypeAnalysis.java:95)
            //     at com.strobel.decompiler.ast.AstOptimizer.optimize(AstOptimizer.java:109)
            //     at com.strobel.decompiler.ast.AstOptimizer.optimize(AstOptimizer.java:42)
            //     at com.strobel.decompiler.languages.java.ast.AstMethodBodyBuilder.createMethodBody(AstMethodBodyBuilder.java:206)
            //     at com.strobel.decompiler.languages.java.ast.AstMethodBodyBuilder.createMethodBody(AstMethodBodyBuilder.java:93)
            //     at com.strobel.decompiler.languages.java.ast.AstBuilder.createMethodBody(AstBuilder.java:868)
            //     at com.strobel.decompiler.languages.java.ast.AstBuilder.createMethod(AstBuilder.java:761)
            //     at com.strobel.decompiler.languages.java.ast.AstBuilder.addTypeMembers(AstBuilder.java:638)
            //     at com.strobel.decompiler.languages.java.ast.AstBuilder.createTypeCore(AstBuilder.java:605)
            //     at com.strobel.decompiler.languages.java.ast.AstBuilder.createTypeNoCache(AstBuilder.java:195)
            //     at com.strobel.decompiler.languages.java.ast.AstBuilder.addTypeMembers(AstBuilder.java:662)
            //     at com.strobel.decompiler.languages.java.ast.AstBuilder.createTypeCore(AstBuilder.java:605)
            //     at com.strobel.decompiler.languages.java.ast.AstBuilder.createTypeNoCache(AstBuilder.java:195)
            //     at com.strobel.decompiler.languages.java.ast.AstBuilder.createType(AstBuilder.java:162)
            //     at com.strobel.decompiler.languages.java.ast.AstBuilder.addType(AstBuilder.java:137)
            //     at com.strobel.decompiler.languages.java.JavaLanguage.buildAst(JavaLanguage.java:71)
            //     at com.strobel.decompiler.languages.java.JavaLanguage.decompileType(JavaLanguage.java:59)
            //     at com.strobel.decompiler.DecompilerDriver.decompileType(DecompilerDriver.java:333)
            //     at com.strobel.decompiler.DecompilerDriver.decompileJar(DecompilerDriver.java:254)
            //     at com.strobel.decompiler.DecompilerDriver.main(DecompilerDriver.java:129)
            // 
            throw new IllegalStateException("An error occurred while decompiling this method.");
        }
    }
    
    public static class LauncherDataResponse
    {
        public UUID owner;
        public GameProfile[] profiles;
        public static final BuilderCodec<LauncherDataResponse> CODEC;
        
        static {
            CODEC = BuilderCodec.builder(LauncherDataResponse.class, LauncherDataResponse::new).append((KeyedCodec<UUID>)SessionServiceClient.externalKey("owner", (Codec<FieldType>)Codec.UUID_STRING), (r, v) -> r.owner = v, r -> r.owner).add().append(SessionServiceClient.externalKey("profiles", new ArrayCodec((Codec<Object>)GameProfile.CODEC, GameProfile[]::new)), (r, v) -> r.profiles = v, r -> r.profiles).add().build();
        }
    }
    
    public static class GameProfile
    {
        public UUID uuid;
        public String username;
        public static final BuilderCodec<GameProfile> CODEC;
        
        static {
            CODEC = BuilderCodec.builder(GameProfile.class, GameProfile::new).append((KeyedCodec<UUID>)SessionServiceClient.externalKey("uuid", (Codec<FieldType>)Codec.UUID_STRING), (p, v) -> p.uuid = v, p -> p.uuid).add().append(SessionServiceClient.externalKey("username", (Codec<Object>)Codec.STRING), (p, v) -> p.username = v, p -> p.username).add().build();
        }
    }
}
