Move the remaining session database logic
This commit is contained in:
@@ -0,0 +1,4 @@
|
|||||||
|
package net.server.coordinator.session;
|
||||||
|
|
||||||
|
public record HwidRelevance(String hwid, int relevance) {
|
||||||
|
}
|
||||||
@@ -27,6 +27,8 @@ import net.server.audit.locks.MonitoredLockType;
|
|||||||
import net.server.audit.locks.factory.MonitoredReentrantLockFactory;
|
import net.server.audit.locks.factory.MonitoredReentrantLockFactory;
|
||||||
import net.server.coordinator.login.LoginStorage;
|
import net.server.coordinator.login.LoginStorage;
|
||||||
import org.apache.mina.core.session.IoSession;
|
import org.apache.mina.core.session.IoSession;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
import tools.DatabaseConnection;
|
import tools.DatabaseConnection;
|
||||||
|
|
||||||
import java.sql.Connection;
|
import java.sql.Connection;
|
||||||
@@ -46,8 +48,8 @@ import java.util.stream.Collectors;
|
|||||||
* @author Ronan
|
* @author Ronan
|
||||||
*/
|
*/
|
||||||
public class MapleSessionCoordinator {
|
public class MapleSessionCoordinator {
|
||||||
|
private static final Logger log = LoggerFactory.getLogger(MapleSessionCoordinator.class);
|
||||||
private final static MapleSessionCoordinator instance = new MapleSessionCoordinator();
|
private static final MapleSessionCoordinator instance = new MapleSessionCoordinator();
|
||||||
|
|
||||||
public static MapleSessionCoordinator getInstance() {
|
public static MapleSessionCoordinator getInstance() {
|
||||||
return instance;
|
return instance;
|
||||||
@@ -78,9 +80,15 @@ public class MapleSessionCoordinator {
|
|||||||
poolLock.add(MonitoredReentrantLockFactory.createLock(MonitoredLockType.SERVER_LOGIN_COORD));
|
poolLock.add(MonitoredReentrantLockFactory.createLock(MonitoredLockType.SERVER_LOGIN_COORD));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static Instant getHwidAccountExpiry(int relevance) {
|
||||||
|
return Instant.ofEpochMilli(Server.getInstance().getCurrentTime() + hwidExpirationUpdate(relevance));
|
||||||
|
}
|
||||||
|
|
||||||
private static long hwidExpirationUpdate(int relevance) {
|
private static long hwidExpirationUpdate(int relevance) {
|
||||||
int degree = 1, i = relevance, subdegree;
|
int degree = 1;
|
||||||
|
int i = relevance;
|
||||||
|
int subdegree;
|
||||||
while ((subdegree = 5 * degree) <= i) {
|
while ((subdegree = 5 * degree) <= i) {
|
||||||
i -= subdegree;
|
i -= subdegree;
|
||||||
degree++;
|
degree++;
|
||||||
@@ -113,22 +121,6 @@ public class MapleSessionCoordinator {
|
|||||||
|
|
||||||
return 3600000 * (baseTime + subdegreeTime);
|
return 3600000 * (baseTime + subdegreeTime);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void updateAccessAccount(Connection con, String remoteHwid, int accountId, int loginRelevance) throws SQLException {
|
|
||||||
java.sql.Timestamp nextTimestamp = new java.sql.Timestamp(Server.getInstance().getCurrentTime() + hwidExpirationUpdate(loginRelevance));
|
|
||||||
if(loginRelevance < Byte.MAX_VALUE) {
|
|
||||||
loginRelevance++;
|
|
||||||
}
|
|
||||||
|
|
||||||
try (PreparedStatement ps = con.prepareStatement("UPDATE hwidaccounts SET relevance = ?, expiresat = ? WHERE accountid = ? AND hwid LIKE ?")) {
|
|
||||||
ps.setInt(1, loginRelevance);
|
|
||||||
ps.setTimestamp(2, nextTimestamp);
|
|
||||||
ps.setInt(3, accountId);
|
|
||||||
ps.setString(4, remoteHwid);
|
|
||||||
|
|
||||||
ps.executeUpdate();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return false if it was already associated, true if a new association was created in this call
|
* @return false if it was already associated, true if a new association was created in this call
|
||||||
@@ -143,7 +135,7 @@ public class MapleSessionCoordinator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (hwids.size() < YamlConfig.config.server.MAX_ALLOWED_ACCOUNT_HWID) {
|
if (hwids.size() < YamlConfig.config.server.MAX_ALLOWED_ACCOUNT_HWID) {
|
||||||
Instant expiry = Instant.ofEpochMilli(Server.getInstance().getCurrentTime() + hwidExpirationUpdate(0));
|
Instant expiry = getHwidAccountExpiry(0);
|
||||||
SessionDAO.registerAccountAccess(con, accountId, remoteHwid, expiry);
|
SessionDAO.registerAccountAccess(con, accountId, remoteHwid, expiry);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -154,37 +146,31 @@ public class MapleSessionCoordinator {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static boolean attemptAccessAccount(String nibbleHwid, int accountId, boolean routineCheck) {
|
private static boolean attemptAccountAccess(int accountId, String nibbleHwid, boolean routineCheck) {
|
||||||
try (Connection con = DatabaseConnection.getConnection()) {
|
try (Connection con = DatabaseConnection.getConnection()) {
|
||||||
int hwidCount = 0;
|
List<HwidRelevance> hwidRelevances = SessionDAO.getHwidRelevance(con, accountId);
|
||||||
|
for (HwidRelevance hwidRelevance : hwidRelevances) {
|
||||||
try (PreparedStatement ps = con.prepareStatement("SELECT SQL_CACHE * FROM hwidaccounts WHERE accountid = ?")) {
|
if (hwidRelevance.hwid().endsWith(nibbleHwid)) {
|
||||||
ps.setInt(1, accountId);
|
if (!routineCheck) {
|
||||||
|
// better update HWID relevance as soon as the login is authenticated
|
||||||
try (ResultSet rs = ps.executeQuery()) {
|
Instant expiry = getHwidAccountExpiry(hwidRelevance.relevance());
|
||||||
while (rs.next()) {
|
int relevance = hwidRelevance.relevance();
|
||||||
String rsHwid = rs.getString("hwid");
|
if (relevance < Byte.MAX_VALUE) {
|
||||||
if (rsHwid.endsWith(nibbleHwid)) {
|
relevance++;
|
||||||
if (!routineCheck) {
|
|
||||||
// better update HWID relevance as soon as the login is authenticated
|
|
||||||
|
|
||||||
int loginRelevance = rs.getInt("relevance");
|
|
||||||
updateAccessAccount(con, rsHwid, accountId, loginRelevance);
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
hwidCount++;
|
SessionDAO.updateAccountAccess(con, nibbleHwid, accountId, expiry, relevance);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (hwidCount < YamlConfig.config.server.MAX_ALLOWED_ACCOUNT_HWID) {
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (SQLException ex) {
|
|
||||||
ex.printStackTrace();
|
if (hwidRelevances.size() < YamlConfig.config.server.MAX_ALLOWED_ACCOUNT_HWID) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
} catch (SQLException e) {
|
||||||
|
log.warn("Failed to update account access. Account id: {}, nibbleHwid: {}", accountId, nibbleHwid, e);
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
@@ -363,14 +349,14 @@ public class MapleSessionCoordinator {
|
|||||||
return AntiMulticlientResult.REMOTE_LOGGEDIN;
|
return AntiMulticlientResult.REMOTE_LOGGEDIN;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!attemptAccessAccount(nibbleHwid, accountId, routineCheck)) {
|
if (!attemptAccountAccess(accountId, nibbleHwid, routineCheck)) {
|
||||||
return AntiMulticlientResult.REMOTE_REACHED_LIMIT;
|
return AntiMulticlientResult.REMOTE_REACHED_LIMIT;
|
||||||
}
|
}
|
||||||
|
|
||||||
session.setAttribute(MapleClient.CLIENT_NIBBLEHWID, nibbleHwid);
|
session.setAttribute(MapleClient.CLIENT_NIBBLEHWID, nibbleHwid);
|
||||||
onlineRemoteHwids.add(nibbleHwid);
|
onlineRemoteHwids.add(nibbleHwid);
|
||||||
} else {
|
} else {
|
||||||
if (!attemptAccessAccount(nibbleHwid, accountId, routineCheck)) {
|
if (!attemptAccountAccess(accountId, nibbleHwid, routineCheck)) {
|
||||||
return AntiMulticlientResult.REMOTE_REACHED_LIMIT;
|
return AntiMulticlientResult.REMOTE_REACHED_LIMIT;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -50,4 +50,36 @@ public class SessionDAO {
|
|||||||
ps.executeUpdate();
|
ps.executeUpdate();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static List<HwidRelevance> getHwidRelevance(Connection con, int accountId) throws SQLException {
|
||||||
|
final List<HwidRelevance> hwidRelevances = new ArrayList<>();
|
||||||
|
|
||||||
|
final String query = "SELECT * FROM hwidaccounts WHERE accountid = ?";
|
||||||
|
try (PreparedStatement ps = con.prepareStatement(query)) {
|
||||||
|
ps.setInt(1, accountId);
|
||||||
|
|
||||||
|
try (ResultSet rs = ps.executeQuery()) {
|
||||||
|
while (rs.next()) {
|
||||||
|
String hwid = rs.getString("hwid");
|
||||||
|
int relevance = rs.getInt("relevance");
|
||||||
|
hwidRelevances.add(new HwidRelevance(hwid, relevance));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return hwidRelevances;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void updateAccountAccess(Connection con, String remoteHwid, int accountId, Instant expiry, int loginRelevance)
|
||||||
|
throws SQLException {
|
||||||
|
final String query = "UPDATE hwidaccounts SET relevance = ?, expiresat = ? WHERE accountid = ? AND hwid LIKE ?";
|
||||||
|
try (PreparedStatement ps = con.prepareStatement(query)) {
|
||||||
|
ps.setInt(1, loginRelevance);
|
||||||
|
ps.setTimestamp(2, Timestamp.from(expiry));
|
||||||
|
ps.setInt(3, accountId);
|
||||||
|
ps.setString(4, remoteHwid);
|
||||||
|
|
||||||
|
ps.executeUpdate();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user