Use Instant instead of long for time measurement
This commit is contained in:
@@ -22,70 +22,60 @@ package net.server.coordinator.login;
|
|||||||
import config.YamlConfig;
|
import config.YamlConfig;
|
||||||
import net.server.Server;
|
import net.server.Server;
|
||||||
|
|
||||||
|
import java.time.Instant;
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.LinkedList;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map.Entry;
|
import java.util.Map.Entry;
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @author Ronan
|
* @author Ronan
|
||||||
*/
|
*/
|
||||||
public class LoginStorage {
|
public class LoginStorage {
|
||||||
|
private final ConcurrentHashMap<Integer, List<Instant>> loginHistory = new ConcurrentHashMap<>(); // Key: accountId
|
||||||
private ConcurrentHashMap<Integer, List<Long>> loginHistory = new ConcurrentHashMap<>();
|
|
||||||
|
|
||||||
public boolean registerLogin(int accountId) {
|
public boolean registerLogin(int accountId) {
|
||||||
List<Long> accHist = loginHistory.get(accountId);
|
List<Instant> attempts = loginHistory.computeIfAbsent(accountId, k -> new ArrayList<>());
|
||||||
if (accHist == null) {
|
|
||||||
accHist = new LinkedList<>();
|
|
||||||
loginHistory.put(accountId, accHist);
|
|
||||||
}
|
|
||||||
|
|
||||||
synchronized (accHist) {
|
|
||||||
if (accHist.size() > YamlConfig.config.server.MAX_ACCOUNT_LOGIN_ATTEMPT) {
|
|
||||||
long blockExpiration = Server.getInstance().getCurrentTime() + YamlConfig.config.server.LOGIN_ATTEMPT_DURATION;
|
|
||||||
Collections.fill(accHist, blockExpiration);
|
|
||||||
|
|
||||||
|
synchronized (attempts) {
|
||||||
|
final Instant attemptExpiry = Instant.ofEpochMilli(Server.getInstance().getCurrentTime() + YamlConfig.config.server.LOGIN_ATTEMPT_DURATION);
|
||||||
|
|
||||||
|
if (attempts.size() > YamlConfig.config.server.MAX_ACCOUNT_LOGIN_ATTEMPT) {
|
||||||
|
Collections.fill(attempts, attemptExpiry);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
accHist.add(Server.getInstance().getCurrentTime() + YamlConfig.config.server.LOGIN_ATTEMPT_DURATION);
|
attempts.add(attemptExpiry);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void updateLoginHistory() {
|
public void clearExpiredAttempts() {
|
||||||
long timeNow = Server.getInstance().getCurrentTime();
|
final Instant now = Instant.ofEpochMilli(Server.getInstance().getCurrentTime());
|
||||||
List<Integer> toRemove = new LinkedList<>();
|
List<Integer> accountIdsToClear = new ArrayList<>();
|
||||||
List<Long> toRemoveAttempt = new LinkedList<>();
|
|
||||||
|
for (Entry<Integer, List<Instant>> loginEntries : loginHistory.entrySet()) {
|
||||||
for (Entry<Integer, List<Long>> loginEntries : loginHistory.entrySet()) {
|
final List<Instant> attempts = loginEntries.getValue();
|
||||||
toRemoveAttempt.clear();
|
synchronized (attempts) {
|
||||||
|
List<Instant> attemptsToRemove = attempts.stream()
|
||||||
List<Long> accAttempts = loginEntries.getValue();
|
.filter(attempt -> attempt.isBefore(now))
|
||||||
synchronized (accAttempts) {
|
.collect(Collectors.toList());
|
||||||
for (Long loginAttempt : accAttempts) {
|
|
||||||
if (loginAttempt < timeNow) {
|
for (Instant attemptToRemove : attemptsToRemove) {
|
||||||
toRemoveAttempt.add(loginAttempt);
|
attempts.remove(attemptToRemove);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!toRemoveAttempt.isEmpty()) {
|
if (attempts.isEmpty()) {
|
||||||
for (Long trAttempt : toRemoveAttempt) {
|
accountIdsToClear.add(loginEntries.getKey());
|
||||||
accAttempts.remove(trAttempt);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (accAttempts.isEmpty()) {
|
|
||||||
toRemove.add(loginEntries.getKey());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (Integer tr : toRemove) {
|
for (Integer accountId : accountIdsToClear) {
|
||||||
loginHistory.remove(tr);
|
loginHistory.remove(accountId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -399,7 +399,7 @@ public class MapleSessionCoordinator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void runUpdateLoginHistory() {
|
public void runUpdateLoginHistory() {
|
||||||
loginStorage.updateLoginHistory();
|
loginStorage.clearExpiredAttempts();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void printSessionTrace() {
|
public void printSessionTrace() {
|
||||||
|
|||||||
Reference in New Issue
Block a user