From ec39f0fa06fe167dde105bfe902185a4c57a0f7b Mon Sep 17 00:00:00 2001 From: P0nk Date: Sat, 28 Sep 2024 06:55:45 +0200 Subject: [PATCH] Avoid additional db query to get login state during login --- src/main/java/client/Client.java | 120 ++++++------------ src/main/java/client/LoginState.java | 10 ++ .../handlers/login/LoginPasswordHandler.java | 2 +- 3 files changed, 47 insertions(+), 85 deletions(-) create mode 100644 src/main/java/client/LoginState.java diff --git a/src/main/java/client/Client.java b/src/main/java/client/Client.java index a8554fa1d7..45e7966a04 100644 --- a/src/main/java/client/Client.java +++ b/src/main/java/client/Client.java @@ -40,7 +40,6 @@ import net.server.channel.Channel; import net.server.coordinator.login.LoginBypassCoordinator; import net.server.coordinator.session.Hwid; import net.server.coordinator.session.SessionCoordinator; -import net.server.coordinator.session.SessionCoordinator.AntiMulticlientResult; import net.server.world.Party; import net.server.world.World; import org.slf4j.Logger; @@ -53,7 +52,6 @@ import scripting.quest.QuestActionManager; import scripting.quest.QuestScriptManager; import server.TimerManager; import server.life.Monster; -import tools.BCrypt; import tools.DatabaseConnection; import tools.PacketCreator; @@ -65,6 +63,7 @@ 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; @@ -110,7 +109,7 @@ public class Client extends ChannelInboundHandlerAdapter { private String accountName = null; private int world; private volatile long lastPong; - private int gmlevel; + private int gmlevel; // TODO: remove? There's a gmlevel in Character too. private Set macs = new HashSet<>(); private Map engines = new HashMap<>(); private byte characterSlots = 3; @@ -531,85 +530,6 @@ public class Client extends ChannelInboundHandlerAdapter { return true; } - // TODO: load account outside in LoginPasswordHandler (from service). - // - public int login(String login, String pwd, Hwid hwid) { - int loginok = 5; - - try (Connection con = DatabaseConnection.getConnection(); - PreparedStatement ps = con.prepareStatement("SELECT id, password, gender, banned, pin, pic, characterslots, tos FROM accounts WHERE name = ?")) { - ps.setString(1, login); - - try (ResultSet rs = ps.executeQuery()) { - accId = -2; - if (rs.next()) { - accId = rs.getInt("id"); - if (accId <= 0) { - log.warn("Tried to log in with accId {}", accId); - return 15; - } - - boolean banned = (rs.getByte("banned") == 1); - gmlevel = 0; - pin = rs.getString("pin"); - pic = rs.getString("pic"); - gender = rs.getByte("gender"); - characterSlots = rs.getByte("characterslots"); - String passhash = rs.getString("password"); - byte tos = rs.getByte("tos"); - - if (banned) { - return 3; - } - - if (getLoginState() > LOGIN_NOTLOGGEDIN) { // already loggedin - loggedIn = false; - loginok = 7; - } else if (BCrypt.checkpw(pwd, passhash)) { - loginok = (tos == 0) ? 23 : 0; - } else { - loggedIn = false; - loginok = 4; - } - } else { - accId = -3; - } - } - } catch (SQLException e) { - e.printStackTrace(); - } - - if (loginok == 0 || loginok == 4) { - AntiMulticlientResult res = SessionCoordinator.getInstance().attemptLoginSession(this, hwid, accId, loginok == 4); - - switch (res) { - case SUCCESS: - if (loginok == 0) { - loginattempt = 0; - } - - return loginok; - - case REMOTE_LOGGEDIN: - return 17; - - case REMOTE_REACHED_LIMIT: - return 13; - - case REMOTE_PROCESSING: - return 10; - - case MANY_ACCOUNT_ATTEMPTS: - return 16; - - default: - return 8; - } - } else { - return loginok; - } - } - // TODO: check tempban directly on loaded account @Deprecated public Calendar getTempBanCalendarFromDB() { @@ -705,12 +625,44 @@ public class Client extends ChannelInboundHandlerAdapter { loggedIn = false; serverTransition = false; setAccID(0); + } else if (newState == LoginState.SERVER_TRANSITION) { + loggedIn = false; + serverTransition = true; } else { - serverTransition = (newState == LOGIN_SERVER_TRANSITION); - loggedIn = !serverTransition; + loggedIn = true; + serverTransition = false; } } + public byte getLoginState(Account account) { + byte loginState = account.loginState(); + if (loginState == LoginState.SERVER_TRANSITION && lastLoginOverThirtySecondsAgo(account)) { + loginState = LoginState.NOT_LOGGED_IN; + updateLoginState(LoginState.NOT_LOGGED_IN); + } + + 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)); + } + // TODO: move to LoginPasswordHandler public int getLoginState() { // 0 = LOGIN_NOTLOGGEDIN, 1= LOGIN_SERVER_TRANSITION, 2 = LOGIN_LOGGEDIN try (Connection con = DatabaseConnection.getConnection()) { diff --git a/src/main/java/client/LoginState.java b/src/main/java/client/LoginState.java new file mode 100644 index 0000000000..695d11a332 --- /dev/null +++ b/src/main/java/client/LoginState.java @@ -0,0 +1,10 @@ +package client; + +/** + * @author Ponk + */ +public class LoginState { + public static final byte NOT_LOGGED_IN = 0; + public static final byte SERVER_TRANSITION = 1; + public static final byte LOGGED_IN = 2; +} diff --git a/src/main/java/net/server/handlers/login/LoginPasswordHandler.java b/src/main/java/net/server/handlers/login/LoginPasswordHandler.java index da9a4bcb37..74a314e544 100644 --- a/src/main/java/net/server/handlers/login/LoginPasswordHandler.java +++ b/src/main/java/net/server/handlers/login/LoginPasswordHandler.java @@ -110,7 +110,7 @@ public final class LoginPasswordHandler implements PacketHandler { c.setAccount(account); - if (c.getLoginState() > Client.LOGIN_NOTLOGGEDIN) { + if (c.getLoginState(account) > Client.LOGIN_NOTLOGGEDIN) { c.sendPacket(PacketCreator.getLoginFailed(7)); return; }