From c87f981d6a588c6f5222d8467cdb847c9675a706 Mon Sep 17 00:00:00 2001 From: Rsl1122 <24460436+Rsl1122@users.noreply.github.com> Date: Mon, 13 Jan 2020 22:40:04 +0200 Subject: [PATCH] Rewrote TPSCounter Task This commit is a squash of 8 optimization commits to TPSCounter. 1. Extracted duplicate code in TPSCounters to ServerSensors. - TPSCounter tasks now live inside common module - ServerTPSCounter and ProxyTPSCounter - Gathering methods are implemented with ServerSensor interface: Player count, TPS, Entity count, Chunk count - ServerProperties#getOnlinePlayers was replaced with ServerSensor - Fixed sonar smells: "Hiding field" in TPSStoreTransaction & NavLink 2. Optimizations down to 0.15ms / run - Optimized entity+chunk count (same for loop) - Added warm-up for system resource methods - Removed Stream API usages - Removed List copy operation - Entities & chunks only count once per minute - CPU & RAM averages now produced with Average class - Maximum player count per minute now produced with Maximum class Affects issues: - Fixed #1289 --- Plan/build.gradle | 2 + .../com/djrapitops/plan/BukkitTaskSystem.java | 16 +- .../plan/gathering/BukkitSensor.java | 99 +++++++++++ .../gathering/timed/BukkitTPSCounter.java | 154 ------------------ .../plan/gathering/timed/PaperTPSCounter.java | 77 --------- .../properties/BukkitServerProperties.java | 3 +- .../bukkit/BukkitSuperClassBindingModule.java | 24 ++- .../com/djrapitops/plan/BungeeTaskSystem.java | 7 +- .../plan/gathering/BungeeSensor.java | 46 ++++++ .../gathering/timed/BungeeTPSCounter.java | 64 -------- .../properties/BungeeServerProperties.java | 3 +- .../bungee/BungeeSuperClassBindingModule.java | 13 +- .../java/com/djrapitops/plan/PlanSystem.java | 12 +- .../rendering/html/structure/NavLink.java | 8 +- .../json/ServerOverviewJSONCreator.java | 6 +- .../network/NetworkOverviewJSONCreator.java | 10 +- .../plan/gathering/ServerSensor.java | 58 +++++++ .../plan/gathering/SystemUsage.java | 4 +- .../plan/gathering/timed/ProxyTPSCounter.java | 95 +++++++++++ .../gathering/timed/ServerTPSCounter.java | 127 +++++++++++++++ .../plan/gathering/timed/TPSCalculator.java | 86 ++++++++++ .../plan/gathering/timed/TPSCounter.java | 49 ++---- .../properties/ServerProperties.java | 10 +- .../modules/ProxySuperClassBindingModule.java | 8 +- .../events/TPSStoreTransaction.java | 31 +--- .../plan/utilities/analysis/Average.java | 50 ++++++ .../plan/utilities/analysis/Maximum.java | 50 ++++++ .../plan/utilities/analysis/TimerAverage.java | 68 ++++++++ .../plan/storage/database/DatabaseTest.java | 17 +- .../dagger/PluginServerPropertiesModule.java | 4 +- .../dagger/PluginSuperClassBindingModule.java | 21 ++- .../com/djrapitops/plan/NukkitTaskSystem.java | 8 +- .../plan/gathering/NukkitSensor.java | 66 ++++++++ .../gathering/timed/NukkitTPSCounter.java | 154 ------------------ .../properties/NukkitServerProperties.java | 3 +- .../nukkit/NukkitSuperClassBindingModule.java | 22 ++- .../com/djrapitops/plan/SpongeTaskSystem.java | 8 +- .../plan/gathering/SpongeSensor.java | 76 +++++++++ .../gathering/timed/SpongeTPSCounter.java | 121 -------------- .../properties/SpongeServerProperties.java | 3 +- .../sponge/SpongeSuperClassBindingModule.java | 24 ++- .../djrapitops/plan/VelocityTaskSystem.java | 7 +- .../plan/gathering/VelocitySensor.java | 44 +++++ .../gathering/timed/VelocityTPSCounter.java | 64 -------- .../properties/VelocityServerProperties.java | 3 +- .../VelocitySuperClassBindingModule.java | 13 +- 46 files changed, 1034 insertions(+), 804 deletions(-) create mode 100644 Plan/bukkit/src/main/java/com/djrapitops/plan/gathering/BukkitSensor.java delete mode 100644 Plan/bukkit/src/main/java/com/djrapitops/plan/gathering/timed/BukkitTPSCounter.java delete mode 100644 Plan/bukkit/src/main/java/com/djrapitops/plan/gathering/timed/PaperTPSCounter.java create mode 100644 Plan/bungeecord/src/main/java/com/djrapitops/plan/gathering/BungeeSensor.java delete mode 100644 Plan/bungeecord/src/main/java/com/djrapitops/plan/gathering/timed/BungeeTPSCounter.java create mode 100644 Plan/common/src/main/java/com/djrapitops/plan/gathering/ServerSensor.java create mode 100644 Plan/common/src/main/java/com/djrapitops/plan/gathering/timed/ProxyTPSCounter.java create mode 100644 Plan/common/src/main/java/com/djrapitops/plan/gathering/timed/ServerTPSCounter.java create mode 100644 Plan/common/src/main/java/com/djrapitops/plan/gathering/timed/TPSCalculator.java create mode 100644 Plan/common/src/main/java/com/djrapitops/plan/utilities/analysis/Average.java create mode 100644 Plan/common/src/main/java/com/djrapitops/plan/utilities/analysis/Maximum.java create mode 100644 Plan/common/src/main/java/com/djrapitops/plan/utilities/analysis/TimerAverage.java create mode 100644 Plan/nukkit/src/main/java/com/djrapitops/plan/gathering/NukkitSensor.java delete mode 100644 Plan/nukkit/src/main/java/com/djrapitops/plan/gathering/timed/NukkitTPSCounter.java create mode 100644 Plan/sponge/src/main/java/com/djrapitops/plan/gathering/SpongeSensor.java delete mode 100644 Plan/sponge/src/main/java/com/djrapitops/plan/gathering/timed/SpongeTPSCounter.java create mode 100644 Plan/velocity/src/main/java/com/djrapitops/plan/gathering/VelocitySensor.java delete mode 100644 Plan/velocity/src/main/java/com/djrapitops/plan/gathering/timed/VelocityTPSCounter.java diff --git a/Plan/build.gradle b/Plan/build.gradle index 405ddf5bb..3fd6f6960 100644 --- a/Plan/build.gradle +++ b/Plan/build.gradle @@ -54,6 +54,8 @@ allprojects { } } +println "Building artifact for version $fullVersion" + subprojects { // Build plugins apply plugin: "java" diff --git a/Plan/bukkit/src/main/java/com/djrapitops/plan/BukkitTaskSystem.java b/Plan/bukkit/src/main/java/com/djrapitops/plan/BukkitTaskSystem.java index 13e06c99b..8f450617f 100644 --- a/Plan/bukkit/src/main/java/com/djrapitops/plan/BukkitTaskSystem.java +++ b/Plan/bukkit/src/main/java/com/djrapitops/plan/BukkitTaskSystem.java @@ -20,22 +20,21 @@ import com.djrapitops.plan.delivery.webserver.cache.JSONCache; import com.djrapitops.plan.extension.ExtensionServerMethodCallerTask; import com.djrapitops.plan.gathering.ShutdownHook; import com.djrapitops.plan.gathering.timed.BukkitPingCounter; -import com.djrapitops.plan.gathering.timed.BukkitTPSCounter; -import com.djrapitops.plan.gathering.timed.PaperTPSCounter; +import com.djrapitops.plan.gathering.timed.ServerTPSCounter; +import com.djrapitops.plan.gathering.timed.TPSCounter; import com.djrapitops.plan.settings.config.PlanConfig; import com.djrapitops.plan.settings.config.paths.DataGatheringSettings; import com.djrapitops.plan.settings.config.paths.TimeSettings; import com.djrapitops.plan.settings.upkeep.ConfigStoreTask; import com.djrapitops.plan.storage.upkeep.DBCleanTask; import com.djrapitops.plan.storage.upkeep.LogsFolderCleanTask; -import com.djrapitops.plugin.api.Check; import com.djrapitops.plugin.api.TimeAmount; import com.djrapitops.plugin.task.RunnableFactory; import org.bukkit.Bukkit; +import org.bukkit.World; import javax.inject.Inject; import javax.inject.Singleton; -import java.util.Optional; import java.util.concurrent.TimeUnit; /** @@ -55,7 +54,7 @@ public class BukkitTaskSystem extends TaskSystem { private final ConfigStoreTask configStoreTask; private final DBCleanTask dbCleanTask; private final ExtensionServerMethodCallerTask extensionServerMethodCallerTask; - private BukkitTPSCounter tpsCounter; + private TPSCounter tpsCounter; @Inject public BukkitTaskSystem( @@ -64,8 +63,7 @@ public class BukkitTaskSystem extends TaskSystem { ShutdownHook shutdownHook, RunnableFactory runnableFactory, - PaperTPSCounter paperTPSCountTimer, - BukkitTPSCounter bukkitTPSCountTimer, + ServerTPSCounter tpsCounter, BukkitPingCounter pingCounter, ExtensionServerMethodCallerTask extensionServerMethodCallerTask, @@ -80,7 +78,7 @@ public class BukkitTaskSystem extends TaskSystem { this.shutdownHook = shutdownHook; this.jsonCacheCleanTask = jsonCacheCleanTask; - this.tpsCounter = Check.isPaperAvailable() ? paperTPSCountTimer : bukkitTPSCountTimer; + this.tpsCounter = tpsCounter; this.pingCounter = pingCounter; this.extensionServerMethodCallerTask = extensionServerMethodCallerTask; @@ -139,6 +137,6 @@ public class BukkitTaskSystem extends TaskSystem { @Override public void disable() { super.disable(); - Optional.ofNullable(Bukkit.getScheduler()).ifPresent(scheduler -> scheduler.cancelTasks(plugin)); + Bukkit.getScheduler().cancelTasks(plugin); } } diff --git a/Plan/bukkit/src/main/java/com/djrapitops/plan/gathering/BukkitSensor.java b/Plan/bukkit/src/main/java/com/djrapitops/plan/gathering/BukkitSensor.java new file mode 100644 index 000000000..461f3d759 --- /dev/null +++ b/Plan/bukkit/src/main/java/com/djrapitops/plan/gathering/BukkitSensor.java @@ -0,0 +1,99 @@ +/* + * 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 . + */ +package com.djrapitops.plan.gathering; + +import com.djrapitops.plan.Plan; +import com.djrapitops.plugin.api.Check; +import org.bukkit.World; + +import javax.inject.Inject; +import javax.inject.Singleton; + +@Singleton +public class BukkitSensor implements ServerSensor { + + private final Plan plugin; + private final boolean hasPaper; + + @Inject + public BukkitSensor( + Plan plugin + ) { + this.plugin = plugin; + hasPaper = Check.isPaperAvailable(); + } + + @Override + public boolean supportsDirectTPS() { + return hasPaper; + } + + @Override + public double getTPS() { + return plugin.getServer().getTPS()[0]; + } + + @Override + public int getChunkCount(World world) { + if (hasPaper) { + try { + return getChunkCountPaperWay(world); + } catch (BootstrapMethodError | NoSuchMethodError e) { + // Use spigot method + } + } + return getChunkCountSpigotWay(world); + } + + private int getChunkCountSpigotWay(World world) { + return world.getLoadedChunks().length; + } + + private int getChunkCountPaperWay(World world) { + return world.getChunkCount(); + } + + @Override + public int getEntityCount(World world) { + if (hasPaper) { + try { + return getEntitiesPaperWay(world); + } catch (BootstrapMethodError | NoSuchMethodError e) { + // Use spigot method + } + } + return getEntitiesSpigotWay(world); + } + + private int getEntitiesSpigotWay(World world) { + return world.getEntities().size(); + } + + private int getEntitiesPaperWay(World world) { + return world.getEntityCount(); + } + + @Override + public int getOnlinePlayerCount() { + return plugin.getServer().getOnlinePlayers().size(); + } + + @Override + public Iterable getWorlds() { + return plugin.getServer().getWorlds(); + } +} diff --git a/Plan/bukkit/src/main/java/com/djrapitops/plan/gathering/timed/BukkitTPSCounter.java b/Plan/bukkit/src/main/java/com/djrapitops/plan/gathering/timed/BukkitTPSCounter.java deleted file mode 100644 index 54093ddd0..000000000 --- a/Plan/bukkit/src/main/java/com/djrapitops/plan/gathering/timed/BukkitTPSCounter.java +++ /dev/null @@ -1,154 +0,0 @@ -/* - * 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 . - */ -package com.djrapitops.plan.gathering.timed; - -import com.djrapitops.plan.Plan; -import com.djrapitops.plan.gathering.SystemUsage; -import com.djrapitops.plan.gathering.domain.TPS; -import com.djrapitops.plan.gathering.domain.builders.TPSBuilder; -import com.djrapitops.plan.identification.ServerInfo; -import com.djrapitops.plan.identification.properties.ServerProperties; -import com.djrapitops.plan.storage.database.DBSystem; -import com.djrapitops.plugin.logging.console.PluginLogger; -import com.djrapitops.plugin.logging.error.ErrorHandler; -import org.bukkit.World; - -import javax.inject.Inject; -import javax.inject.Singleton; -import java.util.concurrent.TimeUnit; - -@Singleton -public class BukkitTPSCounter extends TPSCounter { - - protected final Plan plugin; - private ServerProperties serverProperties; - private long lastCheckNano; - - @Inject - public BukkitTPSCounter( - Plan plugin, - DBSystem dbSystem, - ServerInfo serverInfo, - ServerProperties serverProperties, - PluginLogger logger, - ErrorHandler errorHandler - ) { - super(dbSystem, serverInfo, logger, errorHandler); - this.plugin = plugin; - this.serverProperties = serverProperties; - lastCheckNano = -1; - } - - @Override - public void addNewTPSEntry(long nanoTime, long now) { - long diff = nanoTime - lastCheckNano; - - lastCheckNano = nanoTime; - - if (diff > nanoTime) { // First run's diff = nanoTime + 1, no calc possible. - logger.debug("First run of TPSCountTimer Task."); - return; - } - - history.add(calculateTPS(diff, now)); - } - - /** - * Calculates the TPS - * - * @param diff The time difference between the last run and the new run - * @param now The time right now - * @return the TPS - */ - private TPS calculateTPS(long diff, long now) { - double averageCPUUsage = getCPUUsage(); - long usedMemory = SystemUsage.getUsedMemory(); - long freeDiskSpace = getFreeDiskSpace(); - - int playersOnline = serverProperties.getOnlinePlayers(); - latestPlayersOnline = playersOnline; - int loadedChunks = getLoadedChunks(); - int entityCount = getEntityCount(); - - return getTPS(diff, now, averageCPUUsage, usedMemory, entityCount, loadedChunks, playersOnline, freeDiskSpace); - } - - protected TPS getTPS(long diff, long now, - double cpuUsage, long usedMemory, - int entityCount, int chunksLoaded, - int playersOnline, long freeDiskSpace) { - long difference = diff; - if (difference < TimeUnit.SECONDS.toNanos(1L)) { // No tick count above 20 - difference = TimeUnit.SECONDS.toNanos(1L); - } - - long twentySeconds = TimeUnit.SECONDS.toNanos(20L); - while (difference > twentySeconds) { - // Add 0 TPS since more than 20 ticks has passed. - history.add(TPSBuilder.get() - .date(now) - .tps(0) - .playersOnline(playersOnline) - .usedCPU(cpuUsage) - .usedMemory(usedMemory) - .entities(entityCount) - .chunksLoaded(chunksLoaded) - .freeDiskSpace(freeDiskSpace) - .toTPS()); - difference -= twentySeconds; - } - - double tpsN = twentySeconds * 1.0 / difference; - - return TPSBuilder.get() - .date(now) - .tps(tpsN) - .playersOnline(playersOnline) - .usedCPU(cpuUsage) - .usedMemory(usedMemory) - .entities(entityCount) - .chunksLoaded(chunksLoaded) - .freeDiskSpace(freeDiskSpace) - .toTPS(); - } - - /** - * Gets the amount of loaded chunks - * - * @return amount of loaded chunks - */ - private int getLoadedChunks() { - int sum = 0; - for (World world : plugin.getServer().getWorlds()) { - sum += world.getLoadedChunks().length; - } - return sum; - } - - /** - * Gets the amount of entities on the server for Bukkit / Spigot - * - * @return amount of entities - */ - protected int getEntityCount() { - int sum = 0; - for (World world : plugin.getServer().getWorlds()) { - sum += world.getEntities().size(); - } - return sum; - } -} diff --git a/Plan/bukkit/src/main/java/com/djrapitops/plan/gathering/timed/PaperTPSCounter.java b/Plan/bukkit/src/main/java/com/djrapitops/plan/gathering/timed/PaperTPSCounter.java deleted file mode 100644 index f0aa956be..000000000 --- a/Plan/bukkit/src/main/java/com/djrapitops/plan/gathering/timed/PaperTPSCounter.java +++ /dev/null @@ -1,77 +0,0 @@ -/* - * 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 . - */ -package com.djrapitops.plan.gathering.timed; - -import com.djrapitops.plan.Plan; -import com.djrapitops.plan.gathering.domain.TPS; -import com.djrapitops.plan.gathering.domain.builders.TPSBuilder; -import com.djrapitops.plan.identification.ServerInfo; -import com.djrapitops.plan.storage.database.DBSystem; -import com.djrapitops.plugin.logging.console.PluginLogger; -import com.djrapitops.plugin.logging.error.ErrorHandler; -import org.bukkit.World; - -import javax.inject.Inject; - -public class PaperTPSCounter extends BukkitTPSCounter { - - @Inject - public PaperTPSCounter( - Plan plugin, - DBSystem dbSystem, - ServerInfo serverInfo, - PluginLogger logger, - ErrorHandler errorHandler - ) { - super(plugin, dbSystem, serverInfo, serverInfo.getServerProperties(), logger, errorHandler); - } - - @Override - protected TPS getTPS(long diff, long now, double cpuUsage, long usedMemory, int entityCount, int chunksLoaded, int playersOnline, long freeDiskSpace) { - double tps; - try { - tps = plugin.getServer().getTPS()[0]; - } catch (NoSuchMethodError e) { - // This method is from Paper - return super.getTPS(diff, now, cpuUsage, usedMemory, entityCount, chunksLoaded, playersOnline, freeDiskSpace); - } - - if (tps > 20) { - tps = 20; - } - - return TPSBuilder.get() - .date(now) - .tps(tps) - .playersOnline(playersOnline) - .usedCPU(cpuUsage) - .usedMemory(usedMemory) - .entities(entityCount) - .chunksLoaded(chunksLoaded) - .freeDiskSpace(freeDiskSpace) - .toTPS(); - } - - @Override - protected int getEntityCount() { - try { - return plugin.getServer().getWorlds().stream().mapToInt(World::getEntityCount).sum(); - } catch (BootstrapMethodError | NoSuchMethodError e) { - return super.getEntityCount(); - } - } -} diff --git a/Plan/bukkit/src/main/java/com/djrapitops/plan/identification/properties/BukkitServerProperties.java b/Plan/bukkit/src/main/java/com/djrapitops/plan/identification/properties/BukkitServerProperties.java index 6002acb2f..7bf749789 100644 --- a/Plan/bukkit/src/main/java/com/djrapitops/plan/identification/properties/BukkitServerProperties.java +++ b/Plan/bukkit/src/main/java/com/djrapitops/plan/identification/properties/BukkitServerProperties.java @@ -32,8 +32,7 @@ public class BukkitServerProperties extends ServerProperties { server.getVersion(), server.getBukkitVersion(), server::getIp, - server.getMaxPlayers(), - () -> server.getOnlinePlayers().size() + server.getMaxPlayers() ); } diff --git a/Plan/bukkit/src/main/java/com/djrapitops/plan/modules/bukkit/BukkitSuperClassBindingModule.java b/Plan/bukkit/src/main/java/com/djrapitops/plan/modules/bukkit/BukkitSuperClassBindingModule.java index 7e85b46ad..722d8cb08 100644 --- a/Plan/bukkit/src/main/java/com/djrapitops/plan/modules/bukkit/BukkitSuperClassBindingModule.java +++ b/Plan/bukkit/src/main/java/com/djrapitops/plan/modules/bukkit/BukkitSuperClassBindingModule.java @@ -19,6 +19,8 @@ package com.djrapitops.plan.modules.bukkit; import com.djrapitops.plan.BukkitServerShutdownSave; import com.djrapitops.plan.BukkitTaskSystem; import com.djrapitops.plan.TaskSystem; +import com.djrapitops.plan.gathering.BukkitSensor; +import com.djrapitops.plan.gathering.ServerSensor; import com.djrapitops.plan.gathering.ServerShutdownSave; import com.djrapitops.plan.gathering.importing.BukkitImportSystem; import com.djrapitops.plan.gathering.importing.ImportSystem; @@ -32,9 +34,10 @@ import com.djrapitops.plan.storage.database.BukkitDBSystem; import com.djrapitops.plan.storage.database.DBSystem; import dagger.Binds; import dagger.Module; +import org.bukkit.World; /** - * Module for binding Bukkit specific classes to the interface implementations. + * Module for binding Bukkit specific classes as interface implementations. * * @author Rsl1122 */ @@ -42,24 +45,29 @@ import dagger.Module; public interface BukkitSuperClassBindingModule { @Binds - ServerInfo bindBukkitServerInfo(ServerServerInfo serverServerInfo); + ServerInfo bindServerInfo(ServerServerInfo serverInfo); @Binds - DBSystem bindBukkitDatabaseSystem(BukkitDBSystem dbSystem); + DBSystem bindDBSystem(BukkitDBSystem dbSystem); @Binds - ConfigSystem bindBukkitConfigSystem(BukkitConfigSystem bukkitConfigSystem); + ConfigSystem bindConfigSystem(BukkitConfigSystem configSystem); @Binds - TaskSystem bindBukkitTaskSystem(BukkitTaskSystem bukkitTaskSystem); + TaskSystem bindTaskSystem(BukkitTaskSystem taskSystem); @Binds - ListenerSystem bindBukkitListenerSystem(BukkitListenerSystem bukkitListenerSystem); + ListenerSystem bindListenerSystem(BukkitListenerSystem listenerSystem); @Binds - ImportSystem bindImportSystem(BukkitImportSystem bukkitImportSystem); + ImportSystem bindImportSystem(BukkitImportSystem importSystem); @Binds - ServerShutdownSave bindBukkitServerShutdownSave(BukkitServerShutdownSave bukkitServerShutdownSave); + ServerShutdownSave bindServerShutdownSave(BukkitServerShutdownSave shutdownSave); + @Binds + ServerSensor bindServerSensor(BukkitSensor sensor); + + @Binds + ServerSensor bindGenericsServerSensor(ServerSensor sensor); } \ No newline at end of file diff --git a/Plan/bungeecord/src/main/java/com/djrapitops/plan/BungeeTaskSystem.java b/Plan/bungeecord/src/main/java/com/djrapitops/plan/BungeeTaskSystem.java index 0be92b232..fb0693783 100644 --- a/Plan/bungeecord/src/main/java/com/djrapitops/plan/BungeeTaskSystem.java +++ b/Plan/bungeecord/src/main/java/com/djrapitops/plan/BungeeTaskSystem.java @@ -19,7 +19,8 @@ package com.djrapitops.plan; import com.djrapitops.plan.delivery.webserver.cache.JSONCache; import com.djrapitops.plan.extension.ExtensionServerMethodCallerTask; import com.djrapitops.plan.gathering.timed.BungeePingCounter; -import com.djrapitops.plan.gathering.timed.BungeeTPSCounter; +import com.djrapitops.plan.gathering.timed.ProxyTPSCounter; +import com.djrapitops.plan.gathering.timed.TPSCounter; import com.djrapitops.plan.settings.config.PlanConfig; import com.djrapitops.plan.settings.config.paths.DataGatheringSettings; import com.djrapitops.plan.settings.config.paths.TimeSettings; @@ -43,7 +44,7 @@ public class BungeeTaskSystem extends TaskSystem { private final PlanBungee plugin; private final PlanConfig config; - private final BungeeTPSCounter tpsCounter; + private final TPSCounter tpsCounter; private final BungeePingCounter pingCounter; private final LogsFolderCleanTask logsFolderCleanTask; private final NetworkConfigStoreTask networkConfigStoreTask; @@ -56,7 +57,7 @@ public class BungeeTaskSystem extends TaskSystem { PlanBungee plugin, PlanConfig config, RunnableFactory runnableFactory, - BungeeTPSCounter tpsCounter, + ProxyTPSCounter tpsCounter, BungeePingCounter pingCounter, LogsFolderCleanTask logsFolderCleanTask, NetworkConfigStoreTask networkConfigStoreTask, diff --git a/Plan/bungeecord/src/main/java/com/djrapitops/plan/gathering/BungeeSensor.java b/Plan/bungeecord/src/main/java/com/djrapitops/plan/gathering/BungeeSensor.java new file mode 100644 index 000000000..5f5a6882e --- /dev/null +++ b/Plan/bungeecord/src/main/java/com/djrapitops/plan/gathering/BungeeSensor.java @@ -0,0 +1,46 @@ +/* + * 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 . + */ +package com.djrapitops.plan.gathering; + +import com.djrapitops.plan.PlanBungee; +import com.djrapitops.plan.identification.properties.RedisCheck; +import com.djrapitops.plan.identification.properties.RedisPlayersOnlineSupplier; + +import javax.inject.Inject; +import javax.inject.Singleton; +import java.util.function.IntSupplier; + +@Singleton +public class BungeeSensor implements ServerSensor { + + private final IntSupplier onlinePlayerCountSupplier; + + @Inject + public BungeeSensor(PlanBungee plugin) { + onlinePlayerCountSupplier = RedisCheck.isClassAvailable() ? new RedisPlayersOnlineSupplier() : plugin.getProxy()::getOnlineCount; + } + + @Override + public boolean supportsDirectTPS() { + return false; + } + + @Override + public int getOnlinePlayerCount() { + return onlinePlayerCountSupplier.getAsInt(); + } +} diff --git a/Plan/bungeecord/src/main/java/com/djrapitops/plan/gathering/timed/BungeeTPSCounter.java b/Plan/bungeecord/src/main/java/com/djrapitops/plan/gathering/timed/BungeeTPSCounter.java deleted file mode 100644 index 747e7ed11..000000000 --- a/Plan/bungeecord/src/main/java/com/djrapitops/plan/gathering/timed/BungeeTPSCounter.java +++ /dev/null @@ -1,64 +0,0 @@ -/* - * 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 . - */ -package com.djrapitops.plan.gathering.timed; - -import com.djrapitops.plan.gathering.SystemUsage; -import com.djrapitops.plan.gathering.domain.TPS; -import com.djrapitops.plan.gathering.domain.builders.TPSBuilder; -import com.djrapitops.plan.identification.ServerInfo; -import com.djrapitops.plan.identification.properties.ServerProperties; -import com.djrapitops.plan.storage.database.DBSystem; -import com.djrapitops.plugin.logging.console.PluginLogger; -import com.djrapitops.plugin.logging.error.ErrorHandler; - -import javax.inject.Inject; -import javax.inject.Singleton; - -@Singleton -public class BungeeTPSCounter extends TPSCounter { - - private final ServerProperties serverProperties; - - @Inject - public BungeeTPSCounter( - DBSystem dbSystem, - ServerInfo serverInfo, - ServerProperties serverProperties, - PluginLogger logger, - ErrorHandler errorHandler - ) { - super(dbSystem, serverInfo, logger, errorHandler); - this.serverProperties = serverProperties; - } - - @Override - public void addNewTPSEntry(long nanoTime, long now) { - int onlineCount = serverProperties.getOnlinePlayers(); - TPS tps = TPSBuilder.get() - .date(now) - .playersOnline(onlineCount) - .usedCPU(getCPUUsage()) - .usedMemory(SystemUsage.getUsedMemory()) - .entities(-1) - .chunksLoaded(-1) - .freeDiskSpace(getFreeDiskSpace()) - .toTPS(); - - history.add(tps); - latestPlayersOnline = onlineCount; - } -} diff --git a/Plan/bungeecord/src/main/java/com/djrapitops/plan/identification/properties/BungeeServerProperties.java b/Plan/bungeecord/src/main/java/com/djrapitops/plan/identification/properties/BungeeServerProperties.java index 25243b5ce..b7cbf9f16 100644 --- a/Plan/bungeecord/src/main/java/com/djrapitops/plan/identification/properties/BungeeServerProperties.java +++ b/Plan/bungeecord/src/main/java/com/djrapitops/plan/identification/properties/BungeeServerProperties.java @@ -36,8 +36,7 @@ public class BungeeServerProperties extends ServerProperties { server.getVersion(), server.getVersion(), () -> config.get(ProxySettings.IP), - server.getConfig().getPlayerLimit(), - RedisCheck.isClassAvailable() ? new RedisPlayersOnlineSupplier() : server::getOnlineCount + server.getConfig().getPlayerLimit() ); } } \ No newline at end of file diff --git a/Plan/bungeecord/src/main/java/com/djrapitops/plan/modules/bungee/BungeeSuperClassBindingModule.java b/Plan/bungeecord/src/main/java/com/djrapitops/plan/modules/bungee/BungeeSuperClassBindingModule.java index d0dbaac53..cd5071cbf 100644 --- a/Plan/bungeecord/src/main/java/com/djrapitops/plan/modules/bungee/BungeeSuperClassBindingModule.java +++ b/Plan/bungeecord/src/main/java/com/djrapitops/plan/modules/bungee/BungeeSuperClassBindingModule.java @@ -18,6 +18,8 @@ package com.djrapitops.plan.modules.bungee; import com.djrapitops.plan.BungeeTaskSystem; import com.djrapitops.plan.TaskSystem; +import com.djrapitops.plan.gathering.BungeeSensor; +import com.djrapitops.plan.gathering.ServerSensor; import com.djrapitops.plan.gathering.listeners.BungeeListenerSystem; import com.djrapitops.plan.gathering.listeners.ListenerSystem; import com.djrapitops.plan.identification.BungeeServerInfo; @@ -26,7 +28,7 @@ import dagger.Binds; import dagger.Module; /** - * Module for binding Bungee specific classes to the interface implementations. + * Module for binding Bungee specific classes as interface implementations. * * @author Rsl1122 */ @@ -34,11 +36,14 @@ import dagger.Module; public interface BungeeSuperClassBindingModule { @Binds - ServerInfo bindBungeeServerInfo(BungeeServerInfo bungeeServerInfo); + ServerInfo bindServerInfo(BungeeServerInfo serverInfo); @Binds - TaskSystem bindBungeeTaskSystem(BungeeTaskSystem bungeeTaskSystem); + TaskSystem bindTaskSystem(BungeeTaskSystem taskSystem); @Binds - ListenerSystem bindBungeeListenerSystem(BungeeListenerSystem bungeeListenerSystem); + ListenerSystem bindListenerSystem(BungeeListenerSystem listenerSystem); + + @Binds + ServerSensor bindServerSensor(BungeeSensor sensor); } \ No newline at end of file diff --git a/Plan/common/src/main/java/com/djrapitops/plan/PlanSystem.java b/Plan/common/src/main/java/com/djrapitops/plan/PlanSystem.java index 92062023d..a641f7a35 100644 --- a/Plan/common/src/main/java/com/djrapitops/plan/PlanSystem.java +++ b/Plan/common/src/main/java/com/djrapitops/plan/PlanSystem.java @@ -40,6 +40,8 @@ import com.djrapitops.plan.storage.database.DBSystem; import com.djrapitops.plan.storage.database.queries.objects.ServerQueries; import com.djrapitops.plan.storage.file.PlanFiles; import com.djrapitops.plan.version.VersionCheckSystem; +import com.djrapitops.plugin.benchmarking.Benchmark; +import com.djrapitops.plugin.benchmarking.Timings; import com.djrapitops.plugin.logging.L; import com.djrapitops.plugin.logging.console.PluginLogger; import com.djrapitops.plugin.logging.error.ErrorHandler; @@ -79,6 +81,7 @@ public class PlanSystem implements SubSystem { private final QueryServiceImplementation queryService; private final SettingsServiceImplementation settingsService; private final PluginLogger logger; + private final Timings timings; private final ErrorHandler errorHandler; @Inject @@ -101,7 +104,7 @@ public class PlanSystem implements SubSystem { QueryServiceImplementation queryService, SettingsServiceImplementation settingsService, PluginLogger logger, - ErrorHandler errorHandler, + Timings timings, ErrorHandler errorHandler, PlanAPI.PlanAPIHolder apiHolder ) { this.files = files; @@ -122,6 +125,7 @@ public class PlanSystem implements SubSystem { this.queryService = queryService; this.settingsService = settingsService; this.logger = logger; + this.timings = timings; this.errorHandler = errorHandler; logger.log(L.INFO_COLOR, @@ -179,7 +183,13 @@ public class PlanSystem implements SubSystem { private void enableSystems(SubSystem... systems) throws EnableException { for (SubSystem system : systems) { + logger.debug("Enabling: " + system.getClass().getSimpleName()); + timings.start("subsystem-enable"); system.enable(); + timings.end("subsystem-enable") + .map(Benchmark::toDurationString) + .map(duration -> "Took " + duration) + .ifPresent(logger::debug); } } diff --git a/Plan/common/src/main/java/com/djrapitops/plan/delivery/rendering/html/structure/NavLink.java b/Plan/common/src/main/java/com/djrapitops/plan/delivery/rendering/html/structure/NavLink.java index 15ca17b19..6e62c218c 100644 --- a/Plan/common/src/main/java/com/djrapitops/plan/delivery/rendering/html/structure/NavLink.java +++ b/Plan/common/src/main/java/com/djrapitops/plan/delivery/rendering/html/structure/NavLink.java @@ -59,20 +59,20 @@ public class NavLink { } public String toHtml() { - String tabID = getTabID(); + String usedId = getUsedTabId(); if (collapsed) { - return "" + + return "" + icon.toHtml() + ' ' + tabName + ""; } return "
  • " + - "" + + "" + icon.toHtml() + "" + tabName + "" + "
  • "; } - private String getTabID() { + private String getUsedTabId() { return format(tabID != null ? tabID : tabName); } } diff --git a/Plan/common/src/main/java/com/djrapitops/plan/delivery/rendering/json/ServerOverviewJSONCreator.java b/Plan/common/src/main/java/com/djrapitops/plan/delivery/rendering/json/ServerOverviewJSONCreator.java index f78a351bf..674209963 100644 --- a/Plan/common/src/main/java/com/djrapitops/plan/delivery/rendering/json/ServerOverviewJSONCreator.java +++ b/Plan/common/src/main/java/com/djrapitops/plan/delivery/rendering/json/ServerOverviewJSONCreator.java @@ -21,6 +21,7 @@ import com.djrapitops.plan.delivery.domain.DateObj; import com.djrapitops.plan.delivery.domain.mutators.TPSMutator; import com.djrapitops.plan.delivery.formatting.Formatter; import com.djrapitops.plan.delivery.formatting.Formatters; +import com.djrapitops.plan.gathering.ServerSensor; import com.djrapitops.plan.gathering.domain.TPS; import com.djrapitops.plan.identification.ServerInfo; import com.djrapitops.plan.settings.config.PlanConfig; @@ -58,6 +59,7 @@ public class ServerOverviewJSONCreator implements ServerTabJSONCreator serverSensor; private final Formatter timeAmount; private final Formatter decimals; @@ -70,12 +72,14 @@ public class ServerOverviewJSONCreator implements ServerTabJSONCreator serverSensor, Formatters formatters ) { this.config = config; this.locale = locale; this.dbSystem = dbSystem; this.serverInfo = serverInfo; + this.serverSensor = serverSensor; year = formatters.year(); day = formatters.dayLong(); @@ -149,7 +153,7 @@ public class ServerOverviewJSONCreator implements ServerTabJSONCreator serverSensor; private final Formatter timeAmount; private final Formatter year; @@ -59,11 +61,13 @@ public class NetworkOverviewJSONCreator implements NetworkTabJSONCreator serverSensor, Formatters formatters ) { this.config = config; this.dbSystem = dbSystem; this.serverInfo = serverInfo; + this.serverSensor = serverSensor; year = formatters.year(); day = formatters.dayLong(); @@ -109,7 +113,7 @@ public class NetworkOverviewJSONCreator implements NetworkTabJSONCreator> lastPeak = db.query(TPSQueries.fetchPeakPlayerCount(serverUUID, twoDaysAgo)); Optional> allTimePeak = db.query(TPSQueries.fetchAllTimePeakPlayerCount(serverUUID)); @@ -127,10 +131,6 @@ public class NetworkOverviewJSONCreator implements NetworkTabJSONCreator createWeeksMap() { Database db = dbSystem.getDatabase(); long now = System.currentTimeMillis(); diff --git a/Plan/common/src/main/java/com/djrapitops/plan/gathering/ServerSensor.java b/Plan/common/src/main/java/com/djrapitops/plan/gathering/ServerSensor.java new file mode 100644 index 000000000..60f25dc94 --- /dev/null +++ b/Plan/common/src/main/java/com/djrapitops/plan/gathering/ServerSensor.java @@ -0,0 +1,58 @@ +/* + * 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 . + */ +package com.djrapitops.plan.gathering; + +import java.util.Collections; + +/** + * Allows sensing values from different server platforms. + * + * @param Type of the class representing a minecraft world. + * @author Rsl1122 + */ +public interface ServerSensor { + + /** + * Check if server platform provides TPS calculation. + * + * @return false if the server doesn't count TPS. + */ + boolean supportsDirectTPS(); + + int getOnlinePlayerCount(); + + default double getTPS() { + return -1; + } + + /** + * Get the worlds running on the server platform. + * + * @return Empty collection if the platform doesn't support worlds. + */ + default Iterable getWorlds() { + return Collections.emptyList(); + } + + default int getChunkCount(W world) { + return -1; + } + + default int getEntityCount(W world) { + return -1; + } +} diff --git a/Plan/common/src/main/java/com/djrapitops/plan/gathering/SystemUsage.java b/Plan/common/src/main/java/com/djrapitops/plan/gathering/SystemUsage.java index 17c7a2cf5..b6f31face 100644 --- a/Plan/common/src/main/java/com/djrapitops/plan/gathering/SystemUsage.java +++ b/Plan/common/src/main/java/com/djrapitops/plan/gathering/SystemUsage.java @@ -48,7 +48,7 @@ public class SystemUsage { * - On some OSes CPU usage information is not available, and system load average is used instead. * - On some OSes system load average is not available. * - * @return 0.0 to 1.0 if CPU, or system load average, or -1 if nothing is available. + * @return 0.0 to 100.0 if CPU, or system load average, or -1 if nothing is available. */ public static double getAverageSystemLoad() { double averageUsage; @@ -64,7 +64,7 @@ public class SystemUsage { if (averageUsage < 0) { averageUsage = -1; // If unavailable, getSystemLoadAverage() returns -1 } - return averageUsage; + return averageUsage * 100.0; } /** diff --git a/Plan/common/src/main/java/com/djrapitops/plan/gathering/timed/ProxyTPSCounter.java b/Plan/common/src/main/java/com/djrapitops/plan/gathering/timed/ProxyTPSCounter.java new file mode 100644 index 000000000..4c2c02af6 --- /dev/null +++ b/Plan/common/src/main/java/com/djrapitops/plan/gathering/timed/ProxyTPSCounter.java @@ -0,0 +1,95 @@ +/* + * 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 . + */ +package com.djrapitops.plan.gathering.timed; + +import com.djrapitops.plan.gathering.ServerSensor; +import com.djrapitops.plan.gathering.SystemUsage; +import com.djrapitops.plan.gathering.domain.builders.TPSBuilder; +import com.djrapitops.plan.identification.ServerInfo; +import com.djrapitops.plan.storage.database.DBSystem; +import com.djrapitops.plan.storage.database.transactions.events.TPSStoreTransaction; +import com.djrapitops.plan.utilities.analysis.Average; +import com.djrapitops.plan.utilities.analysis.Maximum; +import com.djrapitops.plan.utilities.analysis.TimerAverage; +import com.djrapitops.plugin.logging.console.PluginLogger; +import com.djrapitops.plugin.logging.error.ErrorHandler; + +import javax.inject.Inject; +import javax.inject.Singleton; +import java.util.concurrent.TimeUnit; + +/** + * TPSCounter extension for game server platforms. + * + * @author Rsl1122 + */ +@Singleton +public class ProxyTPSCounter extends TPSCounter { + + private final ServerSensor serverSensor; + private final DBSystem dbSystem; + private final ServerInfo serverInfo; + private Maximum.ForInteger playersOnline; + private Average cpu; + private TimerAverage ram; + + @Inject + public ProxyTPSCounter( + ServerSensor serverSensor, + DBSystem dbSystem, + ServerInfo serverInfo, + PluginLogger logger, + ErrorHandler errorHandler + ) { + super(logger, errorHandler); + + this.serverSensor = serverSensor; + this.dbSystem = dbSystem; + this.serverInfo = serverInfo; + playersOnline = new Maximum.ForInteger(0); + cpu = new Average(); + ram = new TimerAverage(); + } + + @Override + public void pulse() { + long time = System.currentTimeMillis(); + boolean shouldSave = ram.add(time, SystemUsage.getUsedMemory()); + playersOnline.add(serverSensor.getOnlinePlayerCount()); + cpu.add(SystemUsage.getAverageSystemLoad()); + if (shouldSave) save(time); + } + + private void save(long time) { + long timeLastMinute = time - TimeUnit.MINUTES.toMillis(1L); + int maxPlayers = playersOnline.getMaxAndReset(); + double averageCPU = cpu.getAverageAndReset(); + long averageRAM = (long) ram.getAverageAndReset(time); + long freeDiskSpace = getFreeDiskSpace(); + + dbSystem.getDatabase().executeTransaction(new TPSStoreTransaction( + serverInfo.getServerUUID(), + TPSBuilder.get() + .date(timeLastMinute) + .playersOnline(maxPlayers) + .usedCPU(averageCPU) + .usedMemory(averageRAM) + .freeDiskSpace(freeDiskSpace) + .toTPS() + )); + } +} diff --git a/Plan/common/src/main/java/com/djrapitops/plan/gathering/timed/ServerTPSCounter.java b/Plan/common/src/main/java/com/djrapitops/plan/gathering/timed/ServerTPSCounter.java new file mode 100644 index 000000000..2720f2b90 --- /dev/null +++ b/Plan/common/src/main/java/com/djrapitops/plan/gathering/timed/ServerTPSCounter.java @@ -0,0 +1,127 @@ +/* + * 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 . + */ +package com.djrapitops.plan.gathering.timed; + +import com.djrapitops.plan.gathering.ServerSensor; +import com.djrapitops.plan.gathering.SystemUsage; +import com.djrapitops.plan.gathering.domain.builders.TPSBuilder; +import com.djrapitops.plan.identification.ServerInfo; +import com.djrapitops.plan.storage.database.DBSystem; +import com.djrapitops.plan.storage.database.transactions.events.TPSStoreTransaction; +import com.djrapitops.plan.utilities.analysis.Average; +import com.djrapitops.plan.utilities.analysis.Maximum; +import com.djrapitops.plan.utilities.analysis.TimerAverage; +import com.djrapitops.plugin.logging.console.PluginLogger; +import com.djrapitops.plugin.logging.error.ErrorHandler; + +import javax.inject.Inject; +import javax.inject.Singleton; +import java.util.Optional; +import java.util.concurrent.TimeUnit; + +/** + * TPSCounter extension for game server platforms. + * + * @author Rsl1122 + */ +@Singleton +public class ServerTPSCounter extends TPSCounter { + + private final boolean noDirectTPS; + private final ServerSensor serverSensor; + private final DBSystem dbSystem; + private final ServerInfo serverInfo; + private TPSCalculator indirectTPS; + private TimerAverage directTPS; + private Maximum.ForInteger playersOnline; + private Average cpu; + private Average ram; + + @Inject + public ServerTPSCounter( + ServerSensor serverSensor, + DBSystem dbSystem, + ServerInfo serverInfo, + PluginLogger logger, + ErrorHandler errorHandler + ) { + super(logger, errorHandler); + + noDirectTPS = !serverSensor.supportsDirectTPS(); + this.serverSensor = serverSensor; + this.dbSystem = dbSystem; + this.serverInfo = serverInfo; + if (noDirectTPS) { + indirectTPS = new TPSCalculator(); + } else { + directTPS = new TimerAverage(); + } + playersOnline = new Maximum.ForInteger(0); + cpu = new Average(); + ram = new Average(); + } + + @Override + public void pulse() { + long time = System.currentTimeMillis(); + Optional result = pulseTPS(time); + playersOnline.add(serverSensor.getOnlinePlayerCount()); + cpu.add(SystemUsage.getAverageSystemLoad()); + ram.add(SystemUsage.getUsedMemory()); + result.ifPresent(tps -> save(tps, time)); + } + + private void save(double averageTPS, long time) { + long timeLastMinute = time - TimeUnit.MINUTES.toMillis(1L); + int maxPlayers = playersOnline.getMaxAndReset(); + double averageCPU = cpu.getAverageAndReset(); + long averageRAM = (long) ram.getAverageAndReset(); + int entityCount = 0; + int chunkCount = 0; + for (W world : serverSensor.getWorlds()) { + entityCount += serverSensor.getEntityCount(world); + chunkCount += serverSensor.getChunkCount(world); + } + long freeDiskSpace = getFreeDiskSpace(); + + dbSystem.getDatabase().executeTransaction(new TPSStoreTransaction( + serverInfo.getServerUUID(), + TPSBuilder.get() + .date(timeLastMinute) + .tps(averageTPS) + .playersOnline(maxPlayers) + .usedCPU(averageCPU) + .usedMemory(averageRAM) + .entities(entityCount) + .chunksLoaded(chunkCount) + .freeDiskSpace(freeDiskSpace) + .toTPS() + )); + } + + public Optional pulseTPS(long time) { + if (noDirectTPS) { + return indirectTPS.pulse(time); + } else { + if (directTPS.add(time, serverSensor.getTPS())) { + return Optional.of(directTPS.getAverageAndReset(time)); + } else { + return Optional.empty(); + } + } + } +} diff --git a/Plan/common/src/main/java/com/djrapitops/plan/gathering/timed/TPSCalculator.java b/Plan/common/src/main/java/com/djrapitops/plan/gathering/timed/TPSCalculator.java new file mode 100644 index 000000000..e9b926e21 --- /dev/null +++ b/Plan/common/src/main/java/com/djrapitops/plan/gathering/timed/TPSCalculator.java @@ -0,0 +1,86 @@ +/* + * 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 . + */ +package com.djrapitops.plan.gathering.timed; + +import com.djrapitops.plan.utilities.analysis.TimerAverage; + +import java.util.Optional; +import java.util.concurrent.TimeUnit; + +/** + * Utility for calculating TPS using nano time. + *

    + * Math: + * - Minecraft runs 20 ticks / second, 1 tick = 50ms + * - To return 20 ticks, 1 second is expected + * - If the call time is less than 1 second, the TPS is still 20, excess is not counted. + * - If the call time is more than 1 second, the TPS is below 20 + * - If 2 seconds, TPS is 10 + * - If 4 seconds, TPS is 5 + * - If 20 seconds, TPS is 1 + * - If more than 20 seconds, TPS is 0 for 20 seconds and then according to the other rules. + * + * @author Rsl1122 + */ +public class TPSCalculator { + + public static final long SECOND_NS = TimeUnit.SECONDS.toNanos(1L); + + private long maxBeforeZeroTPS; + private long lastPulse; + + private TimerAverage averager; + + public TPSCalculator() { + maxBeforeZeroTPS = SECOND_NS * 20L; // 20 ticks + lastPulse = -1; + + averager = new TimerAverage(); + } + + /** + * Pulse the TPS clock. + * + * @param time Current epoch ms + * @return Average TPS for the minute, or empty. + */ + public Optional pulse(long time) { + boolean firstRun = lastPulse < 0; + long currentPulse = System.nanoTime(); + long difference = currentPulse - lastPulse; + lastPulse = currentPulse; + if (firstRun) { + return Optional.empty(); // Can not calculate on first check. + } + + // Cap the TPS to a maximum by making nominator 1. + // Expecting the pulse period to be 1 second. + if (difference < SECOND_NS) difference = SECOND_NS; + + // Add missed ticks, TPS has been low for a while, see the math in the class javadoc. + while (difference > maxBeforeZeroTPS) { + averager.add(time, 0.0); + difference -= maxBeforeZeroTPS; + } + + double tps = maxBeforeZeroTPS * 1.0 / difference; + if (averager.add(time, tps)) { + return Optional.of(averager.getAverageAndReset(time)); + } + return Optional.empty(); + } +} \ No newline at end of file diff --git a/Plan/common/src/main/java/com/djrapitops/plan/gathering/timed/TPSCounter.java b/Plan/common/src/main/java/com/djrapitops/plan/gathering/timed/TPSCounter.java index 91fc690af..77ce84680 100644 --- a/Plan/common/src/main/java/com/djrapitops/plan/gathering/timed/TPSCounter.java +++ b/Plan/common/src/main/java/com/djrapitops/plan/gathering/timed/TPSCounter.java @@ -17,18 +17,11 @@ package com.djrapitops.plan.gathering.timed; import com.djrapitops.plan.gathering.SystemUsage; -import com.djrapitops.plan.gathering.domain.TPS; -import com.djrapitops.plan.identification.ServerInfo; -import com.djrapitops.plan.storage.database.DBSystem; -import com.djrapitops.plan.storage.database.transactions.events.TPSStoreTransaction; import com.djrapitops.plugin.logging.L; import com.djrapitops.plugin.logging.console.PluginLogger; import com.djrapitops.plugin.logging.error.ErrorHandler; import com.djrapitops.plugin.task.AbsRunnable; -import java.util.ArrayList; -import java.util.List; - /** * Class responsible for calculating TPS every second. * @@ -36,45 +29,31 @@ import java.util.List; */ public abstract class TPSCounter extends AbsRunnable { - protected final List history; - - protected final DBSystem dbSystem; - protected final ServerInfo serverInfo; protected final PluginLogger logger; protected final ErrorHandler errorHandler; private boolean diskErrored = false; - protected int latestPlayersOnline = 0; - public TPSCounter( - DBSystem dbSystem, - ServerInfo serverInfo, PluginLogger logger, ErrorHandler errorHandler ) { - this.dbSystem = dbSystem; - this.serverInfo = serverInfo; this.logger = logger; this.errorHandler = errorHandler; - history = new ArrayList<>(); + + warmUp(); + } + + public void warmUp() { + SystemUsage.getAverageSystemLoad(); + SystemUsage.getUsedMemory(); + SystemUsage.getFreeDiskSpace(); } @Override public void run() { try { - long nanoTime = System.nanoTime(); - long now = System.currentTimeMillis(); - - addNewTPSEntry(nanoTime, now); - - if (history.size() >= 60) { - dbSystem.getDatabase().executeTransaction(new TPSStoreTransaction( - serverInfo.getServerUUID(), - new ArrayList<>(history) - )); - history.clear(); - } + pulse(); } catch (Exception | NoClassDefFoundError | NoSuchMethodError | NoSuchFieldError e) { logger.error("TPS Count Task Disabled due to error, reload Plan to re-enable."); errorHandler.log(L.ERROR, this.getClass(), e); @@ -82,15 +61,7 @@ public abstract class TPSCounter extends AbsRunnable { } } - public abstract void addNewTPSEntry(long nanoTime, long now); - - public int getLatestPlayersOnline() { - return latestPlayersOnline; - } - - protected double getCPUUsage() { - return SystemUsage.getAverageSystemLoad() * 100.0; - } + public abstract void pulse(); protected long getFreeDiskSpace() { try { diff --git a/Plan/common/src/main/java/com/djrapitops/plan/identification/properties/ServerProperties.java b/Plan/common/src/main/java/com/djrapitops/plan/identification/properties/ServerProperties.java index 2c51d854e..2775fd878 100644 --- a/Plan/common/src/main/java/com/djrapitops/plan/identification/properties/ServerProperties.java +++ b/Plan/common/src/main/java/com/djrapitops/plan/identification/properties/ServerProperties.java @@ -16,7 +16,6 @@ */ package com.djrapitops.plan.identification.properties; -import java.util.function.IntSupplier; import java.util.function.Supplier; /** @@ -34,16 +33,13 @@ public abstract class ServerProperties { private final Supplier ip; private final int maxPlayers; - private final IntSupplier onlinePlayers; - protected ServerProperties( String name, int port, String version, String implVersion, Supplier ip, - int maxPlayers, - IntSupplier onlinePlayers + int maxPlayers ) { this.name = name; this.port = port; @@ -51,7 +47,6 @@ public abstract class ServerProperties { this.implVersion = implVersion; this.ip = ip; this.maxPlayers = maxPlayers; - this.onlinePlayers = onlinePlayers; } /** @@ -83,7 +78,4 @@ public abstract class ServerProperties { return maxPlayers; } - public int getOnlinePlayers() { - return onlinePlayers.getAsInt(); - } } diff --git a/Plan/common/src/main/java/com/djrapitops/plan/modules/ProxySuperClassBindingModule.java b/Plan/common/src/main/java/com/djrapitops/plan/modules/ProxySuperClassBindingModule.java index e14f14bf9..d203865b2 100644 --- a/Plan/common/src/main/java/com/djrapitops/plan/modules/ProxySuperClassBindingModule.java +++ b/Plan/common/src/main/java/com/djrapitops/plan/modules/ProxySuperClassBindingModule.java @@ -16,6 +16,7 @@ */ package com.djrapitops.plan.modules; +import com.djrapitops.plan.gathering.ServerSensor; import com.djrapitops.plan.gathering.importing.EmptyImportSystem; import com.djrapitops.plan.gathering.importing.ImportSystem; import com.djrapitops.plan.settings.ConfigSystem; @@ -34,12 +35,15 @@ import dagger.Module; public interface ProxySuperClassBindingModule { @Binds - DBSystem bindProxyDatabaseSystem(ProxyDBSystem proxyDBSystem); + DBSystem bindDBSystem(ProxyDBSystem dbSystem); @Binds - ConfigSystem bindProxyConfigSystem(ProxyConfigSystem proxyConfigSystem); + ConfigSystem bindConfigSystem(ProxyConfigSystem configSystem); @Binds ImportSystem bindImportSystem(EmptyImportSystem emptyImportSystem); + @Binds + ServerSensor bindServerSensor(ServerSensor sensor); + } \ No newline at end of file diff --git a/Plan/common/src/main/java/com/djrapitops/plan/storage/database/transactions/events/TPSStoreTransaction.java b/Plan/common/src/main/java/com/djrapitops/plan/storage/database/transactions/events/TPSStoreTransaction.java index 4af6f620f..c63d85fdf 100644 --- a/Plan/common/src/main/java/com/djrapitops/plan/storage/database/transactions/events/TPSStoreTransaction.java +++ b/Plan/common/src/main/java/com/djrapitops/plan/storage/database/transactions/events/TPSStoreTransaction.java @@ -17,11 +17,9 @@ package com.djrapitops.plan.storage.database.transactions.events; import com.djrapitops.plan.gathering.domain.TPS; -import com.djrapitops.plan.gathering.domain.builders.TPSBuilder; import com.djrapitops.plan.storage.database.queries.DataStoreQueries; import com.djrapitops.plan.storage.database.transactions.Transaction; -import java.util.List; import java.util.UUID; /** @@ -32,38 +30,15 @@ import java.util.UUID; public class TPSStoreTransaction extends Transaction { private final UUID serverUUID; - private final List tpsList; + private final TPS tps; - public TPSStoreTransaction(UUID serverUUID, List tpsList) { + public TPSStoreTransaction(UUID serverUUID, TPS tps) { this.serverUUID = serverUUID; - this.tpsList = tpsList; + this.tps = tps; } @Override protected void performOperations() { - TPS tps = calculateTPS(); execute(DataStoreQueries.storeTPS(serverUUID, tps)); } - - private TPS calculateTPS() { - long lastDate = tpsList.get(tpsList.size() - 1).getDate(); - double averageTPS = tpsList.stream().mapToDouble(TPS::getTicksPerSecond).average().orElse(0); - int peakPlayersOnline = tpsList.stream().mapToInt(TPS::getPlayers).max().orElse(0); - double averageCPUUsage = tpsList.stream().mapToDouble(TPS::getCPUUsage).average().orElse(0); - long averageUsedMemory = (long) tpsList.stream().mapToLong(TPS::getUsedMemory).average().orElse(0); - int averageEntityCount = (int) tpsList.stream().mapToInt(TPS::getEntityCount).average().orElse(0); - int averageChunksLoaded = (int) tpsList.stream().mapToInt(TPS::getChunksLoaded).average().orElse(0); - long freeDiskSpace = (long) tpsList.stream().mapToLong(TPS::getFreeDiskSpace).average().orElse(0); - - return TPSBuilder.get() - .date(lastDate) - .tps(averageTPS) - .playersOnline(peakPlayersOnline) - .usedCPU(averageCPUUsage) - .usedMemory(averageUsedMemory) - .entities(averageEntityCount) - .chunksLoaded(averageChunksLoaded) - .freeDiskSpace(freeDiskSpace) - .toTPS(); - } } \ No newline at end of file diff --git a/Plan/common/src/main/java/com/djrapitops/plan/utilities/analysis/Average.java b/Plan/common/src/main/java/com/djrapitops/plan/utilities/analysis/Average.java new file mode 100644 index 000000000..760e450bf --- /dev/null +++ b/Plan/common/src/main/java/com/djrapitops/plan/utilities/analysis/Average.java @@ -0,0 +1,50 @@ +/* + * 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 . + */ +package com.djrapitops.plan.utilities.analysis; + +/** + * Utility for averaging data. + * + * @author Rsl1122 + */ +public class Average { + + private double total; + private int count; + + public Average() { + total = 0.0; + count = 0; + } + + /** + * Add a new entry and check if save should be done. + * + * @param value TPS value + */ + public void add(double value) { + total += value; + count++; + } + + public double getAverageAndReset() { + double average = total / count; + total = 0.0; + count = 0; + return average; + } +} \ No newline at end of file diff --git a/Plan/common/src/main/java/com/djrapitops/plan/utilities/analysis/Maximum.java b/Plan/common/src/main/java/com/djrapitops/plan/utilities/analysis/Maximum.java new file mode 100644 index 000000000..7ede1d24b --- /dev/null +++ b/Plan/common/src/main/java/com/djrapitops/plan/utilities/analysis/Maximum.java @@ -0,0 +1,50 @@ +/* + * 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 . + */ +package com.djrapitops.plan.utilities.analysis; + +/** + * Calculates maximum from given values. + * + * @author Rsl1122 + */ +public interface Maximum { + + class ForInteger { + private int max; + private int startingValue; + + public ForInteger() { + this(Integer.MIN_VALUE); + } + + public ForInteger(int startingValue) { + this.startingValue = startingValue; + this.max = startingValue; + } + + public void add(int value) { + if (value > max) max = value; + } + + public int getMaxAndReset() { + int result = max; + max = startingValue; + return result; + } + } + +} \ No newline at end of file diff --git a/Plan/common/src/main/java/com/djrapitops/plan/utilities/analysis/TimerAverage.java b/Plan/common/src/main/java/com/djrapitops/plan/utilities/analysis/TimerAverage.java new file mode 100644 index 000000000..a5eb93b23 --- /dev/null +++ b/Plan/common/src/main/java/com/djrapitops/plan/utilities/analysis/TimerAverage.java @@ -0,0 +1,68 @@ +/* + * 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 . + */ +package com.djrapitops.plan.utilities.analysis; + +import java.util.concurrent.TimeUnit; + +/** + * Utility for averaging time based data. + * + * @author Rsl1122 + */ +public class TimerAverage { + + private long savePeriodMs; + private long lastSaveMs; + + private double total; + private int count; + + public TimerAverage() { + this(TimeUnit.MINUTES.toMillis(1L)); + } + + public TimerAverage(long savePeriodMs) { + this.savePeriodMs = savePeriodMs; + lastSaveMs = 0; + + total = 0.0; + count = 0; + } + + /** + * Add a new entry and check if save should be done. + * + * @param time Current epoch ms + * @param value TPS value + * @return If a save should be performed. + */ + public boolean add(long time, double value) { + if (lastSaveMs <= 0) lastSaveMs = time; + if (value < 0.0) return false; + total += value; + count++; + return time - lastSaveMs >= savePeriodMs; + } + + public double getAverageAndReset(long time) { + lastSaveMs = time; + double average = total / count; + total = 0.0; + count = 0; + return average; + } +} \ No newline at end of file diff --git a/Plan/common/src/test/java/com/djrapitops/plan/storage/database/DatabaseTest.java b/Plan/common/src/test/java/com/djrapitops/plan/storage/database/DatabaseTest.java index 843b003bd..99d9710bd 100644 --- a/Plan/common/src/test/java/com/djrapitops/plan/storage/database/DatabaseTest.java +++ b/Plan/common/src/test/java/com/djrapitops/plan/storage/database/DatabaseTest.java @@ -79,7 +79,6 @@ import java.io.File; import java.lang.management.ManagementFactory; import java.lang.management.OperatingSystemMXBean; import java.nio.file.Files; -import java.security.NoSuchAlgorithmException; import java.sql.ResultSet; import java.sql.SQLException; import java.util.*; @@ -439,7 +438,7 @@ public interface DatabaseTest { } @Test - default void testRemovalEverything() throws NoSuchAlgorithmException { + default void testRemovalEverything() { saveAllData(); db().executeTransaction(new RemoveEverythingTransaction()); @@ -456,7 +455,7 @@ public interface DatabaseTest { assertTrue(db().query(WebUserQueries.fetchAllPlanWebUsers()).isEmpty()); } - default void assertQueryIsEmpty(Database database, Query query) { + default > void assertQueryIsEmpty(Database database, Query query) { assertTrue(database.query(query).isEmpty()); } @@ -782,7 +781,7 @@ public interface DatabaseTest { } @Test - default void testNewContainerForPlayer() throws NoSuchAlgorithmException { + default void testNewContainerForPlayer() { saveAllData(); long start = System.nanoTime(); @@ -837,7 +836,7 @@ public interface DatabaseTest { } @Test - default void playerContainerSupportsAllPlayerKeys() throws NoSuchAlgorithmException, IllegalAccessException { + default void playerContainerSupportsAllPlayerKeys() throws IllegalAccessException { saveAllData(); PlayerContainer playerContainer = db().query(ContainerFetchQueries.fetchPlayerContainer(playerUUID)); @@ -846,7 +845,7 @@ public interface DatabaseTest { List unsupported = new ArrayList<>(); List keys = FieldFetcher.getPublicStaticFields(PlayerKeys.class, Key.class); - for (Key key : keys) { + for (Key key : keys) { if (!playerContainer.supports(key)) { unsupported.add(key.getKeyName()); } @@ -872,14 +871,14 @@ public interface DatabaseTest { } @Test - default void serverContainerSupportsAllServerKeys() throws NoSuchAlgorithmException, IllegalAccessException { + default void serverContainerSupportsAllServerKeys() throws IllegalAccessException { saveAllData(); ServerContainer serverContainer = db().query(ContainerFetchQueries.fetchServerContainer(serverUUID())); List unsupported = new ArrayList<>(); List keys = FieldFetcher.getPublicStaticFields(ServerKeys.class, Key.class); - for (Key key : keys) { + for (Key key : keys) { if (!serverContainer.supports(key)) { unsupported.add(key.getKeyName()); } @@ -963,7 +962,7 @@ public interface DatabaseTest { List tpsData = RandomData.randomTPS(); for (TPS tps : tpsData) { - db().executeTransaction(new TPSStoreTransaction(serverUUID(), Collections.singletonList(tps))); + db().executeTransaction(new TPSStoreTransaction(serverUUID(), tps)); } tpsData.sort(Comparator.comparingInt(TPS::getPlayers)); diff --git a/Plan/common/src/test/java/utilities/dagger/PluginServerPropertiesModule.java b/Plan/common/src/test/java/utilities/dagger/PluginServerPropertiesModule.java index 088389d48..c97171b5f 100644 --- a/Plan/common/src/test/java/utilities/dagger/PluginServerPropertiesModule.java +++ b/Plan/common/src/test/java/utilities/dagger/PluginServerPropertiesModule.java @@ -22,7 +22,6 @@ import dagger.Provides; import javax.inject.Singleton; import java.net.InetSocketAddress; -import java.util.Random; /** * Dagger module for Bukkit ServerProperties. @@ -41,8 +40,7 @@ public class PluginServerPropertiesModule { "1.13", "1.13-git-mock", () -> new InetSocketAddress(25565).getAddress().getHostAddress(), - 20, - () -> new Random().nextInt(20) + 20 ) {}; } } \ No newline at end of file diff --git a/Plan/common/src/test/java/utilities/dagger/PluginSuperClassBindingModule.java b/Plan/common/src/test/java/utilities/dagger/PluginSuperClassBindingModule.java index 0de35ca70..209bd6cd3 100644 --- a/Plan/common/src/test/java/utilities/dagger/PluginSuperClassBindingModule.java +++ b/Plan/common/src/test/java/utilities/dagger/PluginSuperClassBindingModule.java @@ -19,6 +19,7 @@ package utilities.dagger; import com.djrapitops.plan.PlanPlugin; import com.djrapitops.plan.TaskSystem; import com.djrapitops.plan.exceptions.EnableException; +import com.djrapitops.plan.gathering.ServerSensor; import com.djrapitops.plan.gathering.listeners.ListenerSystem; import com.djrapitops.plan.processing.Processing; import com.djrapitops.plan.settings.config.PlanConfig; @@ -28,16 +29,17 @@ import com.djrapitops.plan.storage.database.DBSystem; import com.djrapitops.plan.storage.database.H2DB; import com.djrapitops.plan.storage.database.MySQLDB; import com.djrapitops.plan.storage.database.SQLiteDB; -import com.djrapitops.plugin.benchmarking.Timings; import com.djrapitops.plugin.logging.console.PluginLogger; -import com.djrapitops.plugin.logging.error.ErrorHandler; import com.djrapitops.plugin.task.RunnableFactory; import dagger.Module; import dagger.Provides; +import org.mockito.Mockito; import utilities.mocks.TestProcessing; import javax.inject.Singleton; +import static org.mockito.Mockito.when; + /** * Module for binding Bukkit specific classes to the interface implementations. * @@ -54,9 +56,7 @@ public class PluginSuperClassBindingModule { SQLiteDB.Factory sqLiteDB, H2DB.Factory h2Factory, MySQLDB mySQLDB, - PluginLogger logger, - Timings timings, - ErrorHandler errorHandler + PluginLogger logger ) { return new DBSystem(locale, sqLiteDB, h2Factory, logger) { @Override @@ -105,4 +105,15 @@ public class PluginSuperClassBindingModule { return testProcessing; } + @Provides + @Singleton + ServerSensor provideServerSensor() { + ServerSensor mock = Mockito.mock(ServerSensor.class); + when(mock.getWorlds()).thenCallRealMethod(); + when(mock.getChunkCount(Mockito.any())).thenCallRealMethod(); + when(mock.getEntityCount(Mockito.any())).thenCallRealMethod(); + when(mock.getTPS()).thenCallRealMethod(); + return mock; + } + } \ No newline at end of file diff --git a/Plan/nukkit/src/main/java/com/djrapitops/plan/NukkitTaskSystem.java b/Plan/nukkit/src/main/java/com/djrapitops/plan/NukkitTaskSystem.java index 47dd8c13b..c318297e7 100644 --- a/Plan/nukkit/src/main/java/com/djrapitops/plan/NukkitTaskSystem.java +++ b/Plan/nukkit/src/main/java/com/djrapitops/plan/NukkitTaskSystem.java @@ -17,11 +17,13 @@ package com.djrapitops.plan; import cn.nukkit.Server; +import cn.nukkit.level.Level; import com.djrapitops.plan.delivery.webserver.cache.JSONCache; import com.djrapitops.plan.extension.ExtensionServerMethodCallerTask; import com.djrapitops.plan.gathering.ShutdownHook; import com.djrapitops.plan.gathering.timed.NukkitPingCounter; -import com.djrapitops.plan.gathering.timed.NukkitTPSCounter; +import com.djrapitops.plan.gathering.timed.ServerTPSCounter; +import com.djrapitops.plan.gathering.timed.TPSCounter; import com.djrapitops.plan.settings.config.PlanConfig; import com.djrapitops.plan.settings.config.paths.DataGatheringSettings; import com.djrapitops.plan.settings.config.paths.TimeSettings; @@ -49,11 +51,11 @@ public class NukkitTaskSystem extends TaskSystem { private final ShutdownHook shutdownHook; private final JSONCache.CleanTask jsonCacheCleanTask; private final LogsFolderCleanTask logsFolderCleanTask; + private final TPSCounter tpsCounter; private final NukkitPingCounter pingCounter; private final ConfigStoreTask configStoreTask; private final DBCleanTask dbCleanTask; private final ExtensionServerMethodCallerTask extensionServerMethodCallerTask; - private NukkitTPSCounter tpsCounter; @Inject public NukkitTaskSystem( @@ -62,7 +64,7 @@ public class NukkitTaskSystem extends TaskSystem { ShutdownHook shutdownHook, RunnableFactory runnableFactory, - NukkitTPSCounter tpsCounter, + ServerTPSCounter tpsCounter, NukkitPingCounter pingCounter, ExtensionServerMethodCallerTask extensionServerMethodCallerTask, diff --git a/Plan/nukkit/src/main/java/com/djrapitops/plan/gathering/NukkitSensor.java b/Plan/nukkit/src/main/java/com/djrapitops/plan/gathering/NukkitSensor.java new file mode 100644 index 000000000..8a9cca8a0 --- /dev/null +++ b/Plan/nukkit/src/main/java/com/djrapitops/plan/gathering/NukkitSensor.java @@ -0,0 +1,66 @@ +/* + * 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 . + */ +package com.djrapitops.plan.gathering; + +import cn.nukkit.level.Level; +import com.djrapitops.plan.PlanNukkit; + +import javax.inject.Inject; +import javax.inject.Singleton; + +@Singleton +public class NukkitSensor implements ServerSensor { + + private final PlanNukkit plugin; + + @Inject + public NukkitSensor( + PlanNukkit plugin + ) { + this.plugin = plugin; + } + + @Override + public boolean supportsDirectTPS() { + return true; + } + + @Override + public double getTPS() { + return plugin.getServer().getTicksPerSecondAverage(); + } + + @Override + public int getChunkCount(Level world) { + return world.getChunks().size(); + } + + @Override + public int getEntityCount(Level world) { + return world.getEntities().length; + } + + @Override + public int getOnlinePlayerCount() { + return plugin.getServer().getOnlinePlayers().size(); + } + + @Override + public Iterable getWorlds() { + return plugin.getServer().getLevels().values(); + } +} diff --git a/Plan/nukkit/src/main/java/com/djrapitops/plan/gathering/timed/NukkitTPSCounter.java b/Plan/nukkit/src/main/java/com/djrapitops/plan/gathering/timed/NukkitTPSCounter.java deleted file mode 100644 index 18c0354d9..000000000 --- a/Plan/nukkit/src/main/java/com/djrapitops/plan/gathering/timed/NukkitTPSCounter.java +++ /dev/null @@ -1,154 +0,0 @@ -/* - * 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 . - */ -package com.djrapitops.plan.gathering.timed; - -import cn.nukkit.level.Level; -import com.djrapitops.plan.PlanNukkit; -import com.djrapitops.plan.gathering.SystemUsage; -import com.djrapitops.plan.gathering.domain.TPS; -import com.djrapitops.plan.gathering.domain.builders.TPSBuilder; -import com.djrapitops.plan.identification.ServerInfo; -import com.djrapitops.plan.identification.properties.ServerProperties; -import com.djrapitops.plan.storage.database.DBSystem; -import com.djrapitops.plugin.logging.console.PluginLogger; -import com.djrapitops.plugin.logging.error.ErrorHandler; - -import javax.inject.Inject; -import javax.inject.Singleton; -import java.util.concurrent.TimeUnit; - -@Singleton -public class NukkitTPSCounter extends TPSCounter { - - protected final PlanNukkit plugin; - private ServerProperties serverProperties; - private long lastCheckNano; - - @Inject - public NukkitTPSCounter( - PlanNukkit plugin, - DBSystem dbSystem, - ServerInfo serverInfo, - ServerProperties serverProperties, - PluginLogger logger, - ErrorHandler errorHandler - ) { - super(dbSystem, serverInfo, logger, errorHandler); - this.plugin = plugin; - this.serverProperties = serverProperties; - lastCheckNano = -1; - } - - @Override - public void addNewTPSEntry(long nanoTime, long now) { - long diff = nanoTime - lastCheckNano; - - lastCheckNano = nanoTime; - - if (diff > nanoTime) { // First run's diff = nanoTime + 1, no calc possible. - logger.debug("First run of TPSCountTimer Task."); - return; - } - - history.add(calculateTPS(diff, now)); - } - - /** - * Calculates the TPS - * - * @param diff The time difference between the last run and the new run - * @param now The time right now - * @return the TPS - */ - private TPS calculateTPS(long diff, long now) { - double averageCPUUsage = getCPUUsage(); - long usedMemory = SystemUsage.getUsedMemory(); - long freeDiskSpace = getFreeDiskSpace(); - - int playersOnline = serverProperties.getOnlinePlayers(); - latestPlayersOnline = playersOnline; - int loadedChunks = getLoadedChunks(); - int entityCount = getEntityCount(); - - return getTPS(diff, now, averageCPUUsage, usedMemory, entityCount, loadedChunks, playersOnline, freeDiskSpace); - } - - protected TPS getTPS(long diff, long now, - double cpuUsage, long usedMemory, - int entityCount, int chunksLoaded, - int playersOnline, long freeDiskSpace) { - long difference = diff; - if (difference < TimeUnit.SECONDS.toNanos(1L)) { // No tick count above 20 - difference = TimeUnit.SECONDS.toNanos(1L); - } - - long twentySeconds = TimeUnit.SECONDS.toNanos(20L); - while (difference > twentySeconds) { - // Add 0 TPS since more than 20 ticks has passed. - history.add(TPSBuilder.get() - .date(now) - .tps(0) - .playersOnline(playersOnline) - .usedCPU(cpuUsage) - .usedMemory(usedMemory) - .entities(entityCount) - .chunksLoaded(chunksLoaded) - .freeDiskSpace(freeDiskSpace) - .toTPS()); - difference -= twentySeconds; - } - - double tpsN = twentySeconds * 1.0 / difference; - - return TPSBuilder.get() - .date(now) - .tps(tpsN) - .playersOnline(playersOnline) - .usedCPU(cpuUsage) - .usedMemory(usedMemory) - .entities(entityCount) - .chunksLoaded(chunksLoaded) - .freeDiskSpace(freeDiskSpace) - .toTPS(); - } - - /** - * Gets the amount of loaded chunks - * - * @return amount of loaded chunks - */ - private int getLoadedChunks() { - int sum = 0; - for (Level world : plugin.getServer().getLevels().values()) { - sum += world.getChunks().size(); - } - return sum; - } - - /** - * Gets the amount of entities on the server for Nukkit - * - * @return amount of entities - */ - protected int getEntityCount() { - int sum = 0; - for (Level world : plugin.getServer().getLevels().values()) { - sum += world.getEntities().length; - } - return sum; - } -} diff --git a/Plan/nukkit/src/main/java/com/djrapitops/plan/identification/properties/NukkitServerProperties.java b/Plan/nukkit/src/main/java/com/djrapitops/plan/identification/properties/NukkitServerProperties.java index d82913e68..de51d1809 100644 --- a/Plan/nukkit/src/main/java/com/djrapitops/plan/identification/properties/NukkitServerProperties.java +++ b/Plan/nukkit/src/main/java/com/djrapitops/plan/identification/properties/NukkitServerProperties.java @@ -32,8 +32,7 @@ public class NukkitServerProperties extends ServerProperties { server.getVersion(), server.getNukkitVersion(), server::getIp, - server.getMaxPlayers(), - () -> server.getOnlinePlayers().size() + server.getMaxPlayers() ); } diff --git a/Plan/nukkit/src/main/java/com/djrapitops/plan/modules/nukkit/NukkitSuperClassBindingModule.java b/Plan/nukkit/src/main/java/com/djrapitops/plan/modules/nukkit/NukkitSuperClassBindingModule.java index 5c52b3f19..271fc312f 100644 --- a/Plan/nukkit/src/main/java/com/djrapitops/plan/modules/nukkit/NukkitSuperClassBindingModule.java +++ b/Plan/nukkit/src/main/java/com/djrapitops/plan/modules/nukkit/NukkitSuperClassBindingModule.java @@ -16,9 +16,12 @@ */ package com.djrapitops.plan.modules.nukkit; +import cn.nukkit.level.Level; import com.djrapitops.plan.NukkitServerShutdownSave; import com.djrapitops.plan.NukkitTaskSystem; import com.djrapitops.plan.TaskSystem; +import com.djrapitops.plan.gathering.NukkitSensor; +import com.djrapitops.plan.gathering.ServerSensor; import com.djrapitops.plan.gathering.ServerShutdownSave; import com.djrapitops.plan.gathering.importing.EmptyImportSystem; import com.djrapitops.plan.gathering.importing.ImportSystem; @@ -34,7 +37,7 @@ import dagger.Binds; import dagger.Module; /** - * Module for binding Nukkit specific classes to the interface implementations. + * Module for binding Nukkit specific classes as interface implementations. * * @author Rsl1122 */ @@ -42,24 +45,29 @@ import dagger.Module; public interface NukkitSuperClassBindingModule { @Binds - ServerInfo bindNukkitServerInfo(ServerServerInfo serverServerInfo); + ServerInfo bindServerInfo(ServerServerInfo serverInfo); @Binds - DBSystem bindNukkitDatabaseSystem(NukkitDBSystem dbSystem); + DBSystem bindDBSystem(NukkitDBSystem dbSystem); @Binds - ConfigSystem bindNukkitConfigSystem(NukkitConfigSystem nukkitConfigSystem); + ConfigSystem bindConfigSystem(NukkitConfigSystem configSystem); @Binds - TaskSystem bindNukkitTaskSystem(NukkitTaskSystem nukkitTaskSystem); + TaskSystem bindTaskSystem(NukkitTaskSystem taskSystem); @Binds - ListenerSystem bindNukkitListenerSystem(NukkitListenerSystem nukkitListenerSystem); + ListenerSystem bindListenerSystem(NukkitListenerSystem listenerSystem); @Binds ImportSystem bindImportSystem(EmptyImportSystem emptyImportSystem); @Binds - ServerShutdownSave bindNukkitServerShutdownSave(NukkitServerShutdownSave nukkitServerShutdownSave); + ServerShutdownSave bindServerShutdownSave(NukkitServerShutdownSave shutdownSave); + @Binds + ServerSensor bindServerSensor(NukkitSensor sensor); + + @Binds + ServerSensor bindGenericsServerSensor(ServerSensor sensor); } \ No newline at end of file diff --git a/Plan/sponge/src/main/java/com/djrapitops/plan/SpongeTaskSystem.java b/Plan/sponge/src/main/java/com/djrapitops/plan/SpongeTaskSystem.java index 94c510573..4077811cf 100644 --- a/Plan/sponge/src/main/java/com/djrapitops/plan/SpongeTaskSystem.java +++ b/Plan/sponge/src/main/java/com/djrapitops/plan/SpongeTaskSystem.java @@ -19,8 +19,9 @@ package com.djrapitops.plan; import com.djrapitops.plan.delivery.webserver.cache.JSONCache; import com.djrapitops.plan.extension.ExtensionServerMethodCallerTask; import com.djrapitops.plan.gathering.ShutdownHook; +import com.djrapitops.plan.gathering.timed.ServerTPSCounter; import com.djrapitops.plan.gathering.timed.SpongePingCounter; -import com.djrapitops.plan.gathering.timed.SpongeTPSCounter; +import com.djrapitops.plan.gathering.timed.TPSCounter; import com.djrapitops.plan.settings.config.PlanConfig; import com.djrapitops.plan.settings.config.paths.DataGatheringSettings; import com.djrapitops.plan.settings.config.paths.TimeSettings; @@ -31,6 +32,7 @@ import com.djrapitops.plugin.api.TimeAmount; import com.djrapitops.plugin.task.RunnableFactory; import org.spongepowered.api.Sponge; import org.spongepowered.api.scheduler.Task; +import org.spongepowered.api.world.World; import javax.inject.Inject; import javax.inject.Singleton; @@ -42,7 +44,7 @@ public class SpongeTaskSystem extends TaskSystem { private final PlanSponge plugin; private final PlanConfig config; private final ShutdownHook shutdownHook; - private final SpongeTPSCounter tpsCounter; + private final TPSCounter tpsCounter; private final JSONCache.CleanTask jsonCacheCleanTask; private final SpongePingCounter pingCounter; private final LogsFolderCleanTask logsFolderCleanTask; @@ -57,7 +59,7 @@ public class SpongeTaskSystem extends TaskSystem { ShutdownHook shutdownHook, RunnableFactory runnableFactory, - SpongeTPSCounter tpsCounter, + ServerTPSCounter tpsCounter, SpongePingCounter pingCounter, ExtensionServerMethodCallerTask extensionServerMethodCallerTask, diff --git a/Plan/sponge/src/main/java/com/djrapitops/plan/gathering/SpongeSensor.java b/Plan/sponge/src/main/java/com/djrapitops/plan/gathering/SpongeSensor.java new file mode 100644 index 000000000..e8af5f15f --- /dev/null +++ b/Plan/sponge/src/main/java/com/djrapitops/plan/gathering/SpongeSensor.java @@ -0,0 +1,76 @@ +/* + * 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 . + */ +package com.djrapitops.plan.gathering; + +import com.djrapitops.plan.PlanSponge; +import org.spongepowered.api.world.Chunk; +import org.spongepowered.api.world.World; + +import javax.inject.Inject; +import javax.inject.Singleton; +import java.util.Iterator; + +@Singleton +public class SpongeSensor implements ServerSensor { + + private final PlanSponge plugin; + + @Inject + public SpongeSensor(PlanSponge plugin) { + this.plugin = plugin; + } + + @Override + public boolean supportsDirectTPS() { + return true; + } + + @Override + public int getOnlinePlayerCount() { + return plugin.getGame().getServer().getOnlinePlayers().size(); + } + + @Override + public double getTPS() { + return plugin.getGame().getServer().getTicksPerSecond(); + } + + @Override + public Iterable getWorlds() { + return plugin.getGame().getServer().getWorlds(); + } + + @Override + public int getChunkCount(World world) { + return -1; + } + + private int getLaggyChunkCount(World world) { + Iterator chunks = world.getLoadedChunks().iterator(); + int count = 0; + while (chunks.hasNext()) { + chunks.next(); + count++; + } + return count; + } + + @Override + public int getEntityCount(World world) { + return world.getEntities().size(); + } +} \ No newline at end of file diff --git a/Plan/sponge/src/main/java/com/djrapitops/plan/gathering/timed/SpongeTPSCounter.java b/Plan/sponge/src/main/java/com/djrapitops/plan/gathering/timed/SpongeTPSCounter.java deleted file mode 100644 index 1543452f5..000000000 --- a/Plan/sponge/src/main/java/com/djrapitops/plan/gathering/timed/SpongeTPSCounter.java +++ /dev/null @@ -1,121 +0,0 @@ -/* - * 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 . - */ -package com.djrapitops.plan.gathering.timed; - -import com.djrapitops.plan.PlanSponge; -import com.djrapitops.plan.gathering.SystemUsage; -import com.djrapitops.plan.gathering.domain.TPS; -import com.djrapitops.plan.gathering.domain.builders.TPSBuilder; -import com.djrapitops.plan.identification.ServerInfo; -import com.djrapitops.plan.identification.properties.ServerProperties; -import com.djrapitops.plan.storage.database.DBSystem; -import com.djrapitops.plugin.logging.console.PluginLogger; -import com.djrapitops.plugin.logging.error.ErrorHandler; -import org.spongepowered.api.world.World; - -import javax.inject.Inject; -import javax.inject.Singleton; - -@Singleton -public class SpongeTPSCounter extends TPSCounter { - - private long lastCheckNano; - private final PlanSponge plugin; - private ServerProperties serverProperties; - - @Inject - public SpongeTPSCounter( - PlanSponge plugin, - DBSystem dbSystem, - ServerInfo serverInfo, - ServerProperties serverProperties, - PluginLogger logger, - ErrorHandler errorHandler - ) { - super(dbSystem, serverInfo, logger, errorHandler); - this.plugin = plugin; - this.serverProperties = serverProperties; - lastCheckNano = -1; - } - - @Override - public void addNewTPSEntry(long nanoTime, long now) { - long diff = nanoTime - lastCheckNano; - - lastCheckNano = nanoTime; - - if (diff > nanoTime) { // First run's diff = nanoTime + 1, no calc possible. - logger.debug("First run of TPSCountTimer Task."); - return; - } - - history.add(calculateTPS(now)); - } - - /** - * Calculates the TPS - * - * @param now The time right now - * @return the TPS - */ - private TPS calculateTPS(long now) { - double averageCPUUsage = getCPUUsage(); - - long usedMemory = SystemUsage.getUsedMemory(); - - double tps = plugin.getGame().getServer().getTicksPerSecond(); - int playersOnline = serverProperties.getOnlinePlayers(); - latestPlayersOnline = playersOnline; - int loadedChunks = -1; // getLoadedChunks(); - int entityCount = getEntityCount(); - long freeDiskSpace = getFreeDiskSpace(); - - return TPSBuilder.get() - .date(now) - .tps(tps) - .playersOnline(playersOnline) - .usedCPU(averageCPUUsage) - .usedMemory(usedMemory) - .entities(entityCount) - .chunksLoaded(loadedChunks) - .freeDiskSpace(freeDiskSpace) - .toTPS(); - } - - /** - * Gets the amount of loaded chunks - * - * @return amount of loaded chunks - */ - private int getLoadedChunks() { - // DISABLED - int loaded = 0; - for (World world : plugin.getGame().getServer().getWorlds()) { - loaded += world.getLoadedChunks().spliterator().estimateSize(); - } - return loaded; - } - - /** - * Gets the amount of entities on the server - * - * @return amount of entities - */ - private int getEntityCount() { - return plugin.getGame().getServer().getWorlds().stream().mapToInt(world -> world.getEntities().size()).sum(); - } -} diff --git a/Plan/sponge/src/main/java/com/djrapitops/plan/identification/properties/SpongeServerProperties.java b/Plan/sponge/src/main/java/com/djrapitops/plan/identification/properties/SpongeServerProperties.java index ddf393e38..3d71683c8 100644 --- a/Plan/sponge/src/main/java/com/djrapitops/plan/identification/properties/SpongeServerProperties.java +++ b/Plan/sponge/src/main/java/com/djrapitops/plan/identification/properties/SpongeServerProperties.java @@ -36,8 +36,7 @@ public class SpongeServerProperties extends ServerProperties { () -> game.getServer().getBoundAddress() .orElseGet(() -> new InetSocketAddress(25565)) .getAddress().getHostAddress(), - game.getServer().getMaxPlayers(), - () -> game.getServer().getOnlinePlayers().size() + game.getServer().getMaxPlayers() ); } } \ No newline at end of file diff --git a/Plan/sponge/src/main/java/com/djrapitops/plan/modules/sponge/SpongeSuperClassBindingModule.java b/Plan/sponge/src/main/java/com/djrapitops/plan/modules/sponge/SpongeSuperClassBindingModule.java index c7b38f742..c30f79842 100644 --- a/Plan/sponge/src/main/java/com/djrapitops/plan/modules/sponge/SpongeSuperClassBindingModule.java +++ b/Plan/sponge/src/main/java/com/djrapitops/plan/modules/sponge/SpongeSuperClassBindingModule.java @@ -19,7 +19,9 @@ package com.djrapitops.plan.modules.sponge; import com.djrapitops.plan.SpongeServerShutdownSave; import com.djrapitops.plan.SpongeTaskSystem; import com.djrapitops.plan.TaskSystem; +import com.djrapitops.plan.gathering.ServerSensor; import com.djrapitops.plan.gathering.ServerShutdownSave; +import com.djrapitops.plan.gathering.SpongeSensor; import com.djrapitops.plan.gathering.importing.EmptyImportSystem; import com.djrapitops.plan.gathering.importing.ImportSystem; import com.djrapitops.plan.gathering.listeners.ListenerSystem; @@ -34,9 +36,10 @@ import com.djrapitops.plan.storage.file.PlanFiles; import com.djrapitops.plan.storage.file.SpongePlanFiles; import dagger.Binds; import dagger.Module; +import org.spongepowered.api.world.World; /** - * Module for binding Sponge specific classes to the interface implementations. + * Module for binding Sponge specific classes as interface implementations. * * @author Rsl1122 */ @@ -44,27 +47,32 @@ import dagger.Module; public interface SpongeSuperClassBindingModule { @Binds - PlanFiles bindSpongePlanFiles(SpongePlanFiles files); + PlanFiles bindPlanFiles(SpongePlanFiles files); @Binds - ServerInfo bindSpongeServerInfo(ServerServerInfo serverServerInfo); + ServerInfo bindServerInfo(ServerServerInfo serverInfo); @Binds - DBSystem bindSpongeDatabaseSystem(SpongeDBSystem dbSystem); + DBSystem bindDBSystem(SpongeDBSystem dbSystem); @Binds - ConfigSystem bindSpongeConfigSystem(SpongeConfigSystem spongeConfigSystem); + ConfigSystem bindConfigSystem(SpongeConfigSystem configSystem); @Binds - TaskSystem bindSpongeTaskSystem(SpongeTaskSystem spongeTaskSystem); + TaskSystem bindTaskSystem(SpongeTaskSystem taskSystem); @Binds - ListenerSystem bindSpongeListenerSystem(SpongeListenerSystem spongeListenerSystem); + ListenerSystem bindListenerSystem(SpongeListenerSystem listenerSystem); @Binds ImportSystem bindImportSystem(EmptyImportSystem emptyImportSystem); @Binds - ServerShutdownSave bindSpongeServerShutdownSave(SpongeServerShutdownSave spongeServerShutdownSave); + ServerShutdownSave bindServerShutdownSave(SpongeServerShutdownSave shutdownSave); + @Binds + ServerSensor bindServerSensor(SpongeSensor sensor); + + @Binds + ServerSensor bindGenericsServerSensor(ServerSensor sensor); } \ No newline at end of file diff --git a/Plan/velocity/src/main/java/com/djrapitops/plan/VelocityTaskSystem.java b/Plan/velocity/src/main/java/com/djrapitops/plan/VelocityTaskSystem.java index de208eb98..42a961f90 100644 --- a/Plan/velocity/src/main/java/com/djrapitops/plan/VelocityTaskSystem.java +++ b/Plan/velocity/src/main/java/com/djrapitops/plan/VelocityTaskSystem.java @@ -18,8 +18,9 @@ package com.djrapitops.plan; import com.djrapitops.plan.delivery.webserver.cache.JSONCache; import com.djrapitops.plan.extension.ExtensionServerMethodCallerTask; +import com.djrapitops.plan.gathering.timed.ProxyTPSCounter; +import com.djrapitops.plan.gathering.timed.TPSCounter; import com.djrapitops.plan.gathering.timed.VelocityPingCounter; -import com.djrapitops.plan.gathering.timed.VelocityTPSCounter; import com.djrapitops.plan.settings.config.PlanConfig; import com.djrapitops.plan.settings.config.paths.DataGatheringSettings; import com.djrapitops.plan.settings.config.paths.TimeSettings; @@ -43,7 +44,7 @@ public class VelocityTaskSystem extends TaskSystem { private final PlanVelocity plugin; private final PlanConfig config; - private final VelocityTPSCounter tpsCounter; + private final TPSCounter tpsCounter; private final VelocityPingCounter pingCounter; private final LogsFolderCleanTask logsFolderCleanTask; private final NetworkConfigStoreTask networkConfigStoreTask; @@ -56,7 +57,7 @@ public class VelocityTaskSystem extends TaskSystem { PlanVelocity plugin, PlanConfig config, RunnableFactory runnableFactory, - VelocityTPSCounter tpsCounter, + ProxyTPSCounter tpsCounter, VelocityPingCounter pingCounter, LogsFolderCleanTask logsFolderCleanTask, NetworkConfigStoreTask networkConfigStoreTask, diff --git a/Plan/velocity/src/main/java/com/djrapitops/plan/gathering/VelocitySensor.java b/Plan/velocity/src/main/java/com/djrapitops/plan/gathering/VelocitySensor.java new file mode 100644 index 000000000..ca22e95d4 --- /dev/null +++ b/Plan/velocity/src/main/java/com/djrapitops/plan/gathering/VelocitySensor.java @@ -0,0 +1,44 @@ +/* + * 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 . + */ +package com.djrapitops.plan.gathering; + +import com.djrapitops.plan.PlanVelocity; + +import javax.inject.Inject; +import javax.inject.Singleton; +import java.util.function.IntSupplier; + +@Singleton +public class VelocitySensor implements ServerSensor { + + private final IntSupplier onlinePlayerCountSupplier; + + @Inject + public VelocitySensor(PlanVelocity plugin) { + onlinePlayerCountSupplier = plugin.getProxy()::getPlayerCount; + } + + @Override + public boolean supportsDirectTPS() { + return false; + } + + @Override + public int getOnlinePlayerCount() { + return onlinePlayerCountSupplier.getAsInt(); + } +} diff --git a/Plan/velocity/src/main/java/com/djrapitops/plan/gathering/timed/VelocityTPSCounter.java b/Plan/velocity/src/main/java/com/djrapitops/plan/gathering/timed/VelocityTPSCounter.java deleted file mode 100644 index d8ece9cf2..000000000 --- a/Plan/velocity/src/main/java/com/djrapitops/plan/gathering/timed/VelocityTPSCounter.java +++ /dev/null @@ -1,64 +0,0 @@ -/* - * 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 . - */ -package com.djrapitops.plan.gathering.timed; - -import com.djrapitops.plan.gathering.SystemUsage; -import com.djrapitops.plan.gathering.domain.TPS; -import com.djrapitops.plan.gathering.domain.builders.TPSBuilder; -import com.djrapitops.plan.identification.ServerInfo; -import com.djrapitops.plan.identification.properties.ServerProperties; -import com.djrapitops.plan.storage.database.DBSystem; -import com.djrapitops.plugin.logging.console.PluginLogger; -import com.djrapitops.plugin.logging.error.ErrorHandler; - -import javax.inject.Inject; -import javax.inject.Singleton; - -@Singleton -public class VelocityTPSCounter extends TPSCounter { - - private final ServerProperties serverProperties; - - @Inject - public VelocityTPSCounter( - DBSystem dbSystem, - ServerInfo serverInfo, - ServerProperties serverProperties, - PluginLogger logger, - ErrorHandler errorHandler - ) { - super(dbSystem, serverInfo, logger, errorHandler); - this.serverProperties = serverProperties; - } - - @Override - public void addNewTPSEntry(long nanoTime, long now) { - int onlineCount = serverProperties.getOnlinePlayers(); - TPS tps = TPSBuilder.get() - .date(now) - .playersOnline(onlineCount) - .usedCPU(getCPUUsage()) - .usedMemory(SystemUsage.getUsedMemory()) - .entities(-1) - .chunksLoaded(-1) - .freeDiskSpace(getFreeDiskSpace()) - .toTPS(); - - history.add(tps); - latestPlayersOnline = onlineCount; - } -} diff --git a/Plan/velocity/src/main/java/com/djrapitops/plan/identification/properties/VelocityServerProperties.java b/Plan/velocity/src/main/java/com/djrapitops/plan/identification/properties/VelocityServerProperties.java index aba5297be..b764e502c 100644 --- a/Plan/velocity/src/main/java/com/djrapitops/plan/identification/properties/VelocityServerProperties.java +++ b/Plan/velocity/src/main/java/com/djrapitops/plan/identification/properties/VelocityServerProperties.java @@ -36,8 +36,7 @@ public class VelocityServerProperties extends ServerProperties { server.getClass().getPackage().getImplementationVersion(), server.getClass().getPackage().getImplementationVersion(), () -> config.get(ProxySettings.IP), - -1, - server::getPlayerCount + -1 ); } } \ No newline at end of file diff --git a/Plan/velocity/src/main/java/com/djrapitops/plan/modules/velocity/VelocitySuperClassBindingModule.java b/Plan/velocity/src/main/java/com/djrapitops/plan/modules/velocity/VelocitySuperClassBindingModule.java index d7c8cebc1..31d8d5dad 100644 --- a/Plan/velocity/src/main/java/com/djrapitops/plan/modules/velocity/VelocitySuperClassBindingModule.java +++ b/Plan/velocity/src/main/java/com/djrapitops/plan/modules/velocity/VelocitySuperClassBindingModule.java @@ -18,6 +18,8 @@ package com.djrapitops.plan.modules.velocity; import com.djrapitops.plan.TaskSystem; import com.djrapitops.plan.VelocityTaskSystem; +import com.djrapitops.plan.gathering.ServerSensor; +import com.djrapitops.plan.gathering.VelocitySensor; import com.djrapitops.plan.gathering.listeners.ListenerSystem; import com.djrapitops.plan.gathering.listeners.VelocityListenerSystem; import com.djrapitops.plan.identification.ServerInfo; @@ -26,7 +28,7 @@ import dagger.Binds; import dagger.Module; /** - * Module for binding Velocity specific classes to the interface implementations. + * Module for binding Velocity specific classes as interface implementations. * * @author Rsl1122 */ @@ -34,11 +36,14 @@ import dagger.Module; public interface VelocitySuperClassBindingModule { @Binds - ServerInfo provideVelocityServerInfo(VelocityServerInfo velocityServerInfo); + ServerInfo bindServerInfo(VelocityServerInfo serverInfo); @Binds - TaskSystem provideVelocityTaskSystem(VelocityTaskSystem velocityTaskSystem); + TaskSystem bindTaskSystem(VelocityTaskSystem taskSystem); @Binds - ListenerSystem provideVelocityListenerSystem(VelocityListenerSystem velocityListenerSystem); + ListenerSystem bindListenerSystem(VelocityListenerSystem listenerSystem); + + @Binds + ServerSensor bindServerSensor(VelocitySensor sensor); } \ No newline at end of file