diff --git a/src/main/java/client/Client.java b/src/main/java/client/Client.java index eb0d441035..787b4bca7b 100644 --- a/src/main/java/client/Client.java +++ b/src/main/java/client/Client.java @@ -582,19 +582,20 @@ public class Client extends ChannelInboundHandlerAdapter { return accId; } - public void setLoginState(int newState) { - if (newState == LoginState.LOGGED_OUT) { - loggedIn = false; - inServerTransition = false; - setAccID(0); - } else if (newState == LoginState.SERVER_TRANSITION) { - loggedIn = false; - inServerTransition = true; - } else if (newState == LoginState.LOGGED_IN) { - loggedIn = true; - inServerTransition = false; - } else { - throw new IllegalArgumentException("Invalid login state: " + newState); + public void onChangedLoginState(LoginState newState) { + switch (newState) { + case LoginState.LOGGED_OUT -> { + loggedIn = false; + inServerTransition = false; + } + case LoginState.SERVER_TRANSITION -> { + loggedIn = false; + inServerTransition = true; + } + case LoginState.LOGGED_IN -> { + loggedIn = true; + inServerTransition = false; + } } } diff --git a/src/main/java/client/LoginState.java b/src/main/java/client/LoginState.java index 512c6f2dc5..4d9e0b8d28 100644 --- a/src/main/java/client/LoginState.java +++ b/src/main/java/client/LoginState.java @@ -1,10 +1,29 @@ package client; +import java.util.Arrays; +import java.util.Optional; + /** * @author Ponk */ -public class LoginState { - public static final byte LOGGED_OUT = 0; - public static final byte SERVER_TRANSITION = 1; - public static final byte LOGGED_IN = 2; +public enum LoginState { + LOGGED_OUT(0), + SERVER_TRANSITION(1), + LOGGED_IN(2); + + private final byte value; + + LoginState(int value) { + this.value = (byte) value; + } + + public byte getValue() { + return value; + } + + public static Optional fromValue(int value) { + return Arrays.stream(values()) + .filter(v -> v.getValue() == value) + .findFirst(); + } } diff --git a/src/main/java/database/account/Account.java b/src/main/java/database/account/Account.java index c55f827d5d..9ff22d9bfa 100644 --- a/src/main/java/database/account/Account.java +++ b/src/main/java/database/account/Account.java @@ -1,5 +1,6 @@ package database.account; +import client.LoginState; import lombok.Builder; import java.time.LocalDate; @@ -11,7 +12,7 @@ import java.util.Objects; */ @Builder public record Account(int id, String name, String password, boolean acceptedTos, Byte gender, LocalDate birthdate, - String pin, String pic, byte chrSlots, byte loginState, LocalDateTime lastLogin, boolean banned, + String pin, String pic, byte chrSlots, LoginState loginState, LocalDateTime lastLogin, boolean banned, LocalDateTime tempBanTimestamp) { public Account { Objects.requireNonNull(name); diff --git a/src/main/java/database/account/AccountRepository.java b/src/main/java/database/account/AccountRepository.java index 5368abfc78..588918b86c 100644 --- a/src/main/java/database/account/AccountRepository.java +++ b/src/main/java/database/account/AccountRepository.java @@ -1,5 +1,6 @@ package database.account; +import client.LoginState; import database.PgDatabaseConnection; import org.jdbi.v3.core.Handle; @@ -126,7 +127,7 @@ public class AccountRepository { } } - public boolean setLoginState(int accountId, byte loginState, Instant lastLogin) { + public boolean setLoginState(int accountId, LoginState loginState, Instant lastLogin) { String sql = """ UPDATE account SET login_state = :loginState, last_login = :lastLogin @@ -134,7 +135,7 @@ public class AccountRepository { try (Handle handle = connection.getHandle()) { return handle.createUpdate(sql) .bind("id", accountId) - .bind("loginState", loginState) + .bind("loginState", loginState.getValue()) .bind("lastLogin", lastLogin) .execute() > 0; } diff --git a/src/main/java/database/account/AccountRowMapper.java b/src/main/java/database/account/AccountRowMapper.java index c451fc6379..101f584a0f 100644 --- a/src/main/java/database/account/AccountRowMapper.java +++ b/src/main/java/database/account/AccountRowMapper.java @@ -1,5 +1,7 @@ package database.account; +import client.LoginState; +import lombok.extern.slf4j.Slf4j; import org.jdbi.v3.core.mapper.RowMapper; import org.jdbi.v3.core.statement.StatementContext; @@ -11,6 +13,7 @@ import java.util.Optional; /** * @author Ponk */ +@Slf4j public class AccountRowMapper implements RowMapper { @Override @@ -27,7 +30,7 @@ public class AccountRowMapper implements RowMapper { .orElse(null)) .acceptedTos(rs.getBoolean("tos_accepted")) .chrSlots(rs.getByte("chr_slots")) - .loginState(rs.getByte("login_state")) + .loginState(getLoginState(rs.getByte("login_state"))) .lastLogin(Optional.ofNullable(rs.getTimestamp("last_login")) .map(Timestamp::toLocalDateTime) .orElse(null)) @@ -37,4 +40,12 @@ public class AccountRowMapper implements RowMapper { .orElse(null)) .build(); } + + private static LoginState getLoginState(byte dbValue) { + Optional loginState = LoginState.fromValue(dbValue); + if (loginState.isEmpty()) { + throw new IllegalStateException("Invalid login state: " + dbValue); + } + return loginState.get(); + } } diff --git a/src/main/java/net/server/channel/handlers/PlayerLoggedinHandler.java b/src/main/java/net/server/channel/handlers/PlayerLoggedinHandler.java index 9c5bad4eb2..b00e545992 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 = account.loginState(); + LoginState 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 e24b1b3852..7706a29ebf 100644 --- a/src/main/java/net/server/handlers/login/LoginPasswordHandler.java +++ b/src/main/java/net/server/handlers/login/LoginPasswordHandler.java @@ -113,7 +113,7 @@ public final class LoginPasswordHandler implements PacketHandler { return; } - if (account.loginState() > LoginState.LOGGED_OUT) { + if (account.loginState() != LoginState.LOGGED_OUT) { c.sendPacket(PacketCreator.getLoginFailed(7)); return; } diff --git a/src/main/java/service/AccountService.java b/src/main/java/service/AccountService.java index d606f6ff95..715bbde164 100644 --- a/src/main/java/service/AccountService.java +++ b/src/main/java/service/AccountService.java @@ -219,7 +219,7 @@ public class AccountService { throw new IllegalStateException("Unable to set logged in - no account"); } - int currentState = account.loginState(); + LoginState currentState = account.loginState(); if (currentState != LoginState.LOGGED_OUT && currentState != LoginState.SERVER_TRANSITION) { return false; } @@ -242,22 +242,22 @@ public class AccountService { setLoginState(c, LoginState.SERVER_TRANSITION); } - private void setLoginState(Client c, byte newState) { + private void setLoginState(Client c, LoginState newState) { saveLoginState(c.getAccID(), newState); - c.setLoginState(newState); + c.onChangedLoginState(newState); } - private void saveLoginState(int accountId, byte newState) { + private void saveLoginState(int accountId, LoginState newState) { setLoginStateMysql(accountId, newState); setLoginStatePostgres(accountId, newState); } - private void setLoginStateMysql(int accountId, byte newState) { + private void setLoginStateMysql(int accountId, LoginState 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.setInt(1, newState.getValue()); ps.setTimestamp(2, new java.sql.Timestamp(Server.getInstance().getCurrentTime())); ps.setInt(3, accountId); ps.executeUpdate(); @@ -266,7 +266,7 @@ public class AccountService { } } - private void setLoginStatePostgres(int accountId, byte newState) { + private void setLoginStatePostgres(int accountId, LoginState newState) { Instant loginTime = Instant.now(); boolean success = accountRepository.setLoginState(accountId, newState, loginTime); if (!success) {