LoginState enum

This commit is contained in:
P0nk
2024-09-29 16:22:32 +02:00
parent 5450c29178
commit b45620154c
8 changed files with 63 additions and 30 deletions

View File

@@ -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;
}
}
}

View File

@@ -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<LoginState> fromValue(int value) {
return Arrays.stream(values())
.filter(v -> v.getValue() == value)
.findFirst();
}
}

View File

@@ -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);

View File

@@ -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;
}

View File

@@ -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<Account> {
@Override
@@ -27,7 +30,7 @@ public class AccountRowMapper implements RowMapper<Account> {
.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<Account> {
.orElse(null))
.build();
}
private static LoginState getLoginState(byte dbValue) {
Optional<LoginState> loginState = LoginState.fromValue(dbValue);
if (loginState.isEmpty()) {
throw new IllegalStateException("Invalid login state: " + dbValue);
}
return loginState.get();
}
}

View File

@@ -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);

View File

@@ -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;
}

View File

@@ -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) {