diff --git a/src/main/java/emu/grasscutter/auth/AuthenticationSystem.java b/src/main/java/emu/grasscutter/auth/AuthenticationSystem.java index 6747f5ae4..d7accbf14 100644 --- a/src/main/java/emu/grasscutter/auth/AuthenticationSystem.java +++ b/src/main/java/emu/grasscutter/auth/AuthenticationSystem.java @@ -4,12 +4,11 @@ import emu.grasscutter.game.Account; import emu.grasscutter.server.http.objects.*; import emu.grasscutter.utils.DispatchUtils; import io.javalin.http.Context; +import javax.annotation.Nullable; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Getter; -import javax.annotation.Nullable; - /** Defines an authenticator for the server. Can be changed by plugins. */ public interface AuthenticationSystem { diff --git a/src/main/java/emu/grasscutter/auth/DefaultAuthentication.java b/src/main/java/emu/grasscutter/auth/DefaultAuthentication.java index 3b5ba5bab..4dbfcf967 100644 --- a/src/main/java/emu/grasscutter/auth/DefaultAuthentication.java +++ b/src/main/java/emu/grasscutter/auth/DefaultAuthentication.java @@ -1,14 +1,14 @@ package emu.grasscutter.auth; +import static emu.grasscutter.config.Configuration.ACCOUNT; +import static emu.grasscutter.utils.Language.translate; + import emu.grasscutter.Grasscutter; import emu.grasscutter.auth.DefaultAuthenticators.*; import emu.grasscutter.game.Account; import emu.grasscutter.server.http.objects.ComboTokenResJson; import emu.grasscutter.server.http.objects.LoginResultJson; -import static emu.grasscutter.config.Configuration.ACCOUNT; -import static emu.grasscutter.utils.Language.translate; - /** * The default Grasscutter authentication implementation. Allows all users to access any account. */ diff --git a/src/main/java/emu/grasscutter/auth/DefaultAuthenticators.java b/src/main/java/emu/grasscutter/auth/DefaultAuthenticators.java index 06f55aefc..2439102e7 100644 --- a/src/main/java/emu/grasscutter/auth/DefaultAuthenticators.java +++ b/src/main/java/emu/grasscutter/auth/DefaultAuthenticators.java @@ -1,5 +1,8 @@ package emu.grasscutter.auth; +import static emu.grasscutter.config.Configuration.ACCOUNT; +import static emu.grasscutter.utils.Language.translate; + import at.favre.lib.crypto.bcrypt.BCrypt; import emu.grasscutter.Grasscutter; import emu.grasscutter.auth.AuthenticationSystem.AuthenticationRequest; @@ -13,17 +16,13 @@ import emu.grasscutter.utils.DispatchUtils; import emu.grasscutter.utils.FileUtils; import emu.grasscutter.utils.Utils; import io.javalin.http.ContentType; - -import javax.crypto.Cipher; import java.nio.charset.StandardCharsets; import java.security.KeyFactory; import java.security.interfaces.RSAPrivateKey; import java.security.spec.PKCS8EncodedKeySpec; import java.util.concurrent.CompletableFuture; import java.util.concurrent.TimeUnit; - -import static emu.grasscutter.config.Configuration.ACCOUNT; -import static emu.grasscutter.utils.Language.translate; +import javax.crypto.Cipher; /** A class containing default authenticators. */ public final class DefaultAuthenticators { @@ -382,8 +381,7 @@ public final class DefaultAuthenticators { public HandbookAuthentication() { try { - this.authPage = new String( - FileUtils.readResource("/html/handbook_auth.html")); + this.authPage = new String(FileUtils.readResource("/html/handbook_auth.html")); } catch (Exception ignored) { throw new RuntimeException("Failed to load handbook auth page."); } @@ -395,8 +393,7 @@ public final class DefaultAuthenticators { if (ctx == null) return; // Respond with the handbook auth page. - ctx.contentType(ContentType.TEXT_HTML) - .result(this.authPage); + ctx.contentType(ContentType.TEXT_HTML).result(this.authPage); } @Override @@ -407,28 +404,27 @@ public final class DefaultAuthenticators { // Get the body data. var playerId = ctx.formParam("playerid"); if (playerId == null) { - return Response.builder().status(400) - .body("Invalid player ID.").build(); + return Response.builder().status(400).body("Invalid player ID.").build(); } try { // Get the player's session token. - var sessionKey = DispatchUtils.fetchSessionKey( - Integer.parseInt(playerId)); + var sessionKey = DispatchUtils.fetchSessionKey(Integer.parseInt(playerId)); if (sessionKey == null) { - return Response.builder().status(400) - .body("Invalid player ID.").build(); + return Response.builder().status(400).body("Invalid player ID.").build(); } // Check if the account is banned. - return Response.builder().status(200) - .body(this.authPage.replace("{{VALUE}}", "true") - .replace("{{SESSION_TOKEN}}", sessionKey) - .replace("{{PLAYER_ID}}", playerId)) - .build(); + return Response.builder() + .status(200) + .body( + this.authPage + .replace("{{VALUE}}", "true") + .replace("{{SESSION_TOKEN}}", sessionKey) + .replace("{{PLAYER_ID}}", playerId)) + .build(); } catch (NumberFormatException ignored) { - return Response.builder().status(500) - .body("Invalid player ID.").build(); + return Response.builder().status(500).body("Invalid player ID.").build(); } } } diff --git a/src/main/java/emu/grasscutter/auth/HandbookAuthenticator.java b/src/main/java/emu/grasscutter/auth/HandbookAuthenticator.java index 4aeb46301..732887770 100644 --- a/src/main/java/emu/grasscutter/auth/HandbookAuthenticator.java +++ b/src/main/java/emu/grasscutter/auth/HandbookAuthenticator.java @@ -6,15 +6,16 @@ import lombok.Getter; /** Handles player authentication for the web GM handbook. */ public interface HandbookAuthenticator { - @Getter @Builder + @Getter + @Builder class Response { private final int status; private final String body; } /** - * Invoked when the user requests to authenticate. - * This should respond with a page that allows the user to authenticate. + * Invoked when the user requests to authenticate. This should respond with a page that allows the + * user to authenticate. * * @route GET /handbook/authenticate * @param request The authentication request. @@ -22,10 +23,9 @@ public interface HandbookAuthenticator { void presentPage(AuthenticationRequest request); /** - * Invoked when the user requests to authenticate. - * This is called when the user submits the authentication form. - * This should respond with HTML that sends a message to the GM Handbook. - * See the default handbook authentication page for an example. + * Invoked when the user requests to authenticate. This is called when the user submits the + * authentication form. This should respond with HTML that sends a message to the GM Handbook. See + * the default handbook authentication page for an example. * * @param request The authentication request. * @return The response to send to the client. diff --git a/src/main/java/emu/grasscutter/server/dispatch/DispatchClient.java b/src/main/java/emu/grasscutter/server/dispatch/DispatchClient.java index 59cca9f59..dbd3832f7 100644 --- a/src/main/java/emu/grasscutter/server/dispatch/DispatchClient.java +++ b/src/main/java/emu/grasscutter/server/dispatch/DispatchClient.java @@ -1,5 +1,7 @@ package emu.grasscutter.server.dispatch; +import static emu.grasscutter.config.Configuration.DISPATCH_INFO; + import com.google.gson.JsonElement; import com.google.gson.JsonObject; import emu.grasscutter.Grasscutter; @@ -10,12 +12,6 @@ import emu.grasscutter.utils.Crypto; import emu.grasscutter.utils.DispatchUtils; import emu.grasscutter.utils.JsonUtils; import emu.grasscutter.utils.objects.HandbookBody; -import lombok.Getter; -import org.java_websocket.WebSocket; -import org.java_websocket.client.WebSocketClient; -import org.java_websocket.handshake.ServerHandshake; -import org.slf4j.Logger; - import java.net.ConnectException; import java.net.URI; import java.nio.ByteBuffer; @@ -26,8 +22,11 @@ import java.util.List; import java.util.Map; import java.util.function.BiConsumer; import java.util.function.Consumer; - -import static emu.grasscutter.config.Configuration.DISPATCH_INFO; +import lombok.Getter; +import org.java_websocket.WebSocket; +import org.java_websocket.client.WebSocketClient; +import org.java_websocket.handshake.ServerHandshake; +import org.slf4j.Logger; public final class DispatchClient extends WebSocketClient implements IDispatcher { @Getter private final Logger logger = Grasscutter.getLogger(); @@ -125,13 +124,11 @@ public final class DispatchClient extends WebSocketClient implements IDispatcher // Convert the fields array. var fieldsList = new ArrayList(); - for (var field : fieldsRaw) - fieldsList.add(field.getAsString()); + for (var field : fieldsRaw) fieldsList.add(field.getAsString()); var fields = fieldsList.toArray(new String[0]); // Return the response object. - this.sendMessage(PacketIds.GetPlayerFieldsRsp, - DispatchUtils.getPlayerFields(playerId, fields)); + this.sendMessage(PacketIds.GetPlayerFieldsRsp, DispatchUtils.getPlayerFields(playerId, fields)); } /** diff --git a/src/main/java/emu/grasscutter/server/dispatch/DispatchServer.java b/src/main/java/emu/grasscutter/server/dispatch/DispatchServer.java index cc0b4adc5..5c11f4194 100644 --- a/src/main/java/emu/grasscutter/server/dispatch/DispatchServer.java +++ b/src/main/java/emu/grasscutter/server/dispatch/DispatchServer.java @@ -1,16 +1,12 @@ package emu.grasscutter.server.dispatch; +import static emu.grasscutter.config.Configuration.DISPATCH_INFO; + import com.google.gson.JsonElement; import com.google.gson.JsonObject; import emu.grasscutter.Grasscutter; import emu.grasscutter.database.DatabaseHelper; import emu.grasscutter.utils.Crypto; -import lombok.Getter; -import org.java_websocket.WebSocket; -import org.java_websocket.handshake.ClientHandshake; -import org.java_websocket.server.WebSocketServer; -import org.slf4j.Logger; - import java.net.InetSocketAddress; import java.nio.ByteBuffer; import java.nio.charset.StandardCharsets; @@ -19,8 +15,11 @@ import java.util.List; import java.util.Map; import java.util.function.BiConsumer; import java.util.function.Consumer; - -import static emu.grasscutter.config.Configuration.DISPATCH_INFO; +import lombok.Getter; +import org.java_websocket.WebSocket; +import org.java_websocket.handshake.ClientHandshake; +import org.java_websocket.server.WebSocketServer; +import org.slf4j.Logger; /* Internal communications server. */ public final class DispatchServer extends WebSocketServer implements IDispatcher { @@ -99,8 +98,7 @@ public final class DispatchServer extends WebSocketServer implements IDispatcher // Get the account from the database. var account = DatabaseHelper.getAccountById(accountId); // Send the account. - this.sendMessage(socket, PacketIds.GetAccountRsp, - JSON.toJsonTree(account)); + this.sendMessage(socket, PacketIds.GetAccountRsp, JSON.toJsonTree(account)); } /** diff --git a/src/main/java/emu/grasscutter/server/dispatch/IDispatcher.java b/src/main/java/emu/grasscutter/server/dispatch/IDispatcher.java index 6bea30043..702f1a0a5 100644 --- a/src/main/java/emu/grasscutter/server/dispatch/IDispatcher.java +++ b/src/main/java/emu/grasscutter/server/dispatch/IDispatcher.java @@ -1,14 +1,13 @@ package emu.grasscutter.server.dispatch; +import static emu.grasscutter.config.Configuration.DISPATCH_INFO; + import com.google.gson.Gson; import com.google.gson.GsonBuilder; import com.google.gson.JsonElement; import com.google.gson.JsonObject; import emu.grasscutter.utils.Crypto; import emu.grasscutter.utils.JsonAdapters.ByteArrayAdapter; -import org.java_websocket.WebSocket; -import org.slf4j.Logger; - import java.nio.charset.StandardCharsets; import java.util.LinkedList; import java.util.List; @@ -18,8 +17,8 @@ import java.util.concurrent.TimeUnit; import java.util.function.BiConsumer; import java.util.function.Consumer; import java.util.function.Function; - -import static emu.grasscutter.config.Configuration.DISPATCH_INFO; +import org.java_websocket.WebSocket; +import org.slf4j.Logger; public interface IDispatcher { Gson JSON = @@ -28,8 +27,8 @@ public interface IDispatcher { .registerTypeAdapter(byte[].class, new ByteArrayAdapter()) .create(); - Function DEFAULT_PARSER = (packet) -> - IDispatcher.decode(packet, JsonObject.class); + Function DEFAULT_PARSER = + (packet) -> IDispatcher.decode(packet, JsonObject.class); /** * Decodes an escaped JSON message. @@ -78,8 +77,8 @@ public interface IDispatcher { * @return The fulfilled data, or null. * @param The type of data to be returned. */ - default T await(JsonObject request, int requestId, int responseId, - Function parser) { + default T await( + JsonObject request, int requestId, int responseId, Function parser) { // Perform the setup for the request. var future = this.async(request, requestId, responseId, parser); @@ -92,8 +91,7 @@ public interface IDispatcher { } /** - * Registers a callback for a packet to be received. - * Sends a packet with the provided request. + * Registers a callback for a packet to be received. Sends a packet with the provided request. * * @param request The request object. * @param requestId The packet ID of the request packet. @@ -105,8 +103,7 @@ public interface IDispatcher { } /** - * Registers a callback for a packet to be received. - * Sends a packet with the provided request. + * Registers a callback for a packet to be received. Sends a packet with the provided request. * * @param request The request object. * @param requestId The packet ID of the request packet. @@ -115,14 +112,11 @@ public interface IDispatcher { * @return A promise containing the parsed JSON data. */ default CompletableFuture async( - JsonObject request, int requestId, int responseId, - Function parser - ) { + JsonObject request, int requestId, int responseId, Function parser) { // Create the future. var future = new CompletableFuture(); // Listen for the response. - this.registerCallback(responseId, packet -> - future.complete(parser.apply(packet))); + this.registerCallback(responseId, packet -> future.complete(parser.apply(packet))); // Broadcast the packet. this.sendMessage(requestId, request); diff --git a/src/main/java/emu/grasscutter/server/http/documentation/HandbookHandler.java b/src/main/java/emu/grasscutter/server/http/documentation/HandbookHandler.java index 85918d15a..2f722bd22 100644 --- a/src/main/java/emu/grasscutter/server/http/documentation/HandbookHandler.java +++ b/src/main/java/emu/grasscutter/server/http/documentation/HandbookHandler.java @@ -1,5 +1,7 @@ package emu.grasscutter.server.http.documentation; +import static emu.grasscutter.config.Configuration.HANDBOOK; + import emu.grasscutter.Grasscutter; import emu.grasscutter.auth.AuthenticationSystem.AuthenticationRequest; import emu.grasscutter.server.http.Router; @@ -11,8 +13,6 @@ import io.javalin.Javalin; import io.javalin.http.ContentType; import io.javalin.http.Context; -import static emu.grasscutter.config.Configuration.HANDBOOK; - /** Handles requests for the new GM Handbook. */ public final class HandbookHandler implements Router { private final byte[] handbook; @@ -77,8 +77,8 @@ public final class HandbookHandler implements Router { } else { // Pass the request to the authenticator. Grasscutter.getAuthenticationSystem() - .getHandbookAuthenticator().presentPage( - AuthenticationRequest.builder().context(ctx).build()); + .getHandbookAuthenticator() + .presentPage(AuthenticationRequest.builder().context(ctx).build()); } } @@ -93,17 +93,17 @@ public final class HandbookHandler implements Router { ctx.status(500).result("Handbook not found."); } else { // Pass the request to the authenticator. - var result = Grasscutter.getAuthenticationSystem() - .getHandbookAuthenticator().authenticate( - AuthenticationRequest.builder().context(ctx).build()); + var result = + Grasscutter.getAuthenticationSystem() + .getHandbookAuthenticator() + .authenticate(AuthenticationRequest.builder().context(ctx).build()); if (result == null) { ctx.status(500).result("Authentication failed."); } else { - ctx - .status(result.getStatus()) - .result(result.getBody()) - .contentType(result.getBody().contains("html") ? - ContentType.TEXT_HTML : ContentType.TEXT_PLAIN); + ctx.status(result.getStatus()) + .result(result.getBody()) + .contentType( + result.getBody().contains("html") ? ContentType.TEXT_HTML : ContentType.TEXT_PLAIN); } } } diff --git a/src/main/java/emu/grasscutter/utils/DispatchUtils.java b/src/main/java/emu/grasscutter/utils/DispatchUtils.java index b164cfd18..b46d91c51 100644 --- a/src/main/java/emu/grasscutter/utils/DispatchUtils.java +++ b/src/main/java/emu/grasscutter/utils/DispatchUtils.java @@ -1,5 +1,7 @@ package emu.grasscutter.utils; +import static emu.grasscutter.config.Configuration.DISPATCH_INFO; + import com.google.gson.JsonNull; import com.google.gson.JsonObject; import emu.grasscutter.Grasscutter; @@ -13,16 +15,13 @@ import emu.grasscutter.server.http.handlers.GachaHandler; import emu.grasscutter.server.http.objects.LoginTokenRequestJson; import emu.grasscutter.utils.objects.HandbookBody; import emu.grasscutter.utils.objects.HandbookBody.*; - -import javax.annotation.Nullable; import java.lang.reflect.Field; import java.net.http.HttpClient; import java.util.Arrays; import java.util.HashMap; import java.util.concurrent.CompletableFuture; import java.util.concurrent.TimeUnit; - -import static emu.grasscutter.config.Configuration.DISPATCH_INFO; +import javax.annotation.Nullable; public interface DispatchUtils { /** HTTP client used for dispatch queries. */ @@ -128,12 +127,15 @@ public interface DispatchUtils { request.addProperty("accountId", accountId); // Wait for the request to complete. - yield Grasscutter.getGameServer().getDispatchClient() - .await(request, PacketIds.GetAccountReq, PacketIds.GetAccountRsp, - packet -> IDispatcher.decode(packet, Account.class)); + yield Grasscutter.getGameServer() + .getDispatchClient() + .await( + request, + PacketIds.GetAccountReq, + PacketIds.GetAccountRsp, + packet -> IDispatcher.decode(packet, Account.class)); } - case HYBRID, DISPATCH_ONLY -> - DatabaseHelper.getAccountById(accountId); + case HYBRID, DISPATCH_ONLY -> DatabaseHelper.getAccountById(accountId); }; } @@ -154,32 +156,32 @@ public interface DispatchUtils { // Wait for the request to complete. yield Grasscutter.getDispatchServer() - .await(request, PacketIds.GetPlayerFieldsReq, PacketIds.GetPlayerFieldsRsp, - IDispatcher.DEFAULT_PARSER); + .await( + request, + PacketIds.GetPlayerFieldsReq, + PacketIds.GetPlayerFieldsRsp, + IDispatcher.DEFAULT_PARSER); } case HYBRID, GAME_ONLY -> { // Get the player by ID. - var player = Grasscutter.getGameServer() - .getPlayerByUid(playerId, true); + var player = Grasscutter.getGameServer().getPlayerByUid(playerId, true); if (player == null) yield null; // Prepare field properties. var fieldValues = new JsonObject(); var fieldMap = new HashMap(); Arrays.stream(player.getClass().getDeclaredFields()) - .forEach(field -> fieldMap.put(field.getName(), field)); + .forEach(field -> fieldMap.put(field.getName(), field)); // Find the values of all requested fields. for (var fieldName : fields) { try { var field = fieldMap.get(fieldName); - if (field == null) - fieldValues.add(fieldName, JsonNull.INSTANCE); + if (field == null) fieldValues.add(fieldName, JsonNull.INSTANCE); else { var wasAccessible = field.canAccess(player); field.setAccessible(true); - fieldValues.add(fieldName, - IDispatcher.JSON.toJsonTree(field.get(player))); + fieldValues.add(fieldName, IDispatcher.JSON.toJsonTree(field.get(player))); field.setAccessible(wasAccessible); } } catch (Exception exception) {