From 2a683a0e366c09cca85c2b7acb3348a77026f907 Mon Sep 17 00:00:00 2001 From: KingRainbow44 Date: Wed, 17 May 2023 00:37:37 -0400 Subject: [PATCH] Add handbook IP authentication in hybrid mode --- .../auth/DefaultAuthenticators.java | 28 ++++++++++++--- .../grasscutter/server/game/GameServer.java | 34 ++++++++++++++----- 2 files changed, 49 insertions(+), 13 deletions(-) diff --git a/src/main/java/emu/grasscutter/auth/DefaultAuthenticators.java b/src/main/java/emu/grasscutter/auth/DefaultAuthenticators.java index 2439102e7..2c7a17ddc 100644 --- a/src/main/java/emu/grasscutter/auth/DefaultAuthenticators.java +++ b/src/main/java/emu/grasscutter/auth/DefaultAuthenticators.java @@ -1,10 +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.Grasscutter.ServerRunMode; import emu.grasscutter.auth.AuthenticationSystem.AuthenticationRequest; import emu.grasscutter.database.DatabaseHelper; import emu.grasscutter.game.Account; @@ -16,13 +14,17 @@ 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 javax.crypto.Cipher; + +import static emu.grasscutter.config.Configuration.ACCOUNT; +import static emu.grasscutter.utils.Language.translate; /** A class containing default authenticators. */ public final class DefaultAuthenticators { @@ -392,6 +394,24 @@ public final class DefaultAuthenticators { var ctx = request.getContext(); if (ctx == null) return; + // Check to see if an IP authentication can be performed. + if (Grasscutter.getRunMode() == ServerRunMode.HYBRID) { + var player = Grasscutter.getGameServer() + .getPlayerByIpAddress(ctx.ip()); + if (player != null) { + // Get the player's session token. + var sessionKey = player.getAccount().getSessionKey(); + // Respond with the handbook auth page. + ctx.status(200).result( + this.authPage + .replace("{{VALUE}}", "true") + .replace("{{SESSION_TOKEN}}", sessionKey) + .replace("{{PLAYER_ID}}", String.valueOf(player.getUid())) + ); + return; + } + } + // Respond with the handbook auth page. ctx.contentType(ContentType.TEXT_HTML).result(this.authPage); } diff --git a/src/main/java/emu/grasscutter/server/game/GameServer.java b/src/main/java/emu/grasscutter/server/game/GameServer.java index 97c49b02f..cf9e4457f 100644 --- a/src/main/java/emu/grasscutter/server/game/GameServer.java +++ b/src/main/java/emu/grasscutter/server/game/GameServer.java @@ -1,9 +1,5 @@ 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; @@ -41,17 +37,22 @@ 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 kcp.highway.ChannelConfig; -import kcp.highway.KcpServer; -import lombok.Getter; -import lombok.Setter; -import lombok.SneakyThrows; + +import static emu.grasscutter.config.Configuration.DISPATCH_INFO; +import static emu.grasscutter.config.Configuration.GAME_INFO; +import static emu.grasscutter.utils.Language.translate; @Getter public final class GameServer extends KcpServer { @@ -246,6 +247,21 @@ public final class GameServer extends KcpServer { return playerOpt.orElse(null); } + /** + * Tries to find a player with the matching IP address. + * + * @param ipAddress The IP address. This should just be numbers without a port. + * @return The player, or null if one could not be found. + */ + public Player getPlayerByIpAddress(String ipAddress) { + return this.getPlayers().values().stream() + .map(Player::getSession) + .filter(session -> session != null && + session.getAddress().getHostString().equals(ipAddress)) + .map(GameSession::getPlayer) + .findFirst().orElse(null); + } + public SocialDetail.Builder getSocialDetailByUid(int id) { // Get from online players Player player = this.getPlayerByUid(id, true);