From 5450c291789e21e81d71d5828b0d7a3f358ac950 Mon Sep 17 00:00:00 2001 From: P0nk Date: Sun, 29 Sep 2024 15:55:14 +0200 Subject: [PATCH] Reduce login state updates, fix multi-login on same acc --- src/main/java/client/Client.java | 63 +------------------ .../handlers/PlayerLoggedinHandler.java | 2 +- .../handlers/login/LoginPasswordHandler.java | 18 +++--- src/main/java/service/AccountService.java | 11 +++- 4 files changed, 21 insertions(+), 73 deletions(-) diff --git a/src/main/java/client/Client.java b/src/main/java/client/Client.java index a1adc2a924..eb0d441035 100644 --- a/src/main/java/client/Client.java +++ b/src/main/java/client/Client.java @@ -63,7 +63,6 @@ import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Timestamp; import java.time.LocalDate; -import java.time.LocalDateTime; import java.util.Arrays; import java.util.Calendar; import java.util.Collections; @@ -502,12 +501,7 @@ public class Client extends ChannelInboundHandlerAdapter { } public boolean attemptLogin() { - if (++failedLoginAttempts >= MAX_FAILED_LOGIN_ATTEMPTS) { - SessionCoordinator.getInstance().closeSession(this, false); - return false; - } - - return true; + return ++failedLoginAttempts < MAX_FAILED_LOGIN_ATTEMPTS; } // TODO: check tempban directly on loaded account @@ -588,32 +582,6 @@ public class Client extends ChannelInboundHandlerAdapter { return accId; } - public void updateLoginState(int newState) { - try (Connection con = DatabaseConnection.getConnection(); - PreparedStatement ps = con.prepareStatement("UPDATE accounts SET loggedin = ?, lastlogin = ? WHERE id = ?")) { - // using sql currenttime here could potentially break the login, thanks Arnah for pointing this out - - ps.setInt(1, newState); - ps.setTimestamp(2, new java.sql.Timestamp(Server.getInstance().getCurrentTime())); - ps.setInt(3, getAccID()); - ps.executeUpdate(); - } catch (SQLException e) { - e.printStackTrace(); - } - - if (newState == LoginState.LOGGED_OUT) { - loggedIn = false; - inServerTransition = false; - setAccID(0); - } else if (newState == LoginState.SERVER_TRANSITION) { - loggedIn = false; - inServerTransition = true; - } else { - loggedIn = true; - inServerTransition = false; - } - } - public void setLoginState(int newState) { if (newState == LoginState.LOGGED_OUT) { loggedIn = false; @@ -630,35 +598,6 @@ public class Client extends ChannelInboundHandlerAdapter { } } - public byte getLoginState(Account account) { - byte loginState = account.loginState(); - if (loginState == LoginState.SERVER_TRANSITION && lastLoginOverThirtySecondsAgo(account)) { - loginState = LoginState.LOGGED_OUT; - updateLoginState(LoginState.LOGGED_OUT); - } - - if (loginState == LoginState.LOGGED_IN) { - loggedIn = true; - } else if (loginState == LoginState.SERVER_TRANSITION) { - try (Connection con = DatabaseConnection.getConnection(); - PreparedStatement ps2 = con.prepareStatement("UPDATE accounts SET loggedin = 0 WHERE id = ?")) { - ps2.setInt(1, getAccID()); - ps2.executeUpdate(); - } catch (SQLException e) { - e.printStackTrace(); - } - } - return loginState; - } - - private static boolean lastLoginOverThirtySecondsAgo(Account account) { - if (account.lastLogin() == null) { - return true; - } - - return account.lastLogin().isBefore(LocalDateTime.now().minusSeconds(30)); - } - public boolean checkBirthDate(Calendar date) { return date.get(Calendar.YEAR) == birthday.get(Calendar.YEAR) && date.get(Calendar.MONTH) == birthday.get(Calendar.MONTH) && date.get(Calendar.DAY_OF_MONTH) == birthday.get(Calendar.DAY_OF_MONTH); } diff --git a/src/main/java/net/server/channel/handlers/PlayerLoggedinHandler.java b/src/main/java/net/server/channel/handlers/PlayerLoggedinHandler.java index d74c9ebffb..9c5bad4eb2 100644 --- a/src/main/java/net/server/channel/handlers/PlayerLoggedinHandler.java +++ b/src/main/java/net/server/channel/handlers/PlayerLoggedinHandler.java @@ -192,7 +192,7 @@ public final class PlayerLoggedinHandler extends AbstractPacketHandler { } try { - int state = c.getLoginState(account); + int state = account.loginState(); if (state != LoginState.SERVER_TRANSITION) { c.setPlayer(null); c.setAccID(0); diff --git a/src/main/java/net/server/handlers/login/LoginPasswordHandler.java b/src/main/java/net/server/handlers/login/LoginPasswordHandler.java index 692c51ed50..e24b1b3852 100644 --- a/src/main/java/net/server/handlers/login/LoginPasswordHandler.java +++ b/src/main/java/net/server/handlers/login/LoginPasswordHandler.java @@ -83,8 +83,11 @@ public final class LoginPasswordHandler implements PacketHandler { c.setHwid(new Hwid(HexTool.toCompactHexString(hwidNibbles))); if (!c.attemptLogin()) { + c.sendPacket(PacketCreator.getLoginFailed(10)); + SessionCoordinator.getInstance().closeSession(c, false); return; } + Optional foundAccount = accountService.getAccount(login); if (foundAccount.isEmpty()) { if (YamlConfig.config.server.AUTOMATIC_REGISTER) { @@ -97,6 +100,12 @@ public final class LoginPasswordHandler implements PacketHandler { } Account account = foundAccount.get(); + + if (!correctPassword(pwd, account)) { + c.sendPacket(PacketCreator.getLoginFailed(4)); + return; + } + if (account.banned()) { c.sendPacket(PacketCreator.getLoginFailed(3)); // TODO: send ban reason instead of login failed, something like this: @@ -104,18 +113,13 @@ public final class LoginPasswordHandler implements PacketHandler { return; } - if (!correctPassword(pwd, account)) { - c.sendPacket(PacketCreator.getLoginFailed(4)); + if (account.loginState() > LoginState.LOGGED_OUT) { + c.sendPacket(PacketCreator.getLoginFailed(7)); return; } c.setAccount(account); - if (c.getLoginState(account) > LoginState.LOGGED_OUT) { - c.sendPacket(PacketCreator.getLoginFailed(7)); - return; - } - if (!account.acceptedTos()) { c.sendPacket(PacketCreator.getLoginFailed(23)); return; diff --git a/src/main/java/service/AccountService.java b/src/main/java/service/AccountService.java index 78274979f9..d606f6ff95 100644 --- a/src/main/java/service/AccountService.java +++ b/src/main/java/service/AccountService.java @@ -214,13 +214,17 @@ public class AccountService { } public boolean setLoggedIn(Client c) { - byte newState = LoginState.LOGGED_IN; - int currentState = c.getLoginState(); + Account account = c.getAccount(); + if (account == null) { + throw new IllegalStateException("Unable to set logged in - no account"); + } + + int currentState = account.loginState(); if (currentState != LoginState.LOGGED_OUT && currentState != LoginState.SERVER_TRANSITION) { return false; } - setLoginState(c, newState); + setLoginState(c, LoginState.LOGGED_IN); return true; } @@ -229,6 +233,7 @@ public class AccountService { setLoggedOut(c); } + // TODO: check "stuck" accounts periodically and log them out. public void setLoggedOut(Client c) { setLoginState(c, LoginState.LOGGED_OUT); }