diff --git a/src/main/java/emu/grasscutter/Grasscutter.java b/src/main/java/emu/grasscutter/Grasscutter.java index 78092c02c..d4d579db1 100644 --- a/src/main/java/emu/grasscutter/Grasscutter.java +++ b/src/main/java/emu/grasscutter/Grasscutter.java @@ -1,5 +1,8 @@ package emu.grasscutter; +import static emu.grasscutter.config.Configuration.SERVER; +import static emu.grasscutter.utils.Language.translate; + import ch.qos.logback.classic.Level; import ch.qos.logback.classic.Logger; import emu.grasscutter.auth.AuthenticationSystem; @@ -26,6 +29,12 @@ import emu.grasscutter.server.http.handlers.GenericHandler; import emu.grasscutter.server.http.handlers.LogHandler; import emu.grasscutter.tools.Tools; import emu.grasscutter.utils.*; +import java.io.File; +import java.io.FileWriter; +import java.io.IOError; +import java.io.IOException; +import java.util.Calendar; +import javax.annotation.Nullable; import lombok.Getter; import lombok.Setter; import org.jline.reader.EndOfFileException; @@ -37,16 +46,6 @@ import org.jline.terminal.TerminalBuilder; import org.reflections.Reflections; import org.slf4j.LoggerFactory; -import javax.annotation.Nullable; -import java.io.File; -import java.io.FileWriter; -import java.io.IOError; -import java.io.IOException; -import java.util.Calendar; - -import static emu.grasscutter.config.Configuration.SERVER; -import static emu.grasscutter.utils.Language.translate; - public final class Grasscutter { public static final File configFile = new File("./config.json"); public static final Reflections reflector = new Reflections("emu.grasscutter"); diff --git a/src/main/java/emu/grasscutter/auth/AuthenticationSystem.java b/src/main/java/emu/grasscutter/auth/AuthenticationSystem.java index 33fd4d4f1..c7f1b832e 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 { @@ -107,11 +106,11 @@ public interface AuthenticationSystem { Authenticator getSessionKeyAuthenticator(); /** - * This is the authenticator used for validating session tokens. - * This is a part of the logic in {@link DispatchUtils#authenticate(String, String)}. - *

- * Plugins can override this authenticator to add - * support for alternate session authentication methods. + * This is the authenticator used for validating session tokens. This is a part of the logic in + * {@link DispatchUtils#authenticate(String, String)}. + * + *

Plugins can override this authenticator to add support for alternate session authentication + * methods. * * @return {@code true} if the session token is valid, {@code false} otherwise. */ diff --git a/src/main/java/emu/grasscutter/auth/DefaultAuthentication.java b/src/main/java/emu/grasscutter/auth/DefaultAuthentication.java index 90ee1d02e..d210705b1 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 eb012e5f8..fdb1bc24c 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; @@ -11,17 +14,13 @@ import emu.grasscutter.server.http.objects.ComboTokenResJson; import emu.grasscutter.server.http.objects.LoginResultJson; import emu.grasscutter.utils.FileUtils; import emu.grasscutter.utils.Utils; - -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 { @@ -51,18 +50,18 @@ public final class DefaultAuthenticators { if (account == null) { responseMessage = translate("messages.dispatch.account.username_create_error"); Grasscutter.getLogger() - .info(translate("messages.dispatch.account.account_login_create_error", address)); + .info(translate("messages.dispatch.account.account_login_create_error", address)); } else { // Continue with login. successfulLogin = true; // Log the creation. Grasscutter.getLogger() - .info( - translate( - "messages.dispatch.account.account_login_create_success", - address, - response.data.account.uid)); + .info( + translate( + "messages.dispatch.account.account_login_create_success", + address, + response.data.account.uid)); } } else if (account != null) successfulLogin = true; else @@ -132,25 +131,25 @@ public final class DefaultAuthenticators { if (decryptedPassword.length() >= 8) { account = DatabaseHelper.createAccountWithUid(requestData.account, 0); account.setPassword( - BCrypt.withDefaults().hashToString(12, decryptedPassword.toCharArray())); + BCrypt.withDefaults().hashToString(12, decryptedPassword.toCharArray())); account.save(); // Check if the account was created successfully. if (account == null) { responseMessage = translate("messages.dispatch.account.username_create_error"); loggerMessage = - translate("messages.dispatch.account.account_login_create_error", address); + translate("messages.dispatch.account.account_login_create_error", address); } else { // Continue with login. successfulLogin = true; // Log the creation. Grasscutter.getLogger() - .info( - translate( - "messages.dispatch.account.account_login_create_success", - address, - response.data.account.uid)); + .info( + translate( + "messages.dispatch.account.account_login_create_success", + address, + response.data.account.uid)); } } else { successfulLogin = false; @@ -160,8 +159,8 @@ public final class DefaultAuthenticators { } else if (account != null) { if (account.getPassword() != null && !account.getPassword().isEmpty()) { if (BCrypt.verifyer() - .verify(decryptedPassword.toCharArray(), account.getPassword()) - .verified) { + .verify(decryptedPassword.toCharArray(), account.getPassword()) + .verified) { successfulLogin = true; } else { successfulLogin = false; @@ -171,7 +170,7 @@ public final class DefaultAuthenticators { } else { successfulLogin = false; loggerMessage = - translate("messages.dispatch.account.login_password_storage_error", address); + translate("messages.dispatch.account.login_password_storage_error", address); responseMessage = translate("messages.dispatch.account.password_storage_error"); } } else { @@ -229,7 +228,7 @@ public final class DefaultAuthenticators { // Log the login. loggerMessage = - translate("messages.dispatch.account.login_token_success", address, requestData.uid); + translate("messages.dispatch.account.login_token_success", address, requestData.uid); } else { response.retcode = -201; response.message = translate("messages.dispatch.account.account_cache_error"); @@ -349,20 +348,21 @@ public final class DefaultAuthenticators { var client = Grasscutter.getGameServer().getDispatchClient(); var future = new CompletableFuture(); - client.registerCallback(PacketIds.TokenValidateRsp, packet -> { - var data = IDispatcher.decode(packet); + client.registerCallback( + PacketIds.TokenValidateRsp, + packet -> { + var data = IDispatcher.decode(packet); - // Check if the token is valid. - var valid = data.get("valid").getAsBoolean(); - if (!valid) { - future.complete(null); - return; - } + // Check if the token is valid. + var valid = data.get("valid").getAsBoolean(); + if (!valid) { + future.complete(null); + return; + } - // Return the account data. - future.complete(IDispatcher.decode( - data.get("account"), Account.class)); - }); + // Return the account data. + future.complete(IDispatcher.decode(data.get("account"), Account.class)); + }); client.sendMessage(PacketIds.TokenValidateReq, tokenRequest); try { diff --git a/src/main/java/emu/grasscutter/command/commands/AccountCommand.java b/src/main/java/emu/grasscutter/command/commands/AccountCommand.java index 1b7314c4b..fa9f5be23 100644 --- a/src/main/java/emu/grasscutter/command/commands/AccountCommand.java +++ b/src/main/java/emu/grasscutter/command/commands/AccountCommand.java @@ -1,5 +1,7 @@ package emu.grasscutter.command.commands; +import static emu.grasscutter.utils.Language.translate; + import at.favre.lib.crypto.bcrypt.BCrypt; import emu.grasscutter.Grasscutter; import emu.grasscutter.command.Command; @@ -9,12 +11,9 @@ import emu.grasscutter.database.DatabaseHelper; import emu.grasscutter.database.DatabaseManager; import emu.grasscutter.game.Account; import emu.grasscutter.game.player.Player; - import java.util.List; import java.util.stream.Collectors; -import static emu.grasscutter.utils.Language.translate; - @Command( label = "account", usage = { diff --git a/src/main/java/emu/grasscutter/database/DatabaseManager.java b/src/main/java/emu/grasscutter/database/DatabaseManager.java index 809566559..45ad073fa 100644 --- a/src/main/java/emu/grasscutter/database/DatabaseManager.java +++ b/src/main/java/emu/grasscutter/database/DatabaseManager.java @@ -1,5 +1,7 @@ package emu.grasscutter.database; +import static emu.grasscutter.config.Configuration.DATABASE; + import com.mongodb.MongoCommandException; import com.mongodb.client.MongoClient; import com.mongodb.client.MongoClients; @@ -16,8 +18,6 @@ import emu.grasscutter.Grasscutter.ServerRunMode; import emu.grasscutter.game.Account; import org.reflections.Reflections; -import static emu.grasscutter.config.Configuration.DATABASE; - public final class DatabaseManager { private static Datastore gameDatastore; private static Datastore dispatchDatastore; @@ -27,8 +27,7 @@ public final class DatabaseManager { } public static Datastore getAccountDatastore() { - if (Grasscutter.getRunMode() == ServerRunMode.HYBRID) - return gameDatastore; + if (Grasscutter.getRunMode() == ServerRunMode.HYBRID) return gameDatastore; else return dispatchDatastore; } diff --git a/src/main/java/emu/grasscutter/game/gacha/GachaSystem.java b/src/main/java/emu/grasscutter/game/gacha/GachaSystem.java index 94989aeca..eebd0977d 100644 --- a/src/main/java/emu/grasscutter/game/gacha/GachaSystem.java +++ b/src/main/java/emu/grasscutter/game/gacha/GachaSystem.java @@ -1,5 +1,7 @@ package emu.grasscutter.game.gacha; +import static emu.grasscutter.config.Configuration.GAME_OPTIONS; + import com.sun.nio.file.SensitivityWatchEventModifier; import emu.grasscutter.Grasscutter; import emu.grasscutter.data.DataLoader; @@ -29,14 +31,11 @@ import it.unimi.dsi.fastutil.ints.Int2ObjectMap; import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap; import it.unimi.dsi.fastutil.ints.IntArrayList; import it.unimi.dsi.fastutil.ints.IntList; -import org.greenrobot.eventbus.Subscribe; - import java.nio.file.*; import java.util.ArrayList; import java.util.List; import java.util.concurrent.ThreadLocalRandom; - -import static emu.grasscutter.config.Configuration.GAME_OPTIONS; +import org.greenrobot.eventbus.Subscribe; public class GachaSystem extends BaseGameSystem { private static final int starglitterId = 221; diff --git a/src/main/java/emu/grasscutter/server/dispatch/DispatchClient.java b/src/main/java/emu/grasscutter/server/dispatch/DispatchClient.java index 44ff59efc..38ae5e411 100644 --- a/src/main/java/emu/grasscutter/server/dispatch/DispatchClient.java +++ b/src/main/java/emu/grasscutter/server/dispatch/DispatchClient.java @@ -1,17 +1,13 @@ 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.server.game.GameServer; import emu.grasscutter.server.http.handlers.GachaHandler; import emu.grasscutter.utils.Crypto; -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; @@ -21,17 +17,17 @@ 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(); - @Getter private final Map> handlers - = new HashMap<>(); + @Getter private final Logger logger = Grasscutter.getLogger(); + @Getter private final Map> handlers = new HashMap<>(); - @Getter private final Map>> callbacks - = new HashMap<>(); + @Getter private final Map>> callbacks = new HashMap<>(); public DispatchClient(URI serverUri) { super(serverUri); @@ -58,8 +54,7 @@ public final class DispatchClient extends WebSocketClient implements IDispatcher var response = new JsonObject(); // Find a player with the specified account ID. - var player = Grasscutter.getGameServer() - .getPlayerByAccountId(accountId); + var player = Grasscutter.getGameServer().getPlayerByAccountId(accountId); if (player == null) { response.addProperty("retcode", 1); this.sendMessage(PacketIds.GachaHistoryRsp, response); @@ -67,8 +62,7 @@ public final class DispatchClient extends WebSocketClient implements IDispatcher } // Fetch the gacha records. - GachaHandler.fetchGachaRecords( - player, response, page, type); + GachaHandler.fetchGachaRecords(player, response, page, type); // Send the response. this.sendMessage(PacketIds.GachaHistoryRsp, response); @@ -82,8 +76,7 @@ public final class DispatchClient extends WebSocketClient implements IDispatcher public void sendMessage(int packetId, Object message) { var serverMessage = this.encodeMessage(packetId, message); // Serialize the message into JSON. - var serialized = JSON.toJson(serverMessage) - .getBytes(StandardCharsets.UTF_8); + var serialized = JSON.toJson(serverMessage).getBytes(StandardCharsets.UTF_8); // Encrypt the message. Crypto.xor(serialized, DISPATCH_INFO.encryptionKey); // Send the message. @@ -100,8 +93,7 @@ public final class DispatchClient extends WebSocketClient implements IDispatcher @Override public void onMessage(String message) { - this.getLogger().debug("Received dispatch message from server:\n{}", - message); + this.getLogger().debug("Received dispatch message from server:\n{}", message); } @Override @@ -114,17 +106,20 @@ public final class DispatchClient extends WebSocketClient implements IDispatcher this.getLogger().info("Dispatch connection closed."); // Attempt to reconnect. - new Thread(() -> { - try { - // Wait 5 seconds before reconnecting. - Thread.sleep(5000L); - } catch (Exception ignored) { } + new Thread( + () -> { + try { + // Wait 5 seconds before reconnecting. + Thread.sleep(5000L); + } catch (Exception ignored) { + } - // Attempt to reconnect. - Grasscutter.getGameServer().setDispatchClient( - new DispatchClient(GameServer.getDispatchUrl())); - Grasscutter.getGameServer().getDispatchClient().connect(); - }).start(); + // Attempt to reconnect. + Grasscutter.getGameServer() + .setDispatchClient(new DispatchClient(GameServer.getDispatchUrl())); + Grasscutter.getGameServer().getDispatchClient().connect(); + }) + .start(); } @Override diff --git a/src/main/java/emu/grasscutter/server/dispatch/DispatchServer.java b/src/main/java/emu/grasscutter/server/dispatch/DispatchServer.java index 552eb9545..8aaa09f5c 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,18 +15,18 @@ 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 { - @Getter private final Logger logger - = Grasscutter.getLogger(); - @Getter private final Map> handlers - = new HashMap<>(); + @Getter private final Logger logger = Grasscutter.getLogger(); + @Getter private final Map> handlers = new HashMap<>(); - @Getter private final Map>> callbacks - = new HashMap<>(); + @Getter private final Map>> callbacks = new HashMap<>(); /** * Constructs a new {@code DispatchServer} instance. @@ -52,15 +48,13 @@ public final class DispatchServer extends WebSocketServer implements IDispatcher * @param object The packet data. */ private void handleLogin(WebSocket socket, JsonElement object) { - var dispatchKey = object.getAsString() - .replaceAll("\"", ""); + var dispatchKey = object.getAsString().replaceAll("\"", ""); // Check if the dispatch key is valid. if (!dispatchKey.equals(DISPATCH_INFO.dispatchKey)) { - this.getLogger().warn("Invalid dispatch key received from {}.", - socket.getRemoteSocketAddress()); - this.getLogger().debug("Expected: {}, Received: {}", - DISPATCH_INFO.dispatchKey, dispatchKey); + this.getLogger() + .warn("Invalid dispatch key received from {}.", socket.getRemoteSocketAddress()); + this.getLogger().debug("Expected: {}, Received: {}", DISPATCH_INFO.dispatchKey, dispatchKey); socket.close(); } else { socket.setAttachment(true); @@ -84,8 +78,7 @@ public final class DispatchServer extends WebSocketServer implements IDispatcher // Create the response message. var response = new JsonObject(); response.addProperty("valid", valid); - if (valid) response.add("account", - JSON.toJsonTree(account)); + if (valid) response.add("account", JSON.toJsonTree(account)); // Send the response. this.sendMessage(socket, PacketIds.TokenValidateRsp, response); @@ -98,8 +91,7 @@ public final class DispatchServer extends WebSocketServer implements IDispatcher */ public void sendMessage(int packetId, Object message) { var serverMessage = this.encodeMessage(packetId, message); - this.getConnections().forEach( - socket -> this.sendMessage(socket, serverMessage)); + this.getConnections().forEach(socket -> this.sendMessage(socket, serverMessage)); } /** @@ -110,8 +102,7 @@ public final class DispatchServer extends WebSocketServer implements IDispatcher */ public void sendMessage(WebSocket socket, Object message) { // Serialize the message into JSON. - var serialized = JSON.toJson(message) - .getBytes(StandardCharsets.UTF_8); + var serialized = JSON.toJson(message).getBytes(StandardCharsets.UTF_8); // Encrypt the message. Crypto.xor(serialized, DISPATCH_INFO.encryptionKey); // Send the message. @@ -131,20 +122,18 @@ public final class DispatchServer extends WebSocketServer implements IDispatcher @Override public void onStart() { - this.getLogger().info("Dispatch server started on port {}.", - this.getPort()); + this.getLogger().info("Dispatch server started on port {}.", this.getPort()); } @Override public void onOpen(WebSocket conn, ClientHandshake handshake) { - this.getLogger().debug("Dispatch client connected from {}.", - conn.getRemoteSocketAddress()); + this.getLogger().debug("Dispatch client connected from {}.", conn.getRemoteSocketAddress()); } @Override public void onMessage(WebSocket conn, String message) { - this.getLogger().debug("Received dispatch message from {}:\n{}", - conn.getRemoteSocketAddress(), message); + this.getLogger() + .debug("Received dispatch message from {}:\n{}", conn.getRemoteSocketAddress(), message); } @Override @@ -154,8 +143,7 @@ public final class DispatchServer extends WebSocketServer implements IDispatcher @Override public void onClose(WebSocket conn, int code, String reason, boolean remote) { - this.getLogger().debug("Dispatch client disconnected from {}.", - conn.getRemoteSocketAddress()); + this.getLogger().debug("Dispatch client disconnected from {}.", conn.getRemoteSocketAddress()); } @Override diff --git a/src/main/java/emu/grasscutter/server/dispatch/IDispatcher.java b/src/main/java/emu/grasscutter/server/dispatch/IDispatcher.java index afd987bf6..3e09f4723 100644 --- a/src/main/java/emu/grasscutter/server/dispatch/IDispatcher.java +++ b/src/main/java/emu/grasscutter/server/dispatch/IDispatcher.java @@ -1,28 +1,28 @@ 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; import java.util.Map; import java.util.function.BiConsumer; import java.util.function.Consumer; - -import static emu.grasscutter.config.Configuration.DISPATCH_INFO; +import org.java_websocket.WebSocket; +import org.slf4j.Logger; public interface IDispatcher { - Gson JSON = new GsonBuilder() - .disableHtmlEscaping() - .registerTypeAdapter(byte[].class, new ByteArrayAdapter()) - .create(); + Gson JSON = + new GsonBuilder() + .disableHtmlEscaping() + .registerTypeAdapter(byte[].class, new ByteArrayAdapter()) + .create(); /** * Decodes an escaped JSON message. @@ -47,8 +47,7 @@ public interface IDispatcher { var data = element.getAsString(); // Check if the element starts and ends with quotes. - if (data.startsWith("\"") - && data.endsWith("\"")) { + if (data.startsWith("\"") && data.endsWith("\"")) { // Remove the quotes. data = data.substring(1, data.length() - 1); } @@ -72,8 +71,7 @@ public interface IDispatcher { // Decrypt the message. Crypto.xor(message, DISPATCH_INFO.encryptionKey); // Deserialize the message. - return JSON.fromJson(new String( - message, StandardCharsets.UTF_8), JsonObject.class); + return JSON.fromJson(new String(message, StandardCharsets.UTF_8), JsonObject.class); } /** @@ -116,8 +114,7 @@ public interface IDispatcher { if (packetId != PacketIds.LoginNotify) { if (socket.getAttachment() instanceof Boolean authenticated) { if (!authenticated) { - this.getLogger().warn("Received packet ID {} from unauthenticated client.", - packetId); + this.getLogger().warn("Received packet ID {} from unauthenticated client.", packetId); socket.close(); return; } @@ -138,13 +135,11 @@ public interface IDispatcher { // Get the callbacks. var callbacks = this.getCallbacks().get(packetId); // Call the callbacks. - callbacks.forEach(callback -> - callback.accept(packetData)); + callbacks.forEach(callback -> callback.accept(packetData)); callbacks.clear(); } } catch (Exception exception) { - this.getLogger().warn("Exception occurred while handling packet {}.", - packetId); + this.getLogger().warn("Exception occurred while handling packet {}.", packetId); exception.printStackTrace(); } } diff --git a/src/main/java/emu/grasscutter/server/game/GameServer.java b/src/main/java/emu/grasscutter/server/game/GameServer.java index f88999fb4..97c49b02f 100644 --- a/src/main/java/emu/grasscutter/server/game/GameServer.java +++ b/src/main/java/emu/grasscutter/server/game/GameServer.java @@ -1,5 +1,9 @@ package emu.grasscutter.server.game; +import static emu.grasscutter.config.Configuration.DISPATCH_INFO; +import static emu.grasscutter.config.Configuration.GAME_INFO; +import static emu.grasscutter.utils.Language.translate; + import emu.grasscutter.GameConstants; import emu.grasscutter.Grasscutter; import emu.grasscutter.Grasscutter.ServerRunMode; @@ -37,22 +41,17 @@ import emu.grasscutter.server.event.internal.ServerStopEvent; import emu.grasscutter.server.event.types.ServerEvent; import emu.grasscutter.server.scheduler.ServerTaskScheduler; import emu.grasscutter.task.TaskMap; -import kcp.highway.ChannelConfig; -import kcp.highway.KcpServer; -import lombok.Getter; -import lombok.Setter; -import lombok.SneakyThrows; - import java.net.InetSocketAddress; import java.net.URI; import java.time.Instant; import java.time.OffsetDateTime; import java.util.*; import java.util.concurrent.ConcurrentHashMap; - -import static emu.grasscutter.config.Configuration.DISPATCH_INFO; -import static emu.grasscutter.config.Configuration.GAME_INFO; -import static emu.grasscutter.utils.Language.translate; +import kcp.highway.ChannelConfig; +import kcp.highway.KcpServer; +import lombok.Getter; +import lombok.Setter; +import lombok.SneakyThrows; @Getter public final class GameServer extends KcpServer { diff --git a/src/main/java/emu/grasscutter/server/http/dispatch/AuthenticationHandler.java b/src/main/java/emu/grasscutter/server/http/dispatch/AuthenticationHandler.java index a6420a572..e6fa37042 100644 --- a/src/main/java/emu/grasscutter/server/http/dispatch/AuthenticationHandler.java +++ b/src/main/java/emu/grasscutter/server/http/dispatch/AuthenticationHandler.java @@ -1,5 +1,7 @@ package emu.grasscutter.server.http.dispatch; +import static emu.grasscutter.utils.Language.translate; + import emu.grasscutter.Grasscutter; import emu.grasscutter.auth.AuthenticationSystem; import emu.grasscutter.auth.OAuthAuthenticator.ClientType; @@ -12,8 +14,6 @@ import emu.grasscutter.utils.JsonUtils; import io.javalin.Javalin; import io.javalin.http.Context; -import static emu.grasscutter.utils.Language.translate; - /** Handles requests related to authentication. */ public final class AuthenticationHandler implements Router { /** @@ -96,7 +96,8 @@ public final class AuthenticationHandler implements Router { // Cached token login (from registry). javalin.post("/hk4e_global/mdk/shield/api/verify", AuthenticationHandler::tokenLogin); // Combo token login (from session key). - javalin.post("/hk4e_global/combo/granter/login/v2/login", AuthenticationHandler::sessionKeyLogin); + javalin.post( + "/hk4e_global/combo/granter/login/v2/login", AuthenticationHandler::sessionKeyLogin); // CN // Username & Password login (from client). diff --git a/src/main/java/emu/grasscutter/server/http/dispatch/RegionHandler.java b/src/main/java/emu/grasscutter/server/http/dispatch/RegionHandler.java index feb7d176a..0d3409e9a 100644 --- a/src/main/java/emu/grasscutter/server/http/dispatch/RegionHandler.java +++ b/src/main/java/emu/grasscutter/server/http/dispatch/RegionHandler.java @@ -1,5 +1,7 @@ package emu.grasscutter.server.http.dispatch; +import static emu.grasscutter.config.Configuration.*; + import com.google.gson.JsonArray; import com.google.gson.JsonObject; import com.google.protobuf.ByteString; @@ -21,15 +23,12 @@ import emu.grasscutter.utils.JsonUtils; import emu.grasscutter.utils.Utils; import io.javalin.Javalin; import io.javalin.http.Context; -import org.slf4j.Logger; - import java.time.Instant; import java.util.ArrayList; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; import java.util.regex.Pattern; - -import static emu.grasscutter.config.Configuration.*; +import org.slf4j.Logger; /** Handles requests related to region queries. */ public final class RegionHandler implements Router { @@ -342,7 +341,8 @@ public final class RegionHandler implements Router { * @return A {@link QueryCurrRegionHttpRsp} object. */ public static QueryCurrRegionHttpRsp getCurrentRegion() { - return Grasscutter.getRunMode() == ServerRunMode.HYBRID ? - regions.get("os_usa").getRegionQuery() : null; + return Grasscutter.getRunMode() == ServerRunMode.HYBRID + ? regions.get("os_usa").getRegionQuery() + : null; } } diff --git a/src/main/java/emu/grasscutter/server/http/handlers/GachaHandler.java b/src/main/java/emu/grasscutter/server/http/handlers/GachaHandler.java index 3d3430df3..6253e416c 100644 --- a/src/main/java/emu/grasscutter/server/http/handlers/GachaHandler.java +++ b/src/main/java/emu/grasscutter/server/http/handlers/GachaHandler.java @@ -1,5 +1,7 @@ package emu.grasscutter.server.http.handlers; +import static emu.grasscutter.utils.Language.translate; + import com.google.gson.JsonObject; import emu.grasscutter.Grasscutter; import emu.grasscutter.database.DatabaseHelper; @@ -12,16 +14,13 @@ import io.javalin.Javalin; import io.javalin.http.ContentType; import io.javalin.http.Context; import io.javalin.http.staticfiles.Location; -import lombok.Getter; - import java.io.IOException; import java.nio.charset.StandardCharsets; import java.nio.file.Files; import java.nio.file.Path; import java.util.Arrays; import java.util.LinkedHashSet; - -import static emu.grasscutter.utils.Language.translate; +import lombok.Getter; /** Handles all gacha-related HTTP requests. */ public final class GachaHandler implements Router { @@ -49,8 +48,7 @@ public final class GachaHandler implements Router { if (gachaTypeStr != null) gachaType = Integer.parseInt(gachaTypeStr); // Make request to dispatch server. - var data = DispatchUtils.fetchGachaRecords( - account.getId(), page, gachaType); + var data = DispatchUtils.fetchGachaRecords(account.getId(), page, gachaType); var records = data.get("records").getAsString(); var maxPage = data.get("maxPage").getAsLong(); @@ -77,7 +75,8 @@ public final class GachaHandler implements Router { return; } - String template;try { + String template; + try { template = Files.readString(detailsTemplate); } catch (IOException e) { Grasscutter.getLogger().warn("Failed to read data/gacha/details.html"); @@ -113,8 +112,7 @@ public final class GachaHandler implements Router { // Add 5-star items. var fiveStarItems = new LinkedHashSet(); - Arrays.stream(banner.getRateUpItems5()) - .forEach(i -> fiveStarItems.add(Integer.toString(i))); + Arrays.stream(banner.getRateUpItems5()).forEach(i -> fiveStarItems.add(Integer.toString(i))); Arrays.stream(banner.getFallbackItems5Pool1()) .forEach(i -> fiveStarItems.add(Integer.toString(i))); Arrays.stream(banner.getFallbackItems5Pool2()) @@ -125,8 +123,7 @@ public final class GachaHandler implements Router { // Add 4-star items. var fourStarItems = new LinkedHashSet(); - Arrays.stream(banner.getRateUpItems4()) - .forEach(i -> fourStarItems.add(Integer.toString(i))); + Arrays.stream(banner.getRateUpItems4()).forEach(i -> fourStarItems.add(Integer.toString(i))); Arrays.stream(banner.getFallbackItems4Pool1()) .forEach(i -> fourStarItems.add(Integer.toString(i))); Arrays.stream(banner.getFallbackItems4Pool2()) @@ -136,8 +133,7 @@ public final class GachaHandler implements Router { // Add 3-star items. var threeStarItems = new LinkedHashSet(); - Arrays.stream(banner.getFallbackItems3()) - .forEach(i -> threeStarItems.add(Integer.toString(i))); + Arrays.stream(banner.getFallbackItems3()).forEach(i -> threeStarItems.add(Integer.toString(i))); template = template.replace("{{THREE_STARS}}", "[" + String.join(",", threeStarItems) + "]"); // Done. @@ -153,15 +149,10 @@ public final class GachaHandler implements Router { * @param page The page to fetch. * @param type The gacha type to fetch. */ - public static void fetchGachaRecords( - Player player, JsonObject response, - int page, int type - ) { + public static void fetchGachaRecords(Player player, JsonObject response, int page, int type) { var playerId = player.getUid(); - var records = DatabaseHelper.getGachaRecords( - playerId, page, type).toString(); - var maxPage = DatabaseHelper.getGachaRecordsMaxPage( - playerId, page, type); + var records = DatabaseHelper.getGachaRecords(playerId, page, type).toString(); + var maxPage = DatabaseHelper.getGachaRecordsMaxPage(playerId, page, type); // Finish the response. response.addProperty("retcode", 0); diff --git a/src/main/java/emu/grasscutter/server/http/objects/LoginTokenRequestJson.java b/src/main/java/emu/grasscutter/server/http/objects/LoginTokenRequestJson.java index 14f0a3580..948d4f895 100644 --- a/src/main/java/emu/grasscutter/server/http/objects/LoginTokenRequestJson.java +++ b/src/main/java/emu/grasscutter/server/http/objects/LoginTokenRequestJson.java @@ -2,9 +2,7 @@ package emu.grasscutter.server.http.objects; import lombok.Builder; -/** - * This request object is used in both token-related authenticators. - */ +/** This request object is used in both token-related authenticators. */ @Builder public class LoginTokenRequestJson { public String uid; diff --git a/src/main/java/emu/grasscutter/server/packet/recv/HandlerGetPlayerTokenReq.java b/src/main/java/emu/grasscutter/server/packet/recv/HandlerGetPlayerTokenReq.java index 35a863cc1..e52fe48c5 100644 --- a/src/main/java/emu/grasscutter/server/packet/recv/HandlerGetPlayerTokenReq.java +++ b/src/main/java/emu/grasscutter/server/packet/recv/HandlerGetPlayerTokenReq.java @@ -1,5 +1,7 @@ package emu.grasscutter.server.packet.recv; +import static emu.grasscutter.config.Configuration.ACCOUNT; + import emu.grasscutter.Grasscutter; import emu.grasscutter.database.DatabaseHelper; import emu.grasscutter.game.player.Player; @@ -15,12 +17,9 @@ import emu.grasscutter.utils.ByteHelper; import emu.grasscutter.utils.Crypto; import emu.grasscutter.utils.DispatchUtils; import emu.grasscutter.utils.Utils; - -import javax.crypto.Cipher; import java.nio.ByteBuffer; import java.security.Signature; - -import static emu.grasscutter.config.Configuration.ACCOUNT; +import javax.crypto.Cipher; @Opcodes(PacketOpcodes.GetPlayerTokenReq) public class HandlerGetPlayerTokenReq extends PacketHandler { @@ -30,8 +29,7 @@ public class HandlerGetPlayerTokenReq extends PacketHandler { // Fetch the account from the ID and token. var accountId = req.getAccountUid(); - var account = DispatchUtils.authenticate( - accountId, req.getAccountToken()); + var account = DispatchUtils.authenticate(accountId, req.getAccountToken()); // Check the account. if (account == null) { @@ -47,8 +45,7 @@ public class HandlerGetPlayerTokenReq extends PacketHandler { // secondly !!! // TODO - optimize boolean kicked = false; - var exists = Grasscutter.getGameServer() - .getPlayerByAccountId(accountId); + var exists = Grasscutter.getGameServer().getPlayerByAccountId(accountId); if (exists != null) { var existsSession = exists.getSession(); if (existsSession != session) { // No self-kicking diff --git a/src/main/java/emu/grasscutter/server/packet/send/PacketPlayerLoginRsp.java b/src/main/java/emu/grasscutter/server/packet/send/PacketPlayerLoginRsp.java index 8597f41b0..ad326aee8 100644 --- a/src/main/java/emu/grasscutter/server/packet/send/PacketPlayerLoginRsp.java +++ b/src/main/java/emu/grasscutter/server/packet/send/PacketPlayerLoginRsp.java @@ -1,5 +1,8 @@ package emu.grasscutter.server.packet.send; +import static emu.grasscutter.config.Configuration.GAME_INFO; +import static emu.grasscutter.config.Configuration.lr; + import com.google.protobuf.ByteString; import emu.grasscutter.Grasscutter; import emu.grasscutter.Grasscutter.ServerRunMode; @@ -11,12 +14,8 @@ import emu.grasscutter.net.proto.RegionInfoOuterClass.RegionInfo; import emu.grasscutter.server.game.GameSession; import emu.grasscutter.server.http.dispatch.RegionHandler; import emu.grasscutter.utils.Crypto; - import java.util.Objects; -import static emu.grasscutter.config.Configuration.GAME_INFO; -import static emu.grasscutter.config.Configuration.lr; - public class PacketPlayerLoginRsp extends BasePacket { private static QueryCurrRegionHttpRspOuterClass.QueryCurrRegionHttpRsp regionCache; diff --git a/src/main/java/emu/grasscutter/utils/DispatchUtils.java b/src/main/java/emu/grasscutter/utils/DispatchUtils.java index 827372b82..4e905d627 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.JsonObject; import emu.grasscutter.Grasscutter; import emu.grasscutter.auth.AuthenticationSystem.AuthenticationRequest; @@ -9,20 +11,18 @@ import emu.grasscutter.server.dispatch.IDispatcher; import emu.grasscutter.server.dispatch.PacketIds; import emu.grasscutter.server.http.handlers.GachaHandler; import emu.grasscutter.server.http.objects.LoginTokenRequestJson; - -import javax.annotation.Nullable; import java.net.http.HttpClient; 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. */ - HttpClient HTTP_CLIENT = HttpClient.newBuilder() - .version(HttpClient.Version.HTTP_2) - .followRedirects(HttpClient.Redirect.ALWAYS) - .build(); + HttpClient HTTP_CLIENT = + HttpClient.newBuilder() + .version(HttpClient.Version.HTTP_2) + .followRedirects(HttpClient.Redirect.ALWAYS) + .build(); /** * @return The dispatch URL. @@ -38,22 +38,16 @@ public interface DispatchUtils { * @param token The token. * @return {@code true} if the authentication request is valid, otherwise {@code false}. */ - @Nullable - static Account authenticate(String accountId, String token) { + @Nullable static Account authenticate(String accountId, String token) { return switch (Grasscutter.getRunMode()) { case GAME_ONLY -> - // Use the authentication system to validate the token. - Grasscutter.getAuthenticationSystem() + // Use the authentication system to validate the token. + Grasscutter.getAuthenticationSystem() .getSessionTokenValidator() .authenticate( - AuthenticationRequest.builder() - .tokenRequest( - LoginTokenRequestJson.builder() - .uid(accountId) - .token(token) - .build() - ).build() - ); + AuthenticationRequest.builder() + .tokenRequest(LoginTokenRequestJson.builder().uid(accountId).token(token).build()) + .build()); case HYBRID, DISPATCH_ONLY -> { // Fetch the account from the database. var account = DatabaseHelper.getAccountById(accountId); @@ -86,8 +80,9 @@ public interface DispatchUtils { var future = new CompletableFuture(); // Listen for the response. var server = Grasscutter.getDispatchServer(); - server.registerCallback(PacketIds.GachaHistoryRsp, packet -> - future.complete(IDispatcher.decode(packet, JsonObject.class))); + server.registerCallback( + PacketIds.GachaHistoryRsp, + packet -> future.complete(IDispatcher.decode(packet, JsonObject.class))); // Broadcast the request. server.sendMessage(PacketIds.GachaHistoryReq, request); @@ -104,16 +99,14 @@ public interface DispatchUtils { var response = new JsonObject(); // Get the player's ID from the account. - var player = Grasscutter.getGameServer() - .getPlayerByAccountId(accountId); + var player = Grasscutter.getGameServer().getPlayerByAccountId(accountId); if (player == null) { response.addProperty("retcode", 1); yield response; } // Fetch the gacha records. - GachaHandler.fetchGachaRecords( - player, response, page, gachaType); + GachaHandler.fetchGachaRecords(player, response, page, gachaType); yield response; } diff --git a/src/main/java/emu/grasscutter/utils/JsonAdapters.java b/src/main/java/emu/grasscutter/utils/JsonAdapters.java index f6e64b05e..184c70691 100644 --- a/src/main/java/emu/grasscutter/utils/JsonAdapters.java +++ b/src/main/java/emu/grasscutter/utils/JsonAdapters.java @@ -11,13 +11,12 @@ import emu.grasscutter.data.common.DynamicFloat; import it.unimi.dsi.fastutil.floats.FloatArrayList; import it.unimi.dsi.fastutil.ints.IntArrayList; import it.unimi.dsi.fastutil.ints.IntList; -import lombok.val; - import java.io.IOException; import java.lang.reflect.Field; import java.util.ArrayList; import java.util.HashMap; import java.util.Objects; +import lombok.val; public class JsonAdapters { static class DynamicFloatAdapter extends TypeAdapter { diff --git a/src/main/java/emu/grasscutter/utils/Language.java b/src/main/java/emu/grasscutter/utils/Language.java index c92e7a2a0..b79110d9f 100644 --- a/src/main/java/emu/grasscutter/utils/Language.java +++ b/src/main/java/emu/grasscutter/utils/Language.java @@ -1,5 +1,9 @@ package emu.grasscutter.utils; +import static emu.grasscutter.config.Configuration.FALLBACK_LANGUAGE; +import static emu.grasscutter.utils.FileUtils.getCachePath; +import static emu.grasscutter.utils.FileUtils.getResourcePath; + import com.google.gson.JsonElement; import com.google.gson.JsonObject; import emu.grasscutter.Grasscutter; @@ -13,8 +17,6 @@ import it.unimi.dsi.fastutil.ints.IntOpenHashSet; import it.unimi.dsi.fastutil.ints.IntSet; import it.unimi.dsi.fastutil.objects.Object2IntMap; import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap; -import lombok.EqualsAndHashCode; - import java.io.*; import java.nio.charset.StandardCharsets; import java.nio.file.Files; @@ -26,10 +28,7 @@ import java.util.regex.Matcher; import java.util.regex.Pattern; import java.util.stream.Collectors; import java.util.stream.IntStream; - -import static emu.grasscutter.config.Configuration.FALLBACK_LANGUAGE; -import static emu.grasscutter.utils.FileUtils.getCachePath; -import static emu.grasscutter.utils.FileUtils.getResourcePath; +import lombok.EqualsAndHashCode; public final class Language { private static final Map cachedLanguages = new ConcurrentHashMap<>(); @@ -133,13 +132,13 @@ public final class Language { for (var i = 0; i < args.length; i++) { args[i] = - switch (args[i].getClass().getSimpleName()) { - case "String" -> args[i]; - case "TextStrings" -> ((TextStrings) args[i]) - .getGC(langCode) - .replace("\\\\n", "\n"); // Note that we don't unescape \n for server console - default -> args[i].toString(); - }; + switch (args[i].getClass().getSimpleName()) { + case "String" -> args[i]; + case "TextStrings" -> ((TextStrings) args[i]) + .getGC(langCode) + .replace("\\\\n", "\n"); // Note that we don't unescape \n for server console + default -> args[i].toString(); + }; } try { diff --git a/src/main/java/emu/grasscutter/utils/StartupArguments.java b/src/main/java/emu/grasscutter/utils/StartupArguments.java index 913955c0e..f9fa8a66a 100644 --- a/src/main/java/emu/grasscutter/utils/StartupArguments.java +++ b/src/main/java/emu/grasscutter/utils/StartupArguments.java @@ -1,73 +1,78 @@ package emu.grasscutter.utils; +import static emu.grasscutter.config.Configuration.*; + import ch.qos.logback.classic.Level; import ch.qos.logback.classic.Logger; import emu.grasscutter.BuildConfig; import emu.grasscutter.Grasscutter; import emu.grasscutter.net.packet.PacketOpcodesUtils; import emu.grasscutter.tools.Dumpers; -import org.slf4j.LoggerFactory; - import java.util.HashMap; import java.util.Map; import java.util.function.Function; - -import static emu.grasscutter.config.Configuration.*; +import org.slf4j.LoggerFactory; /** A parser for start-up arguments. */ public final class StartupArguments { /* A map of parameter -> argument handler. */ - private static final Map> argumentHandlers = new HashMap<>() { - { - putAll(Map.of("-dumppacketids", - parameter -> { - PacketOpcodesUtils.dumpPacketIds(); - return true; - }, - "-version", StartupArguments::printVersion, - "-debug", StartupArguments::enableDebug, - "-lang", - parameter -> { - Grasscutter.setPreferredLanguage(parameter); - return false; - }, - "-game", - parameter -> { - Grasscutter.setRunModeOverride(Grasscutter.ServerRunMode.GAME_ONLY); - return false; - }, - "-dispatch", - parameter -> { - Grasscutter.setRunModeOverride(Grasscutter.ServerRunMode.DISPATCH_ONLY); - return false; - }, - "-noconsole", - parameter -> { - Grasscutter.setNoConsole(true); - return false; - }, - "-test", - parameter -> { - // Disable the console. - SERVER.game.enableConsole = false; - // Disable HTTP encryption. - SERVER.http.encryption.useEncryption = false; - return false; - }, - "-dump", StartupArguments::dump, + private static final Map> argumentHandlers = + new HashMap<>() { + { + putAll( + Map.of( + "-dumppacketids", + parameter -> { + PacketOpcodesUtils.dumpPacketIds(); + return true; + }, + "-version", + StartupArguments::printVersion, + "-debug", + StartupArguments::enableDebug, + "-lang", + parameter -> { + Grasscutter.setPreferredLanguage(parameter); + return false; + }, + "-game", + parameter -> { + Grasscutter.setRunModeOverride(Grasscutter.ServerRunMode.GAME_ONLY); + return false; + }, + "-dispatch", + parameter -> { + Grasscutter.setRunModeOverride(Grasscutter.ServerRunMode.DISPATCH_ONLY); + return false; + }, + "-noconsole", + parameter -> { + Grasscutter.setNoConsole(true); + return false; + }, + "-test", + parameter -> { + // Disable the console. + SERVER.game.enableConsole = false; + // Disable HTTP encryption. + SERVER.http.encryption.useEncryption = false; + return false; + }, + "-dump", + StartupArguments::dump, - // Aliases. - "-v", StartupArguments::printVersion - )); - putAll(Map.of( - "-debugall", - parameter -> { - StartupArguments.enableDebug("all"); - return false; + // Aliases. + "-v", + StartupArguments::printVersion)); + putAll( + Map.of( + "-debugall", + parameter -> { + StartupArguments.enableDebug("all"); + return false; + })); } - )); - } - }; + }; private StartupArguments() { // This class is not meant to be instantiated.