From 5595f5763bfa03ca3077de05e348fb1b3313f9fe Mon Sep 17 00:00:00 2001 From: P0nk Date: Sat, 28 Sep 2024 18:30:41 +0200 Subject: [PATCH] Log in through AccountService --- src/main/java/client/Client.java | 19 +--- src/main/java/net/PacketProcessor.java | 2 +- .../handlers/PlayerLoggedinHandler.java | 87 +++++++++---------- .../handlers/login/AcceptToSHandler.java | 8 +- .../handlers/login/LoginPasswordHandler.java | 6 +- src/main/java/service/AccountService.java | 12 +++ 6 files changed, 62 insertions(+), 72 deletions(-) diff --git a/src/main/java/client/Client.java b/src/main/java/client/Client.java index 7a4cbc1f74..5c81216035 100644 --- a/src/main/java/client/Client.java +++ b/src/main/java/client/Client.java @@ -119,7 +119,6 @@ public class Client extends ChannelInboundHandlerAdapter { private boolean disconnecting = false; private final Semaphore actionsSemaphore = new Semaphore(7); private final Lock lock = new ReentrantLock(true); - private final Lock encoderLock = new ReentrantLock(true); private final Lock announcerLock = new ReentrantLock(true); // thanks Masterrulax & try2hack for pointing out a bottleneck issue with shared locks, shavit for noticing an opportunity for improvement private Calendar tempBanCalendar; @@ -453,21 +452,6 @@ public class Client extends ChannelInboundHandlerAdapter { } } - public boolean finishLogin() { - encoderLock.lock(); - try { - if (getLoginState() > LoginState.NOT_LOGGED_IN) { // 0 = LOGIN_NOTLOGGEDIN, 1= LOGIN_SERVER_TRANSITION, 2 = LOGIN_LOGGEDIN - loggedIn = false; - return false; - } - updateLoginState(LoginState.LOGGED_IN); - } finally { - encoderLock.unlock(); - } - - return true; - } - public void setPin(String pin) { this.pin = pin; } @@ -755,6 +739,8 @@ public class Client extends ChannelInboundHandlerAdapter { } } + // TODO: move to postgres. Called from all CharSelect handlers (6 in total). + // public void setCharacterOnSessionTransitionState(int cid) { this.updateLoginState(LoginState.SERVER_TRANSITION); this.inTransition = true; @@ -832,7 +818,6 @@ public class Client extends ChannelInboundHandlerAdapter { if (lastPong < pingedAt) { if (ioChannel.isActive()) { log.info("Disconnected {} due to idling. Reason: {}", remoteAddress, event.state()); - updateLoginState(LoginState.NOT_LOGGED_IN); disconnectSession(); } } diff --git a/src/main/java/net/PacketProcessor.java b/src/main/java/net/PacketProcessor.java index f302b8a204..b76e4c81ff 100644 --- a/src/main/java/net/PacketProcessor.java +++ b/src/main/java/net/PacketProcessor.java @@ -318,7 +318,7 @@ public final class PacketProcessor { registerHandler(RecvOpcode.ITEM_MOVE, new ItemMoveHandler()); registerHandler(RecvOpcode.MESO_DROP, new MesoDropHandler()); registerHandler(RecvOpcode.PLAYER_LOGGEDIN, new PlayerLoggedinHandler(channelDeps.characterLoader(), - channelDeps.noteService())); + channelDeps.accountService(), channelDeps.noteService())); registerHandler(RecvOpcode.CHANGE_MAP, new ChangeMapHandler()); registerHandler(RecvOpcode.MOVE_LIFE, new MoveLifeHandler()); registerHandler(RecvOpcode.CLOSE_RANGE_ATTACK, new CloseRangeDamageHandler(channelDeps.dropProvider(), channelDeps.banService())); diff --git a/src/main/java/net/server/channel/handlers/PlayerLoggedinHandler.java b/src/main/java/net/server/channel/handlers/PlayerLoggedinHandler.java index 248d4ad8a3..f39a929592 100644 --- a/src/main/java/net/server/channel/handlers/PlayerLoggedinHandler.java +++ b/src/main/java/net/server/channel/handlers/PlayerLoggedinHandler.java @@ -39,6 +39,7 @@ import client.inventory.Pet; import client.keybind.KeyBinding; import config.YamlConfig; import constants.game.GameConstants; +import database.account.Account; import database.character.CharacterLoader; import model.CharacterIdentity; import net.AbstractPacketHandler; @@ -61,6 +62,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import scripting.event.EventInstanceManager; import server.life.MobSkill; +import service.AccountService; import service.NoteService; import tools.DatabaseConnection; import tools.PacketCreator; @@ -86,10 +88,12 @@ public final class PlayerLoggedinHandler extends AbstractPacketHandler { private static final Set attemptingLoginAccounts = new HashSet<>(); private final CharacterLoader chrLoader; + private final AccountService accountService; private final NoteService noteService; - public PlayerLoggedinHandler(CharacterLoader chrLoader, NoteService noteService) { + public PlayerLoggedinHandler(CharacterLoader chrLoader, AccountService accountService, NoteService noteService) { this.chrLoader = chrLoader; + this.accountService = accountService; this.noteService = noteService; } @@ -159,65 +163,54 @@ public final class PlayerLoggedinHandler extends AbstractPacketHandler { throw new GameViolationException("Attempt to enter game without chr id in transition"); } - boolean newcomer = false; + boolean newlyLoggedIn = false; if (player == null) { Optional loadedChr = chrLoader.loadForChannel(chrId, c); if (loadedChr.isPresent()) { player = loadedChr.get(); - newcomer = true; + newlyLoggedIn = true; } else { throw new GameViolationException("Unable to load chr"); } } c.setPlayer(player); - c.setAccID(player.getAccountID()); - boolean allowLogin = true; + Optional foundAccount = accountService.getAccount(player.getAccountID()); + if (foundAccount.isEmpty()) { + c.sendPacket(PacketCreator.getAfterLoginError(5)); + return; + } + Account account = foundAccount.get(); + c.setAccount(account); - /* is this check really necessary? - if (state == LoginState.SERVER_TRANSITION || state == LoginState.NOT_LOGGED_IN) { - List charNames = c.loadCharacterNames(c.getWorld()); - if(!newcomer) { - charNames.remove(player.getName()); - } - - for (String charName : charNames) { - if(wserv.getPlayerStorage().getCharacterByName(charName) != null) { - allowLogin = false; - break; - } - } - } - */ - - int accId = c.getAccID(); - if (tryAcquireAccount(accId)) { // Sync this to prevent wrong login state for double loggedin handling - try { - int state = c.getLoginState(); - if (state != LoginState.SERVER_TRANSITION || !allowLogin) { - c.setPlayer(null); - c.setAccID(0); - - if (state == LoginState.LOGGED_IN) { - throw new GameViolationException("Attempt to log in when already logged in"); - } else { - c.sendPacket(PacketCreator.getAfterLoginError(7)); - } - - return; - } - c.updateLoginState(LoginState.LOGGED_IN); - } finally { - releaseAccount(accId); - } - } else { + int accId = account.id(); + if (!tryAcquireAccount(accId)) { // Sync this to prevent wrong login state for double loggedin handling c.setPlayer(null); c.setAccID(0); c.sendPacket(PacketCreator.getAfterLoginError(10)); return; } - if (!newcomer) { + try { + int state = c.getLoginState(account); + if (state != LoginState.SERVER_TRANSITION) { + c.setPlayer(null); + c.setAccID(0); + + if (state == LoginState.LOGGED_IN) { + throw new GameViolationException("Attempt to log in when already logged in"); + } else { + c.sendPacket(PacketCreator.getAfterLoginError(7)); + } + + return; + } + c.updateLoginState(LoginState.LOGGED_IN); + } finally { + releaseAccount(accId); + } + + if (!newlyLoggedIn) { c.setCharacterSlots((byte) player.getClient().getCharacterSlots()); player.newClient(c); } @@ -315,7 +308,7 @@ public final class PlayerLoggedinHandler extends AbstractPacketHandler { c.sendPacket(GuildPackets.updateAllianceInfo(newAlliance, c.getWorld())); c.sendPacket(GuildPackets.allianceNotice(newAlliance.getId(), newAlliance.getNotice())); - if (newcomer) { + if (newlyLoggedIn) { server.allianceMessage(allianceId, GuildPackets.allianceMemberOnline(player, true), player.getId(), -1); } } @@ -361,7 +354,7 @@ public final class PlayerLoggedinHandler extends AbstractPacketHandler { player.changeSkillLevel(SkillFactory.getSkill(10000000 * player.getJobType() + 12), (byte) (player.getLinkedLevel() / 10), 20, -1); player.checkBerserk(player.isHidden()); - if (newcomer) { + if (newlyLoggedIn) { for (Pet pet : player.getPets()) { if (pet != null) { wserv.registerPetHunger(player, player.getPetIndex(pet)); @@ -423,7 +416,7 @@ public final class PlayerLoggedinHandler extends AbstractPacketHandler { } } - if (newcomer) { + if (newlyLoggedIn) { EventInstanceManager eim = EventRecallCoordinator.getInstance().recallEventInstance(chrId); if (eim != null) { eim.registerPlayer(player); @@ -443,7 +436,7 @@ public final class PlayerLoggedinHandler extends AbstractPacketHandler { c.sendPacket(PacketCreator.setNPCScriptable(npcsIds)); } - if (newcomer) { + if (newlyLoggedIn) { player.setLoginTime(System.currentTimeMillis()); } } catch (Exception e) { diff --git a/src/main/java/net/server/handlers/login/AcceptToSHandler.java b/src/main/java/net/server/handlers/login/AcceptToSHandler.java index 7722500aa8..dfac36d326 100644 --- a/src/main/java/net/server/handlers/login/AcceptToSHandler.java +++ b/src/main/java/net/server/handlers/login/AcceptToSHandler.java @@ -29,10 +29,10 @@ public final class AcceptToSHandler extends AbstractPacketHandler { throw new GameViolationException("ToS not accepted"); } - if (c.finishLogin()) { - c.sendPacket(PacketCreator.getAuthSuccess(c)); - } else { - c.sendPacket(PacketCreator.getLoginFailed(9));//shouldn't happen XD + if (!accountService.logIn(c)) { + c.sendPacket(PacketCreator.getLoginFailed(7)); } + + c.sendPacket(PacketCreator.getAuthSuccess(c)); } } diff --git a/src/main/java/net/server/handlers/login/LoginPasswordHandler.java b/src/main/java/net/server/handlers/login/LoginPasswordHandler.java index 7507a82b8a..bc48a7adb9 100644 --- a/src/main/java/net/server/handlers/login/LoginPasswordHandler.java +++ b/src/main/java/net/server/handlers/login/LoginPasswordHandler.java @@ -149,10 +149,10 @@ public final class LoginPasswordHandler implements PacketHandler { return; } - if (!c.finishLogin()) { + if (!accountService.logIn(c)) { c.sendPacket(PacketCreator.getLoginFailed(7)); } - checkChar(c); + removeOnlineAccountChrs(c); c.sendPacket(PacketCreator.getAuthSuccess(c)); Server.getInstance().registerLoginState(c); @@ -200,7 +200,7 @@ public final class LoginPasswordHandler implements PacketHandler { }; } - private void checkChar(Client c) { // issue with multiple chars from same account login found by shavit, resinate + private void removeOnlineAccountChrs(Client c) { // issue with multiple chars from same account login found by shavit, resinate if (!YamlConfig.config.server.USE_CHARACTER_ACCOUNT_CHECK) { return; } diff --git a/src/main/java/service/AccountService.java b/src/main/java/service/AccountService.java index 0ec68c1a59..25adf70c5d 100644 --- a/src/main/java/service/AccountService.java +++ b/src/main/java/service/AccountService.java @@ -213,6 +213,18 @@ public class AccountService { return accountRepository.setChrSlots(accountId, chrSlots); } + public boolean logIn(Client c) { + byte newState = LoginState.LOGGED_IN; + if (c.getLoginState() != LoginState.NOT_LOGGED_IN) { + return false; + } + + setLoginStateMysql(c.getAccID(), newState); + setLoginStatePostgres(c.getAccID(), newState); + c.setLoginState(newState); + return true; + } + public void logOut(Client c) { SessionCoordinator.getInstance().closeSession(c, false); byte newState = LoginState.NOT_LOGGED_IN;