From 8041ccd6bd85e0e117478ce38ad8f294b9b649f2 Mon Sep 17 00:00:00 2001 From: P0nk Date: Sun, 27 Jun 2021 09:43:40 +0200 Subject: [PATCH] Move some session database logic to dedicated class I need to clean up this class before attempting to migrate away from IoSession for session handling. --- .../session/MapleSessionCoordinator.java | 68 +++++++------------ .../coordinator/session/SessionDAO.java | 53 +++++++++++++++ 2 files changed, 77 insertions(+), 44 deletions(-) create mode 100644 src/main/java/net/server/coordinator/session/SessionDAO.java diff --git a/src/main/java/net/server/coordinator/session/MapleSessionCoordinator.java b/src/main/java/net/server/coordinator/session/MapleSessionCoordinator.java index a41b296c11..032f9acf99 100644 --- a/src/main/java/net/server/coordinator/session/MapleSessionCoordinator.java +++ b/src/main/java/net/server/coordinator/session/MapleSessionCoordinator.java @@ -33,13 +33,13 @@ import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; +import java.time.Instant; import java.util.*; import java.util.Map.Entry; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; -import java.util.regex.Matcher; -import java.util.regex.Pattern; +import java.util.stream.Collectors; /** * @@ -129,38 +129,23 @@ public class MapleSessionCoordinator { ps.executeUpdate(); } } - - private static void registerAccessAccount(Connection con, String remoteHwid, int accountId) throws SQLException { - try (PreparedStatement ps = con.prepareStatement("INSERT INTO hwidaccounts (accountid, hwid, expiresat) VALUES (?, ?, ?)")) { - ps.setInt(1, accountId); - ps.setString(2, remoteHwid); - ps.setTimestamp(3, new java.sql.Timestamp(Server.getInstance().getCurrentTime() + hwidExpirationUpdate(0))); - - ps.executeUpdate(); - } - } - + + /** + * @return false if it was already associated, true if a new association was created in this call + */ private static boolean associateHwidAccountIfAbsent(String remoteHwid, int accountId) { try (Connection con = DatabaseConnection.getConnection()) { - int hwidCount = 0; + List hwids = SessionDAO.getHwidsForAccount(con, accountId); - try (PreparedStatement ps = con.prepareStatement("SELECT SQL_CACHE hwid FROM hwidaccounts WHERE accountid = ?")) { - ps.setInt(1, accountId); - try (ResultSet rs = ps.executeQuery()) { - while (rs.next()) { - String rsHwid = rs.getString("hwid"); - if (rsHwid.contentEquals(remoteHwid)) { - return false; - } + boolean containsRemoteHwid = hwids.stream().anyMatch(hwid -> hwid.contentEquals(remoteHwid)); + if (containsRemoteHwid) { + return false; + } - hwidCount++; - } - } - - if (hwidCount < YamlConfig.config.server.MAX_ALLOWED_ACCOUNT_HWID) { - registerAccessAccount(con, remoteHwid, accountId); - return true; - } + if (hwids.size() < YamlConfig.config.server.MAX_ALLOWED_ACCOUNT_HWID) { + Instant expiry = Instant.ofEpochMilli(Server.getInstance().getCurrentTime() + hwidExpirationUpdate(0)); + SessionDAO.registerAccountAccess(con, accountId, remoteHwid, expiry); + return true; } } catch (SQLException ex) { ex.printStackTrace(); @@ -551,12 +536,7 @@ public class MapleSessionCoordinator { } public void runUpdateHwidHistory() { - try (Connection con = DatabaseConnection.getConnection(); - PreparedStatement ps = con.prepareStatement("DELETE FROM hwidaccounts WHERE expiresat < CURRENT_TIMESTAMP")) { - ps.executeUpdate(); - } catch (SQLException ex) { - ex.printStackTrace(); - } + SessionDAO.deleteExpiredHwidAccounts(); long timeNow = Server.getInstance().getCurrentTime(); List toRemove = new LinkedList<>(); @@ -581,12 +561,13 @@ public class MapleSessionCoordinator { public void printSessionTrace() { if (!onlineClients.isEmpty()) { List> elist = new ArrayList<>(onlineClients.entrySet()); - elist.sort((e1, e2) -> e1.getKey().compareTo(e2.getKey())); + String commaSeparatedClients = elist.stream() + .map(Entry::getKey) + .sorted(Integer::compareTo) + .map(Object::toString) + .collect(Collectors.joining(", ")); - System.out.println("Current online clients: "); - for (Entry e : elist) { - System.out.println(" " + e.getKey()); - } + System.out.println("Current online clients: " + commaSeparatedClients); } if (!onlineRemoteHwids.isEmpty()) { @@ -601,8 +582,7 @@ public class MapleSessionCoordinator { if (!loginRemoteHosts.isEmpty()) { List>> elist = new ArrayList<>(loginRemoteHosts.entrySet()); - - elist.sort((e1, e2) -> e1.getKey().compareTo(e2.getKey())); + elist.sort(Entry.comparingByKey()); System.out.println("Current login sessions: "); for (Entry> e : elist) { @@ -616,7 +596,7 @@ public class MapleSessionCoordinator { if (!onlineClients.isEmpty()) { List> elist = new ArrayList<>(onlineClients.entrySet()); - elist.sort((e1, e2) -> e1.getKey().compareTo(e2.getKey())); + elist.sort(Entry.comparingByKey()); str += ("Current online clients:\r\n"); for (Entry e : elist) { diff --git a/src/main/java/net/server/coordinator/session/SessionDAO.java b/src/main/java/net/server/coordinator/session/SessionDAO.java new file mode 100644 index 0000000000..5d822a4cc1 --- /dev/null +++ b/src/main/java/net/server/coordinator/session/SessionDAO.java @@ -0,0 +1,53 @@ +package net.server.coordinator.session; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import tools.DatabaseConnection; + +import java.sql.*; +import java.time.Instant; +import java.util.ArrayList; +import java.util.List; + +public class SessionDAO { + private static final Logger log = LoggerFactory.getLogger(SessionDAO.class); + + public static void deleteExpiredHwidAccounts() { + final String query = "DELETE FROM hwidaccounts WHERE expiresat < CURRENT_TIMESTAMP"; + try (Connection con = DatabaseConnection.getConnection(); + PreparedStatement ps = con.prepareStatement(query)) { + ps.executeUpdate(); + } catch (SQLException e) { + log.warn("Failed to delete expired hwidaccounts", e); + } + } + + public static List getHwidsForAccount(Connection con, int accountId) throws SQLException { + final List hwids = new ArrayList<>(); + + final String query = "SELECT hwid FROM hwidaccounts WHERE accountid = ?"; + try (PreparedStatement ps = con.prepareStatement(query)) { + ps.setInt(1, accountId); + + try (ResultSet rs = ps.executeQuery()) { + while (rs.next()) { + hwids.add(rs.getString("hwid")); + } + } + } + + return hwids; + } + + public static void registerAccountAccess(Connection con, int accountId, String remoteHwid, Instant expiry) + throws SQLException { + final String query = "INSERT INTO hwidaccounts (accountid, hwid, expiresat) VALUES (?, ?, ?)"; + try (PreparedStatement ps = con.prepareStatement(query)) { + ps.setInt(1, accountId); + ps.setString(2, remoteHwid); + ps.setTimestamp(3, Timestamp.from(expiry)); + + ps.executeUpdate(); + } + } +}