Log out through AccountService

This commit is contained in:
P0nk
2024-09-28 07:22:30 +02:00
parent 93bbe868cb
commit 55c9d4abbb
7 changed files with 81 additions and 21 deletions

View File

@@ -630,6 +630,20 @@ public class Client extends ChannelInboundHandlerAdapter {
}
}
public void setLoginState(int newState) {
if (newState == LoginState.NOT_LOGGED_IN) {
loggedIn = false;
serverTransition = false;
setAccID(0);
} else if (newState == LoginState.SERVER_TRANSITION) {
loggedIn = false;
serverTransition = true;
} else {
loggedIn = true;
serverTransition = false;
}
}
public byte getLoginState(Account account) {
byte loginState = account.loginState();
if (loginState == LoginState.SERVER_TRANSITION && lastLoginOverThirtySecondsAgo(account)) {

View File

@@ -3,6 +3,7 @@ package database.account;
import database.PgDatabaseConnection;
import org.jdbi.v3.core.Handle;
import java.time.Instant;
import java.util.Optional;
/**
@@ -124,4 +125,18 @@ public class AccountRepository {
.execute() > 0;
}
}
public boolean setLoginState(int accountId, byte loginState, Instant lastLogin) {
String sql = """
UPDATE account
SET login_state = :loginState, last_login = :lastLogin
WHERE id = :id""";
try (Handle handle = connection.getHandle()) {
return handle.createUpdate(sql)
.bind("id", accountId)
.bind("loginState", loginState)
.bind("lastLogin", lastLogin)
.execute() > 0;
}
}
}

View File

@@ -277,7 +277,7 @@ public final class PacketProcessor {
private void registerLoginHandlers() {
registerHandler(RecvOpcode.ACCEPT_TOS, new AcceptToSHandler(channelDeps.accountService()));
registerHandler(RecvOpcode.AFTER_LOGIN, new AfterLoginHandler());
registerHandler(RecvOpcode.AFTER_LOGIN, new AfterLoginHandler(channelDeps.accountService()));
registerHandler(RecvOpcode.SERVERLIST_REREQUEST, new ServerlistRequestHandler());
registerHandler(RecvOpcode.CHARLIST_REQUEST, new CharlistRequestHandler());
registerHandler(RecvOpcode.CHAR_SELECT, new CharSelectedHandler());

View File

@@ -22,13 +22,17 @@
package net.server.handlers.login;
import client.Client;
import client.LoginState;
import net.AbstractPacketHandler;
import net.packet.InPacket;
import net.server.coordinator.session.SessionCoordinator;
import service.AccountService;
import tools.PacketCreator;
public final class AfterLoginHandler extends AbstractPacketHandler {
private final AccountService accountService;
public AfterLoginHandler(final AccountService accountService) {
this.accountService = accountService;
}
@Override
public final void handlePacket(InPacket p, Client c) {
@@ -58,8 +62,7 @@ public final class AfterLoginHandler extends AbstractPacketHandler {
c.sendPacket(PacketCreator.requestPinAfterFailure());
}
} else if (c2 == 0 && c3 == 5) {
SessionCoordinator.getInstance().closeSession(c, false);
c.updateLoginState(LoginState.NOT_LOGGED_IN);
accountService.logOut(c);
}
}
}

View File

@@ -22,10 +22,8 @@
package net.server.handlers.login;
import client.Client;
import client.LoginState;
import net.AbstractPacketHandler;
import net.packet.InPacket;
import net.server.coordinator.session.SessionCoordinator;
import service.AccountService;
import tools.PacketCreator;
@@ -44,8 +42,7 @@ public final class RegisterPinHandler extends AbstractPacketHandler {
public void handlePacket(InPacket p, Client c) {
boolean cancel = p.readByte() == 0;
if (cancel) {
SessionCoordinator.getInstance().closeSession(c, false);
c.updateLoginState(LoginState.NOT_LOGGED_IN);
accountService.logOut(c);
return;
}
@@ -54,7 +51,6 @@ public final class RegisterPinHandler extends AbstractPacketHandler {
c.setPin(pin);
c.sendPacket(PacketCreator.pinRegistered());
SessionCoordinator.getInstance().closeSession(c, false);
c.updateLoginState(LoginState.NOT_LOGGED_IN);
accountService.logOut(c);
}
}

View File

@@ -24,11 +24,9 @@ package net.server.handlers.login;
import client.Client;
import client.Gender;
import client.LoginState;
import net.AbstractPacketHandler;
import net.packet.InPacket;
import net.server.Server;
import net.server.coordinator.session.SessionCoordinator;
import service.AccountService;
import tools.PacketCreator;
@@ -46,24 +44,24 @@ public class SetGenderHandler extends AbstractPacketHandler {
@Override
public void handlePacket(InPacket p, Client c) {
if (c.getGender() != Gender.NOT_SET) { // Packet shouldn't come if Gender isn't 10.
close(c);
logOut(c);
return;
}
byte confirmed = p.readByte();
if (confirmed != 0x01) {
close(c);
logOut(c);
return;
}
byte gender = p.readByte();
if (gender != Gender.MALE && gender != Gender.FEMALE) {
close(c);
logOut(c);
return;
}
if (!accountService.setGender(c.getAccID(), gender)) {
close(c);
logOut(c);
return;
}
@@ -72,9 +70,8 @@ public class SetGenderHandler extends AbstractPacketHandler {
Server.getInstance().registerLoginState(c);
}
private void close(Client c) {
SessionCoordinator.getInstance().closeSession(c, false);
c.updateLoginState(LoginState.NOT_LOGGED_IN);
private void logOut(Client c) {
accountService.logOut(c);
}
}

View File

@@ -1,9 +1,12 @@
package service;
import client.Client;
import client.LoginState;
import database.account.Account;
import database.account.AccountRepository;
import lombok.extern.slf4j.Slf4j;
import net.server.Server;
import net.server.coordinator.session.SessionCoordinator;
import tools.BCrypt;
import tools.DatabaseConnection;
@@ -11,6 +14,7 @@ import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.time.Instant;
import java.time.LocalDate;
import java.util.Optional;
@@ -34,7 +38,7 @@ public class AccountService {
.password(hashPassword(password))
.birthdate(GMS_RELEASE)
.chrSlots(INITIAL_CHR_SLOTS)
.loginState((byte) Client.LOGIN_NOTLOGGEDIN)
.loginState(LoginState.NOT_LOGGED_IN)
.gender(null)
.build();
@@ -209,4 +213,35 @@ public class AccountService {
return accountRepository.setChrSlots(accountId, chrSlots);
}
public void logOut(Client c) {
SessionCoordinator.getInstance().closeSession(c, false);
byte newState = LoginState.NOT_LOGGED_IN;
int accountId = c.getAccID();
setLoginStateMysql(accountId, newState);
setLoginStatePostgres(accountId, newState);
c.setLoginState(newState);
}
private void setLoginStateMysql(int accountId, byte 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, accountId);
ps.executeUpdate();
} catch (SQLException e) {
e.printStackTrace();
}
}
private void setLoginStatePostgres(int accountId, byte newState) {
Instant loginTime = Instant.now();
boolean success = accountRepository.setLoginState(accountId, newState, loginTime);
if (!success) {
log.warn("Failed to set login state - account:{}, newState:{}, loginTime:{}", accountId, newState, loginTime);
}
}
}