mirror of
https://github.com/plan-player-analytics/Plan.git
synced 2024-12-27 09:00:28 +08:00
Reduce the amount of tasks used for upkeep
- Ping gathering now uses a map of timestamps - Removes a task that waited for ping data to be reliable (one task / join) - Cookie expiration now uses a map of timestamps - Removes a task that waited for cookie to expire (one task / login cookie) Affects issues: - Possibly fixed #1984
This commit is contained in:
parent
f26e17c437
commit
a7478645bd
Plan
bukkit/src
main/java/com/djrapitops/plan
test/java/utilities/mocks
bungeecord/src
main/java/com/djrapitops/plan
test/java/utilities/mocks
common/src
main/java/com/djrapitops/plan
delivery/webserver/auth
settings
storage/database
test/java
com/djrapitops/plan
utilities/mocks
fabric/src
main/java/net/playeranalytics/plan
test/java/utilities/mocks
nukkit/src
main/java/com/djrapitops/plan
test/java/utilities/mocks
sponge/src
main/java/com/djrapitops/plan
test/java/utilities/mocks
velocity/src
main/java/com/djrapitops/plan
test/java
com/djrapitops/plan/gathering/timed
utilities/mocks
@ -44,6 +44,7 @@ import org.bukkit.event.player.PlayerQuitEvent;
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
@ -63,13 +64,13 @@ public class BukkitPingCounter extends TaskSystem.Task implements Listener {
|
||||
//https://github.com/bergerkiller/CraftSource/blob/master/net.minecraft.server/PlayerConnection.java#L178
|
||||
|
||||
|
||||
private final Map<UUID, Long> startRecording;
|
||||
private final Map<UUID, List<DateObj<Integer>>> playerHistory;
|
||||
|
||||
private final Listeners listeners;
|
||||
private final PlanConfig config;
|
||||
private final DBSystem dbSystem;
|
||||
private final ServerInfo serverInfo;
|
||||
private final RunnableFactory runnableFactory;
|
||||
|
||||
private final boolean pingMethodAvailable;
|
||||
private PingMethod pingMethod;
|
||||
@ -79,14 +80,13 @@ public class BukkitPingCounter extends TaskSystem.Task implements Listener {
|
||||
Listeners listeners,
|
||||
PlanConfig config,
|
||||
DBSystem dbSystem,
|
||||
ServerInfo serverInfo,
|
||||
RunnableFactory runnableFactory
|
||||
ServerInfo serverInfo
|
||||
) {
|
||||
this.listeners = listeners;
|
||||
this.config = config;
|
||||
this.dbSystem = dbSystem;
|
||||
this.serverInfo = serverInfo;
|
||||
this.runnableFactory = runnableFactory;
|
||||
startRecording = new ConcurrentHashMap<>();
|
||||
playerHistory = new HashMap<>();
|
||||
|
||||
Optional<PingMethod> pingMethod = loadPingMethod();
|
||||
@ -138,6 +138,16 @@ public class BukkitPingCounter extends TaskSystem.Task implements Listener {
|
||||
@Override
|
||||
public void run() {
|
||||
long time = System.currentTimeMillis();
|
||||
|
||||
Iterator<Map.Entry<UUID, Long>> starts = startRecording.entrySet().iterator();
|
||||
while (starts.hasNext()) {
|
||||
Map.Entry<UUID, Long> start = starts.next();
|
||||
if (time >= start.getValue()) {
|
||||
addPlayer(start.getKey());
|
||||
starts.remove();
|
||||
}
|
||||
}
|
||||
|
||||
Iterator<Map.Entry<UUID, List<DateObj<Integer>>>> iterator = playerHistory.entrySet().iterator();
|
||||
|
||||
while (iterator.hasNext()) {
|
||||
@ -164,11 +174,12 @@ public class BukkitPingCounter extends TaskSystem.Task implements Listener {
|
||||
}
|
||||
}
|
||||
|
||||
public void addPlayer(Player player) {
|
||||
playerHistory.put(player.getUniqueId(), new ArrayList<>());
|
||||
public void addPlayer(UUID uuid) {
|
||||
playerHistory.put(uuid, new ArrayList<>());
|
||||
}
|
||||
|
||||
public void removePlayer(Player player) {
|
||||
startRecording.remove(player.getUniqueId());
|
||||
playerHistory.remove(player.getUniqueId());
|
||||
}
|
||||
|
||||
@ -182,15 +193,11 @@ public class BukkitPingCounter extends TaskSystem.Task implements Listener {
|
||||
@EventHandler
|
||||
public void onPlayerJoin(PlayerJoinEvent joinEvent) {
|
||||
Player player = joinEvent.getPlayer();
|
||||
Long pingDelay = config.get(TimeSettings.PING_PLAYER_LOGIN_DELAY);
|
||||
if (pingDelay >= TimeUnit.HOURS.toMillis(2L)) {
|
||||
Long pingDelayMs = config.get(TimeSettings.PING_PLAYER_LOGIN_DELAY);
|
||||
if (pingDelayMs >= TimeUnit.HOURS.toMillis(2L)) {
|
||||
return;
|
||||
}
|
||||
runnableFactory.create(() -> {
|
||||
if (player.isOnline()) {
|
||||
addPlayer(player);
|
||||
}
|
||||
}).runTaskLater(TimeAmount.toTicks(pingDelay, TimeUnit.MILLISECONDS));
|
||||
startRecording.put(player.getUniqueId(), System.currentTimeMillis() + pingDelayMs);
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
|
@ -19,6 +19,7 @@ package com.djrapitops.plan.modules.bukkit;
|
||||
import com.djrapitops.plan.TaskSystem;
|
||||
import com.djrapitops.plan.delivery.web.ResourceWriteTask;
|
||||
import com.djrapitops.plan.delivery.web.WebAssetVersionCheckTask;
|
||||
import com.djrapitops.plan.delivery.webserver.auth.ActiveCookieExpiryCleanupTask;
|
||||
import com.djrapitops.plan.delivery.webserver.cache.JSONFileStorage;
|
||||
import com.djrapitops.plan.extension.ExtensionServerDataUpdater;
|
||||
import com.djrapitops.plan.gathering.ShutdownDataPreservation;
|
||||
@ -93,4 +94,8 @@ public interface BukkitTaskModule {
|
||||
@Binds
|
||||
@IntoSet
|
||||
TaskSystem.Task bindWebAssetVersionCheckTask(WebAssetVersionCheckTask webAssetVersionCheckTask);
|
||||
|
||||
@Binds
|
||||
@IntoSet
|
||||
TaskSystem.Task bindActiveCookieStoreExpiryTask(ActiveCookieExpiryCleanupTask activeCookieExpiryCleanupTask);
|
||||
}
|
||||
|
@ -20,6 +20,7 @@ import com.djrapitops.plan.DaggerPlanBukkitComponent;
|
||||
import com.djrapitops.plan.PlanBukkitComponent;
|
||||
import com.djrapitops.plan.PlanPlugin;
|
||||
import com.djrapitops.plan.PlanSystem;
|
||||
import com.djrapitops.plan.storage.database.SQLDB;
|
||||
import org.bukkit.Server;
|
||||
import org.bukkit.command.ConsoleCommandSender;
|
||||
import org.bukkit.scheduler.BukkitScheduler;
|
||||
@ -44,6 +45,7 @@ public class BukkitMockComponent {
|
||||
|
||||
public BukkitMockComponent(Path tempDir) {
|
||||
this.tempDir = tempDir;
|
||||
SQLDB.setDownloadDriver(false);
|
||||
}
|
||||
|
||||
public PlanPlugin getPlanMock() throws Exception {
|
||||
|
@ -44,6 +44,7 @@ import net.playeranalytics.plugin.server.Listeners;
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
/**
|
||||
@ -54,35 +55,43 @@ import java.util.concurrent.TimeUnit;
|
||||
@Singleton
|
||||
public class BungeePingCounter extends TaskSystem.Task implements Listener {
|
||||
|
||||
private final Map<UUID, Long> startRecording;
|
||||
private final Map<UUID, List<DateObj<Integer>>> playerHistory;
|
||||
|
||||
private final Listeners listeners;
|
||||
private final PlanConfig config;
|
||||
private final DBSystem dbSystem;
|
||||
private final ServerInfo serverInfo;
|
||||
private final RunnableFactory runnableFactory;
|
||||
|
||||
@Inject
|
||||
public BungeePingCounter(
|
||||
Listeners listeners,
|
||||
PlanConfig config,
|
||||
DBSystem dbSystem,
|
||||
ServerInfo serverInfo,
|
||||
RunnableFactory runnableFactory
|
||||
ServerInfo serverInfo
|
||||
) {
|
||||
this.listeners = listeners;
|
||||
this.config = config;
|
||||
this.dbSystem = dbSystem;
|
||||
this.serverInfo = serverInfo;
|
||||
this.runnableFactory = runnableFactory;
|
||||
startRecording = new ConcurrentHashMap<>();
|
||||
playerHistory = new HashMap<>();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
long time = System.currentTimeMillis();
|
||||
Iterator<Map.Entry<UUID, List<DateObj<Integer>>>> iterator = playerHistory.entrySet().iterator();
|
||||
|
||||
Iterator<Map.Entry<UUID, Long>> starts = startRecording.entrySet().iterator();
|
||||
while (starts.hasNext()) {
|
||||
Map.Entry<UUID, Long> start = starts.next();
|
||||
if (time >= start.getValue()) {
|
||||
addPlayer(start.getKey());
|
||||
starts.remove();
|
||||
}
|
||||
}
|
||||
|
||||
Iterator<Map.Entry<UUID, List<DateObj<Integer>>>> iterator = playerHistory.entrySet().iterator();
|
||||
while (iterator.hasNext()) {
|
||||
Map.Entry<UUID, List<DateObj<Integer>>> entry = iterator.next();
|
||||
UUID uuid = entry.getKey();
|
||||
@ -119,12 +128,13 @@ public class BungeePingCounter extends TaskSystem.Task implements Listener {
|
||||
}
|
||||
}
|
||||
|
||||
public void addPlayer(ProxiedPlayer player) {
|
||||
playerHistory.put(player.getUniqueId(), new ArrayList<>());
|
||||
public void addPlayer(UUID uuid) {
|
||||
playerHistory.put(uuid, new ArrayList<>());
|
||||
}
|
||||
|
||||
public void removePlayer(ProxiedPlayer player) {
|
||||
playerHistory.remove(player.getUniqueId());
|
||||
startRecording.remove(player.getUniqueId());
|
||||
}
|
||||
|
||||
private int getPing(ProxiedPlayer player) {
|
||||
@ -134,15 +144,11 @@ public class BungeePingCounter extends TaskSystem.Task implements Listener {
|
||||
@EventHandler
|
||||
public void onPlayerJoin(ServerConnectedEvent joinEvent) {
|
||||
ProxiedPlayer player = joinEvent.getPlayer();
|
||||
Long pingDelay = config.get(TimeSettings.PING_PLAYER_LOGIN_DELAY);
|
||||
if (pingDelay >= TimeUnit.HOURS.toMillis(2L)) {
|
||||
Long pingDelayMs = config.get(TimeSettings.PING_PLAYER_LOGIN_DELAY);
|
||||
if (pingDelayMs >= TimeUnit.HOURS.toMillis(2L)) {
|
||||
return;
|
||||
}
|
||||
runnableFactory.create(() -> {
|
||||
if (player.isConnected()) {
|
||||
addPlayer(player);
|
||||
}
|
||||
}).runTaskLater(TimeAmount.toTicks(pingDelay, TimeUnit.MILLISECONDS));
|
||||
startRecording.put(player.getUniqueId(), System.currentTimeMillis() + pingDelayMs);
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
|
@ -19,6 +19,7 @@ package com.djrapitops.plan.modules.bungee;
|
||||
import com.djrapitops.plan.TaskSystem;
|
||||
import com.djrapitops.plan.delivery.web.ResourceWriteTask;
|
||||
import com.djrapitops.plan.delivery.web.WebAssetVersionCheckTask;
|
||||
import com.djrapitops.plan.delivery.webserver.auth.ActiveCookieExpiryCleanupTask;
|
||||
import com.djrapitops.plan.delivery.webserver.cache.JSONFileStorage;
|
||||
import com.djrapitops.plan.extension.ExtensionServerDataUpdater;
|
||||
import com.djrapitops.plan.gathering.timed.BungeePingCounter;
|
||||
@ -82,4 +83,8 @@ public interface BungeeTaskModule {
|
||||
@Binds
|
||||
@IntoSet
|
||||
TaskSystem.Task bindWebAssetVersionCheckTask(WebAssetVersionCheckTask webAssetVersionCheckTask);
|
||||
|
||||
@Binds
|
||||
@IntoSet
|
||||
TaskSystem.Task bindActiveCookieStoreExpiryTask(ActiveCookieExpiryCleanupTask activeCookieExpiryCleanupTask);
|
||||
}
|
||||
|
@ -20,6 +20,7 @@ import com.djrapitops.plan.DaggerPlanBungeeComponent;
|
||||
import com.djrapitops.plan.PlanBungee;
|
||||
import com.djrapitops.plan.PlanBungeeComponent;
|
||||
import com.djrapitops.plan.PlanSystem;
|
||||
import com.djrapitops.plan.storage.database.SQLDB;
|
||||
|
||||
import java.nio.file.Path;
|
||||
|
||||
@ -37,6 +38,7 @@ public class BungeeMockComponent {
|
||||
|
||||
public BungeeMockComponent(Path tempDir) {
|
||||
this.tempDir = tempDir;
|
||||
SQLDB.setDownloadDriver(false);
|
||||
}
|
||||
|
||||
public PlanBungee getPlanMock() throws Exception {
|
||||
|
@ -0,0 +1,73 @@
|
||||
/*
|
||||
* This file is part of Player Analytics (Plan).
|
||||
*
|
||||
* Plan is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License v3 as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Plan is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with Plan. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.djrapitops.plan.delivery.webserver.auth;
|
||||
|
||||
import com.djrapitops.plan.TaskSystem;
|
||||
import dagger.Lazy;
|
||||
import net.playeranalytics.plugin.scheduling.RunnableFactory;
|
||||
import net.playeranalytics.plugin.scheduling.TimeAmount;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
@Singleton
|
||||
public class ActiveCookieExpiryCleanupTask extends TaskSystem.Task {
|
||||
|
||||
private final Lazy<ActiveCookieStore> activeCookieStore;
|
||||
|
||||
private final Map<String, Long> expiryDates;
|
||||
|
||||
@Inject
|
||||
public ActiveCookieExpiryCleanupTask(Lazy<ActiveCookieStore> activeCookieStore) {
|
||||
this.activeCookieStore = activeCookieStore;
|
||||
this.expiryDates = new ConcurrentHashMap<>();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void register(RunnableFactory runnableFactory) {
|
||||
runnableFactory.create(this)
|
||||
.runTaskTimerAsynchronously(
|
||||
TimeAmount.toTicks(5, TimeUnit.SECONDS),
|
||||
TimeAmount.toTicks(1, TimeUnit.SECONDS));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
long time = System.currentTimeMillis();
|
||||
Set<String> removed = new HashSet<>();
|
||||
for (Map.Entry<String, Long> entry : expiryDates.entrySet()) {
|
||||
Long expiryTime = entry.getValue();
|
||||
if (expiryTime >= time) {
|
||||
String cookie = entry.getKey();
|
||||
activeCookieStore.get().removeCookie(cookie);
|
||||
}
|
||||
}
|
||||
|
||||
for (String removedCookie : removed) {
|
||||
expiryDates.remove(removedCookie);
|
||||
}
|
||||
}
|
||||
|
||||
public void addExpiry(String cookie, Long time) {
|
||||
expiryDates.put(cookie, time);
|
||||
}
|
||||
}
|
@ -24,14 +24,13 @@ import com.djrapitops.plan.settings.config.paths.WebserverSettings;
|
||||
import com.djrapitops.plan.storage.database.DBSystem;
|
||||
import com.djrapitops.plan.storage.database.queries.objects.WebUserQueries;
|
||||
import com.djrapitops.plan.storage.database.transactions.events.CookieChangeTransaction;
|
||||
import net.playeranalytics.plugin.scheduling.RunnableFactory;
|
||||
import net.playeranalytics.plugin.scheduling.Task;
|
||||
import net.playeranalytics.plugin.scheduling.TimeAmount;
|
||||
import org.apache.commons.codec.digest.DigestUtils;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
import java.util.*;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
@ -42,28 +41,25 @@ public class ActiveCookieStore implements SubSystem {
|
||||
public static long cookieExpiresAfter = TimeUnit.HOURS.toMillis(2L);
|
||||
private static ActiveCookieStore activeCookieStore;
|
||||
|
||||
private final ActiveCookieExpiryCleanupTask activeCookieExpiryCleanupTask;
|
||||
|
||||
private final PlanConfig config;
|
||||
private final DBSystem dbSystem;
|
||||
private final RunnableFactory runnableFactory;
|
||||
private final Processing processing;
|
||||
|
||||
private final Collection<Task> expiryTasks;
|
||||
|
||||
@Inject
|
||||
public ActiveCookieStore(
|
||||
ActiveCookieExpiryCleanupTask activeCookieExpiryCleanupTask,
|
||||
PlanConfig config,
|
||||
DBSystem dbSystem,
|
||||
RunnableFactory runnableFactory,
|
||||
Processing processing
|
||||
) {
|
||||
this.activeCookieExpiryCleanupTask = activeCookieExpiryCleanupTask;
|
||||
ActiveCookieStore.activeCookieStore = this;
|
||||
|
||||
this.config = config;
|
||||
this.dbSystem = dbSystem;
|
||||
this.processing = processing;
|
||||
this.runnableFactory = runnableFactory;
|
||||
|
||||
expiryTasks = new ArrayList<>();
|
||||
}
|
||||
|
||||
private static void removeCookieStatic(String cookie) {
|
||||
@ -88,22 +84,13 @@ public class ActiveCookieStore implements SubSystem {
|
||||
USERS_BY_COOKIE.putAll(dbSystem.getDatabase().query(WebUserQueries.fetchActiveCookies()));
|
||||
for (Map.Entry<String, Long> entry : dbSystem.getDatabase().query(WebUserQueries.getCookieExpiryTimes()).entrySet()) {
|
||||
long timeToExpiry = Math.max(entry.getValue() - System.currentTimeMillis(), 0L);
|
||||
expiryTasks.add(runnableFactory.create(() -> removeCookie(entry.getKey()))
|
||||
.runTaskLaterAsynchronously(TimeAmount.toTicks(timeToExpiry, TimeUnit.MILLISECONDS)));
|
||||
activeCookieExpiryCleanupTask.addExpiry(entry.getKey(), System.currentTimeMillis() + timeToExpiry);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void disable() {
|
||||
USERS_BY_COOKIE.clear();
|
||||
expiryTasks.forEach(task -> {
|
||||
try {
|
||||
task.cancel();
|
||||
} catch (Exception e) {
|
||||
// Ignore, task has already been cancelled
|
||||
}
|
||||
});
|
||||
expiryTasks.clear();
|
||||
}
|
||||
|
||||
public Optional<User> checkCookie(String cookie) {
|
||||
@ -114,8 +101,7 @@ public class ActiveCookieStore implements SubSystem {
|
||||
String cookie = DigestUtils.sha256Hex(user.getUsername() + UUID.randomUUID() + System.currentTimeMillis());
|
||||
USERS_BY_COOKIE.put(cookie, user);
|
||||
saveNewCookie(user, cookie, System.currentTimeMillis());
|
||||
expiryTasks.add(runnableFactory.create(() -> removeCookie(cookie))
|
||||
.runTaskLaterAsynchronously(TimeAmount.toTicks(cookieExpiresAfter, TimeUnit.MILLISECONDS)));
|
||||
activeCookieExpiryCleanupTask.addExpiry(cookie, System.currentTimeMillis() + cookieExpiresAfter);
|
||||
return cookie;
|
||||
}
|
||||
|
||||
|
@ -16,7 +16,7 @@
|
||||
*/
|
||||
package com.djrapitops.plan.settings;
|
||||
|
||||
import net.playeranalytics.plugin.scheduling.RunnableFactory;
|
||||
import com.djrapitops.plan.processing.Processing;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
@ -24,16 +24,16 @@ import javax.inject.Singleton;
|
||||
@Singleton
|
||||
public class SchedulerSvc implements SchedulerService {
|
||||
|
||||
private final RunnableFactory runnableFactory;
|
||||
private final Processing processing;
|
||||
|
||||
@Inject
|
||||
public SchedulerSvc(RunnableFactory runnableFactory) {
|
||||
this.runnableFactory = runnableFactory;
|
||||
public SchedulerSvc(Processing processing) {
|
||||
this.processing = processing;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void runAsync(Runnable runnable) {
|
||||
runnableFactory.create(runnable).runTaskAsynchronously();
|
||||
processing.submitNonCritical(runnable);
|
||||
}
|
||||
|
||||
public void register() {
|
||||
|
@ -46,6 +46,7 @@ import net.playeranalytics.plugin.scheduling.TimeAmount;
|
||||
import net.playeranalytics.plugin.server.PluginLogger;
|
||||
import org.apache.commons.lang3.concurrent.BasicThreadFactory;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.sql.Connection;
|
||||
import java.sql.SQLException;
|
||||
import java.util.*;
|
||||
@ -60,6 +61,8 @@ import java.util.function.Supplier;
|
||||
*/
|
||||
public abstract class SQLDB extends AbstractDatabase {
|
||||
|
||||
private static boolean downloadDriver = true;
|
||||
|
||||
private static final List<Repository> DRIVER_REPOSITORIES = Arrays.asList(
|
||||
new StandardRepository("https://papermc.io/repo/repository/maven-public/"),
|
||||
new StandardRepository("https://repo1.maven.org/maven2/")
|
||||
@ -74,7 +77,7 @@ public abstract class SQLDB extends AbstractDatabase {
|
||||
protected final PluginLogger logger;
|
||||
protected final ErrorLogger errorLogger;
|
||||
|
||||
protected IsolatedClassLoader driverClassLoader;
|
||||
protected ClassLoader driverClassLoader;
|
||||
|
||||
private Supplier<ExecutorService> transactionExecutorServiceProvider;
|
||||
private ExecutorService transactionExecutor;
|
||||
@ -110,16 +113,24 @@ public abstract class SQLDB extends AbstractDatabase {
|
||||
};
|
||||
}
|
||||
|
||||
public static void setDownloadDriver(boolean downloadDriver) {
|
||||
SQLDB.downloadDriver = downloadDriver;
|
||||
}
|
||||
|
||||
protected abstract List<String> getDependencyResource();
|
||||
|
||||
public void downloadDriver() {
|
||||
DependencyManager dependencyManager = new DependencyManager(files.getDataDirectory().resolve("libraries"));
|
||||
dependencyManager.loadFromResource(getDependencyResource());
|
||||
dependencyManager.download(null, DRIVER_REPOSITORIES);
|
||||
if (downloadDriver) {
|
||||
DependencyManager dependencyManager = new DependencyManager(files.getDataDirectory().resolve("libraries"));
|
||||
dependencyManager.loadFromResource(getDependencyResource());
|
||||
dependencyManager.download(null, DRIVER_REPOSITORIES);
|
||||
|
||||
IsolatedClassLoader classLoader = new IsolatedClassLoader();
|
||||
dependencyManager.load(null, classLoader);
|
||||
this.driverClassLoader = classLoader;
|
||||
IsolatedClassLoader classLoader = new IsolatedClassLoader();
|
||||
dependencyManager.load(null, classLoader);
|
||||
this.driverClassLoader = classLoader;
|
||||
} else {
|
||||
this.driverClassLoader = getClass().getClassLoader();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -262,9 +273,21 @@ public abstract class SQLDB extends AbstractDatabase {
|
||||
public void close() {
|
||||
if (getState() == State.OPEN) setState(State.CLOSING);
|
||||
closeTransactionExecutor(transactionExecutor);
|
||||
unloadDriverClassloader();
|
||||
setState(State.CLOSED);
|
||||
}
|
||||
|
||||
private void unloadDriverClassloader() {
|
||||
try {
|
||||
if (driverClassLoader != null && driverClassLoader instanceof IsolatedClassLoader) {
|
||||
((IsolatedClassLoader) driverClassLoader).close();
|
||||
}
|
||||
driverClassLoader = null;
|
||||
} catch (IOException e) {
|
||||
errorLogger.error(e, ErrorContext.builder().build());
|
||||
}
|
||||
}
|
||||
|
||||
public abstract Connection getConnection() throws SQLException;
|
||||
|
||||
public abstract void returnToPool(Connection connection);
|
||||
|
@ -46,7 +46,7 @@ class ActiveCookieStoreTest {
|
||||
when(dbSystem.getDatabase()).thenReturn(db);
|
||||
|
||||
underTest = new ActiveCookieStore(
|
||||
Mockito.mock(PlanConfig.class),
|
||||
activeCookieExpiryCleanupTask, Mockito.mock(PlanConfig.class),
|
||||
dbSystem,
|
||||
new TestRunnableFactory(),
|
||||
Mockito.mock(Processing.class)
|
||||
|
@ -78,7 +78,7 @@ public interface WebUserQueriesTest extends DatabaseTestPreparer {
|
||||
userIsRegistered();
|
||||
User user = db().query(WebUserQueries.fetchUser(WEB_USERNAME)).orElseThrow(AssertionError::new);
|
||||
|
||||
ActiveCookieStore cookieStore = new ActiveCookieStore(Mockito.mock(PlanConfig.class), dbSystem(), new TestRunnableFactory(), Mockito.mock(Processing.class));
|
||||
ActiveCookieStore cookieStore = new ActiveCookieStore(activeCookieExpiryCleanupTask, Mockito.mock(PlanConfig.class), dbSystem(), new TestRunnableFactory(), Mockito.mock(Processing.class));
|
||||
|
||||
String cookie = cookieStore.generateNewCookie(user);
|
||||
|
||||
@ -92,7 +92,7 @@ public interface WebUserQueriesTest extends DatabaseTestPreparer {
|
||||
userIsRegistered();
|
||||
User user = db().query(WebUserQueries.fetchUser(WEB_USERNAME)).orElseThrow(AssertionError::new);
|
||||
|
||||
ActiveCookieStore cookieStore = new ActiveCookieStore(Mockito.mock(PlanConfig.class), dbSystem(), new TestRunnableFactory(), Mockito.mock(Processing.class));
|
||||
ActiveCookieStore cookieStore = new ActiveCookieStore(activeCookieExpiryCleanupTask, Mockito.mock(PlanConfig.class), dbSystem(), new TestRunnableFactory(), Mockito.mock(Processing.class));
|
||||
|
||||
String cookie = cookieStore.generateNewCookie(user);
|
||||
|
||||
@ -106,7 +106,7 @@ public interface WebUserQueriesTest extends DatabaseTestPreparer {
|
||||
userIsRegistered();
|
||||
User user = db().query(WebUserQueries.fetchUser(WEB_USERNAME)).orElseThrow(AssertionError::new);
|
||||
|
||||
ActiveCookieStore cookieStore = new ActiveCookieStore(Mockito.mock(PlanConfig.class), dbSystem(), new TestRunnableFactory(), Mockito.mock(Processing.class));
|
||||
ActiveCookieStore cookieStore = new ActiveCookieStore(activeCookieExpiryCleanupTask, Mockito.mock(PlanConfig.class), dbSystem(), new TestRunnableFactory(), Mockito.mock(Processing.class));
|
||||
|
||||
String cookie = cookieStore.generateNewCookie(user);
|
||||
|
||||
|
@ -18,6 +18,7 @@ package utilities.mocks;
|
||||
|
||||
import com.djrapitops.plan.PlanPlugin;
|
||||
import com.djrapitops.plan.PlanSystem;
|
||||
import com.djrapitops.plan.storage.database.SQLDB;
|
||||
import com.djrapitops.plan.utilities.logging.PluginErrorLogger;
|
||||
import net.playeranalytics.plugin.PlatformAbstractionLayer;
|
||||
import utilities.dagger.DaggerPlanPluginComponent;
|
||||
@ -40,6 +41,7 @@ public class PluginMockComponent {
|
||||
|
||||
public PluginMockComponent(Path tempDir) {
|
||||
this.tempDir = tempDir;
|
||||
SQLDB.setDownloadDriver(false);
|
||||
}
|
||||
|
||||
public PlanPlugin getPlanMock() throws Exception {
|
||||
|
@ -41,6 +41,7 @@ import net.playeranalytics.plugin.server.Listeners;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
/**
|
||||
@ -51,13 +52,13 @@ import java.util.concurrent.TimeUnit;
|
||||
*/
|
||||
public class FabricPingCounter extends TaskSystem.Task implements FabricListener {
|
||||
|
||||
private final Map<UUID, Long> startRecording;
|
||||
private final Map<UUID, List<DateObj<Integer>>> playerHistory;
|
||||
|
||||
private final Listeners listeners;
|
||||
private final PlanConfig config;
|
||||
private final DBSystem dbSystem;
|
||||
private final ServerInfo serverInfo;
|
||||
private final RunnableFactory runnableFactory;
|
||||
private final MinecraftDedicatedServer server;
|
||||
|
||||
private boolean isEnabled = false;
|
||||
@ -68,15 +69,14 @@ public class FabricPingCounter extends TaskSystem.Task implements FabricListener
|
||||
PlanConfig config,
|
||||
DBSystem dbSystem,
|
||||
ServerInfo serverInfo,
|
||||
RunnableFactory runnableFactory,
|
||||
MinecraftDedicatedServer server
|
||||
) {
|
||||
this.listeners = listeners;
|
||||
this.config = config;
|
||||
this.dbSystem = dbSystem;
|
||||
this.serverInfo = serverInfo;
|
||||
this.runnableFactory = runnableFactory;
|
||||
this.server = server;
|
||||
startRecording = new ConcurrentHashMap<>();
|
||||
playerHistory = new HashMap<>();
|
||||
ServerPlayConnectionEvents.JOIN.register((handler, sender, minecraftServer) -> onPlayerJoin(handler.player));
|
||||
ServerPlayConnectionEvents.DISCONNECT.register((handler, minecraftServer) -> onPlayerQuit(handler.player));
|
||||
@ -88,6 +88,16 @@ public class FabricPingCounter extends TaskSystem.Task implements FabricListener
|
||||
return;
|
||||
}
|
||||
long time = System.currentTimeMillis();
|
||||
|
||||
Iterator<Map.Entry<UUID, Long>> starts = startRecording.entrySet().iterator();
|
||||
while (starts.hasNext()) {
|
||||
Map.Entry<UUID, Long> start = starts.next();
|
||||
if (time >= start.getValue()) {
|
||||
addPlayer(start.getKey());
|
||||
starts.remove();
|
||||
}
|
||||
}
|
||||
|
||||
Iterator<Map.Entry<UUID, List<DateObj<Integer>>>> iterator = playerHistory.entrySet().iterator();
|
||||
|
||||
while (iterator.hasNext()) {
|
||||
@ -126,12 +136,13 @@ public class FabricPingCounter extends TaskSystem.Task implements FabricListener
|
||||
this.enable();
|
||||
}
|
||||
|
||||
public void addPlayer(ServerPlayerEntity player) {
|
||||
playerHistory.put(player.getUuid(), new ArrayList<>());
|
||||
public void addPlayer(UUID uuid) {
|
||||
playerHistory.put(uuid, new ArrayList<>());
|
||||
}
|
||||
|
||||
public void removePlayer(ServerPlayerEntity player) {
|
||||
playerHistory.remove(player.getUuid());
|
||||
startRecording.remove(player.getUuid());
|
||||
}
|
||||
|
||||
private int getPing(ServerPlayerEntity player) {
|
||||
@ -143,15 +154,11 @@ public class FabricPingCounter extends TaskSystem.Task implements FabricListener
|
||||
return;
|
||||
}
|
||||
|
||||
Long pingDelay = config.get(TimeSettings.PING_PLAYER_LOGIN_DELAY);
|
||||
if (pingDelay >= TimeUnit.HOURS.toMillis(2L)) {
|
||||
Long pingDelayMs = config.get(TimeSettings.PING_PLAYER_LOGIN_DELAY);
|
||||
if (pingDelayMs >= TimeUnit.HOURS.toMillis(2L)) {
|
||||
return;
|
||||
}
|
||||
runnableFactory.create(() -> {
|
||||
if (server.getPlayerManager().getPlayerList().contains(player)) {
|
||||
addPlayer(player);
|
||||
}
|
||||
}).runTaskLater(TimeAmount.toTicks(pingDelay, TimeUnit.MILLISECONDS));
|
||||
startRecording.put(player.getUuid(), System.currentTimeMillis() + pingDelayMs);
|
||||
}
|
||||
|
||||
public void onPlayerQuit(ServerPlayerEntity player) {
|
||||
|
@ -18,6 +18,7 @@ package net.playeranalytics.plan.modules.fabric;
|
||||
|
||||
import com.djrapitops.plan.TaskSystem;
|
||||
import com.djrapitops.plan.delivery.web.ResourceWriteTask;
|
||||
import com.djrapitops.plan.delivery.webserver.auth.ActiveCookieExpiryCleanupTask;
|
||||
import com.djrapitops.plan.delivery.webserver.cache.JSONFileStorage;
|
||||
import com.djrapitops.plan.extension.ExtensionServerDataUpdater;
|
||||
import com.djrapitops.plan.gathering.ShutdownDataPreservation;
|
||||
@ -88,4 +89,8 @@ public interface FabricTaskModule {
|
||||
@Binds
|
||||
@IntoSet
|
||||
TaskSystem.Task bindResourceWriteTask(ResourceWriteTask resourceWriteTask);
|
||||
|
||||
@Binds
|
||||
@IntoSet
|
||||
TaskSystem.Task bindActiveCookieStoreExpiryTask(ActiveCookieExpiryCleanupTask activeCookieExpiryCleanupTask);
|
||||
}
|
||||
|
@ -18,6 +18,7 @@ package utilities.mocks;
|
||||
|
||||
import com.djrapitops.plan.PlanPlugin;
|
||||
import com.djrapitops.plan.PlanSystem;
|
||||
import com.djrapitops.plan.storage.database.SQLDB;
|
||||
import net.minecraft.server.dedicated.MinecraftDedicatedServer;
|
||||
import net.playeranalytics.plan.DaggerPlanFabricComponent;
|
||||
import net.playeranalytics.plan.PlanFabricComponent;
|
||||
@ -43,6 +44,7 @@ public class FabricMockComponent {
|
||||
|
||||
public FabricMockComponent(Path tempDir) {
|
||||
this.tempDir = tempDir;
|
||||
SQLDB.setDownloadDriver(false);
|
||||
}
|
||||
|
||||
public PlanPlugin getPlanMock() {
|
||||
|
@ -44,6 +44,7 @@ import net.playeranalytics.plugin.server.Listeners;
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
/**
|
||||
@ -57,33 +58,42 @@ import java.util.concurrent.TimeUnit;
|
||||
@Singleton
|
||||
public class NukkitPingCounter extends TaskSystem.Task implements Listener {
|
||||
|
||||
private final Map<UUID, Long> startRecording;
|
||||
private final Map<UUID, List<DateObj<Integer>>> playerHistory;
|
||||
|
||||
private final Listeners listeners;
|
||||
private final PlanConfig config;
|
||||
private final DBSystem dbSystem;
|
||||
private final ServerInfo serverInfo;
|
||||
private final RunnableFactory runnableFactory;
|
||||
|
||||
@Inject
|
||||
public NukkitPingCounter(
|
||||
Listeners listeners,
|
||||
PlanConfig config,
|
||||
DBSystem dbSystem,
|
||||
ServerInfo serverInfo,
|
||||
RunnableFactory runnableFactory
|
||||
ServerInfo serverInfo
|
||||
) {
|
||||
this.listeners = listeners;
|
||||
this.config = config;
|
||||
this.dbSystem = dbSystem;
|
||||
this.serverInfo = serverInfo;
|
||||
this.runnableFactory = runnableFactory;
|
||||
startRecording = new ConcurrentHashMap<>();
|
||||
playerHistory = new HashMap<>();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
long time = System.currentTimeMillis();
|
||||
|
||||
Iterator<Map.Entry<UUID, Long>> starts = startRecording.entrySet().iterator();
|
||||
while (starts.hasNext()) {
|
||||
Map.Entry<UUID, Long> start = starts.next();
|
||||
if (time >= start.getValue()) {
|
||||
addPlayer(start.getKey());
|
||||
starts.remove();
|
||||
}
|
||||
}
|
||||
|
||||
Iterator<Map.Entry<UUID, List<DateObj<Integer>>>> iterator = playerHistory.entrySet().iterator();
|
||||
|
||||
while (iterator.hasNext()) {
|
||||
@ -121,26 +131,23 @@ public class NukkitPingCounter extends TaskSystem.Task implements Listener {
|
||||
}
|
||||
}
|
||||
|
||||
public void addPlayer(Player player) {
|
||||
playerHistory.put(player.getUniqueId(), new ArrayList<>());
|
||||
public void addPlayer(UUID uuid) {
|
||||
playerHistory.put(uuid, new ArrayList<>());
|
||||
}
|
||||
|
||||
public void removePlayer(Player player) {
|
||||
playerHistory.remove(player.getUniqueId());
|
||||
startRecording.remove(player.getUniqueId());
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onPlayerJoin(PlayerJoinEvent joinEvent) {
|
||||
Player player = joinEvent.getPlayer();
|
||||
Long pingDelay = config.get(TimeSettings.PING_PLAYER_LOGIN_DELAY);
|
||||
if (pingDelay >= TimeUnit.HOURS.toMillis(2L)) {
|
||||
Long pingDelayMs = config.get(TimeSettings.PING_PLAYER_LOGIN_DELAY);
|
||||
if (pingDelayMs >= TimeUnit.HOURS.toMillis(2L)) {
|
||||
return;
|
||||
}
|
||||
runnableFactory.create(() -> {
|
||||
if (player.isOnline()) {
|
||||
addPlayer(player);
|
||||
}
|
||||
}).runTaskLater(TimeAmount.toTicks(pingDelay, TimeUnit.MILLISECONDS));
|
||||
startRecording.put(player.getUniqueId(), System.currentTimeMillis() + pingDelayMs);
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
|
@ -20,6 +20,7 @@ import cn.nukkit.level.Level;
|
||||
import com.djrapitops.plan.TaskSystem;
|
||||
import com.djrapitops.plan.delivery.web.ResourceWriteTask;
|
||||
import com.djrapitops.plan.delivery.web.WebAssetVersionCheckTask;
|
||||
import com.djrapitops.plan.delivery.webserver.auth.ActiveCookieExpiryCleanupTask;
|
||||
import com.djrapitops.plan.delivery.webserver.cache.JSONFileStorage;
|
||||
import com.djrapitops.plan.extension.ExtensionServerDataUpdater;
|
||||
import com.djrapitops.plan.gathering.ShutdownDataPreservation;
|
||||
@ -93,4 +94,8 @@ public interface NukkitTaskModule {
|
||||
@Binds
|
||||
@IntoSet
|
||||
TaskSystem.Task bindWebAssetVersionCheckTask(WebAssetVersionCheckTask webAssetVersionCheckTask);
|
||||
|
||||
@Binds
|
||||
@IntoSet
|
||||
TaskSystem.Task bindActiveCookieStoreExpiryTask(ActiveCookieExpiryCleanupTask activeCookieExpiryCleanupTask);
|
||||
}
|
||||
|
@ -20,6 +20,7 @@ import com.djrapitops.plan.DaggerPlanNukkitComponent;
|
||||
import com.djrapitops.plan.PlanNukkit;
|
||||
import com.djrapitops.plan.PlanNukkitComponent;
|
||||
import com.djrapitops.plan.PlanSystem;
|
||||
import com.djrapitops.plan.storage.database.SQLDB;
|
||||
|
||||
import java.nio.file.Path;
|
||||
|
||||
@ -37,6 +38,7 @@ public class NukkitMockComponent {
|
||||
|
||||
public NukkitMockComponent(Path tempDir) {
|
||||
this.tempDir = tempDir;
|
||||
SQLDB.setDownloadDriver(false);
|
||||
}
|
||||
|
||||
public PlanNukkit getPlanMock() throws Exception {
|
||||
|
@ -41,6 +41,7 @@ import org.spongepowered.api.event.network.ClientConnectionEvent;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
/**
|
||||
@ -50,33 +51,42 @@ import java.util.concurrent.TimeUnit;
|
||||
*/
|
||||
public class SpongePingCounter extends TaskSystem.Task {
|
||||
|
||||
private final Map<UUID, Long> startRecording;
|
||||
private final Map<UUID, List<DateObj<Integer>>> playerHistory;
|
||||
|
||||
private final Listeners listeners;
|
||||
private final PlanConfig config;
|
||||
private final DBSystem dbSystem;
|
||||
private final ServerInfo serverInfo;
|
||||
private final RunnableFactory runnableFactory;
|
||||
|
||||
@Inject
|
||||
public SpongePingCounter(
|
||||
Listeners listeners,
|
||||
PlanConfig config,
|
||||
DBSystem dbSystem,
|
||||
ServerInfo serverInfo,
|
||||
RunnableFactory runnableFactory
|
||||
ServerInfo serverInfo
|
||||
) {
|
||||
this.listeners = listeners;
|
||||
this.config = config;
|
||||
this.dbSystem = dbSystem;
|
||||
this.serverInfo = serverInfo;
|
||||
this.runnableFactory = runnableFactory;
|
||||
playerHistory = new HashMap<>();
|
||||
startRecording = new ConcurrentHashMap<>();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
long time = System.currentTimeMillis();
|
||||
|
||||
Iterator<Map.Entry<UUID, Long>> starts = startRecording.entrySet().iterator();
|
||||
while (starts.hasNext()) {
|
||||
Map.Entry<UUID, Long> start = starts.next();
|
||||
if (time >= start.getValue()) {
|
||||
addPlayer(start.getKey());
|
||||
starts.remove();
|
||||
}
|
||||
}
|
||||
|
||||
Iterator<Map.Entry<UUID, List<DateObj<Integer>>>> iterator = playerHistory.entrySet().iterator();
|
||||
|
||||
while (iterator.hasNext()) {
|
||||
@ -114,12 +124,13 @@ public class SpongePingCounter extends TaskSystem.Task {
|
||||
}
|
||||
}
|
||||
|
||||
public void addPlayer(Player player) {
|
||||
playerHistory.put(player.getUniqueId(), new ArrayList<>());
|
||||
public void addPlayer(UUID uuid) {
|
||||
playerHistory.put(uuid, new ArrayList<>());
|
||||
}
|
||||
|
||||
public void removePlayer(Player player) {
|
||||
playerHistory.remove(player.getUniqueId());
|
||||
startRecording.remove(player.getUniqueId());
|
||||
}
|
||||
|
||||
private int getPing(Player player) {
|
||||
@ -129,15 +140,11 @@ public class SpongePingCounter extends TaskSystem.Task {
|
||||
@Listener
|
||||
public void onPlayerJoin(ClientConnectionEvent.Join joinEvent) {
|
||||
Player player = joinEvent.getTargetEntity();
|
||||
Long pingDelay = config.get(TimeSettings.PING_PLAYER_LOGIN_DELAY);
|
||||
if (pingDelay >= TimeUnit.HOURS.toMillis(2L)) {
|
||||
Long pingDelayMs = config.get(TimeSettings.PING_PLAYER_LOGIN_DELAY);
|
||||
if (pingDelayMs >= TimeUnit.HOURS.toMillis(2L)) {
|
||||
return;
|
||||
}
|
||||
runnableFactory.create(() -> {
|
||||
if (player.isOnline()) {
|
||||
addPlayer(player);
|
||||
}
|
||||
}).runTaskLater(TimeAmount.toTicks(pingDelay, TimeUnit.MILLISECONDS));
|
||||
startRecording.put(player.getUniqueId(), System.currentTimeMillis() + pingDelayMs);
|
||||
}
|
||||
|
||||
@Listener
|
||||
|
@ -19,6 +19,7 @@ package com.djrapitops.plan.modules.sponge;
|
||||
import com.djrapitops.plan.TaskSystem;
|
||||
import com.djrapitops.plan.delivery.web.ResourceWriteTask;
|
||||
import com.djrapitops.plan.delivery.web.WebAssetVersionCheckTask;
|
||||
import com.djrapitops.plan.delivery.webserver.auth.ActiveCookieExpiryCleanupTask;
|
||||
import com.djrapitops.plan.delivery.webserver.cache.JSONFileStorage;
|
||||
import com.djrapitops.plan.extension.ExtensionServerDataUpdater;
|
||||
import com.djrapitops.plan.gathering.ShutdownDataPreservation;
|
||||
@ -93,4 +94,8 @@ public interface SpongeTaskModule {
|
||||
@Binds
|
||||
@IntoSet
|
||||
TaskSystem.Task bindWebAssetVersionCheckTask(WebAssetVersionCheckTask webAssetVersionCheckTask);
|
||||
|
||||
@Binds
|
||||
@IntoSet
|
||||
TaskSystem.Task bindActiveCookieStoreExpiryTask(ActiveCookieExpiryCleanupTask activeCookieExpiryCleanupTask);
|
||||
}
|
||||
|
@ -20,6 +20,7 @@ import com.djrapitops.plan.DaggerPlanSpongeComponent;
|
||||
import com.djrapitops.plan.PlanPlugin;
|
||||
import com.djrapitops.plan.PlanSpongeComponent;
|
||||
import com.djrapitops.plan.PlanSystem;
|
||||
import com.djrapitops.plan.storage.database.SQLDB;
|
||||
import org.mockito.Mockito;
|
||||
import org.spongepowered.api.Game;
|
||||
import org.spongepowered.api.MinecraftVersion;
|
||||
@ -50,6 +51,7 @@ public class SpongeMockComponent {
|
||||
|
||||
public SpongeMockComponent(Path tempDir) {
|
||||
this.tempDir = tempDir;
|
||||
SQLDB.setDownloadDriver(false);
|
||||
}
|
||||
|
||||
public PlanPlugin getPlanMock() throws Exception {
|
||||
|
@ -43,6 +43,7 @@ import net.playeranalytics.plugin.server.Listeners;
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
/**
|
||||
@ -55,6 +56,7 @@ import java.util.concurrent.TimeUnit;
|
||||
@Singleton
|
||||
public class VelocityPingCounter extends TaskSystem.Task {
|
||||
|
||||
private final Map<UUID, Long> startRecording;
|
||||
final Map<UUID, List<DateObj<Integer>>> playerHistory;
|
||||
|
||||
private final Listeners listeners;
|
||||
@ -62,7 +64,6 @@ public class VelocityPingCounter extends TaskSystem.Task {
|
||||
private final PlanConfig config;
|
||||
private final DBSystem dbSystem;
|
||||
private final ServerInfo serverInfo;
|
||||
private final RunnableFactory runnableFactory;
|
||||
|
||||
@Inject
|
||||
public VelocityPingCounter(
|
||||
@ -70,21 +71,30 @@ public class VelocityPingCounter extends TaskSystem.Task {
|
||||
PlanVelocity plugin,
|
||||
PlanConfig config,
|
||||
DBSystem dbSystem,
|
||||
ServerInfo serverInfo,
|
||||
RunnableFactory runnableFactory
|
||||
ServerInfo serverInfo
|
||||
) {
|
||||
this.listeners = listeners;
|
||||
this.plugin = plugin;
|
||||
this.config = config;
|
||||
this.dbSystem = dbSystem;
|
||||
this.serverInfo = serverInfo;
|
||||
this.runnableFactory = runnableFactory;
|
||||
startRecording = new ConcurrentHashMap<>();
|
||||
playerHistory = new HashMap<>();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
long time = System.currentTimeMillis();
|
||||
|
||||
Iterator<Map.Entry<UUID, Long>> starts = startRecording.entrySet().iterator();
|
||||
while (starts.hasNext()) {
|
||||
Map.Entry<UUID, Long> start = starts.next();
|
||||
if (time >= start.getValue()) {
|
||||
addPlayer(start.getKey());
|
||||
starts.remove();
|
||||
}
|
||||
}
|
||||
|
||||
Iterator<Map.Entry<UUID, List<DateObj<Integer>>>> iterator = playerHistory.entrySet().iterator();
|
||||
|
||||
while (iterator.hasNext()) {
|
||||
@ -122,8 +132,8 @@ public class VelocityPingCounter extends TaskSystem.Task {
|
||||
}
|
||||
}
|
||||
|
||||
void addPlayer(Player player) {
|
||||
playerHistory.put(player.getUniqueId(), new ArrayList<>());
|
||||
void addPlayer(UUID playerUuid) {
|
||||
playerHistory.put(playerUuid, new ArrayList<>());
|
||||
}
|
||||
|
||||
public void removePlayer(Player player) {
|
||||
@ -137,15 +147,11 @@ public class VelocityPingCounter extends TaskSystem.Task {
|
||||
@Subscribe
|
||||
public void onPlayerJoin(ServerConnectedEvent joinEvent) {
|
||||
Player player = joinEvent.getPlayer();
|
||||
Long pingDelay = config.get(TimeSettings.PING_PLAYER_LOGIN_DELAY);
|
||||
if (pingDelay >= TimeUnit.HOURS.toMillis(2L)) {
|
||||
Long pingDelayMs = config.get(TimeSettings.PING_PLAYER_LOGIN_DELAY);
|
||||
if (pingDelayMs >= TimeUnit.HOURS.toMillis(2L)) {
|
||||
return;
|
||||
}
|
||||
runnableFactory.create(() -> {
|
||||
if (player.isActive()) {
|
||||
addPlayer(player);
|
||||
}
|
||||
}).runTaskLater(TimeAmount.toTicks(pingDelay, TimeUnit.MILLISECONDS));
|
||||
startRecording.put(player.getUniqueId(), System.currentTimeMillis() + pingDelayMs);
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
|
@ -19,6 +19,7 @@ package com.djrapitops.plan.modules.velocity;
|
||||
import com.djrapitops.plan.TaskSystem;
|
||||
import com.djrapitops.plan.delivery.web.ResourceWriteTask;
|
||||
import com.djrapitops.plan.delivery.web.WebAssetVersionCheckTask;
|
||||
import com.djrapitops.plan.delivery.webserver.auth.ActiveCookieExpiryCleanupTask;
|
||||
import com.djrapitops.plan.delivery.webserver.cache.JSONFileStorage;
|
||||
import com.djrapitops.plan.extension.ExtensionServerDataUpdater;
|
||||
import com.djrapitops.plan.gathering.timed.ProxyTPSCounter;
|
||||
@ -82,4 +83,8 @@ public interface VelocityTaskModule {
|
||||
@Binds
|
||||
@IntoSet
|
||||
TaskSystem.Task bindWebAssetVersionCheckTask(WebAssetVersionCheckTask webAssetVersionCheckTask);
|
||||
|
||||
@Binds
|
||||
@IntoSet
|
||||
TaskSystem.Task bindActiveCookieStoreExpiryTask(ActiveCookieExpiryCleanupTask activeCookieExpiryCleanupTask);
|
||||
}
|
||||
|
@ -58,10 +58,10 @@ class VelocityPingCounterTest {
|
||||
|
||||
@Test
|
||||
void offlinePlayerIsRemovedFromPlayerHistory() {
|
||||
VelocityPingCounter counter = new VelocityPingCounter(Mockito.mock(Listeners.class), plugin, null, null, null, null);
|
||||
VelocityPingCounter counter = new VelocityPingCounter(Mockito.mock(Listeners.class), plugin, null, null, null);
|
||||
|
||||
assertTrue(counter.playerHistory.isEmpty());
|
||||
counter.addPlayer(player);
|
||||
counter.addPlayer(player.getUniqueId());
|
||||
assertFalse(counter.playerHistory.isEmpty());
|
||||
|
||||
counter.run();
|
||||
|
@ -20,6 +20,7 @@ import com.djrapitops.plan.DaggerPlanVelocityComponent;
|
||||
import com.djrapitops.plan.PlanSystem;
|
||||
import com.djrapitops.plan.PlanVelocity;
|
||||
import com.djrapitops.plan.PlanVelocityComponent;
|
||||
import com.djrapitops.plan.storage.database.SQLDB;
|
||||
|
||||
import java.nio.file.Path;
|
||||
|
||||
@ -37,6 +38,7 @@ public class VelocityMockComponent {
|
||||
|
||||
public VelocityMockComponent(Path tempDir) {
|
||||
this.tempDir = tempDir;
|
||||
SQLDB.setDownloadDriver(false);
|
||||
}
|
||||
|
||||
public PlanVelocity getPlanMock() throws Exception {
|
||||
|
Loading…
Reference in New Issue
Block a user