From 2b6ef9feb59956550f06d56690f1af205e7220d5 Mon Sep 17 00:00:00 2001 From: P0nk Date: Thu, 3 Oct 2024 08:28:22 +0200 Subject: [PATCH] Save client addresses async on chr select Almost rid of all db queries in Client --- src/main/java/client/Client.java | 41 ++++--------------- .../database/account/AccountRepository.java | 15 +++++++ src/main/java/net/PacketProcessor.java | 16 ++++---- .../handlers/login/CharSelectedHandler.java | 17 ++++---- .../login/CharSelectedWithPicHandler.java | 16 ++++---- .../handlers/login/RegisterPicHandler.java | 10 ++--- .../login/ViewAllCharRegisterPicHandler.java | 12 +++--- .../login/ViewAllCharSelectedHandler.java | 16 ++++---- .../ViewAllCharSelectedWithPicHandler.java | 16 ++++---- src/main/java/service/AccountService.java | 15 +++++++ 10 files changed, 91 insertions(+), 83 deletions(-) diff --git a/src/main/java/client/Client.java b/src/main/java/client/Client.java index 4b69c52bc6..4ee4a3c61d 100644 --- a/src/main/java/client/Client.java +++ b/src/main/java/client/Client.java @@ -69,7 +69,6 @@ import java.util.Calendar; import java.util.Collections; import java.util.HashMap; import java.util.HashSet; -import java.util.Iterator; import java.util.LinkedList; import java.util.List; import java.util.Map; @@ -269,6 +268,13 @@ public class Client extends ChannelInboundHandlerAdapter { this.hwid = hwid; } + public void setMacs(String macs) { + if (macs == null || macs.isEmpty()) { + throw new IllegalArgumentException("macs cannot be empty"); + } + this.macs.addAll(Arrays.asList(macs.split(", "))); + } + public String getRemoteAddress() { return remoteAddress; } @@ -427,39 +433,6 @@ public class Client extends ChannelInboundHandlerAdapter { return account != null && account.bannedUntil() != null && account.bannedUntil().isAfter(recentThreshold); } - public void updateHwid(Hwid hwid) { - try (Connection con = DatabaseConnection.getConnection(); - PreparedStatement ps = con.prepareStatement("UPDATE accounts SET hwid = ? WHERE id = ?")) { - ps.setString(1, hwid.hwid()); - ps.setInt(2, accId); - ps.executeUpdate(); - } catch (SQLException e) { - e.printStackTrace(); - } - } - - public void updateMacs(String macData) { - macs.addAll(Arrays.asList(macData.split(", "))); - StringBuilder newMacData = new StringBuilder(); - Iterator iter = macs.iterator(); - while (iter.hasNext()) { - String cur = iter.next(); - newMacData.append(cur); - if (iter.hasNext()) { - newMacData.append(", "); - } - } - - try (Connection con = DatabaseConnection.getConnection(); - PreparedStatement ps = con.prepareStatement("UPDATE accounts SET macs = ? WHERE id = ?")) { - ps.setString(1, newMacData.toString()); - ps.setInt(2, accId); - ps.executeUpdate(); - } catch (SQLException e) { - e.printStackTrace(); - } - } - public void setAccID(int id) { this.accId = id; } diff --git a/src/main/java/database/account/AccountRepository.java b/src/main/java/database/account/AccountRepository.java index 218f758859..57b44d27ba 100644 --- a/src/main/java/database/account/AccountRepository.java +++ b/src/main/java/database/account/AccountRepository.java @@ -169,4 +169,19 @@ public class AccountRepository { .execute() > 0; } } + + public void setIpAndMacsAndHwid(int accountId, String ip, String hwid, String macs) { + String sql = """ + UPDATE account + SET ip = :ip, macs = :macs, hwid = :hwid + WHERE id = :id"""; + try (Handle handle = connection.getHandle()) { + handle.createUpdate(sql) + .bind("id", accountId) + .bind("ip", ip) + .bind("hwid", hwid) + .bind("macs", macs) + .execute(); + } + } } diff --git a/src/main/java/net/PacketProcessor.java b/src/main/java/net/PacketProcessor.java index 2367de85c7..dd3248a40d 100644 --- a/src/main/java/net/PacketProcessor.java +++ b/src/main/java/net/PacketProcessor.java @@ -280,8 +280,8 @@ public final class PacketProcessor { 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(channelDeps.banService(), - channelDeps.transitionService())); + registerHandler(RecvOpcode.CHAR_SELECT, new CharSelectedHandler(channelDeps.accountService(), + channelDeps.banService(), channelDeps.transitionService())); registerHandler(RecvOpcode.LOGIN_PASSWORD, new LoginPasswordHandler(channelDeps.accountService(), channelDeps.transitionService(), channelDeps.banService())); registerHandler(RecvOpcode.RELOG, new RelogRequestHandler()); @@ -291,17 +291,17 @@ public final class PacketProcessor { registerHandler(RecvOpcode.CREATE_CHAR, new CreateCharHandler(channelDeps.characterCreator())); registerHandler(RecvOpcode.DELETE_CHAR, new DeleteCharHandler()); registerHandler(RecvOpcode.VIEW_ALL_CHAR, new ViewAllCharHandler()); - registerHandler(RecvOpcode.PICK_ALL_CHAR, new ViewAllCharSelectedHandler(channelDeps.banService(), - channelDeps.transitionService())); + registerHandler(RecvOpcode.PICK_ALL_CHAR, new ViewAllCharSelectedHandler(channelDeps.accountService(), + channelDeps.banService(), channelDeps.transitionService())); registerHandler(RecvOpcode.REGISTER_PIN, new RegisterPinHandler(channelDeps.accountService())); registerHandler(RecvOpcode.GUEST_LOGIN, new GuestLoginHandler()); registerHandler(RecvOpcode.REGISTER_PIC, new RegisterPicHandler(channelDeps.banService(), channelDeps.accountService(), channelDeps.transitionService())); - registerHandler(RecvOpcode.CHAR_SELECT_WITH_PIC, new CharSelectedWithPicHandler(channelDeps.banService(), - channelDeps.transitionService())); + registerHandler(RecvOpcode.CHAR_SELECT_WITH_PIC, new CharSelectedWithPicHandler(channelDeps.accountService(), + channelDeps.banService(), channelDeps.transitionService())); registerHandler(RecvOpcode.SET_GENDER, new SetGenderHandler(channelDeps.accountService())); - registerHandler(RecvOpcode.VIEW_ALL_WITH_PIC, new ViewAllCharSelectedWithPicHandler(channelDeps.banService(), - channelDeps.transitionService())); + registerHandler(RecvOpcode.VIEW_ALL_WITH_PIC, new ViewAllCharSelectedWithPicHandler(channelDeps.accountService(), + channelDeps.banService(), channelDeps.transitionService())); registerHandler(RecvOpcode.VIEW_ALL_PIC_REGISTER, new ViewAllCharRegisterPicHandler(channelDeps.banService(), channelDeps.accountService(), channelDeps.transitionService())); } diff --git a/src/main/java/net/server/handlers/login/CharSelectedHandler.java b/src/main/java/net/server/handlers/login/CharSelectedHandler.java index a7f9a7d3dc..82dc55b000 100644 --- a/src/main/java/net/server/handlers/login/CharSelectedHandler.java +++ b/src/main/java/net/server/handlers/login/CharSelectedHandler.java @@ -22,6 +22,7 @@ package net.server.handlers.login; import client.Client; +import lombok.extern.slf4j.Slf4j; import net.AbstractPacketHandler; import net.packet.InPacket; import net.server.Server; @@ -29,8 +30,7 @@ import net.server.coordinator.session.Hwid; import net.server.coordinator.session.SessionCoordinator; import net.server.coordinator.session.SessionCoordinator.AntiMulticlientResult; import net.server.world.World; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; +import service.AccountService; import service.BanService; import service.TransitionService; import tools.PacketCreator; @@ -38,13 +38,16 @@ import tools.PacketCreator; import java.net.InetAddress; import java.net.UnknownHostException; +// TODO: create abstract class for all six "char selected" handlers. +@Slf4j public final class CharSelectedHandler extends AbstractPacketHandler { - private static final Logger log = LoggerFactory.getLogger(CharSelectedHandler.class); - + private final AccountService accountService; private final BanService banService; private final TransitionService transitionService; - public CharSelectedHandler(BanService banService, TransitionService transitionService) { + public CharSelectedHandler(AccountService accountService, BanService banService, + TransitionService transitionService) { + this.accountService = accountService; this.banService = banService; this.transitionService = transitionService; } @@ -75,9 +78,9 @@ public final class CharSelectedHandler extends AbstractPacketHandler { return; } - c.updateMacs(macs); - c.updateHwid(hwid); c.setHwid(hwid); + c.setMacs(macs); + accountService.setIpAndMacsAndHwidAsync(c.getAccID(), c.getRemoteAddress(), macs, hwid); AntiMulticlientResult res = SessionCoordinator.getInstance().attemptGameSession(c, c.getAccID(), hwid); if (res != AntiMulticlientResult.SUCCESS) { diff --git a/src/main/java/net/server/handlers/login/CharSelectedWithPicHandler.java b/src/main/java/net/server/handlers/login/CharSelectedWithPicHandler.java index 952a577e2b..15c2e2fef4 100644 --- a/src/main/java/net/server/handlers/login/CharSelectedWithPicHandler.java +++ b/src/main/java/net/server/handlers/login/CharSelectedWithPicHandler.java @@ -1,6 +1,7 @@ package net.server.handlers.login; import client.Client; +import lombok.extern.slf4j.Slf4j; import net.AbstractPacketHandler; import net.packet.InPacket; import net.server.Server; @@ -8,8 +9,7 @@ import net.server.coordinator.session.Hwid; import net.server.coordinator.session.SessionCoordinator; import net.server.coordinator.session.SessionCoordinator.AntiMulticlientResult; import net.server.world.World; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; +import service.AccountService; import service.BanService; import service.TransitionService; import tools.PacketCreator; @@ -17,13 +17,15 @@ import tools.PacketCreator; import java.net.InetAddress; import java.net.UnknownHostException; +@Slf4j public class CharSelectedWithPicHandler extends AbstractPacketHandler { - private static final Logger log = LoggerFactory.getLogger(CharSelectedWithPicHandler.class); - + private final AccountService accountService; private final BanService banService; private final TransitionService transitionService; - public CharSelectedWithPicHandler(BanService banService, TransitionService transitionService) { + public CharSelectedWithPicHandler(AccountService accountService, BanService banService, + TransitionService transitionService) { + this.accountService = accountService; this.banService = banService; this.transitionService = transitionService; } @@ -55,9 +57,9 @@ public class CharSelectedWithPicHandler extends AbstractPacketHandler { return; } - c.updateMacs(macs); - c.updateHwid(hwid); c.setHwid(hwid); + c.setMacs(macs); + accountService.setIpAndMacsAndHwidAsync(c.getAccID(), c.getRemoteAddress(), macs, hwid); if (banService.isBanned(c)) { SessionCoordinator.getInstance().closeSession(c, true); diff --git a/src/main/java/net/server/handlers/login/RegisterPicHandler.java b/src/main/java/net/server/handlers/login/RegisterPicHandler.java index 270f587324..6b0b464649 100644 --- a/src/main/java/net/server/handlers/login/RegisterPicHandler.java +++ b/src/main/java/net/server/handlers/login/RegisterPicHandler.java @@ -1,6 +1,7 @@ package net.server.handlers.login; import client.Client; +import lombok.extern.slf4j.Slf4j; import net.AbstractPacketHandler; import net.packet.InPacket; import net.server.Server; @@ -8,8 +9,6 @@ import net.server.coordinator.session.Hwid; import net.server.coordinator.session.SessionCoordinator; import net.server.coordinator.session.SessionCoordinator.AntiMulticlientResult; import net.server.world.World; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; import service.AccountService; import service.BanService; import service.TransitionService; @@ -18,9 +17,8 @@ import tools.PacketCreator; import java.net.InetAddress; import java.net.UnknownHostException; +@Slf4j public final class RegisterPicHandler extends AbstractPacketHandler { - private static final Logger log = LoggerFactory.getLogger(RegisterPicHandler.class); - private final BanService banService; private final TransitionService transitionService; private final AccountService accountService; @@ -48,9 +46,9 @@ public final class RegisterPicHandler extends AbstractPacketHandler { return; } - c.updateMacs(macs); - c.updateHwid(hwid); c.setHwid(hwid); + c.setMacs(macs); + accountService.setIpAndMacsAndHwidAsync(c.getAccID(), c.getRemoteAddress(), macs, hwid); AntiMulticlientResult res = SessionCoordinator.getInstance().attemptGameSession(c, c.getAccID(), hwid); if (res != AntiMulticlientResult.SUCCESS) { diff --git a/src/main/java/net/server/handlers/login/ViewAllCharRegisterPicHandler.java b/src/main/java/net/server/handlers/login/ViewAllCharRegisterPicHandler.java index e713eb98e6..09395638f2 100644 --- a/src/main/java/net/server/handlers/login/ViewAllCharRegisterPicHandler.java +++ b/src/main/java/net/server/handlers/login/ViewAllCharRegisterPicHandler.java @@ -1,6 +1,7 @@ package net.server.handlers.login; import client.Client; +import lombok.extern.slf4j.Slf4j; import net.AbstractPacketHandler; import net.packet.InPacket; import net.server.Server; @@ -8,8 +9,6 @@ import net.server.coordinator.session.Hwid; import net.server.coordinator.session.SessionCoordinator; import net.server.coordinator.session.SessionCoordinator.AntiMulticlientResult; import net.server.world.World; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; import service.AccountService; import service.BanService; import service.TransitionService; @@ -19,9 +18,8 @@ import tools.Randomizer; import java.net.InetAddress; import java.net.UnknownHostException; +@Slf4j public final class ViewAllCharRegisterPicHandler extends AbstractPacketHandler { - private static final Logger log = LoggerFactory.getLogger(ViewAllCharRegisterPicHandler.class); - private final BanService banService; private final AccountService accountService; private final TransitionService transitionService; @@ -39,7 +37,7 @@ public final class ViewAllCharRegisterPicHandler extends AbstractPacketHandler { int charId = p.readInt(); p.readInt(); // please don't let the client choose which world they should login - String mac = p.readString(); + String macs = p.readString(); String hostString = p.readString(); final Hwid hwid; @@ -51,9 +49,9 @@ public final class ViewAllCharRegisterPicHandler extends AbstractPacketHandler { return; } - c.updateMacs(mac); - c.updateHwid(hwid); c.setHwid(hwid); + c.setMacs(macs); + accountService.setIpAndMacsAndHwidAsync(c.getAccID(), c.getRemoteAddress(), macs, hwid); if (banService.isBanned(c)) { SessionCoordinator.getInstance().closeSession(c, true); diff --git a/src/main/java/net/server/handlers/login/ViewAllCharSelectedHandler.java b/src/main/java/net/server/handlers/login/ViewAllCharSelectedHandler.java index 30c07f8451..d542f254f0 100644 --- a/src/main/java/net/server/handlers/login/ViewAllCharSelectedHandler.java +++ b/src/main/java/net/server/handlers/login/ViewAllCharSelectedHandler.java @@ -22,6 +22,7 @@ package net.server.handlers.login; import client.Client; +import lombok.extern.slf4j.Slf4j; import net.AbstractPacketHandler; import net.packet.InPacket; import net.server.Server; @@ -29,8 +30,7 @@ import net.server.coordinator.session.Hwid; import net.server.coordinator.session.SessionCoordinator; import net.server.coordinator.session.SessionCoordinator.AntiMulticlientResult; import net.server.world.World; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; +import service.AccountService; import service.BanService; import service.TransitionService; import tools.PacketCreator; @@ -39,13 +39,15 @@ import tools.Randomizer; import java.net.InetAddress; import java.net.UnknownHostException; +@Slf4j public final class ViewAllCharSelectedHandler extends AbstractPacketHandler { - private static final Logger log = LoggerFactory.getLogger(ViewAllCharSelectedHandler.class); - + private final AccountService accountService; private final BanService banService; private final TransitionService transitionService; - public ViewAllCharSelectedHandler(BanService banService, TransitionService transitionService) { + public ViewAllCharSelectedHandler(AccountService accountService, BanService banService, + TransitionService transitionService) { + this.accountService = accountService; this.banService = banService; this.transitionService = transitionService; } @@ -77,9 +79,9 @@ public final class ViewAllCharSelectedHandler extends AbstractPacketHandler { return; } - c.updateMacs(macs); - c.updateHwid(hwid); c.setHwid(hwid); + c.setMacs(macs); + accountService.setIpAndMacsAndHwidAsync(c.getAccID(), c.getRemoteAddress(), macs, hwid); if (banService.isBanned(c)) { SessionCoordinator.getInstance().closeSession(c, true); diff --git a/src/main/java/net/server/handlers/login/ViewAllCharSelectedWithPicHandler.java b/src/main/java/net/server/handlers/login/ViewAllCharSelectedWithPicHandler.java index 2ea0391aca..2ab8b68a98 100644 --- a/src/main/java/net/server/handlers/login/ViewAllCharSelectedWithPicHandler.java +++ b/src/main/java/net/server/handlers/login/ViewAllCharSelectedWithPicHandler.java @@ -1,6 +1,7 @@ package net.server.handlers.login; import client.Client; +import lombok.extern.slf4j.Slf4j; import net.AbstractPacketHandler; import net.packet.InPacket; import net.server.Server; @@ -8,8 +9,7 @@ import net.server.coordinator.session.Hwid; import net.server.coordinator.session.SessionCoordinator; import net.server.coordinator.session.SessionCoordinator.AntiMulticlientResult; import net.server.world.World; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; +import service.AccountService; import service.BanService; import service.TransitionService; import tools.PacketCreator; @@ -18,13 +18,15 @@ import tools.Randomizer; import java.net.InetAddress; import java.net.UnknownHostException; +@Slf4j public class ViewAllCharSelectedWithPicHandler extends AbstractPacketHandler { - private static final Logger log = LoggerFactory.getLogger(ViewAllCharSelectedWithPicHandler.class); - + private final AccountService accountService; private final BanService banService; private final TransitionService transitionService; - public ViewAllCharSelectedWithPicHandler(BanService banService, TransitionService transitionService) { + public ViewAllCharSelectedWithPicHandler(AccountService accountService, BanService banService, + TransitionService transitionService) { + this.accountService = accountService; this.banService = banService; this.transitionService = transitionService; } @@ -58,9 +60,9 @@ public class ViewAllCharSelectedWithPicHandler extends AbstractPacketHandler { return; } - c.updateMacs(macs); - c.updateHwid(hwid); c.setHwid(hwid); + c.setMacs(macs); + accountService.setIpAndMacsAndHwidAsync(c.getAccID(), c.getRemoteAddress(), macs, hwid); if (banService.isBanned(c)) { SessionCoordinator.getInstance().closeSession(c, true); diff --git a/src/main/java/service/AccountService.java b/src/main/java/service/AccountService.java index cb4fb9364d..ff8ee86c5e 100644 --- a/src/main/java/service/AccountService.java +++ b/src/main/java/service/AccountService.java @@ -7,7 +7,9 @@ import database.account.Account; import database.account.AccountRepository; import lombok.extern.slf4j.Slf4j; import net.server.Server; +import net.server.coordinator.session.Hwid; import net.server.coordinator.session.SessionCoordinator; +import server.TimerManager; import tools.BCrypt; import tools.DatabaseConnection; @@ -301,6 +303,19 @@ public class AccountService { } } + public void setIpAndMacsAndHwidAsync(int accountId, final String ip, final String macs, Hwid hwid) { + final String hwidToSave = hwid != null ? hwid.hwid() : null; + TimerManager.getInstance().schedule(() -> { + try { + accountRepository.setIpAndMacsAndHwid(accountId, ip, hwidToSave, macs); + } catch (Exception e) { + log.error("Failed to save ip: {}, macs: {}, hwid: {} for accountId: {}", ip, hwidToSave, macs, + accountId, e); + } + }, 0); + + } + public boolean ban(int accountId, Instant bannedUntil, byte banReason, String description) { return accountRepository.setBanned(accountId, bannedUntil, banReason, description); }